Liczby w JavaScript to binarne zmiennoprzecinkowe podwójnej precyzji IEEE-754, dość kompaktowy format (64 bity), który zapewnia szybkie obliczenia i szeroki zakres. Czyni to poprzez przechowywanie liczby jako bitu znaku, 11-bitowego wykładnika i 52-bitowego znaczenia (chociaż dzięki sprytowi faktycznie uzyskuje 53 bity precyzji). Jest to liczba zmiennoprzecinkowa binarna (podstawa 2): Mantyga (plus trochę sprytu) daje nam wartość, a wykładnik potęgi podaje wielkość liczby.
Oczywiście przy tak wielu znaczących bitach nie każda liczba może zostać zapisana. Oto numer 1, a następny najwyższy numer po 1, że format może przechowywać, 1 + 2 -52 ≈ +1,00000000000000022, a następnego najwyższy po tym 1 + 2 x 2 -52 ≈ 1.00000000000000044:
+ ------------------------------------------------- -------------- znak bitu
/ + ------- + ---------------------------------------- -------------- wykładnik
/ / | + ------------------------------------------------- + - znacznik
/ / | / |
0 01111111111 00000000000000000000000000000000000000000000000000
= 1
0 01111111111 00000000000000000000000000000000000000000000000001
≈ 1,00000000000000022
0 01111111111 00000000000000000000000000000000000000000000000010
≈ 1,00000000000000044
Zwróć uwagę na skok od 1,00000000000000022 do 1,00000000000000044; nie ma sposobu na przechowywanie 1,0000000000000003. Co może się zdarzyć z liczb całkowitych, za: Number.MAX_SAFE_INTEGER(9,007,199,254,740,991) jest najwyższą wartością dodatnią liczbą całkowitą, że format może pomieścić gdzie ii i + 1są zarówno dokładnie reprezentowalna ( specyfikacja ). Można przedstawić zarówno 9 007 199 254 740 991, jak i 9 007 199 254 740 992, ale następna liczba całkowita 9 007 199 254 740 993 nie; następna liczba całkowita, którą możemy przedstawić po 9,007,199,254,740,992, to 9007,199,254,740,994. Oto wzory bitów, zwróć uwagę na najbardziej prawy (najmniej znaczący) bit:
+ ------------------------------------------------- -------------- znak bitu
/ + ------- + ---------------------------------------- -------------- wykładnik
/ / | + ------------------------------------------------- + - znacznik
/ / | / |
0 10000110011 1111111111111111111111111111111111111111111111111111
= 9007199254740991 (Number.MAX_SAFE_INTEGER)
0 10000110100 00000000000000000000000000000000000000000000000000
= 9007199254740992 (liczba.MAX_SAFE_INTEGER + 1)
x xxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Nie można zapisać 9007199254740993 (Number.MAX_SAFE_INTEGER + 2)
0 10000110100 00000000000000000000000000000000000000000000000001
= 9007199254740994 (liczba.MAX_SAFE_INTEGER + 3)
Pamiętaj, że format to podstawa 2, a przy tym wykładniku najmniej znaczący bit nie jest już ułamkowy; ma wartość 2. Może być wyłączony (9 007 199 254 740 992) lub włączony (9 007 199 254 740 994); więc w tym momencie zaczęliśmy tracić precyzję nawet na skali liczb całkowitych (całkowitej). Co ma wpływ na naszą pętlę!
Po wykonaniu i = 9,007,199,254,740,992pętli i++daje nam ... i = 9,007,199,254,740,992znowu; nie ma zmiany i, ponieważ nie można zapisać następnej liczby całkowitej, a obliczenia kończą się zaokrągleniem w dół. izmieniłby się, gdybyśmy to zrobili i += 2, ale i++nie możemy tego zmienić. Osiągnęliśmy więc stan ustalony: inigdy się nie zmienia, a pętla nigdy się nie kończy.