Une sortie étrange lorsque l’on compare les mêmes valeurs flottantes?

Comparer les mêmes valeurs flottantes en C

sortie étrange en comparaison de float avec float littéral

Ajout de flotteurs promu au double?


J’ai lu les liens ci-dessus sur les points flottants, mais j’ai même des résultats étranges.

#include int main() { float x = 0.5; if (x == 0.5) printf("IF"); else if (x == 0.5f) printf("ELSE IF"); else printf("ELSE"); } 

Maintenant, selon les règles de la promotion, ” ELSE IF ” ne doit-il pas être imprimé?

Mais, ici, il affiche ” IF


EDIT: Est-ce parce que 0,5 = 0,1 en binary et que tout est 0 ensuite et que la perte de précision est donc nulle, la comparaison IF renvoie true.

Si cela avait été 0,1, 0,2, 0,3, 0,4, 0,6, 0,7 …, puis Else Si le bloc retourne vrai.


Pardonnez-moi de poser la même question, car j’ai lu dans les liens ci-dessus que la comparaison flottante ne doit jamais être faite.

Mais, quelle est la raison de ce comportement inattendu?

Les nombres à virgule flottante ne sont jamais précis.

Cette déclaration est fausse. Certains nombres en virgule flottante sont exacts, tels que 1.0, 12345.0, 12345.5, -2.25. Tous ces nombres peuvent être représentés sous forme d’entiers générés par une puissance de 2. Tous les nombres qui ne peuvent pas non plus ne sont pas exacts.

Dans votre cas spécifique, float x = 0.5 résultat x ayant la valeur 1.00000000 * 2^-1 . Lorsque vous comparez cela au double 0.5 , les deux opérandes sont convertis en double . La comparaison devient donc 1.000000000000000 * 2^-1 == 1.000000000000000 * 2^-1 , ce qui aboutit.

Pour float x = 0.1 , le résultat est différent. La valeur est stockée sous la forme 1.01010101 * 2^-3 (ou similaire). Notez que ce n’est déjà pas précis. Lorsque vous comparez cette valeur à la double 0.1 , le flottant est étendu avec des zéros à la fin, la comparaison devient 1.010101010000000 * 2^-3 == 1.010101010101010 * 2^-3 , ce qui échoue.

Comme vous avez lu les liens concernant les problèmes liés aux types à virgule flottante et aux comparaisons, vous vous attendez probablement à ce que 0,5 soit arrondi lors de la conversion et que, par conséquent, la comparaison échoue. Mais 0.5 est une puissance de 2 et peut être parfaitement représenté sans arrondi dans une variable de type float ou double. Par conséquent, la comparaison aboutit à VRAI.

Après avoir modifié votre question: Oui, si vous avez pris 0.1 ou l’une des autres valeurs que vous mentionnez, vous devriez courir dans la partie else.

La première instruction if est évaluée à true , si IF est imprimé. Les autres expressions ne sont même pas vérifiées.