Zahlen in JavaScript sind binäre Gleitkommazahlen mit doppelter Genauigkeit nach IEEE-754, ein ziemlich kompaktes Format (64 Bit), das schnelle Berechnungen und einen großen Bereich ermöglicht. Dazu wird die Zahl als Vorzeichenbit, 11-Bit-Exponent und 52-Bit-Signifikand gespeichert (obwohl sie durch Cleverness tatsächlich 53 Bit Genauigkeit erhält). Es ist ein binärer Gleitkomma (Basis 2): Der Signifikand (plus etwas Klugheit) gibt uns den Wert und der Exponent gibt uns die Größe der Zahl.
Natürlich kann mit nur so vielen signifikanten Bits nicht jede Zahl gespeichert werden. Hier ist die Zahl 1 und die nächsthöhere Zahl nach 1, die das Format speichern kann, 1 + 2 -52 ≈ 1.00000000000000022 und die nächsthöhere Zahl danach 1 + 2 × 2 -52 ≈ 1.00000000000000044:
+ --------------------------------------------- -------------- Zeichenbit
/ + ------- + ------------------------------------ -------------- Exponent
// | + --------------------------------------------- + - Bedeutung
// | / |
0 01111111111 00000000000000000000000000000000000000000000000000000000
= 1
0 01111111111 000000000000000000000000000000000000000000000000000001
≈ 1.00000000000000022
0 01111111111 000000000000000000000000000000000000000000000000000010
≈ 1.00000000000000044
Beachten Sie den Sprung von 1.00000000000000022 auf 1.00000000000000044; Es gibt keine Möglichkeit, 1.0000000000000003 zu speichern. Das kann mit ganzen Zahlen passieren, auch: Number.MAX_SAFE_INTEGER(9,007,199,254,740,991) ist die höchste positive Zahl , dass das Format halten kann , wo iund i + 1sind beide exakt darstellbar ( spec ). Sowohl 9.007.199.254.740.991 als auch 9.007.199.254.740.992 können dargestellt werden, die nächste Ganzzahl, 9.007.199.254.740.993, jedoch nicht. Die nächste Ganzzahl, die wir nach 9.007.199.254.740.992 darstellen können, ist 9.007.199.254.740.994. Hier sind die Bitmuster. Beachten Sie das Bit ganz rechts (niedrigstwertig):
+ --------------------------------------------- -------------- Zeichenbit
/ + ------- + ------------------------------------ -------------- Exponent
// | + --------------------------------------------- + - Bedeutung
// | / |
0 10000110011 111111111111111111111111111111111111111111111111111111
= 9007199254740991 (Number.MAX_SAFE_INTEGER)
0 10000110100 000000000000000000000000000000000000000000000000000000
= 9007199254740992 (Number.MAX_SAFE_INTEGER + 1)
x xxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
9007199254740993 (Number.MAX_SAFE_INTEGER + 2) kann nicht gespeichert werden
0 10000110100 000000000000000000000000000000000000000000000000000001
= 9007199254740994 (Number.MAX_SAFE_INTEGER + 3)
Denken Sie daran, dass das Format Basis 2 ist und mit diesem Exponenten das niedrigstwertige Bit nicht mehr gebrochen ist. es hat einen Wert von 2. Es kann aus (9.007.199.254.740.992) oder ein (9.007.199.254.740.994) sein; Zu diesem Zeitpunkt haben wir begonnen, die Genauigkeit selbst auf der ganzen Zahlenskala (Ganzzahlskala) zu verlieren. Was Auswirkungen auf unsere Schleife hat!
Nach Abschluss der i = 9,007,199,254,740,992Schleife i++gibt uns ... i = 9,007,199,254,740,992wieder; Es gibt keine Änderung in i, da die nächste Ganzzahl nicht gespeichert werden kann und die Berechnung abgerundet wird. iwürde sich ändern, wenn wir es tun würden i += 2, i++kann es aber nicht ändern. Wir haben also den stationären Zustand erreicht: iÄndert sich nie und die Schleife endet nie.