Udostępnij za pośrednictwem


Dlaczego liczby zmiennoprzecinkowe mogą tracić dokładność

Zwykle zmiennoprzecinkowych wartości dziesiętne nie mają dokładne reprezentacja binarna.Jest to efekt uboczny jak CPU reprezentuje ruchomy punkt danych.Z tego powodu mogą wystąpić utratę precyzji, a niektóre operacje zmiennoprzecinkowe może powodować nieoczekiwane rezultaty.

Takie zachowanie wynika z jedną z następujących czynności:

  • Liczba dziesiętna reprezentacja binarna nie może być dokładne.

  • Istnieje niezgodność typów między numerami używanymi (np. mieszanie pływaka i podwójne).

Aby rozwiązać problem, większość programistów, który albo zapewnienia, że wartość jest większa lub mniejsza niż to, co jest potrzebne, lub pobrać i używać biblioteki Binary Coded Decimal (BCD), która zachowa dokładność.

Reprezentacja binarna wartości zmiennoprzecinkowych ma wpływ na dokładność obliczeń zmiennoprzecinkowych.Microsoft Visual C++ korzysta z format liczb zmiennoprzecinkowych IEEE.

Przykład

// Floating-point_number_precision.c
// Compile options needed: none. Value of c is printed with a decimal 
// point precision of 10 and 6 (printf rounded value by default) to 
// show the difference
#include <stdio.h>

#define EPSILON 0.0001   // Define your own tolerance
#define FLOAT_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))

int main() {
   float a, b, c;

   a = 1.345f;
   b = 1.123f;
   c = a + b;
   // if (FLOAT_EQ(c, 2.468)) // Remove comment for correct result
   if (c == 2.468)            // Comment this line for correct result
      printf_s("They are equal.\n");
   else
      printf_s("They are not equal! The value of c is %13.10f "
                "or %f",c,c);
}
     

Komentarze

Dla EPSILON, można używać stałych FLT_EPSILON, który jest zdefiniowany dla float jako 1.192092896e-07F, lub DBL_EPSILON, który jest zdefiniowany dla podwójne jako 2.2204460492503131e-016.Konieczne jest uwzględnienie float.h dla tych stałych.Te stałe są zdefiniowane jako najmniejsza liczba dodatnia x, że x + 1.0 nie jest równy 1.0.Ponieważ jest to bardzo małą liczbą, powinny zostać zdefiniowane przez użytkownika tolerancji dla obliczeń wymagających bardzo dużej liczby.

Zobacz też

Koncepcje

Optymalizacja kodu