Viele Antworten aus früheren Zeiten haben das Ergebnis zeigen , true
der 9007199254740992 === 9007199254740992 + 1
zu verifizieren , dass 9 007 199 254 740 991 die maximale und sichere ganze Zahl ist.
Was ist, wenn wir weiter akkumulieren:
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
Wir konnten feststellen, dass unter den Zahlen von mehr als 9 007 199 254 740 992 , nur gerade Zahlen sind darstellbar .
Es ist ein Eingang, um zu erklären, wie das 64-Bit-Binärformat mit doppelter Genauigkeit dabei funktioniert. Mal sehen, wie 9 007 199 254 740 992 unter Verwendung dieses Binärformats gehalten (dargestellt) werden.
Verwenden Sie eine kurze Version, um dies anhand von 4 503 599 627 370 496 zu demonstrieren :
1 . 0000 ---- 0000 * 2^52 => 1 0000 ---- 0000.
|-- 52 bits --| |exponent part| |-- 52 bits --|
Auf der linken Seite des Pfeils haben wir den Bitwert 1 und einen benachbarten Radixpunkt. Durch Multiplizieren 2^52
bewegen wir den Radixpunkt 52 Schritte nach rechts und er geht bis zum Ende. Jetzt erhalten wir 4503599627370496 in binärer Form.
Jetzt beginnen wir, 1 auf diesen Wert zu akkumulieren, bis alle Bits auf 1 gesetzt sind, was 9 007 199 254 740 991 in Dezimalzahl entspricht.
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.
Da im 64-Bit-Binärformat mit doppelter Genauigkeit ausschließlich 52 Bit für den Bruch zugewiesen werden, steht kein Bit mehr zum Hinzufügen einer weiteren 1 zur Verfügung. Wir können also alle Bits auf 0 und zurücksetzen manipuliere den Exponententeil:
|--> 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 --|
Jetzt bekommen wir die 9 007 199 254 740 992 , und mit der Nummer größer ist als es, was das Format halten könnte , ist 2 mal die Fraktion , bedeutet dies nun all 1 zusätzlich auf dem Bruchteil entspricht tatsächlich bis 2 hinaus, das ist , warum Doppel -präzises 64-Bit-Binärformat kann keine ungeraden Zahlen enthalten, wenn die Zahl größer als 9 007 199 254 740 992 ist :
(consume 2^52 to move radix point to the end)
1 . 0000 ---- 0001 * 2^53 => 1 0000 ---- 0001. * 2
|-- 52 bits --| |-- 52 bits --|
Wenn also die Zahl größer als 9 007 199 254 740 992 * 2 = 18 014 398 509 481 984 wird, kann nur das 4-fache der Fraktion gehalten werden:
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
Wie wäre es mit einer Zahl zwischen [ 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 --|
Der Bitwert 1 nach dem Radixpunkt ist genau 2 ^ -1. (= 1/2 , = 0,5) Wenn also die Zahl kleiner als 4 503 599 627 370 496 (2 ^ 52) ist, steht ein Bit zur Verfügung, um das 1/2-fache der Ganzzahl darzustellen :
input: 4503599627370495.5 output: 4503599627370495.5
input: 4503599627370495.75 output: 4503599627370495.5
Weniger als 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"
Und was ist der verfügbare Bereich des Exponententeils ? Das Format weist 11 Bits dafür zu. Vollständiges Format aus dem Wiki : (Weitere Details finden Sie dort)
Damit der Exponententeil 2 ^ 52 ist, müssen wir genau e = 1075 setzen.