2012-04-03 18 views
7

Me encontré con un problema extraño, quiero hacer algunas comprobaciones básicas de matemáticas. He leído para evitar números flotantes, así que decidí multiplicar mis valores matemáticos con , porque mi valor puede estar entre 0,9 y 0,0025.Multiplicación de JavaScript no precisa

Todo funciona correctamente a excepción de dos valores: 0,56 y 0,57:

var result = 0.57 * 10000 

El resultado es: 5.699,999999999999, esperaba para 5700 !! Y 0.56 también está yendo mal, pero todos los otros valores son correctos, ¿qué me falta aquí?

+4

[Lo que todo informático debe saber sobre la aritmética de punto flotante] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) –

+0

@JamesAllardice El famoso Goldberg Variaciones! – kojiro

Respuesta

3

Sus opciones en Javascript (de hecho, en la mayoría de los idiomas) son números enteros o números de punto flotante. Si escribe "0.57", lo está forzando al mundo del punto flotante, donde la precisión es limitada.

Si desea una precisión absoluta, deberá trabajar exclusivamente en enteros.

3
var result = 0.57 * 10000; 
alert (Math.round(result));​ 
0

solución Hacky: value.toFixed(4).substr(-4).replace(/^0+/, "");

11

La mejor solución sería utilizar toFixed (x), y establecer x un número de decimales que siempre debe ser más de los resultados esperados decimales (8 Yo suelo poner allí).

Pero en lugar de piratear -como kirilloid-, debe convertir nuevamente el resultado al número, de modo que se eliminen los decimales innecesarios. Después de eso, realice cualquier formateo que desee en el número.

lo que esta sería devolver el resultado necesario:

var result = +(0.57 * 10000).toFixed(8) 

resultado sería ahora

El signo + delante, convierte la cadena resultado de "toFixed" a un número nuevo.

Espero que haya ayudado!

0
var multiply = function(a, b) { 
    var commonMultiplier = 1000000; 

    a *= commonMultiplier; 
    b *= commonMultiplier; 

    return (a * b)/(commonMultiplier * commonMultiplier); 
}; 

Esto funciona en un rango conocido. Por lo tanto, podría ser una buena idea redondear el número a un punto decimal menor que commonMultiplier.

> multiply(3, .1) 
< 0.3 
> multiply(5, .03) 
< 0.15