Ist dies in der Sprache festgelegt? Gibt es ein bestimmtes Maximum? Ist es in verschiedenen Browsern unterschiedlich?
Antworten
Zu viele Anzeigen?JavaScript hat zwei Zahlentypen: Number
y BigInt
.
Der am häufigsten verwendete Zahlentyp, Number
ist ein 64-Bit-Gleitkomma IEEE 754 Nummer.
Der größte exakte Integralwert dieser Art ist Number.MAX_SAFE_INTEGER
das ist:
- 2 53 -1, oder
- +/- 9.007.199.254.740.991, oder
- neun Quadrillionen sieben Billionen einhundertneunundneunzig Milliarden zweihundertvierundfünfzig Millionen siebenhundertvierzigtausendneunhunderteinundneunzig
Zum Vergleich: Eine Billiarde Bytes ist ein Petabyte (oder tausend Terabytes).
"Sicher" bezieht sich in diesem Zusammenhang auf die Fähigkeit, ganze Zahlen exakt darzustellen und korrekt zu vergleichen.
Beachten Sie, dass alle positiven und negativen ganzen Zahlen, deren Betrag nicht größer als 2 53 sind darstellbar in der
Number
Typ (in der Tat ist die Ganzzahl 0 hat zwei Darstellungen, +0 und -0).
Um ganze Zahlen, die größer sind, sicher zu verwenden, müssen Sie BigInt
die keine Obergrenze hat.
Beachten Sie, dass die bitweisen Operatoren und die Verschiebeoperatoren mit 32-Bit-Ganzzahlen arbeiten, so dass in diesem Fall die maximal sichere Ganzzahl 2 ist 31 -1, also 2.147.483.647.
const log = console.log
var x = 9007199254740992
var y = -x
log(x == x + 1) // true !
log(y == y - 1) // also true !
// Arithmetic operators work, but bitwise/shifts only operate on int32:
log(x / 2) // 4503599627370496
log(x >> 1) // 0
log(x | 1) // 1
Technische Anmerkung zur Zahl 9.007.199.254.740.992: Es gibt eine exakte IEEE-754-Darstellung dieses Wertes, und Sie können diesen Wert einer Variablen zuweisen und aus ihr lesen, also für sehr sorgfältig gewählten Anwendungen im Bereich der ganzen Zahlen, die kleiner oder gleich diesem Wert sind, könnten Sie dies als Maximalwert behandeln.
Im allgemeinen Fall müssen Sie diesen IEEE-754-Wert als ungenau behandeln, da es nicht eindeutig ist, ob er den logischen Wert 9.007.199.254.740.992 oder 9.007.199.254.740.993 kodiert.
>= ES6:
Number.MIN_SAFE_INTEGER;
Number.MAX_SAFE_INTEGER;
<= ES5
Von die Referenz :
Number.MAX_VALUE;
Number.MIN_VALUE;
console.log('MIN_VALUE', Number.MIN_VALUE);
console.log('MAX_VALUE', Number.MAX_VALUE);
console.log('MIN_SAFE_INTEGER', Number.MIN_SAFE_INTEGER); //ES6
console.log('MAX_SAFE_INTEGER', Number.MAX_SAFE_INTEGER); //ES6
Es sind 2 53 \== 9 007 199 254 740 992. Der Grund dafür ist Number
s werden als Fließkommazahlen mit einer Mantisse von 52 Bit gespeichert.
Der Mindestwert ist -2 53 .
Dies macht einige lustige Dinge passieren
Math.pow(2, 53) == Math.pow(2, 53) + 1
>> true
Und kann auch gefährlich sein :)
var MAX_INT = Math.pow(2, 53); // 9 007 199 254 740 992
for (var i = MAX_INT; i < MAX_INT + 2; ++i) {
// infinite loop
}
Lesen Sie weiter: <a href="http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html" rel="noreferrer">http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html</a>
Viele frühere Antworten haben gezeigt 9007199254740992 === 9007199254740992 + 1
es wahr um zu überprüfen, dass 9,007,199,254,740,991 ist die maximale und sichere ganze Zahl.
Aber 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 können sehen, dass unter den Zahlen größer als 9,007,199,254,740,992 sind nur gerade Zahlen darstellbar .
Es ist ein Eintrag, der erklärt, wie die Doppelpräzisions-64-Bit-Binärformat Werke. Schauen wir mal, wie 9,007,199,254,740,992 unter Verwendung dieses Binärformats gespeichert (dargestellt) werden.
Zur Veranschaulichung eine kurze Version aus 4,503,599,627,370,496 :
1 . 0000 ---- 0000 * 2^52 => 1 0000 ---- 0000.
|-- 52 bits --| |exponent part| |-- 52 bits --|
Auf der linken Seite des Pfeils haben wir Bitwert 1 und ein angrenzendes Radixpunkt . Durch den Verbrauch des Exponententeils auf der linken Seite wird der Radixpunkt um 52 Schritte nach rechts verschoben. Der Radixpunkt landet am Ende, und wir erhalten 4503599627370496 in reinem Binärformat.
Nun erhöhen wir den Bruchteil so lange um 1, bis alle Bits auf 1 gesetzt sind, was gleichbedeutend ist mit 9,007,199,254,740,991 in Dezimalzahlen.
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 das 64-Bit-Doppelpräzisionsformat 52 Bits für den Bruchteil vorsieht, sind keine weiteren Bits verfügbar, wenn wir eine weitere 1 hinzufügen:
This bit is implicit and persistent.
1 . 1111 ---- 1111 * 2^52 => 1 1111 ---- 1111.
|-- 52 bits --| |-- 52 bits --|
(+1)
1 . 0000 ---- 0000 * 2^52 * 2 => 1 0000 ---- 0000. * 2
|-- 52 bits --| |-- 52 bits --|
(By consuming the 2^52, radix
point has no way to go, but
there is still one 2 left in
exponent part)
=> 1 . 0000 ---- 0000 * 2^53
|-- 52 bits --|
Jetzt bekommen wir die 9,007,199,254,740,992 und für die Zahlen, die darüber liegen, kann das Format nur 2er-Schritte verarbeiten, da jeder 1er-Schritt im Bruchteil mit der linken 2 im Exponententeil multipliziert wird. Deshalb ist Doppelpräzisions-64-Bit-Binärformat kann keine ungeraden Zahlen enthalten, wenn die Zahl größer ist als 9,007,199,254,740,992 :
(consume 2^52 to move radix point to the end)
1 . 0000 ---- 0001 * 2^53 => 1 0000 ---- 0001. * 2
|-- 52 bits --| |-- 52 bits --|
Wenn die Zahl größer als 9.007.199.254.740.992 * 2 = 18.014.398.509.481.984 ist, kann der Bruch nur viermal 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 Zahlen 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 Wert 0,1 ist im Binärsystem genau 2^-1 (=1/2) (=0,5) Wenn die Zahl also kleiner ist als 4,503,599,627,370,496 (2^52) steht ein Bit zur Verfügung, das die 1/2 mal der ganzen Zahl :
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
/**
Please note that if you try this yourself and, say, log
these numbers to the console, they will get rounded. JavaScript
rounds if the number of digits exceed 17. The value
is internally 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 wie groß ist die verfügbare Reichweite von Exponententeil ? 11 Bits, die das Format dafür vorsieht.
Von Wikipedia (weitere Einzelheiten finden Sie dort)
Damit der Exponent Teil 2^52 ist, müssen wir e = 1075 setzen.
- See previous answers
- Weitere Antworten anzeigen