Freigeben über


Warum Gleitkommazahlen an Genauigkeit verlieren können

Dezimale Gleitkommawerte können im Allgemeinen binär nicht exakt dargestellt werden.Das ist ein Nebeneffekt der Darstellungsweise von Gleitkommazahlen durch die CPU.Aus diesem Grund könnte ein gewisser Genauigkeitsverlust auftreten, und manche Gleitkommaoperationen können unerwartete Ergebnisse hervorbringen.

Dieses Verhalten kann auf die folgenden Umstände zurückgeführt werden:

  • Die Binärdarstellung der Dezimalzahl ist möglicherweise nicht genau.

  • Es gibt einen Typenkonflikt zwischen den verwendeten Zahlen (z. B., wenn float und double gemischt werden).

Um das Verhalten zu korrigieren, stellen die meisten Programmierer entweder sicher, dass der Wert größer oder kleiner als benötigt ist, oder sie verwenden eine BCD (Binary Coded Decimal)-Bibliothek, durch die Genauigkeit gewährleistet wird.

Die binäre Darstellung von Gleitkommawerten beeinflusst die Genauigkeit und Exaktheit von Gleitkommaberechnungen.Microsoft Visual C++ verwendet das IEEE-Gleitkommaformat.

Beispiel

// 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);
}
  
  

Kommentare

Für EPSILON können Sie die FLT_EPSILON-Konstante verwenden, die für float mit 1.192092896e-07F definiert ist, oder die DBL_EPSILON-Konstante, die für double mit 2.2204460492503131e-016 definiert ist.Sie müssen float.h für diese Konstanten einschließen.Die Konstanten werden als die kleinste positive Zahl x definiert, bei der x+1,0 nicht gleich 1,0 ist.Da dies eine sehr kleine Zahl ist, ist es ratsam, eine benutzerdefinierte Toleranz für Berechnungen mit sehr großen Zahlen anzuwenden.

Siehe auch

Konzepte

Codeoptimierung