web-dev-qa-db-fra.com

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

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

est ma vérification préférée qu'une langue utilise l'arithmétique native à virgule flottante.

C++

#include <cstdio>

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

Production:

1

http://ideone.com/ErBMd

Python

print(0.1 + 0.2 != 0.3)

Production:

True

http://ideone.com/TuKsd

Autres exemples

Pourquoi est-ce pas vrai pour D? Comme on le comprend, D utilise des nombres natifs à virgule flottante. Est-ce un bug? Utilisent-ils une représentation numérique spécifique? Autre chose? Assez déroutant.

import std.stdio;

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

Production:

false

http://ideone.com/mX6zF


MISE À JOUR

Merci à LukeH . Il s'agit d'un effet du pliage constant 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
}

Production:

false
true

http://ideone.com/z6ZLk

75
Stas

Il 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.

47
Flynn1179

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


Vous semblez supposer, OP, que l'inexactitude en virgule flottante de votre code est déterministe et prévisible (d'une certaine manière, votre approche est l'opposé polaire de celle des personnes qui ne comprennent pas le flottant point encore).

Bien que (comme le souligne Ben) l'inexactitude en virgule flottante 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, cela ne sera pas être le cas. Un certain nombre de facteurs peuvent conduire à 0.1 + 0.2 == 0.3 réussie, l'optimisation à la compilation en étant une, les valeurs modifiées pour ces littéraux en étant une autre.

Fiez-vous ici ni au succès ni à l'échec; ne comptez pas sur l'égalité à virgule flottante dans les deux cas.

53

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

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

5
Jean Hominal