Angka dalam JavaScript adalah titik mengambang biner presisi ganda IEEE-754, format yang cukup ringkas (64 bit) yang menyediakan penghitungan cepat dan jangkauan yang luas. Ini dilakukan dengan menyimpan angka sebagai bit tanda, eksponen 11-bit, dan signifikansi 52-bit (meskipun melalui kepintaran itu sebenarnya mendapat presisi 53 bit). Ini adalah titik mengambang biner (basis 2): Signifikan (ditambah beberapa kepintaran) memberi kita nilai, dan eksponen memberi kita besarnya angka tersebut.
Secara alami, dengan begitu banyak bit yang signifikan, tidak setiap nomor dapat disimpan. Berikut adalah angka 1, dan angka tertinggi berikutnya setelah 1 yang dapat disimpan oleh format, 1 + 2 -52 ≈ 1,00000000000000022, dan tertinggi berikutnya setelah itu 1 + 2 × 2 -52 ≈ 1,00000000000000044:
+ ------------------------------------------------- -------------- tanda sedikit
/ + ------- + ---------------------------------------- -------------- eksponen
/ / | + ------------------------------------------------- + - signifikan
/ / | / |
0 01111111111 000000000000000000000000000000000000000000000000000000
= 1
0 01111111111 0000000000000000000000000000000000000000000000000001
≈ 1,00000000000000022
0 01111111111 0000000000000000000000000000000000000000000000000010
≈ 1,00000000000000044
Perhatikan lompatan dari 1.00000000000000022 ke 1.00000000000000044; tidak ada cara untuk menyimpan 1.0000000000000003. Itu juga bisa terjadi dengan bilangan bulat: Number.MAX_SAFE_INTEGER(9,007,199,254,740,991) adalah nilai bilangan bulat positif tertinggi yang dapat disimpan oleh format di mana idan i + 1keduanya dapat direpresentasikan secara tepat ( spesifikasi ). Baik 9.007.199.254.740.991 dan 9.007.199.254.740.992 dapat direpresentasikan, tetapi bilangan bulat berikutnya , 9.007.199.254.740.993, tidak dapat; bilangan bulat berikutnya yang dapat kita wakili setelah 9.007.199.254.740.992 adalah 9.007.199.254.740.994. Berikut adalah pola bitnya, perhatikan bit paling kanan (paling tidak signifikan):
+ ------------------------------------------------- -------------- tanda sedikit
/ + ------- + ---------------------------------------- -------------- eksponen
/ / | + ------------------------------------------------- + - signifikan
/ / | / |
0 10000110011 1111111111111111111111111111111111111111111111111111
= 9007199254740991 (Nomor.MAX_SAFE_INTEGER)
0 10000110100 000000000000000000000000000000000000000000000000000000
= 9007199254740992 (Bilangan.MAX_SAFE_INTEGER + 1)
x xxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
9007199254740993 (Number.MAX_SAFE_INTEGER + 2) tidak dapat disimpan
0 10000110100 0000000000000000000000000000000000000000000000000001
= 9007199254740994 (Bilangan.MAX_SAFE_INTEGER + 3)
Ingat, formatnya adalah basis 2, dan dengan eksponen tersebut bit yang paling tidak signifikan tidak lagi pecahan; itu memiliki nilai 2. Bisa off (9,007,199,254,740,992) atau pada (9,007,199,254,740,994); jadi pada titik ini, kita mulai kehilangan presisi bahkan pada skala bilangan bulat (integer). Yang berimplikasi pada loop kami!
Setelah menyelesaikan i = 9,007,199,254,740,992perulangan, i++berikan kami ... i = 9,007,199,254,740,992lagi; tidak ada perubahan i, karena bilangan bulat berikutnya tidak dapat disimpan dan kalkulasi berakhir dengan pembulatan ke bawah. iakan berubah jika kita melakukannya i += 2, tetapi i++tidak dapat mengubahnya. Jadi kita telah mencapai kondisi mapan: itidak pernah berubah, dan loop tidak pernah berhenti.