Is this defined by the language? Is there a defined maximum? Is it different in different browsers?
-
6You don't need to depend on JS's limits with libraries like https://github.com/MikeMcl/big.js, see e.g. [here for its reliability tests](https://github.com/dmitriz/better-math/blob/master/test.js) – Dmitri Zaitsev May 18 '16 at 04:26
-
4what's the highest integer value you can use with big.js ? – George Mar 26 '18 at 20:41
-
@George Here is big.js API: https://mikemcl.github.io/big.js/#dp – simhumileco Jul 18 '18 at 09:35
-
The question doesn't make sense. What does it mean that a number "goes to" an integer value? If you just want to ask what is the highest integer you can represent in JS, the highest (finite) Number itself is an integer. – Veky Oct 26 '18 at 03:04
-
1@DmitriZaitsev We don't need to depend on external libraries any more (on some browsers, at least). `1n << 10000n` is a really, really big integer, without losing any precision, without requiring any dependencies (and needless to say, not even close to a limit). – Amadan Jan 06 '20 at 09:12
-
@Amadan Where does `1n << 10000n` come from here? – Dmitri Zaitsev Jan 08 '20 at 06:09
-
@DmitriZaitsev Just a random example of a big number. – Amadan Jan 08 '20 at 07:10
-
@Amadan So how can this random number remove the need for external libraries? – Dmitri Zaitsev Jan 08 '20 at 11:21
-
1@DmitriZaitsev Notice the `n` suffix. `BigInt` class is a part of ES2020 spec draft, already implemented in the majority of browsers; you can try to evaluate that in e.g. Chrome or Firefox, with no external libraries, and get a 3011-digit `BigInt`. – Amadan Jan 08 '20 at 11:41
-
@Amadan It is only for integers. E.g. how do you add `.1+.2` precisely? – Dmitri Zaitsev Jan 08 '20 at 12:00
-
2@DmitriZaitsev: Yes, it is only for integers. This question is about integers. – Amadan Jan 08 '20 at 12:01
-
In case someone like me wants to know the equivalent max safe integer when used as a `float`, it's `2**(f+1)-1`, where `f` = *number of significand precision bits explicitly stored*. So, for `float32`, the fraction part stores 23 bits (24 bits implicit), then max safe int is `2**24-1` = `16777215`. – geekley Jan 13 '23 at 08:56
21 Answers
JavaScript has two number types: Number
and BigInt
.
The most frequently-used number type, Number
, is a 64-bit floating point IEEE 754 number.
The largest exact integral value of this type is Number.MAX_SAFE_INTEGER
, which is:
- 253-1, or
- +/- 9,007,199,254,740,991, or
- nine quadrillion seven trillion one hundred ninety-nine billion two hundred fifty-four million seven hundred forty thousand nine hundred ninety-one
To put this in perspective: one quadrillion bytes is a petabyte (or one thousand terabytes).
"Safe" in this context refers to the ability to represent integers exactly and to correctly compare them.
Note that all the positive and negative integers whose magnitude is no greater than 253 are representable in the
Number
type (indeed, the integer 0 has two representations, +0 and -0).
To safely use integers larger than this, you need to use BigInt
, which has no upper bound.
Note that the bitwise operators and shift operators operate on 32-bit integers, so in that case, the max safe integer is 231-1, or 2,147,483,647.
const log = console.log
var x = 9007199254740992
var y = -x
log(x == x + 1) // true !
log(y == y - 1) // also true !
// Arithmetic operators work, but bitwise/shifts only operate on int32:
log(x / 2) // 4503599627370496
log(x >> 1) // 0
log(x | 1) // 1
Technical note on the subject of the number 9,007,199,254,740,992: There is an exact IEEE-754 representation of this value, and you can assign and read this value from a variable, so for very carefully chosen applications in the domain of integers less than or equal to this value, you could treat this as a maximum value.
In the general case, you must treat this IEEE-754 value as inexact, because it is ambiguous whether it is encoding the logical value 9,007,199,254,740,992 or 9,007,199,254,740,993.

- 53
- 6

