C'est quelque chose qui m'a mordu aussi.
Oui, les nombres à virgule flottante ne devraient jamais être comparés pour l'égalité en raison d'une erreur d'arrondi, et vous le saviez probablement.
Mais dans ce cas, vous calculez t1+t2
, puis vous le calculez à nouveau. Sûrement qui doit produire un résultat identique?
Voici ce qui se passe probablement. Je parie que vous exécutez ceci sur un processeur x86, correct? La FPU x86 utilise 80 bits pour ses registres internes, mais les valeurs en mémoire sont stockées en tant que doubles de 64 bits.
Donc, t1+t2
est d'abord calculé avec 80 bits de précision, puis - je présume - stocké dans la mémoire en sum_2
avec 64 bits de précision - et certains arrondis se produit. Pour l'assert, il est chargé dans un registre à virgule flottante, et t1+t2
est de nouveau calculé, toujours avec 80 bits de précision. Donc maintenant vous comparez sum_2
, qui était auparavant arrondi à une valeur à virgule flottante de 64 bits, avec t1+t2
, qui a été calculé avec une précision plus élevée (80 bits) - et c'est pourquoi les valeurs ne sont pas exactement identiques.
Modifier Alors, pourquoi le premier test est-il réussi? Dans ce cas, le compilateur évalue probablement 4.0+6.3
au moment de la compilation et le stocke comme une quantité de 64 bits - à la fois pour l'affectation et pour l'affirmation.Des valeurs identiques sont donc comparées, et l'affirmation passe.
Second Edition Voici le code assembleur généré pour la deuxième partie du code (gcc, x86), avec des commentaires - à peu près suit le scénario décrit ci-dessus:
// t1 = 4.0
fldl LC3
fstpl -16(%ebp)
// t2 = 6.3
fldl LC4
fstpl -24(%ebp)
// sum_2 = t1+t2
fldl -16(%ebp)
faddl -24(%ebp)
fstpl -32(%ebp)
// Compute t1+t2 again
fldl -16(%ebp)
faddl -24(%ebp)
// Load sum_2 from memory and compare
fldl -32(%ebp)
fxch %st(1)
fucompp
note intéressante: Cette a été compilé sans optimisation. Lorsqu'il est compilé avec -O3
, le compilateur optimise tous les du code.
Vous pouvez également consulter: - [http://stackoverflow.com/questions/21265/comparing-ieee-floats-and-doubles-for-equality](http://stackoverflow.com/questions/21265/ comparaison-ieee-floats-et-doubles-for-égalité) - [http://stackoverflow.com/questions/17333/most-effective-way-for-float-and-double-comparison](http://stackoverflow .com/questions/17333/le plus efficace-pour-float-et-double-comparaison) - [http://stackoverflow.com/questions/713763/strange-results-with-floating-point-comparison] (http://stackoverflow.com/questions/713763/strange-results-with-floating-point-comparison) – pingw33n