Reputation: 392
Number() function returns incorrect values on some arguments, like this:
Number('10000000712224641') returns 10000000712224640
Number('10000000544563531') returns 10000000544563532
I tested this on Firefox, Chome, IE and Node.js. Why is this happening?
Upvotes: 6
Views: 1800
Reputation: 92274
JavaScript safely supports approximately up to 17 digits and all numbers, whether floats or integers, are expressed in 64-bit IEEE-754 binary floating.
Number.MAX_SAFE_INTEGER // 9007199254740991
When you get above that number, the trailing digits get rounded unless you have a power of 2 (or the addition of powers of two)
Math.pow(2, 54) // 18014398509481984 (not rounded)
Math.pow(2, 54) + 1 // 18014398509481984 (rounded)
Math.pow(2, 54) - 1 // 18014398509481984 (rounded)
Math.pow(2,57) + Math.pow(2,52) // 148618787703226370 (not rounded)
Math.pow(2, 57) + Math.pow(2, 52) + 1 // 148618787703226370 (rounded)
Upvotes: 10
Reputation: 1499770
Javascript uses 64-bit IEEE-754 binary floating point to store all numbers - like double
in C# and Java, for example. There isn't a different type to store integers. (The actual implementation may use optimizations to avoid always performing arithmetic in this way, but from an end-user perspective the results will always be as if every number were treated as a 64-bit binary floating point value.)
That means only 52 bits are available to store the significand, with the other bits being used for the exponent and sign. With normalization, that means you can effectively store values with 53 significant bits of precision. That means beyond 253-1 (which is the value 9007199254740991 as quoted in other answers), the distance between "adjacent" numbers is more than 1, so you can't store all integers exactly.
Upvotes: 7
Reputation: 586
This is due to the fact that javascript supports a number of digits. The maximum safe integer possible is stored in a constant called MAX_SAFE_INTEGER which contains value 9007199254740991.
Upvotes: 2