Многие ответы ранее показывают результат true
из 9007199254740992 === 9007199254740992 + 1
сказать, что 9 007 199 254 740 991 является максимально безопасным целым числом.
Что если мы продолжим накопление:
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
Мы могли бы выяснить, что среди чисел, больших 9 007 199 254 740 992 , только четные числа представимы .
Это запись, объясняющая, как 64-битный двоичный формат двойной точности работает над этим. Давайте посмотрим, как 9 007 199 254 740 992 хранится (представляется) с использованием этого двоичного формата.
Мы начинаем с 4 503 599 627 370 496 с первой краткой версией формата:
1 . 0000 ---- 0000 * 2^52 => 1 0000 ---- 0000.
|-- 52 bits --| |exponent part| |-- 52 bits --|
На стороне перед стрелкой у нас есть битовое значение 1 и смежная осевая точка , затем, умножив 2^52
, мы вправо переместим основную точку 52 шага, и это идет до конца. Теперь мы получаем 4503599627370496 в двоичном формате.
Теперь мы начинаем накапливать 1 к этому значению, пока все биты не будут установлены в 1, что равняется 9 007 199 254 740 991 в десятичном виде.
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.
Теперь, поскольку в 64-битном двоичном формате с двойной точностью он строго выделяет 52 бита для дроби, больше нет битов для переноса для добавления еще 1, поэтому мы можем сделать следующее: устанавливая все биты обратно в 0 и манипулируя экспонентой:
|--> This bit is implicit and persistent.
|
1 . 1111 ---- 1111 * 2^52 => 1 1111 ---- 1111.
|-- 52 bits --| |-- 52 bits --|
(+1)
(radix point has no way to go)
1 . 0000 ---- 0000 * 2^52 * 2 => 1 0000 ---- 0000. * 2
|-- 52 bits --| |-- 52 bits --|
=> 1 . 0000 ---- 0000 * 2^53
|-- 52 bits --|
Теперь мы получаем 9 007 199 254 740 992 , и с числом, большим его, формат может содержать 2 раза от дроби :
(consume 2^52 to move radix point to the end)
1 . 0000 ---- 0001 * 2^53 => 1 0000 ---- 0001. * 2
|-- 52 bits --| |-- 52 bits --|
Таким образом, когда число становится больше 9 007 199 254 740 992 * 2 = 18 014 398 509 481 984, может быть проведено только 4 раза от дроби :
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
Как насчет числа между [ 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 --|
Значение бита 1 после радикальной точки равно 2 ^ -1. (= 1/2, = 0,5)
Таким образом, когда число меньше 4 503 599 627 370 496 (2 ^ 52), становится доступным один бит для представления 1/2 раз целого числа :
input: 4503599627370495.5 output: 4503599627370495.5
input: 4503599627370495.75 output: 4503599627370495.5
Менее 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
// If the digits exceed 17, JavaScript round it to print it.
//, but the value is 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"
А каков доступный диапазон экспонентной части ? формат выделяет для него 11 битов.
Полный формат: Wiki : (для более подробной информации перейдите по ссылке)
Таким образом, чтобы сделать экспоненту 2 ^ 52, нам точно нужно установить e = 1075.