Consider this code (node v5.0.0)
const a = Math.pow(2, 53)
const b = Math.pow(2, 53) + 1
const c = Math.pow(2, 53) + 2
console.log(a === b) // true
console.log(a === c) // false
Why a === b
is true?
What is the maximum integer value javascript can handle?
I'm implementing random integer generator up to 2^64. Is there any pitfall I should be aware of?
Consider this code (node v5.0.0)
const a = Math.pow(2, 53)
const b = Math.pow(2, 53) + 1
const c = Math.pow(2, 53) + 2
console.log(a === b) // true
console.log(a === c) // false
Why a === b
is true?
What is the maximum integer value javascript can handle?
I'm implementing random integer generator up to 2^64. Is there any pitfall I should be aware of?
Share Improve this question edited Jul 7, 2016 at 16:59 Charlie 23.9k12 gold badges63 silver badges95 bronze badges asked Jul 7, 2016 at 16:44 user1518183user1518183 4,7715 gold badges29 silver badges39 bronze badges 6- 1 developer.mozilla/en-US/docs/Web/JavaScript/Reference/… – Gerardo Furtado Commented Jul 7, 2016 at 16:45
- Sorry, already fixed. – user1518183 Commented Jul 7, 2016 at 16:47
- a and b are the same number, and same numbers are the same, or equal. – dandavis Commented Jul 7, 2016 at 16:48
- why the need for such large integers? can you make two 32 char numbers and concat them as a string? – dandavis Commented Jul 7, 2016 at 16:49
-
I made a simple simulation of floating points in base 10 (N.B: your puter uses base 2!): jsfiddle/unhLemoa As you can see, if you shift the mantissa up as high as it will go, you can get big numbers like
123456789100000000
, but you can't actually increment that number by one; the closest higher number you can create is123456789200000000
– apsillers Commented Jul 7, 2016 at 17:19
5 Answers
Reset to default 4How javascript treat large integers?
JS does not have integers. JS numbers are 64 bit floats. They are stored as a mantissa and an exponent.
The precision is given by the mantissa, the magnitude by the exponent.
If your number needs more precision than what can be stored in the mantissa, the least significant bits will be truncated.
9007199254740992; // 9007199254740992
(9007199254740992).toString(2);
// "100000000000000000000000000000000000000000000000000000"
// \ \ ... /\
// 1 10 53 54
// The 54-th is not stored, but is not a problem because it's 0
9007199254740993; // 9007199254740992
(9007199254740993).toString(2);
// "100000000000000000000000000000000000000000000000000000"
// \ \ ... /\
// 1 10 53 54
// The 54-th bit should be 1, but the mantissa only has 53 bits!
9007199254740994; // 9007199254740994
(9007199254740994).toString(2);
// "100000000000000000000000000000000000000000000000000010"
// \ \ ... /\
// 1 10 53 54
// The 54-th is not stored, but is not a problem because it's 0
Then, you can store all these integers:
-9007199254740992, -9007199254740991, ..., 9007199254740991, 9007199254740992
The second one is called the minimum safe integer:
The value of
Number.MIN_SAFE_INTEGER
is the smallest integer n such that n and n − 1 are both exactly representable as a Number value.The value of
Number.MIN_SAFE_INTEGER
is −9007199254740991 (−(253−1)).
The second last one is called the maximum safe integer:
The value of
Number.MAX_SAFE_INTEGER
is the largest integer n such that n and n + 1 are both exactly representable as a Number value.The value of
Number.MAX_SAFE_INTEGER
is 9007199254740991 (253−1).
Answering your second question, here is your maximum safe integer in JavaScript:
console.log( Number.MAX_SAFE_INTEGER );
All the rest is written in MDN:
The
MAX_SAFE_INTEGER
constant has a value of9007199254740991
. The reasoning behind that number is that JavaScript uses double-precision floating-point format numbers as specified in IEEE 754 and can only safely represent numbers between-(2 ** 53 - 1)
and2 ** 53 - 1
.Safe in this context refers to the ability to represent integers exactly and to correctly pare them. For example,
Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2
will evaluate totrue
, which is mathematically incorrect. SeeNumber.isSafeInteger()
for more information.
.:: JavaScript only supports 53 bit integers ::.
All numbers in JavaScript are floating point which means that integers are always represented as
sign × mantissa × 2exponent
The mantissa has 53 bits. You can use the exponent to get higher integers, but then they won’t be contiguous, any more. For example, you generally need to multiply the mantissa by two (exponent 1) in order to reach the 54th bit.
However, if you multiply by two, you will only be able to represent every second integer:
Math.pow(2, 53) // 54 bits 9007199254740992
Math.pow(2, 53) + 1 // 9007199254740992
Math.pow(2, 53) + 2 //9007199254740994
Math.pow(2, 53) + 3 //9007199254740996
Math.pow(2, 53) + 4 //9007199254740996
Rounding effects during the addition make things unpredictable for odd increments (+1 versus +3). The actual representation is a bit more plicated but this explanation should help you understand the basic problem.
You can safely use strint library to encode large integers in strings and perform arithmetic operations on them too.
Here is the full article.
Number.MAX_VALUE
will tell you the largest floating-point value representable in your JS implementation. The answer will likely be: 1.7976931348623157e+308. But that doesn't mean that every integer up to 10^308 can be represented exactly. As your example code shows, beyond 2^53 only even numbers can be represented, and as you go farther out on the number line the gaps get much wider.
If you need exact integers larger than 2^53, you probably want to work with a bignum package, which allows for arbitrarily large integers (within the bounds of available memory). Two packages that I happen to know are:
BigInt by Leemon
and
Crunch
To supplement to other answers here, it's worth mentioning that BigInt exists. This allows JavaScript to handle arbitrarily large integers.
Use the n
suffix on your numbers and use regular operators like 2n ** 53n + 2n
. Important to point out that a BigInt is not a Number, but you can do range-limited interoperation with Number via explicit conversions.
Some examples at the Node.js REPL:
> 999999999999999999999999999999n + 1n 1000000000000000000000000000000n > 2n ** 53n 9007199254740992n > 2n ** 53n + 1n 9007199254740993n > 2n ** 53n == 2n ** 53n + 1n false > typeof 1n 'bigint' > 3 * 4n TypeError: Cannot mix BigInt and other types, use explicit conversions > BigInt(3) * 4n 12n > 3 * Number(4n) 12 > Number(2n ** 53n) == Number(2n ** 53n + 1n) true