Название | JavaScript – Das Handbuch für die Praxis |
---|---|
Автор произведения | David Flanagan |
Жанр | Математика |
Серия | |
Издательство | Математика |
Год выпуска | 0 |
isbn | 9783960104926 |
-Number.MIN_VALUE/2 // => -0: Negative Null.
-1/Infinity // -> -0: Ebenfalls negative Null.
-0
// Die folgenden Eigenschaften des Number-Datentyps sind in ES6 definiert.
Number.parseInt() // Dasselbe wie die globale parseInt()-Funktion.
Number.parseFloat() // Dasselbe wie die globale parseFloat()-Funktion.
Number.isNaN(x) // Ist x der NaN-Wert?
Number.isFinite(x) // Ist x eine Zahl und endlich?
Number.isInteger(x) // Ist x eine Ganzzahl?
Number.isSafeInteger(x) // Ist x eine Ganzzahl -(2**53) < x < 2**53?
Number.MIN_SAFE_INTEGER // => -(2**53 - 1)
Number.MAX_SAFE_INTEGER // => 2**53 - 1
Number.EPSILON // => 2**-52: Kleinste Differenz zwischen Zahlen.
NaN hat in JavaScript eine ungewöhnliche Eigenschaft: Dieser Wert ist keinem anderen Wert gleich, nicht einmal sich selbst. Das heißt, Sie können nicht x === NaN benutzen, um zu prüfen, ob der Wert einer Variablen x gleich NaN ist. Stattdessen müssen Sie x != x oder Number.isNaN(x) schreiben. Diese Ausdrücke sind wahr, wenn – und nur, wenn – x den gleichen Wert wie die globale Konstante NaN hat.
Die globale Funktion isNaN() ähnelt Number.isNaN(). Sie liefert true, wenn ihr Argument NaN ist oder ein nicht numerischer Wert, der nicht in einen numerischen Wert umgewandelt werden kann. Die verwandte Funktion Number.isFinite() liefert true, wenn ihr Argument eine Zahl ungleich NaN, Infinity oder -Infinity ist. Die globale Funktion isFinite() gibt true zurück, wenn ihr Argument eine endliche Zahl ist oder in diese konvertiert werden kann.
Der negative Nullwert ist ebenfalls etwas ungewöhnlich. Er wird als gleich (selbst beim strikten Gleichheitstest von JavaScript) mit der positiven Null erkannt, sodass die beiden Werte kaum zu unterscheiden sind, es sei denn, sie werden als Divisor verwendet:
let zero = 0; // Gewöhnliche Null.
let negz = -0; // Negative Null.
zero === negz // => true: Die beiden Nullwerte sind gleich.
1/zero === 1/negz // => false: Infinity und -Infinity sind nicht gleich.
3.2.4Binäre Gleitkomma- und Rundungsfehler
Es gibt unendlich viele reelle Zahlen, aber nur eine begrenzte Anzahl von ihnen (18.437.736.874.454.810.627, um genau zu sein) kann durch das JavaScript-Gleitkommaformat exakt dargestellt werden. Das heißt, dass die Darstellungen der Gleitkommazahlen, mit denen Sie in JavaScript arbeiten, häufig nur Näherungswerte der eigentlichen Zahlen sind.
Die von JavaScript (und so gut wie allen anderen modernen Programmiersprachen) genutzte IEEE-754-Gleitkommarepräsentation ist eine binäre Darstellung, die Brüche wie 1/2, 1/8 und 1/1024 genau abbilden kann. Unglücklicherweise sind die Brüche, die wir am häufigsten verwenden (insbesondere bei der Durchführung von finanzmathematischen Berechnungen), dezimale Brüche wie 1/10, 1/100 usw. Binäre Gleitkommarepräsentationen können deshalb so einfache Zahlen wie 0,1 nicht genau darstellen.
In JavaScript besitzen Zahlen eine hohe Genauigkeit und können sich 0,1 sehr stark nähern. Dass eine Zahl wie 0,1 aber nicht exakt dargestellt werden kann, führt bisweilen zu Problemen. Betrachten Sie zur Illustration folgenden Code:
let x = .3 - .2; // 30 Cent minus 20 Cent.
let y = .2 - .1; // 20 Cent minus 10 Cent.
x === y // => false: Die beiden Werte sind nicht gleich!
x === .1 // => false: .3 - .2 ist nicht gleich .1.
y === .1 // => true: .2 - .1 ist gleich .1.
Der Rundungsfehler ist dafür verantwortlich, dass der Unterschied zwischen den Näherungswerten für 0,3 und 0,2 nicht dem Unterschied zwischen den Näherungswerten für 0,2 und 0,1 entspricht. Sie sollten sich dessen bewusst sein, dass dies kein JavaScript-spezifisches Problem ist – es betrifft alle Programmiersprachen, die mit binären Gleitkommazahlen arbeiten. Beachten Sie bitte auch, dass die Werte von x und y im hier gezeigten Code einander und dem korrekten Wert sehr nahe kommen. Die berechneten Werte sind für die meisten Zwecke also vollkommen ausreichend – bemerkbar macht sich dieses Problem vor allem, wenn wir Werte auf Gleichheit prüfen.
Falls diese Gleitkommanäherungen für Ihre Programme problematisch sind, sollten Sie die Verwendung skalierter Ganzzahlen in Betracht ziehen. Beispielsweise könnten Sie Werte, die Geldbeträge repräsentieren, als ganze Cent statt anteilige Euro ausdrücken.
3.2.5Langzahlarithmetik mit BigInt
Eines der neuesten JavaScript-Features, definiert in ES2020, ist ein neuer numerischer Typ, bekannt als BigInt. Anfang 2020 war BigInt in Chrome, Firefox, Edge und Node implementiert. Die Umsetzung in Safari war zu diesem Zeitpunkt noch nicht abgeschlossen. Wie der Name schon sagt, ist BigInt ein numerischer Datentyp, dessen Werte Ganzzahlen sind. Dieser Typ wurde JavaScript hauptsächlich hinzugefügt, um die Darstellung von 64-Bit-Ganzzahlen zu ermöglichen, die für die Kompatibilität mit vielen anderen Programmiersprachen und APIs erforderlich sind. BigInt-Werte können Tausende oder sogar Millionen von Ziffern haben, sollten Sie mit so großen Zahlen arbeiten müssen. (Bitte beachten Sie, dass BigInt-Implementierungen nicht für Kryptografie geeignet sind, da sie nicht versuchen, Rechenzeitangriffe zu verhindern.)
BigInt-Literale werden als Zeichenketten aus Ziffern geschrieben, gefolgt von einem Kleinbuchstaben n. Standardmäßig beziehen sie sich auf die Basis 10. Sie können die Präfixe 0b, 0o und 0x für binäre, oktale und hexadezimale BigInts verwenden:
1234n // Ein nicht so großes BigInt-Literal.
0b111111n // Ein binäres BigInt.
0o7777n // Ein oktales BigInt.
0x8000000000000000n // => 2n**63n: Eine 64-Bit-Ganzzahl.
Sie können BigInt() als Funktion verwenden, um reguläre JavaScript-Zahlen oder -Strings in BigInt-Werte zu konvertieren:
BigInt(Number.MAX_SAFE_INTEGER) // => 9007199254740991n
let string = "1" + "0".repeat(100); // 1 gefolgt von 100 Nullen.
BigInt(string) // => 10n**100n: Ein Googol.
Die Arithmetik mit BigInt-Werten funktioniert wie die Arithmetik mit regulären JavaScript-Zahlen, abgesehen davon, dass bei Divisionen der Rest abgeschnitten und abgerundet wird (also Richtung null):
1000n + 2000n // => 3000n
3000n - 2000n // => 1000n
2000n * 3000n // => 6000000n
3000n / 997n // => 3n: Der Quotient ist 3.
3000n % 997n // => 9n: Der Rest ist 9.
(2n ** 131071n) - 1n // Eine Mersenne-Primzahl mit 39.457 Dezimalstellen.
Obwohl die Standardoperatoren +, -, *, /, % und ** mit BigInt arbeiten, muss man beachten, dass Operanden des Typs BigInt nicht mit regulären Zahlen als Operanden gemischt werden dürfen. Dies mag zunächst verwirrend erscheinen, aber es gibt einen guten Grund dafür. Wäre ein numerischer Typ allgemeiner als der andere, könnte man die Arithmetik auf gemischten Operanden so definieren, dass einfach ein Wert des allgemeineren Typs zurückgegeben wird. Aber keiner der beiden Typen ist allgemeiner als der andere: BigInt kann außerordentlich große Werte darstellen, was diesen Datentyp allgemeiner macht als normale Zahlen. BigInt kann jedoch nur ganze Zahlen darstellen, was wiederum den regulären JavaScript-Typ Number zum allgemeineren macht. Das Problem lässt sich nicht so einfach lösen, sodass JavaScript es stattdessen vermeidet,