J'ai eu un petit moment WTF ce matin. WTF Thessaloniciens peut se résumer avec ceci:L'ajout de flotteur promu à doubler?
float x = 0.2f;
float y = 0.1f;
float z = x + y;
assert(z == x + y); //This assert is triggered! (Atleast with visual studio 2008)
La raison semble être que l'expression x + y
est promu deux fois et comparée à la version tronquée en z
. (Si je change z
en double
l'assertion n'est pas déclenchée).
Je peux voir que pour des raisons de précision, il serait logique d'effectuer toutes les opérations arithmétiques en virgule flottante en double précision avant de convertir le résultat en simple précision. J'ai trouvé le paragraphe suivant dans la norme (que je suppose que je savais déjà, mais pas dans ce contexte):
4.6.1. « Un rvalue de type float
peut être converti en un rvalue de type double
. La valeur est inchangée »
Ma question est, est x + y
garanti d'être promu doubler ou est à la discrétion du compilateur?
MISE À JOUR: Comme beaucoup de gens a affirmé que l'on devrait pas utiliser ==
pour virgule flottante, je voulais juste dire que dans le cas particulier, je travaille avec une comparaison exacte est justifiée.
La comparaison de point flottant est difficile, voici un intéressant link sur le sujet qui je pense n'a pas été mentionné.
Vous pouvez également essayer "juste pour le plaisir de celui-ci" pour forcer les calculs de précision simples sur FPU par appeler: _controlfp (_PC_24, MCW_PC); – MaR