- 89,068
- 17
- 119
- 137
-
77This seems right, but is there someplace where this is defined, á la C's MAX_INT or Java's Integer.MAX_VALUE? – TALlama Nov 20 '08 at 23:35
-
5according to IEEE_754 standard, 64-bit floating point uses 53 bits for the mantissa. As far as a javascript constant, I'm not aware of any. – Jimmy Nov 21 '08 at 18:14
-
53
-
13So what's the smallest and largest integer we can use to assure exact precision? – Pacerier Oct 15 '11 at 16:21
-
for simple operations, `2^53` as the first part of my answer states. I've edited to make the answer more clear – Jimmy Oct 15 '11 at 18:56
-
41Maybe worth noting that there is no actual (int) in javascript. Every instance of Number is (float) or NaN. – Beetroot-Beetroot Aug 31 '12 at 13:09
-
5
-
5@LucioM.Tato Question specifically asks for "without losing precision" Number.MAX_VALUE is the "largest value, period" but for example, `Number.MAX_VALUE - 1` is not a valid value. – Jimmy May 28 '13 at 17:15
-
5Every instance of Number is (float)
"or NaN." ... "Or +/- Infinity": Redundant, IEEE-754 (float) encodes NaN and +/-Infinity as part of the format. Also -0 – MickLH Nov 26 '13 at 08:57 -
6@TALlama In ES6, there will be a constant for that: `Number.MAX_SAFE_INTEGER` (already landed in Chrome with experimental JS on). For now this answer is fine. – rvighne Mar 16 '14 at 23:57
-
609007199254740992 is not really the maximum value, the last bit here is already assumed to be zero and so you have lost 1 bit of precision. The real safe number is 9007199254740991 ( Number.MAX_SAFE_INTEGER ) – Willem D'Haeseleer Aug 21 '14 at 17:59
-
4By the way, that number reads as: nine quadrillion , seven trillion , one hundred ninety nine billion , two hundred fifty four million , seven hundred forty thousand , nine hundred ninety one – K Lee Mar 13 '15 at 16:11
-
1Anybody explain me one thing. "The MAX_VALUE property has a value of approximately 1.79E+308 (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_VALUE). 1.79E+308 is a very big number which is much bigger than 2^53. What does mean Number.MAX_VALUE? – Evgeni Nabokov Mar 24 '16 at 12:49
-
3@EvgeniNabokov: Number.MAX_VALUE is the largest value representable by a 64-bit float. However, a 64-bit float cannot represent all integers less than 1.79E+308 (as you probably know, 64-bits can only represent 2^64 = 1.84E+19 unique values). Number.MAX_SAFE_VALUE, or 9007199254740991, has the property that every positive integer <= 9007199254740991 is exactly representable by a 64-bit float without losing precision. You can see in my code snippet in the answer that for values of x greater than 9007199254740991, you can have `x == x + 1`, which means we are losing precision. – Jimmy Mar 24 '16 at 19:12
-
+1 for specifying the limitations of bitwise operators !! It completely eludes me why on earth they chose to use 32-bit there, since it obviously uses 64 for Number. – Ciprian Tomoiagă Mar 10 '17 at 13:02
-
-
-
1@CiprianTomoiaga: Because 80386 was a 32 bit cpu and couldn't do that operations on 64 bit. And 80387 doesn't have shift operations. Please remember, that JS dates back a bit ... – Bodo Thiesen Aug 23 '17 at 21:52
-
@BodoThiesen: Was there ever a time when extending bitwise operators out to 53 bits would have had any meaningful adverse effect on Javascript performance? In the early days of Javascript when 32-bit CPUs ruled the roost, performance would be constrolled more by the speed of the interpreter and symbolic lookup than anything having to do with actual numeric operations. – supercat Jun 12 '18 at 19:29
-
Why it's 53-bit when the document says there are 52 bits to hold the fraction? I think it's worth mentioning the reason behind this (at least I wasn't smart enough to figure it out by myself), [this article](https://medium.com/dailyjs/javascripts-number-type-8d59199db1b6) explains it near its "Examples of how integers are stored" section. – Marty ZHANG Jun 21 '18 at 12:45
-
@supercat, I didn't say, I believe this was a "good" reason, I just said, I belive, this WAS the reason. And people sometimes tend to optimize at the wrong places. Anyway: Doing the shift on a double value create the need to either convert it to integer and back or heavy rounding prior to and after the shift. And yes: Doing a 64 bit shift would be only one instruction more than doing a 32 bit shift. – Bodo Thiesen Jul 06 '18 at 15:03
-
2@T.J.Crowder that's just a different definition of "losing precision", and I think a more unsafe one to use as a general principle. The IEEE-754 representation for the value 9007199254740992 is the same as representation for the value 9007199254740993, so if you ever have this bit pattern, you have to treat it as an inexact value since you can't be sure which of the two values it means. – Jimmy Sep 29 '18 at 17:11
-
1@Jimmy - It's all a bit arbitrary. :-) But I like your reasoning, though I quibble with *"The IEEE-754 representation for the value 9007199254740992 is the same as representation for the value 9007199254740993..."* There isn't any representation for 9007199254740993, at all. It's not that it's the same as 9007199254740992; there isn't one. So anything trying to use that value has to go down to 9007199254740992 or up to 9007199254740994. *(cont'd)* – T.J. Crowder Sep 29 '18 at 17:16
-
*(continuing)* But separately, in support of your definition: 9007199254740991 is the last value for which there's a bit for the 1's place; as of 9007199254740992, the least significant bit is the 2's place. Thus, loss of precision. So yeah, different ways to look at it, but I like your point. :-) Perhaps fold some of this into the answer? Since 9007199254740992 is held precisely... – T.J. Crowder Sep 29 '18 at 17:17
-
Thanks for the note on "bitwise operators and shift operators operate on 32-bit ints". Just noticed 1073741824 * 2 is 2147483648 but 1073741824 << 1 is -2147483648 – Galaxy Sep 08 '19 at 22:25
-
How do we calculate the maximum number given a certain amount of decimal places? – Dominic Oct 16 '20 at 05:53
-
@Dominic There is no number of decimal places X > 0 such that all decimal numbers to that precision are representable. for example, 0.1 decimal has no exact representation in binary and cannot be exactly represented by floats – Jimmy Oct 16 '20 at 22:44
>= ES6:
Number.MIN_SAFE_INTEGER;
Number.MAX_SAFE_INTEGER;
<= ES5
From the reference:
Number.MAX_VALUE;
Number.MIN_VALUE;
console.log('MIN_VALUE', Number.MIN_VALUE);
console.log('MAX_VALUE', Number.MAX_VALUE);
console.log('MIN_SAFE_INTEGER', Number.MIN_SAFE_INTEGER); //ES6
console.log('MAX_SAFE_INTEGER', Number.MAX_SAFE_INTEGER); //ES6

