Puzzle de comparaison à virgule flottante
Considérez le code C suivant :
int main() { float a = 0.7; float b = 0.5; if (a < 0.7) { if (b < 0.5) printf("2 are right"); else printf("1 is right"); } else printf("0 are right"); }
Vous vous attendriez intuitivement à ce que la sortie être "0 ont raison." Cependant, le résultat surprenant est « 1 a raison ». Pourquoi cela se produit-il ?
Les pièges de la comparaison à virgule flottante
La clé réside dans les différences entre les nombres à virgule flottante et les nombres à double précision en C. Dans le code, les variables a et b sont déclarées sous forme de flottants, qui sont des nombres à virgule flottante de 32 bits. Cependant, les deux comparaisons (a < 0,7 et b < 0,5) impliquent des doubles, car les littéraux 0,7 et 0,5 sont traités comme des doubles.
Pendant la comparaison, les variables flottantes sont promues en doubles, permettant un portée et précision plus élevées. Cependant, cette conversion peut introduire des artefacts subtils en raison de la précision limitée des flotteurs. Dans ce cas, 0,7 en tant que flottant n'est pas exactement équivalent à 0,7 en tant que double.
Plus précisément, 0,7 en tant que flottant est représenté par 0x3f000000 dans la norme IEEE 754. Lorsqu’elle est promue au niveau double, cette valeur n’est pas une représentation exacte de 0,7. Au lieu de cela, il devient légèrement supérieur, autour de 0x3f00000000000000 (environ 0,7000000000000001).
La cause du résultat inattendu
À la suite de cette promotion, la condition a < 0,7 devient vrai parce que la double représentation de a est légèrement inférieure à 0,7. Par la suite, la deuxième comparaison b < 0,5 est évalué comme faux car b (représenté exactement par un double) est égal à 0,5. Ainsi, le code affiche "1 est correct."
Solutions
Pour résoudre ce problème, vous pouvez soit :
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!