2012-02-15 29 views
16

Me encontré con este problema con parseInt y no estoy seguro de por qué sucede esto.parseInt redondea incorrectamente

console.log(parseInt("16980884512690999")); // gives 16980884512691000 
console.log(parseInt("169808845126909101"));​ // gives 169808845126909100 

que claramente no golpear ningún límite de número en los límites de JavaScript (Number.MAX_VALUE = 1.7976931348623157e+308)

con WIN 7 64 bits si lo que importa.

¿Qué estoy pasando por alto?

Fiddle

Respuesta

15

no hay que confundir con la máxima precisión Number.MAX_VALUE valor . Todos los números en javascript se almacenan como punto flotante de 64 bits, lo que significa que puede obtener números altos (y bajos), pero solo serán precisos hasta cierto punto.

Los puntos flotantes dobles (es decir, Javascript) tienen 53 bits de precisión significativa, lo que significa que el entero "ciertamente exacto" más alto/más bajo en javascript es +/- 9007199254740992 (2^53). Los números arriba/abajo que pueden resultan para ser precisos (los que simplemente agregan 0 en el extremo, porque los bits del exponente se pueden usar para representar eso).

O, en palabras de ECMAScript: "Tenga en cuenta que todos los enteros positivos y negativos cuya magnitud no es mayor que 2^53 son representables en el tipo Número (de hecho, el entero 0 tiene dos representaciones, +0 y - 0). "

actualización

sólo para añadir un poco a la pregunta existente, la especificación ECMAScript requiere que si un número entero tiene menos de 22 dígitos, .toString() es la salida que en notación decimal estándar (por ejemplo 169808845126909100000 como en su ejemplo). Si tiene 22 o más dígitos, saldrá en notación científica normalizada (por ejemplo, 1698088451269091000000 - 0 adicional se emite como 1.698088451269091e+21).

+0

Ambas respuestas son correctas, sin embargo, esta la explica en detalle y también explica lo que significa mi salida aparentemente anormal. – Mrchief

12

De this answer

Todos los números en Javascript son de 64 bits en coma flotante "doble" de precisión IEE754 .

El número entero positivo más grande que puede por lo tanto ser exactamente representado es 2^53. Los bits restantes están reservados para el exponente.

2^53 = 9007199254740992

+1

Sí; también vea http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html "Lo que todo científico informático debería saber sobre la aritmética de coma flotante" –

+0

¿Por qué obtengo '169808845126909100' en lugar de algunos ¿error de desbordamiento o algo más? Eso es más grande que '9007199254740992' – Mrchief

+1

Ver mi respuesta. Porque '1698088451269091' está por debajo de ese número, y los 0 del extremo son parte del exponente (es decir, se puede escribir como 1698088451269091 x 10^2). No se desborda, porque así es como funciona la aritmética de coma flotante. No importa que estés buscando enteros. – JimmiTh