- 21,961
- 19
- 54
- 57

- 105,256
- 31
- 182
- 206
-
23I've edited the question to be a bit more precise about wanting the max Integer values, not just the max Number value. Sorry for the confusion, here. – TALlama Nov 20 '08 at 23:21
-
5
-
7Note that `Number.MIN_VALUE` is the smallest possible _positive_ number. The _least_ value (i.e. less than anything else) is probably `-Number.MAX_VALUE`. – Michael Scheper Jun 10 '14 at 23:19
-
2This is the maximum floating point value. The question is about the highest integer value. And while `Number.MAX_VALUE` is an integer, you can't go past `2^53` without losing precision. – Teepeemm Jul 22 '14 at 22:01
-
1@Teepeemm This is a nearly six-year-old answer to a nearly six-year-old question, so it's curious that you'd care about sharp-shooting it now. But, if you care to look at the edit history, you'll see that the original question didn't specify integers http://stackoverflow.com/posts/307179/revisions, not to mention the OP's comment just 4 comments up where he mentions making this edit/clarification. – Peter Bailey Jul 22 '14 at 22:08
-
37ES6 introduces `Number.MIN_SAFE_INTEGER` and `Number.MAX_SAFE_INTEGER` – superlukas Aug 31 '14 at 15:23
-
2So, in this case, should we down vote the answer because it is wrong for the updated question, or leave it because the Peter Baily was right at the time it was answered? – rocketsarefast May 27 '15 at 16:28
-
@Pacerier - a good question that has been ignored: the answer happens to be *yes*: all conforming implementations of ECMAscript are required to behave as if Numbers are stored as IEEE 754 double precision floating point numbers, so all implementations should give the same answers for these constants. – Jules Feb 22 '18 at 15:04
-
@rocketsarefast I updated the text of the answer to include ES6 information, but you can vote however you like. I think there is sufficient information and conversation here that votes at this stage, for a question/answer this old, are basically like no-ops. – Peter Bailey Mar 01 '18 at 19:14
-
2This answer as it currently stands is incorrect because it is implying that MAX_SAFE_INTEGER and MAX_VALUE both answer the question, and that the difference is only in which ES versions support them. In fact only MAX_SAFE_INTEGER correctly answers the question as it stands, and only MAX_VALUE answered the question as it was originally posted. MIN_SAFE_INTEGER and MIN_VALUE are irrelevant to the precise question. – Daira Hopwood Oct 17 '20 at 12:23
It is 253 == 9 007 199 254 740 992. This is because Number
s are stored as floating-point in a 52-bit mantissa.
The min value is -253.
This makes some fun things happening
Math.pow(2, 53) == Math.pow(2, 53) + 1
>> true
And can also be dangerous :)
var MAX_INT = Math.pow(2, 53); // 9 007 199 254 740 992
for (var i = MAX_INT; i < MAX_INT + 2; ++i) {
// infinite loop
}
Further reading: http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html
-
1though one would never reach the end of that for loop in a sane timeframe, you may wish to say `i += 1000000000` – ninjagecko Jul 08 '15 at 20:18
-
4@ninjagecko, he starts at MAX_INT so the end is right there. Also using i+= 1000000000 would make it no longer an infinite loop. Try it. – Ted Bigham Jan 05 '16 at 00:52
-
@TedBigham: Ah oops, was ready too quickly through that. Thanks for correcting me twice. – ninjagecko Jan 05 '16 at 08:34
-
1See Jimmy's argument for 9,007,199,254,740,991 instead of 9,007,199,254,740,992 [here](https://stackoverflow.com/questions/307179/what-is-javascripts-highest-integer-value-that-a-number-can-go-to-without-losin/307200?noredirect=1#comment92078006_307200). That, combined with my follow-up, seems persuasive. – T.J. Crowder Sep 29 '18 at 17:19
In JavaScript, there is a number called Infinity
.
Examples:
(Infinity>100)
=> true
// Also worth noting
Infinity - 1 == Infinity
=> true
Math.pow(2,1024) === Infinity
=> true
This may be sufficient for some questions regarding this topic.

