Pregunta ¿Por qué 0.1 + 0.2 == 0.3 en D?


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

es mi verificación favorita de que un idioma usa aritmética nativa de coma flotante.

C ++

#include <cstdio>

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

Salida:

1

http://ideone.com/ErBMd

Pitón

print(0.1 + 0.2 != 0.3)

Salida:

True

http://ideone.com/TuKsd

Otros ejemplos

¿Por qué esto no es cierto para D? Como entiende, D usa números de coma flotante nativos. ¿Es esto un error? ¿Usan alguna representación numérica específica? ¿Algo más? Bastante confuso

re

import std.stdio;

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

Salida:

false

http://ideone.com/mX6zF

ACTUALIZAR

Gracias a LukeH. Este es un efecto de Floating Point Constant Folding descrito ahí.

Código:

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
}

Salida:

false
true

http://ideone.com/z6ZLk


74
2017-07-29 14:03


origen


Respuestas:


Probablemente esté siendo optimizado para (0.3! = 0.3). Lo cual es obviamente falso. Verifique la configuración de optimización, asegúrese de que estén apagados y vuelva a intentarlo.


47
2017-07-29 14:06



(La respuesta de Flynn es la respuesta correcta. Esta aborda el problema de manera más general).


Usted parece estar asumiendo, OP, que la imprecisión de coma flotante en su código es determinista y predeciblemente mal (En cierto modo, su enfoque es el polo opuesto al de las personas que aún no entienden el punto flotante).

Aunque (como señala Ben) la imprecisión en coma flotante es determinista, desde el punto de vista de su código, si no está siendo muy deliberado sobre lo que está sucediendo con sus valores en cada paso, este no será el caso. Cualquier cantidad de factores podría llevar a 0.1 + 0.2 == 0.3 teniendo éxito, la optimización en tiempo de compilación siendo uno, los valores ajustados para esos literales siendo otro.

Confíe aquí ninguno en el éxito ni en el fracaso; no confíe en la igualdad de coma flotante de cualquier manera.


54
2017-07-29 14:21



De acuerdo con mi interpretación del D especificación del lenguajeLa aritmética de punto flotante en x86 usaría 80 bits de precisión internamente, en lugar de solo 64 bits.

Sin embargo, habría que verificar que eso sea suficiente para explicar el resultado que observas.


5
2017-07-29 14:14