Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Number() return wrong values with very large integers?

Tags:

javascript

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?

like image 630
user3383116 Avatar asked Mar 01 '16 16:03

user3383116


People also ask

How do large numbers work in JavaScript?

We can deal with large numbers in JavaScript using the data type BigInt. Advantages: It can hold numbers of large size. It perform arithmetic operations.

How do you input large numbers in Python?

Python supports a "bignum" integer type which can work with arbitrarily large numbers. In Python 2.5+, this type is called long and is separate from the int type, but the interpreter will automatically use whichever is more appropriate.

What is Big Int in JavaScript?

BigInt is a primitive wrapper object used to represent and manipulate primitive bigint values — which are too large to be represented by the number primitive.


2 Answers

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)
like image 105
Juan Mendes Avatar answered Nov 15 '22 06:11

Juan Mendes


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.

like image 20
Jon Skeet Avatar answered Nov 15 '22 05:11

Jon Skeet