- 30,738
- 21
- 105
- 131

- 10,322
- 7
- 46
- 66
-
27
-
8But it's good enough to initialize a `min` variable when you're looking for a minimum value. – djjeck Oct 23 '12 at 21:30
-
9
-
2
-
The Math.pow(2,1024) === Infinity is awesome. going to add that one. – BananaNeil Oct 30 '13 at 20:22
-
6Also worth nothing that it does handle negative Infinity too. So `1 - Infinity === -Infinity` – dmccabe Nov 05 '14 at 21:51
-
-
-
1
Many earlier answers have shown 9007199254740992 === 9007199254740992 + 1
is true to verify that 9,007,199,254,740,991 is the maximum and safe integer.
But what if we keep doing accumulation:
input: 9007199254740992 + 1 output: 9007199254740992 // expected: 9007199254740993
input: 9007199254740992 + 2 output: 9007199254740994 // expected: 9007199254740994
input: 9007199254740992 + 3 output: 9007199254740996 // expected: 9007199254740995
input: 9007199254740992 + 4 output: 9007199254740996 // expected: 9007199254740996
We can see that among numbers greater than 9,007,199,254,740,992, only even numbers are representable.
It's an entry to explain how the double-precision 64-bit binary format works. Let's see how 9,007,199,254,740,992 be held (represented) by using this binary format.
Using a brief version to demonstrate it from 4,503,599,627,370,496:
1 . 0000 ---- 0000 * 2^52 => 1 0000 ---- 0000.
|-- 52 bits --| |exponent part| |-- 52 bits --|
On the left side of the arrow, we have bit value 1, and an adjacent radix point. By consuming the exponent part on the left, the radix point is moved 52 steps to the right. The radix point ends up at the end, and we get 4503599627370496 in pure binary.
Now let's keep incrementing the fraction part with 1 until all the bits are set to 1, which equals 9,007,199,254,740,991 in decimal.
1 . 0000 ---- 0000 * 2^52 => 1 0000 ---- 0000.
(+1)
1 . 0000 ---- 0001 * 2^52 => 1 0000 ---- 0001.
(+1)
1 . 0000 ---- 0010 * 2^52 => 1 0000 ---- 0010.
(+1)
.
.
.
1 . 1111 ---- 1111 * 2^52 => 1 1111 ---- 1111.
Because the 64-bit double-precision format strictly allots 52 bits for the fraction part, no more bits are available if we add another 1, so what we can do is setting all bits back to 0, and manipulate the exponent part:
┏━━▶ This bit is implicit and persistent.
┃
1 . 1111 ---- 1111 * 2^52 => 1 1111 ---- 1111.
|-- 52 bits --| |-- 52 bits --|
(+1)
1 . 0000 ---- 0000 * 2^52 * 2 => 1 0000 ---- 0000. * 2
|-- 52 bits --| |-- 52 bits --|
(By consuming the 2^52, radix
point has no way to go, but
there is still one 2 left in
exponent part)
=> 1 . 0000 ---- 0000 * 2^53
|-- 52 bits --|
Now we get the 9,007,199,254,740,992, and for the numbers greater than it, the format can only handle increments of 2 because every increment of 1 on the fraction part ends up being multiplied by the left 2 in the exponent part. That's why double-precision 64-bit binary format cannot hold odd numbers when the number is greater than 9,007,199,254,740,992:
(consume 2^52 to move radix point to the end)
1 . 0000 ---- 0001 * 2^53 => 1 0000 ---- 0001. * 2
|-- 52 bits --| |-- 52 bits --|
Following this pattern, when the number gets greater than 9,007,199,254,740,992 * 2 = 18,014,398,509,481,984 only 4 times the fraction can be held:
input: 18014398509481984 + 1 output: 18014398509481984 // expected: 18014398509481985
input: 18014398509481984 + 2 output: 18014398509481984 // expected: 18014398509481986
input: 18014398509481984 + 3 output: 18014398509481984 // expected: 18014398509481987
input: 18014398509481984 + 4 output: 18014398509481988 // expected: 18014398509481988
How about numbers between [ 2 251 799 813 685 248, 4 503 599 627 370 496 )?
1 . 0000 ---- 0001 * 2^51 => 1 0000 ---- 000.1
|-- 52 bits --| |-- 52 bits --|
The value 0.1 in binary is exactly 2^-1 (=1/2) (=0.5) So when the number is less than 4,503,599,627,370,496 (2^52), there is one bit available to represent the 1/2 times of the integer:
input: 4503599627370495.5 output: 4503599627370495.5
input: 4503599627370495.75 output: 4503599627370495.5
Less than 2,251,799,813,685,248 (2^51)
input: 2251799813685246.75 output: 2251799813685246.8 // expected: 2251799813685246.75
input: 2251799813685246.25 output: 2251799813685246.2 // expected: 2251799813685246.25
input: 2251799813685246.5 output: 2251799813685246.5
/**
Please note that if you try this yourself and, say, log
these numbers to the console, they will get rounded. JavaScript
rounds if the number of digits exceed 17. The value
is internally held correctly:
*/
input: 2251799813685246.25.toString(2)
output: "111111111111111111111111111111111111111111111111110.01"
input: 2251799813685246.75.toString(2)
output: "111111111111111111111111111111111111111111111111110.11"
input: 2251799813685246.78.toString(2)
output: "111111111111111111111111111111111111111111111111110.11"
And what is the available range of exponent part? 11 bits allotted for it by the format.
From Wikipedia (for more details, go there)
So to make the exponent part be 2^52, we exactly need to set e = 1075.

