C- Précision en virgule flottante

J’ai un programme:

int main() { float f = 0.0f; int i; for (i = 0 ; i < 10 ; i++) f = f + 0.1f; if (f == 1.0f) printf("f is 1.0 \n"); else printf("f is NOT 1.0\n"); return 0; } 

Il imprime toujours f is NOT 1.0 . Je comprends que cela est lié à la précision de la virgule flottante en C. Mais je ne sais pas exactement où cela va être gâché. Quelqu’un peut-il m’expliquer s’il vous plaît pourquoi il n’imprime pas l’autre ligne?

La virgule flottante binary ne peut pas représenter exactement la valeur 0.1, car son développement binary n’a pas un nombre fini de chiffres (exactement de la même manière que le développement décimal de 1/7).

L’expansion binary de 0.1 est

 0.000110011001100110011001100... 

Lorsque tronqué à la précision simple IEEE-754, il correspond à environ 0.100000001490116119 en décimal. Cela signifie que chaque fois que vous ajoutez la valeur “presque 0,1” à votre variable, vous accumulez une petite erreur. La valeur finale est donc légèrement supérieure à 1.0 .

Vous ne pouvez pas comparer des flotteurs comme celui-ci. Vous devez définir un seuil et comparer sur cette base. Ce blog explique

Cela équivaut à append 0,33 fois 3 fois (0,99) et à se demander pourquoi il n’est pas égal à 1,0.

Vous voudrez peut-être lire Ce que tout programmeur devrait savoir sur l’arithmétique en virgule flottante

Pour les nombres en virgule flottante, vous devez toujours utiliser une valeur epsilon lorsque vous les comparez:

 #define EPSILON 0.00001f inline int floatsEqual(float f1, float f2) { return fabs(f1 - f2) < EPSILON; // or fabsf }