Подтвердить что ты не робот

Почему Number.MAX_SAFE_INTEGER 9,007,199,254,740,991, а не 9 007 199 254 740 992?

ECMAScript 6 Number.MAX_SAFE_INTEGER предположительно представляет максимальное числовое значение, которое JavaScript может хранить до возникновения проблем с точностью с плавающей запятой. Однако это требование, чтобы число 1, добавленное к этому значению, также должно быть представлено как Number.

Number.MAX_SAFE_INTEGER

ПРИМЕЧАНИЕ. Значение Number.MAX_SAFE_INTEGER является наибольшим целым числом n таким образом, что n и n + 1 оба точно представляются как значение Number.

Значение Number.MAX_SAFE_INTEGER равно 9007199254740991 (2^53−1).

- Спецификация языка ECMAScript

Консоли JavaScript Chrome, Firefox, Opera и IE11 могут безопасно выполнять вычисления с номером 9,007,199,254,740,992. Некоторые тесты:

// Valid
Math.pow(2, 53)                         // 9007199254740992
9007199254740991 + 1                    // 9007199254740992
9007199254740992 - 1                    // 9007199254740991
9007199254740992 / 2                    // 4503599627370496
4503599627370496 * 2                    // 9007199254740992
parseInt('20000000000000', 16)          // 9007199254740992
parseInt('80000000000', 32)             // 9007199254740992
9007199254740992 - 9007199254740992     // 0
9007199254740992 == 9007199254740991    // false
9007199254740992 == 9007199254740992    // true

// Erroneous
9007199254740992 + 1                    // 9007199254740992
9007199254740993 + ""                   // "9007199254740992"
9007199254740992 == 9007199254740993    // true

Почему требуется, чтобы n + 1 также представлялся как Number? Почему это не делает это опасным?

4b9b3361

Ответ 1

Я бы сказал, потому что, хотя Math.pow(2, 53) является наибольшим непосредственно представимым целым числом, его небезопасно в том, что его также первое значение, которое представляет собой также приближение другого значения:

9007199254740992 == 9007199254740993 // true

В отличие от Math.pow(2, 53) - 1

9007199254740991 == 9007199254740993 // false