- 2,691
- 1
- 19
- 27
Jimmy's answer correctly represents the continuous JavaScript integer spectrum as -9007199254740992 to 9007199254740992 inclusive (sorry 9007199254740993, you might think you are 9007199254740993, but you are wrong! Demonstration below or in jsfiddle).
console.log(9007199254740993);
However, there is no answer that finds/proves this programatically (other than the one CoolAJ86 alluded to in his answer that would finish in 28.56 years ;), so here's a slightly more efficient way to do that (to be precise, it's more efficient by about 28.559999999968312 years :), along with a test fiddle:
/**
* Checks if adding/subtracting one to/from a number yields the correct result.
*
* @param number The number to test
* @return true if you can add/subtract 1, false otherwise.
*/
var canAddSubtractOneFromNumber = function(number) {
var numMinusOne = number - 1;
var numPlusOne = number + 1;
return ((number - numMinusOne) === 1) && ((number - numPlusOne) === -1);
}
//Find the highest number
var highestNumber = 3; //Start with an integer 1 or higher
//Get a number higher than the valid integer range
while (canAddSubtractOneFromNumber(highestNumber)) {
highestNumber *= 2;
}
//Find the lowest number you can't add/subtract 1 from
var numToSubtract = highestNumber / 4;
while (numToSubtract >= 1) {
while (!canAddSubtractOneFromNumber(highestNumber - numToSubtract)) {
highestNumber = highestNumber - numToSubtract;
}
numToSubtract /= 2;
}
//And there was much rejoicing. Yay.
console.log('HighestNumber = ' + highestNumber);

- 1,560
- 12
- 26

