Pourquoi les nombres en virgule flottante ne peuvent-ils pas être comparés?

Dupliquer possible:
sortie étrange dans la comparaison entre float et float littéral

#include int main() { float me = 1.7; if(me==1.7) printf("C"); else printf("C++"); } Output: C++ 

Maintenant, la raison de ce comportement est que beaucoup de nombres en virgule flottante ne peuvent pas être représentés avec une précision absolue en binary.

Ma question est la suivante: si l’ordinateur pense et manipule en binary. Toute incertitude dans la représentation de me serait la même pour 1.7 en comparaison. Donc, les deux devraient être égaux.

Aussi comment typecasting résout ce problème? (float)1.7

Vous comparez un float à un double. le littéral 1.7 est un double.

Vous l’avez stocké dans un float, qui peut avoir moins de précision qu’un double, ainsi le me == 1.7 compare 1.7 en tant que float (promu à un double) à 1.7 en tant que double.

Dans ce cas, me == 1.7f devrait les comparer, ou me == 1.7f par un double double me = 1.7;

Dans le cas général cependant, vous voudriez que l’égalité soit comparée en utilisant un epsilon comme le montre @duffymo.

Aussi, lecture obligatoire .

Ce que tout informaticien devrait savoir sur l’arithmétique en virgule flottante

La représentation la plus proche de 1.7 est différente pour float et double, aussi le fait de lancer un float devrait normalement donner le même nombre.

L’une des principales raisons pour lesquelles vous ne pouvez pas comparer les nombres en virgule flottante est que les identités qui fonctionnent pour les nombres réels et les nombres entiers ne fonctionnent pas nécessairement pour les nombres en virgule flottante en raison de l’arrondissement – ie (x + y) + z et x + (y + z) peut souvent être différent (notez que les écrire de cette façon ne changera souvent pas le comportement du compilateur, mais vous pouvez induire l’ordre en faisant quelque chose que le compilateur n’optimisera pas).

Par exemple, (100 – (100 – .0000000001))! = .00000000001 utilisant des doublons IEEE-754, même si mathématiquement dit qu’ils devraient être égaux. Donc, le calcul qui devrait produire .00000000001 sera légèrement en retrait. Ceci est particulièrement problématique avec des calculs plus compliqués, tels que l’algèbre linéaire, où la réponse peut être le résultat de milliers d’additions et de soustractions, chacune pouvant append à l’erreur d’arrondi en virgule flottante.

La virgule flottante IEEE-754 peut être très délicate si vous ne comprenez pas vraiment ce qui se passe.

Je recommande l’excellent “Ce que tous les informaticiens devraient savoir sur l’arithmétique en virgule flottante”: http://docs.sun.com/source/806-3568/ncg_goldberg.html

En supposant une représentation IEEE-754, les littéraux 1.7f et 1.7 correspondent aux valeurs suivantes:

 1.7f == 1.7000000476837158203125 1.7 == 1.6999999999999999555910790149937383830547332763671875 

Clairement, ce ne sont pas la même valeur, et ils se comparent donc à faux.

me flotte = 1.7f;

C’est un problème de représentation concernant numerical analysis , puisque vous avez un nombre limité de bits pour représenter le nombre, ce qui est représenté n’est pas exactement égal au nombre que vous vouliez dire, c’est juste une approximation proche du nombre le plus proche pouvant être représenté avec le bit que vous voulez. avoir. Prenez une lecture ici

Le 1.7 est automatiquement converti en double dans la comparaison. Vous comparez donc 1,7 à 1,7d, ce qui diffère probablement de certains (doubles) epsilons de machines.