2011-07-04 14 views
6

No sé si estoy perdiendo algo obvio aquí, pero ...Firefox y Javascript reglas de redondeo

En IE, Opera y Chrome, consigo lo que espero de redondeo de números que terminan en un 5:

125 toPrecision(2) => 130 
11.5 toPrecision(2) => 12 

Esto es lo que esperaría.

Firefox, sin embargo, es un poco más 'sofisticada' produciendo el siguiente:

125 toPrecision(2) => 120 //wtf!!! 
11.5 toPrecision(2) => 12 

Después de un poco de rascarse la cabeza, he llegado a la conclusión de que Firefox utiliza una 'incluso redondeo' regla donde, si el dígito antes de que el 5 es aún el número se redondea hacia abajo y si el dígito antes del 5 es impar el número se redondea:

0.5 => 0 
1.5 => 2 
2.5 => 2 
3.5 => 4, etc. 

estoy usando los resultados redondeados para probar las soluciones de los estudiantes a las preguntas de ingeniería con seudo -Intervenciones de preguntas generadas aleatoriamente. Una pregunta introducida en Chrome podría ser h = 1020 mm pero h = 1030 mm en FF, Chrome u Opera.

Necesito una función para hacer el redondeo consistente, es decir, quiero que 0.00redondee hasta 0.000124 y quiero que 1234 redondee a 1240, así que no puedo usar un simple num = Math.floor (num + 0.5); Para complicar las cosas un poco, quiero variables de entrada y las respuestas de los estudiantes para ser correctos a 3 sig excavaciones a menos que el primer dígito es un 1, en cuyo caso quiero 4 sig cava:

234.5 => 235 
134.5 => 134.5 

He hackeado una solución a las 3 o 4 sig excavaciones dependiendo del primer dígito convirtiendo el número en una cadena y probando el primer carácter distinto de cero, no decimal y no negativo para '1'; no es bonito, pero funciona. Podría hacer algo similar para el problema de redondeo, verificando si el dígito que se redondeará es un 5, pero me pregunto si existe una solución inteligente a nivel de bit.

+0

"Quiero 1234 redondear a 1240"? –

Respuesta

1

favor, eche un vistazo a las pruebas aquí

http://yuiblog.com/blog/2009/03/10/when-you-cant-count-on-your-numbers/

JavaScript tiene un solo tipo de número: IEEE 754 flotante de doble precisión punto. Tener un solo tipo de número es una de las mejores características de JavaScript. Los tipos de número múltiple pueden ser una fuente de complejidad, confusión y error. Un tipo simple se está simplificando y estabilizando .

Lamentablemente, un tipo de punto flotante binario tiene algunas desventajas significativas . Lo peor es que no puede representar con precisión las fracciones decimales , que es un gran problema porque la humanidad ha estado haciendo comercio en decimales durante un largo, largo vez. Habría ventajas para cambiar a un sistema de número binario , pero eso no va a suceder . Como consecuencia, 0.1 + 0.2 === 0.3 es falso, lo cual es fuente de mucha confusión.

También echa un vistazo a las preguntas SO:

https://stackoverflow.com/questions/287744/good-open-source-javascript-math-library-for-floating-point-operations

y

https://stackoverflow.com/questions/744099/javascript-bigdecimal-library/1575569#1575569

+0

¿Podría poner la esencia de la información detrás de los enlaces en línea en su respuesta? De esta manera, la información permanecerá disponible incluso si los enlaces se vuelven obsoletos. –

+0

Solo el primero fue externo – mplungjan

0

Sobre "Quiero 0,00para redondear hasta 0,000124": Esto no lo hace mucho sentido ya que a diferencia de 0.5, 1.5, 2.5, etc., el número decimal 0.00no es exactamente representable en la raíz 2; así que su redondeo puede estar un poco por encima (A) o un poco por debajo (B) del valor exacto, donde (A) y (B) arrojarían diferentes redondeos: 0.000124 para (A), 0.00para (B).

Incluso si obtiene un número fraccionario como 1.5 para que se redondee a un entero después de algunos cálculos, (1.5) .toPrecision (2) no arrojará necesariamente el valor que esté más cerca del valor exacto. La razón es que el valor exacto puede estar justo por debajo de 1.5, en cuyo caso el redondeo correcto es 1, no 2. Este problema se conoce como Dilema de Table Maker.

Esto también significa que si dos estudiantes usan métodos ligeramente diferentes (ambos bastante precisos) y redondean sus aproximaciones, obtendrán diferentes resultados redondeados (aunque sus aproximaciones podrían ser muy cercanas entre sí). En caso de un empate como 0.00(que se redondeará a 0.000124), el dilema de Table Maker es inevitable a menos que todos los cálculos se lleven a cabo exactamente o el algoritmo verifique específicamente los casos de empate.

Sin embargo, si el resultado exacto es un empate o muy cerca de un empate, aún es posible verificar si el estudiante ha respondido ya sea (A) o (B).