- 8,342
- 3
- 33
- 53
-
8@CoolAJ86: Lol, I'm looking forward to March 15, 2040. If our numbers match we should throw a party :) – Briguy37 Feb 12 '13 at 22:15
-
-
@MickLH: I get 9007199254740992 with [that code](http://jsfiddle.net/briguy37/XH3bT/). What JavaScript engine are you using to test? – Briguy37 Nov 18 '13 at 15:52
-
You get 9007199254740992 with your own code, I did not use the final value of x, but the final evaulation of x++ for paranoid reasons. Google Chrome btw. – MickLH Nov 18 '13 at 18:00
-
@MickLH: evaluating `x++` gives you the value of x _before_ the increment has occurred, so that probably explains the discrepancy. If you want the expression to evaluate to the same thing as the final value of x, you should change it to `++x`. – peterflynn Nov 24 '13 at 07:51
-
Thank you but I do know the semantics of the post-increment, and used it's "final evaluation" (as opposed to the final value of x) because it provides the number where (x!=x+1) aka the "last number where +1 works" as opposed to the "first number where it fails" – MickLH Nov 25 '13 at 05:26
-
@MickLH: `"last number where +1 works" == "max number w/out losing precision" - 1` – Briguy37 Nov 25 '13 at 16:41
-
1. the question has an accepted answer so your implication to something _I did not say_ is either wrong or useless, objectively. 2. the purpose of my comment is to show that the large algorithm you wrote is a rather useless waste of time, good day sir. (I am sorry that you take such offense to my explaining of my concept with a highly related algorithm that also serves a purpose which is actually useful to me, also it does calculate the same X ;) ) – MickLH Nov 25 '13 at 17:39
-
@MickLH: Ok, I completely misunderstood what you were trying to say. I thought your first algorithm was to show that 9007199254740991 was the correct answer. Instead, it was to show that mine was a useless waste of time. I'm glad we cleared that up... – Briguy37 Nov 25 '13 at 20:52
-
but love you bro, don't make it out like im the evil ass who don't appreciate dat efficiency – MickLH Nov 26 '13 at 08:55
-
Couldnt you speed this up a lot by starting with a big value and only testing smaller values when you lose precision? Instead of adding 1 per loop lol – Marie Jul 20 '17 at 19:41
To be safe
var MAX_INT = 4294967295;
Reasoning
I thought I'd be clever and find the value at which x + 1 === x
with a more pragmatic approach.
My machine can only count 10 million per second or so... so I'll post back with the definitive answer in 28.56 years.
If you can't wait that long, I'm willing to bet that
- Most of your loops don't run for 28.56 years
9007199254740992 === Math.pow(2, 53) + 1
is proof enough- You should stick to
4294967295
which isMath.pow(2,32) - 1
as to avoid expected issues with bit-shifting
Finding x + 1 === x
:
(function () {
"use strict";
var x = 0
, start = new Date().valueOf()
;
while (x + 1 != x) {
if (!(x % 10000000)) {
console.log(x);
}
x += 1
}
console.log(x, new Date().valueOf() - start);
}());

- 74,004
- 20
- 105
- 125
-
5cant you just start it at 2^53 - 2 to test? (yes you can, I just tried it, even with -3 to be safe: var x=Math.pow(2,53)-3;while (x!=x+1) x++;) -> 9007199254740991 – MickLH Nov 17 '13 at 23:14
-
1Nice answer! Moreover, I know the value is settled, but why not use binary search for its finding? – higuaro Mar 03 '14 at 18:22
-
1What's the fun in that? Besides, @Briguy37 beat me to it: http://stackoverflow.com/a/11639621/151312 – coolaj86 Mar 04 '14 at 19:04
-
note that this 'safe' MAX_INT based on 32 bits will not work when comparing with Date values. 4294967295 is so yesterday! – Jerry May 20 '14 at 22:08
-
-1; I simply found this confusing. Sometimes I appreciate humour answers, but I think that this whole topic is complicated enough - especially given that some readers may not know that integers are stored as floats in JavaScript, or understand floating point imprecision - that adding a "fun" answer to the page that intermixes true claims and good advice with silliness is a harmful move. Also, perhaps I just have a bad sense of humour, but I didn't find it funny. – Mark Amery Dec 26 '14 at 17:45
-
Additionally, I'm still completely unsure what the "expected issues with bit-shifting" are. – Mark Amery Dec 26 '14 at 17:48
-
1The answer "To be safe: var MAX_INT = 4294967295;" isn't humorous. If you're not bitshifting, don't worry about it (unless you need an int larger than 4294967295, in which case you should probably store it as a string and use a bigint library). – coolaj86 Dec 27 '14 at 19:43
-
bad advice. You commonly want numbers over 4 billion like file sizes, but you don't need numbers over 9000 trillion. Bitwise operations were not in the question. – Ben Bryant Jul 31 '21 at 15:42
The short answer is “it depends.”
If you’re using bitwise operators anywhere (or if you’re referring to the length of an Array), the ranges are:
Unsigned: 0…(-1>>>0)
Signed: (-(-1>>>1)-1)…(-1>>>1)
(It so happens that the bitwise operators and the maximum length of an array are restricted to 32-bit integers.)
If you’re not using bitwise operators or working with array lengths:
Signed: (-Math.pow(2,53))…(+Math.pow(2,53))
These limitations are imposed by the internal representation of the “Number” type, which generally corresponds to IEEE 754 double-precision floating-point representation. (Note that unlike typical signed integers, the magnitude of the negative limit is the same as the magnitude of the positive limit, due to characteristics of the internal representation, which actually includes a negative 0!)

- 11,804
- 7
- 44
- 52
-
This is the answer I wanted to stumble upon on how to convert X to a 32 bit integer or unsigned integer. Upvoted your answer for that. – Charlie Affumigato Nov 24 '13 at 02:51
ECMAScript 6:
Number.MAX_SAFE_INTEGER = Math.pow(2, 53)-1;
Number.MIN_SAFE_INTEGER = -Number.MAX_SAFE_INTEGER;

