Why is Number.MAX_SAFE_INTEGER 9,007,199,254,740,991 and not 9,007,199,254,740,992? Why is Number.MAX_SAFE_INTEGER 9,007,199,254,740,991 and not 9,007,199,254,740,992? javascript javascript

Why is Number.MAX_SAFE_INTEGER 9,007,199,254,740,991 and not 9,007,199,254,740,992?


I would say its because while Math.pow(2, 53) is the largest directly representable integer, its unsafe in that its also the first value who's representation is also an approximation of another value:

9007199254740992 == 9007199254740993 // true

In contrast to Math.pow(2, 53) - 1:

9007199254740991 == 9007199254740993 // false


the only number which is in close proximity of anotherwhen compared with its next number shows true

9007199254740992 == 9007199254740993true9007199254740993 == 9007199254740994false9007199254740991 == 9007199254740992false9007199254740997 == 9007199254740998false


I also have the same concern about the question. <JavaScript: The Definitive Guide> said the safe range is -2^53~2^53(Including boundary values) while <You don't know JavaScript> said the range is-2^53+1~2^53-1.

Finally, I found the Correct interpretation in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger

It said, the "safe"means :

  1. can be exactly represented as an IEEE-754 double precision number, and
  2. whose IEEE-754 representation cannot be the result of rounding any other integer to fit the IEEE-754 representation.

So 2^53 is not a safe integer because :it can be exactly represented in IEEE-754, but the integer 2^53 + 1 can't be directly represented in IEEE-754 but instead rounds to 2^53 under round-to-nearest and round-to-zero rounding.