Pourquoi les nombres à virgule flottante peuvent manquer de précision

Les valeurs décimales à virgule flottante n’ont généralement pas de représentation binaire exacte. Il s’agit d’un effet secondaire de la façon dont le processeur représente les données à virgule flottante. Pour cette raison, vous pouvez rencontrer une perte de précision, et certaines opérations à virgule flottante peuvent produire des résultats inattendus.

Ce comportement est le résultat de l’une des opérations suivantes :

  • La représentation binaire du nombre décimal peut ne pas être exacte.

  • Il existe une incompatibilité de type entre les nombres utilisés (par exemple, mélange de float et de double).

Pour résoudre le comportement, la plupart des programmeurs s’assurent que la valeur est supérieure ou inférieure à ce qui est nécessaire, ou qu’elles obtiennent et utilisent une bibliothèque de décimales codées binaires (BCD) qui maintient la précision.

La représentation binaire des valeurs à virgule flottante affecte la précision et la précision des calculs à virgule flottante. Microsoft Visual C++ utilise le format à virgule flottante IEEE.

Exemple

// 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

Commentaires

Pour EPSILON, vous pouvez utiliser les constantes FLT_EPSILON, qui est définie pour float comme 1.192092896e-07F, ou DBL_EPSILON, qui est définie pour double comme 2.2204460492503131e-016. Vous devez inclure float.h pour ces constantes. Ces constantes sont définies comme le plus petit nombre positif x, de sorte que x+1.0 n’est pas égal à 1,0. Étant donné qu’il s’agit d’un très petit nombre, vous devez utiliser la tolérance définie par l’utilisateur pour les calculs impliquant de très grands nombres.

Voir aussi

Optimisation du code