- 1,296
- 1
- 14
- 15
-
1**Beware** [this is not (yet) supported by all browsers!](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) Today iOS (not even chrome), Safari and IE don't like it. – cregox May 06 '15 at 22:45
-
6Please read the answer carefully, we are not using the default implementation of Number.MAX_SAFE_INTEGER in ECMAScript 6, we are defining it by Math.pow(2, 53)-1 – WaiKit Kung May 08 '15 at 01:17
-
I thought it was just a reference to how it is implemented in ECMA 6! :P I think my comment is still valid, though. All a matter of context. ;) – cregox May 08 '15 at 01:24
-
3Is it reliable to calculate `MAX_SAFE_INTEGER` in all browsers by working backwards? Should you move forwards instead? I.e., Number.MAX_SAFE_INTEGER = 2 * (Math.pow(2, 52) - 1) + 1; – kjv May 26 '15 at 18:45
-
Is `Math.pow(2, 53)-1` a safe operation? It goes one larger than the largest safe integer. – ioquatix Mar 13 '17 at 03:09
-
Yes, this computation is correct. `Math.pow(2, 53)` is exactly representable, and the subtraction is well-defined and exact. – Daira Hopwood Oct 17 '20 at 12:26
Other may have already given the generic answer, but I thought it would be a good idea to give a fast way of determining it :
for (var x = 2; x + 1 !== x; x *= 2);
console.log(x);
Which gives me 9007199254740992 within less than a millisecond in Chrome 30.
It will test powers of 2 to find which one, when 'added' 1, equals himself.

- 380
- 4
- 9
Anything you want to use for bitwise operations must be between 0x80000000 (-2147483648 or -2^31) and 0x7fffffff (2147483647 or 2^31 - 1).
The console will tell you that 0x80000000 equals +2147483648, but 0x80000000 & 0x80000000 equals -2147483648.

- 30,738
- 21
- 105
- 131

- 91
- 1
- 1
JavaScript has received a new data type in ECMAScript 2020: BigInt
. It introduced numerical literals having an "n" suffix and allows for arbitrary precision:
var a = 123456789012345678901012345678901n;
Precision will still be lost, of course, when such big integer is (maybe unintentionally) coerced to a number data type.
And, obviously, there will always be precision limitations due to finite memory, and a cost in terms of time in order to allocate the necessary memory and to perform arithmetic on such large numbers.
For instance, the generation of a number with a hundred thousand decimal digits, will take a noticeable delay before completion:
console.log(BigInt("1".padEnd(100000,"0")) + 1n)
...but it works.

- 317,000
- 35
- 244
- 286
Try:
maxInt = -1 >>> 1
In Firefox 3.6 it's 2^31 - 1.

- 30,738
- 21
- 105
- 131

- 113
- 1
- 1
-
2@danorton: I'm not sure you understand what you are doing. `^`means **raised to the power**. In the javascript console, `^` is **XOR**, not raised-to – kumarharsh Dec 24 '13 at 11:09
-
1@Kumar, I don’t understand your meaning or how any other meaning of “^” is relevant here in this question about JavaScript. – danorton Dec 25 '13 at 14:42
-
2open Chrome/Firefox console. Type 5^2. In binary, 5 is `101` and 2 is `010`. Now, if you Bitwise XOR them, you'll get `5(101) ^ 2(010) = 7(111)` [READ THIS IF YOU'RE CONFUSED](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators) What is being discussed here is `Math.pow()` not the `^` operator – kumarharsh Dec 25 '13 at 15:22
-
3Again, I am not at all confused. I have commented and downvoted on what is _written_. If Math.pow() is what is meant, then that is what should be written. In an answer to a question about JavaScript, it is inappropriate to use syntax of a different language. It is even more inappropriate to use a syntax that is valid in JavaScript, but with an interpretation in JavaScript that has a different meaning than what is intended. – danorton Dec 31 '13 at 18:56
-
112^31 is how one writes two to the thirty-first power in English. It's not in a code block. Would you complain about someone using a ; in an answer, because that's a character with a different meaning in Javascript? – lmm Mar 05 '14 at 13:55
-
3Even though one *should* write **2³¹** and not **2^31** in plain text its common to do so, because most keyboard layouts doesn't have those characters by default. At least I did not have any problems understanding what was meant in this answer. – Jocke Jun 02 '15 at 21:07
-
I was gonna say :^) but this made me realize it's no more than a disgusting syntax error – Gershom Maes Sep 13 '19 at 14:42
I did a simple test with a formula, X-(X+1)=-1, and the largest value of X I can get to work on Safari, Opera and Firefox (tested on OS X) is 9e15. Here is the code I used for testing:
javascript: alert(9e15-(9e15+1));

