I have seen in multiple posts that max safe integer representable in IEEE double format is 253:
But there is this one post which says it's 254:
https://stackoverflow.com/a/12445693
Range within which all integers can be represented (including boundaries)
- 254 as an upper bound
- -254 as a lower bound
Is this answer wrong or am I missing something?
Above post seems to be corrected now.
But there is this one post which says it's 254: https://stackoverflow.com/a/12445693
Range within which all integers can be represented (including boundaries) 254 as an upper bound -254 as a lower bound
Is this answer wrong or am I missing something?
You're not missing something. The first integer that IEEE 754 double-precision binary floating point ("double") can't represent is 253 + 1, which is well within the claimed -254..254 bounds. It's probably a typo, since all integers in the range -253..253 (inclusive) can be represented. From 253 onward, only multiples of 2 can be represented (so 253 + 2 is fine, but not 253 + 1). Since JavaScript uses this form of double, it's easy to see this in action:
const x = 2**53;
const y = x + 1;
console.log(x.toLocaleString()); // 9,007,199,254,740,992
console.log(y.toLocaleString()); // 9,007,199,254,740,992 -- the same
console.log(x === y); // true
const z = x + 2;
console.log(z.toLocaleString()); // 9,007,199,254,740,994
With a double, 253 - 1 is the last so-called "safe" integer, where "safe" is defined as "you can add 1 to it and get the next integer." (In fact, JavaScript even has a constant for the value 253 - 1: Number.MAX_SAFE_INTEGER
.) The next integer you get when you add 1 is (of course) 253 — the first integer at which the format can no longer handle every distinct integer. Starting with 253, a double can only count by twos: 253, 253 + 2, 253 + 4, ... That is, at that point it can only store multiples of 2. (And then later, it can only count by fours [multiples of 4], and then later only by eights [multiples of 8], etc.)
For completeness: The format can (exactly) represent much larger integers, it's just that at that magnitude, it can't represent all of them, because the format uses a base value (mantissa) and an exponent, and when you reach 253, the exponent is such that only even numbers (multiples of 2) can be represented. Later the exponent rolls over again and only multiples of 4 can be represented, etc.
Let's visualize this a bit. IEEE-754 is fairly complex, but let's take a simplified example (which isn't IEEE-754) just for the purposes of explanation. Suppose we have four bits to store an exponent and eight bits to store a mantissa, and let's say we only store whole numbers. That means with exponent = 1, we can store the values 0 through 255:
CONCEPTUAL, *NOT* IEEE-754!
Exponent (binary) Mantissa (binary) Result Value (decimal)
0 0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 1 1
0 0 0 1 0 0 0 0 0 0 1 0 2
...
0 0 0 1 1 1 1 1 1 1 1 0 254
0 0 0 1 1 1 1 1 1 1 1 1 255
We're maxed out in the mantissa, so we sacrifice precision for range by using exponent = 2 and making the mantissa multiples of 2. Now we can only count by twos:
CONCEPTUAL, *NOT* IEEE-754!
Exponent (binary) Mantissa (binary) Result Value (decimal)
0 0 0 2 0 0 0 0 0 0 0 1 2
0 0 0 2 0 0 0 0 0 0 1 0 4
...
0 0 0 2 0 1 1 1 1 1 1 1 254
0 0 0 2 1 0 0 0 0 0 0 0 256
0 0 0 2 1 0 0 0 0 0 0 1 258
...
0 0 0 2 1 1 1 1 1 1 1 0 508
0 0 0 2 1 1 1 1 1 1 1 1 510
Notice that we can represent the value 256 precisely, even though it's out of the range the mantissa could handle on its own (0-255), because with the exponent we take the mantissa value (128) and double it to get 256. That's exactly what happens with 253 in a double. But we can't represent 257, because at that magnitude we can only handle multiples of 2. That's what happens with 253 + 1 in a double, we can't represent it. We can represent 253 + 2 though.