75 votes

Pourquoi 0,1 + 0,2 == 0,3 en D ?

assert(0.1 + 0.2 != 0.3); // shall be true

est mon test préféré pour vérifier qu'un langage utilise une arithmétique à virgule flottante native.

C++

#include <cstdio>

int main()
{
   printf("%d\n", (0.1 + 0.2 != 0.3));
   return 0;
}

Sortie :

1

http://ideone.com/ErBMd

Python

print(0.1 + 0.2 != 0.3)

Sortie :

True

http://ideone.com/TuKsd

Autres exemples

Pourquoi cela n'est-il pas vrai pour D ? Comme je l'ai compris, D utilise des nombres à virgule flottante natifs. Est-ce un bug ? Utilise-t-il une représentation spécifique des nombres ? Quelque chose d'autre ? C'est assez déroutant.

D

import std.stdio;

void main()
{
   writeln(0.1 + 0.2 != 0.3);
}

Sortie :

false

http://ideone.com/mX6zF


UPDATE

Merci à LukeH . Il s'agit d'un effet du pliage des constantes en virgule flottante décrit .

Code :

import std.stdio;

void main()
{
   writeln(0.1 + 0.2 != 0.3); // constant folding is done in real precision

   auto a = 0.1;
   auto b = 0.2;
   writeln(a + b != 0.3);     // standard calculation in double precision
}

Sortie :

false
true

http://ideone.com/z6ZLk

53voto

(La réponse de Flynn est la bonne réponse. Celle-ci aborde le problème de manière plus générale).


Vous semblez supposer, OP, que l'imprécision de la virgule flottante dans votre code est déterministe et comme prévu, faux (d'une certaine manière, votre approche est à l'opposé de celle des personnes qui ne comprennent pas encore la virgule flottante).

Bien que (comme Ben le souligne) l'imprécision des points flottants est déterministe, du point de vue de votre code, si vous n'êtes pas très délibéré sur ce qui arrive à vos valeurs à chaque étape, ce ne sera pas le cas. Un certain nombre de facteurs peuvent conduire à 0.1 + 0.2 == 0.3 qui se succèdent, l'optimisation de la compilation en étant une, les valeurs modifiées pour ces littéraux en étant une autre.

Comptez sur nous ni en cas de succès ou d'échec ; ne vous fiez pas à l'égalité en virgule flottante dans tous les cas .

47voto

Flynn1179 Points 6900

C'est probablement optimisé pour (0.3 != 0.3). Ce qui est évidemment faux. Vérifiez les paramètres d'optimisation, assurez-vous qu'ils sont désactivés, et réessayez.

5voto

Jean Hominal Points 7001

Selon mon interprétation de la Spécification du langage D Ainsi, l'arithmétique à virgule flottante sur x86 utiliserait 80 bits de précision en interne, au lieu de 64 bits seulement.

Il faudrait cependant vérifier que cela suffit à expliquer le résultat que vous observez.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X