Delen via


Waarom Floating-Point getallen mogelijk precisie verliezen

Decimale waarden voor drijvende komma hebben over het algemeen geen exacte binaire weergave. Dit is een neveneffect van hoe de CPU drijvendekommagegevens vertegenwoordigt. Daarom kan er sprake zijn van verlies van precisie en kunnen sommige zwevendekommabewerkingen onverwachte resultaten opleveren.

Dit gedrag is het resultaat van een van de volgende:

  • De binaire weergave van het decimale getal is mogelijk niet exact.

  • Er is een typeongelijkheid tussen de gebruikte getallen (bijvoorbeeld het door elkaar gebruiken van float en double).

Om het gedrag op te lossen, zorgen de meeste programmeurs ervoor dat de waarde groter of kleiner is dan nodig is, of dat ze een BCD-bibliotheek (Binary Coded Decimal) krijgen en gebruiken die de precisie behoudt.

Binaire weergave van drijvende kommawaarden is van invloed op de precisie en nauwkeurigheid van berekeningen met drijvende kommawaarden. Microsoft C++ maakt gebruik van de IEEE-indeling voor drijvende komma.

Voorbeeld

// 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);
}
They are not equal! The value of c is  2.4679999352 or 2.468000

Opmerkingen

Voor EPSILON kunt u de constanten FLT_EPSILON gebruiken, die is gedefinieerd voor float als 1,192092896e-07F of DBL_EPSILON, die is gedefinieerd voor double as 2,2204460492503131e-016. U moet float.h voor deze constanten opnemen. Deze constanten worden gedefinieerd als het kleinste positieve getal x, zodat x+1,0 niet gelijk is aan 1,0. Omdat dit een zeer klein aantal is, moet u door de gebruiker gedefinieerde tolerantie gebruiken voor berekeningen met zeer grote aantallen.

Zie ook

Uw code optimaliseren