Ce ne sera pas vrai si x
es NaN
puisque les comparaisons sur NaN
sont toujours faux (oui, même NaN == NaN
). Pour tous les autres cas (valeurs normales, valeurs subnormales, infinis, zéros) cette assertion sera vraie.
Les conseils pour éviter ==
pour les flottants s'applique à calculs en raison de l'incapacité des nombres à virgule flottante à exprimer exactement de nombreux résultats lorsqu'ils sont utilisés dans des expressions arithmétiques. L'affectation n'est pas un calcul et il n'y a aucune raison pour que l'affectation donne une valeur différente de l'original.
L'évaluation à précision étendue ne devrait pas poser de problème si la norme est respectée. À partir de <cfloat>
hérité de C [5.2.4.2.2.8] ( c'est moi qui souligne ):
À l'exception de l'assignation et du cast (qui suppriment toute portée et précision supplémentaires). les valeurs des opérations avec des opérandes flottants et des valeurs soumises aux conversions arithmétiques habituelles et des constantes flottantes sont évaluées dans un format dont la plage et la précision peuvent être supérieures à celles requises par le type.
Cependant, comme les commentaires l'ont souligné, certains compilateurs, options de compilation et cibles peuvent être utilisés. pourrait rendent cette affirmation paradoxalement fausse.
78 votes
Permettez-moi d'offrir une prime de 50 euros à celui qui prouvera réellement l'inégalité par une démonstration avec du code réel. Je veux voir le truc 80 vs 64 bits en action. Plus 50 autres pour une explication du code assembleur généré qui montre qu'une variable est dans un registre et que l'autre ne l'est pas (ou quelle que soit la raison de l'inégalité, j'aimerais que ce soit expliqué à un bas niveau).
1 votes
@ThomasWeller le bug de GCC à ce sujet : gcc.gnu.org/bugzilla/show_bug.cgi?id=323 Cependant, je viens d'essayer de le reproduire sur un système x86-64 et ça ne marche pas, même avec -ffast-math. Je soupçonne que vous avez besoin d'un vieux GCC sur un système 32 bits.
5 votes
@pjc50 : En fait, vous avez besoin d'un système 80 bits pour reproduire le bug 323 ; c'est la FPU 80x87 qui a causé le problème. x86-64 utilise la FPU SSE. Les bits supplémentaires causent le problème, car ils sont arrondis lors du déversement d'une valeur dans un flottant 32 bits.
4 votes
Si la théorie de MSalters est correcte (et je la soupçonne de l'être), alors vous pouvez reproduire soit en compilant pour 32 bits (
-m32
), ou en demandant à GCC d'utiliser la FPU x87 (-mfpmath=387
).0 votes
Il y a le problème que, sur un matériel mythique, la valeur flottante pourrait être convertie de 32 bits en stockage à 48 bits dans un registre, puis revenir à 32 lors du stockage. Cela peut entraîner une très légère modification de la valeur binaire, surtout si cette opération permet de "normaliser" une valeur qui ne l'était pas initialement.
4 votes
Remplacez "48 bits" par "80 bits", et vous pourrez alors supprimer l'adjectif "mythique", @Hot. C'est précisément ce dont il était question juste avant votre commentaire. Le x87 (FPU pour l'architecture x86) utilise des registres de 80 bits, un format de "précision étendue".
0 votes
@CodyGray : Une mise en œuvre ciblant par exemple un ARM 32 bits pourrait bénéficier de l'exécution de
float
les calculs utilisant un "float étendu" de 64 bits avec un signe+exposant de 32 bits et un significand de 32 bits. Les valeurs de typefloat
devront être converties dans un tel format lorsqu'on effectue des calculs sur elles, et si l'on donne une expression commea+b+c
, en gardanta+b
dans un format non nécessairement normalisé sans le normaliser avant de l'ajouterc
serait plus rapide que de reconvertir le résultat intermédiaire enfloat
.