Je suis tombé sur l'exemple suivant sur Wikipedia ( http://fr.wikipedia.org/wiki / Type_conversion # implicit_type_conversion ). Leur explication: "Ce comportement impair est causé par une coute implicite d'i_value à flotter lorsqu'elle est comparée à F_Value; un casting qui perd une précision , rendre les valeurs comparées différentes. " P> n'est-ce pas faux? Si i_Value était lancé pour flotter, les deux auraient la même perte de précision et ils seraient égaux.
Donc i_value doit être coulé au double. P> p>
3 Réponses :
Je crois que la plus grande valeur entière d'un point flottant IEEE 32 bits peut contenir est 1048576, ce qui est inférieur au nombre ci-dessus. Donc, il est définitivement vrai que la valeur ponctuelle flottante ne tiendra pas exactement 16777217. P>
La pièce, je ne suis pas sûr de savoir comment le compilateur fait la comparaison entre deux types de nombres différents (c'est-à-dire un flotteur et un int). Je peux penser à trois manières différentes que cela pourrait être fait: p>
1) Convertissez les deux valeurs en "float" (cela doit apporter les valeurs identiques, ce n'est probablement pas ce que le compilateur fait) P>
2) Convertissez les deux valeurs en "INT" (ceci peut ou ne peut pas leur montrer la même chose ... la conversion à un intors tronque souvent, de sorte que la valeur du point flottant est 16777216.99999, puis la conversion de "INT" tronquerait ) p>
3) Convertissez les deux valeurs en «Double». Je suppose que c'est ce que le compilateur ferait. Si c'est ce que fait le compilateur, les deux valeurs seraient définitivement différentes. Un double peut tenir 16777217 exactement, et cela pourrait également représenter exactement la valeur du point flottant que 16777217.0 se convertit (ce qui n'est pas exactement 16777217.0). P>
Non, dans le cas de l'exploitant d'égalité, les "conversions arithmétiques habituelles" em> se produisent, qui commencent: p>
Ce dernier cas s'applique ici: La raison pour laquelle vous pouvez voir un résultat étrange de la comparaison, malgré em> cela, c'est à cause de cette mise en garde aux conversions arithmétiques habituelles: P>
Les valeurs des opérandes flottantes et des résultats de flottants
Les expressions peuvent être représentées en plus de précision et de gamme que
cela requis par le type; Les types ne sont pas modifiés ainsi. P>
blockQuote>
C'est ce qui se passe: le type du type converti Si votre compilateur est code> GCC code>, vous pouvez désactiver cette précision supplémentaire en donnant à l'option
double code>, l'autre opérande est converti, sans changement de type
Domaine, à un type dont le type réel correspondant est
Long Double Code>. Li>
double code>, l'autre opérande est converti, sans changement de type
domaine, à un type dont le type réel correspondant est
double code>. li>
float code>, l'autre opérande est converti, sans changement de type
domaine, à un type dont le type réel correspondant est
float code>. li>
ul>
blockQuote>
i_value code> est converti en
float code>. P>
i_value code> est toujours
float code>, mais dans cette expression, votre compilateur profite de cette latitude et de la représentation plus grande précision que
float code>. Il s'agit de comportement typique du compilateur lors de la compilation du point flottant compatible 387, car le compilateur laisse des valeurs temporaires sur la pile à point flottant, qui stocke des nombres de points flottants dans un format de précision étendu 80 bits. P>
-ffloat-store code> ligne de commande. p>
Sur X64 GCC utilise une instruction CVTSI2SSL explicite qui convertit entier pour flotter. Sur le X86, cependant, c'est ce qui se passe exactement et qu'une plus grande précision est en fait encore supérieure à la double.
@ KONRAD.KRUCZYNSKI: Oui, et vous pouvez obtenir le même résultat sur x86 en fournissant l'option -mfpmath = sse code> (qui nécessite également un
-MSse code> ou une option qui implique cette).
Il y a de bonnes réponses ici. Vous devez faire très attention à la conversion entre divers entiers et diverses représentations de points flottants. p>
Je ne teste généralement pas les numéros de points flottants pour l'égalité, en particulier si l'un d'entre eux provient d'un couplage implicite ou explicite d'un type entier. Je travaille sur une application remplie de calculs géométriques. Autant que possible, nous travaillons avec des entiers normalisés (en forçant une précision maximale que nous accepterons dans les données d'entrée). Pour les cas où vous devez utiliser un point flottant, nous appliquerons une valeur absolue à la différence si la comparaison est nécessaire. P>
Avec g ++ (GCC 4.6.2), j'obtiens
1 code> pour l'égalité.
@Kerrek: Et moi. Dans vs, je reçois 0.
@Olicharlesworth: Je suis curieux de changer le littéral sur
f code> ou du type à
double code> - i get
1 code> dans tous les cas ...
Vous utilisez probablement un système X64 qui n'utilise pas 10 octets étendus, mais plutôt doubles habituels. Vous pouvez également l'observer sur CPU 32 bits avec -MFPMath = SSE -MSSE.