- 30,738
- 21
- 105
- 131

- 463
- 6
- 16
-
1
-
69e15 = 9000000000000000. 2^53 = 9007199254740992. Therefore to be pedantic, 9e15 is only approximately equal to 2^53 (with two significant digits). – devios1 Sep 19 '12 at 22:24
-
@chaiguy In `9000000000000000` there is 1 significant figure. in ` 9007199254740992` there are 15 significant figures. – Royi Namir Nov 13 '13 at 06:36
-
@RoyiNamir Not wanting to start a pointless argument here, but 9000000000000000 has 16 significant digits. If you want only 1, it would have to be written as 9x10^15. – devios1 Nov 13 '13 at 18:01
-
1@chaiguy No. `9000000000000000` as it is - has `1` SF. where `90*10^14` has 2. (http://sigfigscalculator.appspot.com/) & http://mathsfirst.massey.ac.nz/Algebra/Decimals/SigFig.htm (bottom section) – Royi Namir Nov 13 '13 at 18:17
I write it like this:
var max_int = 0x20000000000000;
var min_int = -0x20000000000000;
(max_int + 1) === 0x20000000000000; //true
(max_int - 1) < 0x20000000000000; //true
Same for int32
var max_int32 = 0x80000000;
var min_int32 = -0x80000000;

- 173
- 1
- 7
Let's get to the sources
Description
The
MAX_SAFE_INTEGER
constant has a value of9007199254740991
(9,007,199,254,740,991 or ~9 quadrillion). 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 compare them. For example,
Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2
will evaluate to true, which is mathematically incorrect. See Number.isSafeInteger() for more information.Because
MAX_SAFE_INTEGER
is a static property of Number, you always use it asNumber.MAX_SAFE_INTEGER
, rather than as a property of a Number object you created.
Browser compatibility

- 1
- 1

- 31,877
- 16
- 137
- 115
In JavaScript the representation of numbers is 2^53 - 1
.

- 4,167
- 8
- 39
- 80
-
1This is an important point. It is why I am here googling max int size. Other answers suggest 53 bits, so I coded it up thinking I could do bit wise arithmetic of positive values safely up to 52 bits. But it failed after 31 bits. Thanks @Marwen – JimbobTheSailor Mar 08 '21 at 01:03
In the Google Chrome built-in javascript, you can go to approximately 2^1024 before the number is called infinity.

- 99
- 1
- 6
-
[Math.pow(base, exponent)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow) – jkdev Feb 10 '15 at 03:27
Scato wrotes:
anything you want to use for bitwise operations must be between 0x80000000 (-2147483648 or -2^31) and 0x7fffffff (2147483647 or 2^31 - 1).
the console will tell you that 0x80000000 equals +2147483648, but 0x80000000 & 0x80000000 equals -2147483648
Hex-Decimals are unsigned positive values, so 0x80000000 = 2147483648 - thats mathematically correct. If you want to make it a signed value you have to right shift: 0x80000000 >> 0 = -2147483648. You can write 1 << 31 instead, too.

- 554
- 1
- 6
- 4
Node.js and Google Chrome seem to both be using 1024 bit floating point values so:
Number.MAX_VALUE = 1.7976931348623157e+308

- 30,738
- 21
- 105
- 131

- 5,275
- 3
- 28
- 24
-
1-1: the maximum representable (non-exact integral) number may be ~2^1024, but that doesn't mean they're deviating from the IEEE-754 **64**-bit standard. – Roy Tinker Apr 03 '13 at 21:44
-
2
-
3that's maximum of a **floating point** value. It doesn't mean that you can store an int that long – phuclv Aug 04 '13 at 10:30
-
1Or more to the point, you can't *reliably* store an int that long *without loss of accuracy*. `2^53` is referred to as `MAX_SAFE_INT` because above that point the values become approximations, in the same way fractions are. – IMSoP Jun 16 '14 at 18:32
Firefox 3 doesn't seem to have a problem with huge numbers.
1e+200 * 1e+100 will calculate fine to 1e+300.
Safari seem to have no problem with it as well. (For the record, this is on a Mac if anyone else decides to test this.)
Unless I lost my brain at this time of day, this is way bigger than a 64-bit integer.

- 30,738
- 21
- 105
- 131

- 24,126
- 6
- 49
- 75
-
18its not a 64 bit integer, its a 64-bit floating point number, of which 52/53 bits are the integer portion. so it will handle up to 1e300, but not with exact precision. – Jimmy Nov 21 '08 at 18:11
-
4Jimmy is correct. Try this in your browser or JS command line: `100000000000000010 - 1 => 100000000000000020` – Ryan Oct 07 '11 at 21:54