2011-09-30 9 views
6

Duplicar posibles:
Is JavaScript's Math broken?
Why can't decimal numbers be represented exactly in binary?Suma de 3 variables: comportamiento extraño

¿Cuál será resultado de la siguiente código:

if(0.3 == (0.1 + 0.1 + 0.1)) 
{ 
     alert(true); 
} 
else 
{ 
     alert(false); 
} 

Es extraño, pero el resultado será falso.

La razón es que la consecuencia de

0,1 + 0,1 + 0,1

será

0,30000000000000004

¿Cómo se puede explicar este comportamiento?

+2

Ver http://stackoverflow.com/questions/1089018/why-cant-decimal-numbers-be-represented-excaly-in-binary – mtrw

+1

Y, más específicamente en JavaScript, http://stackoverflow.com/questions/4088590/0-43-in-javascript-not-1-2-its-1-20000000002-what-happening –

+2

Tal vez deba seguir los consejos en las Preguntas frecuentes y buscar antes de hacer una pregunta que ya se ha hecho miles de veces antes . – paxdiablo

Respuesta

2

Es la misma razón 1/3 + 1/3 + 1/3 no se le puede dar exactamente 1 en decimal. Si usa 1/3 como .33333333, entonces 1/3 + 1/3 + 1/3 le dará .9999999 que no es exactamente uno.

A menos que sepa exactamente lo que está haciendo, no compare los tipos numéricos no enteros para la igualdad.

1

Se debe a la naturaleza de los flotadores almacenados en las computadoras. No existe una forma exacta de almacenar un número de coma flotante arbitrario. Lo que se hace normalmente cuando se comparan los flotadores es ver si la diferencia es menor que un pequeño número de épsilon, como esto:

function equals(f1, f2){ 
    var epsilon = 0.00001; //arbitrary choice 
    return (f1-f2 < epsilon && f2-f1 < epsilon); 
} 

por lo que en su caso, el cambio si (== 0,3 (0,1 + 0,1 + 0,1)) a if (es igual a 0.3, (0.1 + 0.1 + 0.1))

1

Lo que está experimentando es un error de redondeo de coma flotante básico.

No podemos representar con precisión 0,1 sin algún error debido a la naturaleza de los números binarios. WolframAlpha reports decimal 0.1 a igual binario ~ 0.00011001100110011 ... ¿Observe cómo no puede representarse finitamente en el sistema de números binarios? Esto significa que tenemos que decidir un punto de corte en el cual dejar de calcular este número, de lo contrario estaríamos aquí para siempre.

Esto introduce un error. Y este error se ha acumulado a medida que el código agrega los números, lo que resulta en una cantidad increíblemente pequeña añadida al final de su suma. Esto asegura que la suma nunca será EXACTAMENTE 0.3, que es lo que está buscando la prueba IF.

Algunos números decimales, sin embargo, se pueden representar con precisión en binario, como dec 0.5 = bin 0.1 y dec 0.25 = bin 0.01.

We can demonstrate this de forma similar a su código original usando 0.5 = (0.25 + 0.25).


Para obtener más información al respecto, recomiendo The Floating-Point Guide.

Proporciona una buena visión general del concepto de números flotantes y cómo pueden surgir errores en el cálculo. También hay una sección sobre Javascript que muestra cómo superar los errores de redondeo que estás experimentando.