Baseline Widely available
BigInt
Werte repräsentieren Ganzzahlwerte, die zu hoch oder zu niedrig sind, um durch den number
Primitiv dargestellt zu werden.
Ein BigInt Wert, manchmal einfach nur BigInt genannt, ist ein bigint
Primitiv, das durch Anhängen von n
an das Ende eines ganzzahligen Literals erstellt wird oder durch Aufrufen der BigInt()
Funktion (ohne den new
Operator) unter Angabe eines Ganzzahlen- oder Stringwerts.
const previouslyMaxSafeInteger = 9007199254740991n;
const alsoHuge = BigInt(9007199254740991);
// 9007199254740991n
const hugeString = BigInt("9007199254740991");
// 9007199254740991n
const hugeHex = BigInt("0x1fffffffffffff");
// 9007199254740991n
const hugeOctal = BigInt("0o377777777777777777");
// 9007199254740991n
const hugeBin = BigInt(
"0b11111111111111111111111111111111111111111111111111111",
);
// 9007199254740991n
BigInt-Werte sind in einigen Aspekten ähnlich zu Number-Werten, unterscheiden sich jedoch in einigen wichtigen Punkten: Ein BigInt-Wert kann nicht mit Methoden des eingebauten Math
Objekts verwendet werden und kann in Operationen nicht mit einem Number-Wert gemischt werden; sie müssen auf denselben Typ gezwungen werden. Seien Sie vorsichtig beim Hin- und Herzwingen von Werten, da die Genauigkeit eines BigInt-Werts verloren gehen kann, wenn er in einen Number-Wert umgewandelt wird.
Beim Testen mit typeof
gibt ein BigInt-Wert (bigint
Primitiv) "bigint"
zurück:
typeof 1n === "bigint"; // true
typeof BigInt("1") === "bigint"; // true
Ein BigInt-Wert kann auch in einem Object
verpackt werden:
typeof Object(1n) === "object"; // true
Operatoren
Die meisten Operatoren unterstützen BigInts, jedoch erlauben die meisten keine Operanden aus gemischten Typen â beide Operanden müssen BigInt sein oder keiner:
+
, -
, *
, /
, %
, **
>>
, <<
, &
, |
, ^
, ~
-
)++
, --
Die boolean-rückgebenden Operatoren erlauben die Mischung von Zahlen und BigInts als Operanden:
>
, <
, >=
, <=
, ==
, !=
, ===
, !==
Einige Operatoren unterstützen BigInt überhaupt nicht:
+
) kann nicht unterstützt werden aufgrund der widersprüchlichen Nutzung in asm.js und wurde ausgelassen um asm.js nicht zu beschädigen.>>>
) ist der einzige bitweise Operator, der nicht unterstützt wird, da jeder BigInt-Wert ein Vorzeichen hat.Besondere Fälle:
+
), die eine Zeichenkette und ein BigInt beinhaltet, gibt eine Zeichenkette zurück./
) schneidet gebrochene Komponenten Richtung Null ab, da BigInt nicht in der Lage ist, gebrochene Mengen darzustellen.const previousMaxSafe = BigInt(Number.MAX_SAFE_INTEGER); // 9007199254740991n
const maxPlusOne = previousMaxSafe + 1n; // 9007199254740992n
const theFuture = previousMaxSafe + 2n; // 9007199254740993n, this works now!
const prod = previousMaxSafe * 2n; // 18014398509481982n
const diff = prod - 10n; // 18014398509481972n
const mod = prod % 10n; // 2n
const bigN = 2n ** 54n; // 18014398509481984n
bigN * -1n; // -18014398509481984n
const expected = 4n / 2n; // 2n
const truncated = 5n / 2n; // 2n, not 2.5n
Vergleiche
Ein BigInt-Wert ist nicht strikt gleich einem Number-Wert, aber er ist es lose:
0n === 0; // false
0n == 0; // true
Ein Number-Wert und ein BigInt-Wert können wie gewohnt verglichen werden:
1n < 2; // true
2n > 1; // true
2 > 2; // false
2n > 2; // false
2n >= 2; // true
BigInt- und Number-Werte können in Arrays gemischt und sortiert werden:
const mixed = [4n, 6, -12n, 10, 4, 0, 0n];
// [4n, 6, -12n, 10, 4, 0, 0n]
mixed.sort(); // default sorting behavior
// [ -12n, 0, 0n, 10, 4n, 4, 6 ]
mixed.sort((a, b) => a - b);
// won't work since subtraction will not work with mixed types
// TypeError: can't convert BigInt value to Number value
// sort with an appropriate numeric comparator
mixed.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
// [ -12n, 0, 0n, 4n, 4, 6, 10 ]
Beachten Sie, dass Vergleiche mit Object
-eingewickelten BigInt-Werten wie mit anderen Objekten agieren und nur Gleichheit anzeigen, wenn derselbe Objektinstanz verglichen wird:
Object(0n) === 0n; // false
Object(0n) === Object(0n); // false
const o = Object(0n);
o === o; // true
Da das Erzwingen zwischen Number-Werten und BigInt-Werten zu einem Verlust der Präzision führen kann, wird folgendes empfohlen:
Ein BigInt-Wert folgt denselben Konvertierungsregeln wie Numbers, wenn:
Boolean
konvertiert wird: über die Boolean
Funktion;||
, &&
und !
verwendet wird; oderif
Statement.Nämlich, nur 0n
ist falsy; alles andere ist truthy.
if (0n) {
console.log("Hello from the if!");
} else {
console.log("Hello from the else!");
}
// "Hello from the else!"
0n || 12n; // 12n
0n && 12n; // 0n
Boolean(0n); // false
Boolean(12n); // true
!12n; // false
!0n; // true
Kryptografie
Die auf BigInt-Werten unterstützten Operationen sind nicht konstant der Zeit und somit anfällig für Timing-Angriffe. JavaScript BigInts könnten daher gefährlich sein, wenn sie ohne AbhilfemaÃnahmen in der Kryptografie verwendet werden. Ein sehr generisches Beispiel könnte ein Angreifer die Zeitdifferenz zwischen 101n ** 65537n
und 17n ** 9999n
messen und die GröÃe von Geheimnissen, wie privaten Schlüsseln, basierend auf der verstrichenen Zeit ableiten. Wenn Sie dennoch BigInts verwenden müssen, schauen Sie sich den Timing Attack FAQ für allgemeine Ratschläge zu diesem Thema an.
Die Verwendung von JSON.stringify()
mit einem BigInt-Wert wird einen TypeError
auslösen, da BigInt-Werte im JSON standardmäÃig nicht serialisiert werden. Allerdings lässt JSON.stringify()
speziell eine Hintertür für BigInt-Werte: es versucht, die toJSON()
Methode des BigInt aufzurufen. (Dies geschieht nicht für andere primitive Werte.) Daher können Sie Ihre eigene toJSON()
Methode implementieren (was einer der wenigen Fälle ist, in denen das Patchen von eingebauten Objekten nicht ausdrücklich entmutigt wird):
BigInt.prototype.toJSON = function () {
return { $bigint: this.toString() };
};
Anstatt einen Fehler auszulösen, erzeugt JSON.stringify()
nun einen String wie diesen:
console.log(JSON.stringify({ a: 1n }));
// {"a":{"$bigint":"1"}}
Wenn Sie nicht BigInt.prototype
patchen möchten, können Sie den replacer
Parameter von JSON.stringify
verwenden, um BigInt-Werte zu serialisieren:
const replacer = (key, value) =>
typeof value === "bigint" ? { $bigint: value.toString() } : value;
const data = {
number: 1,
big: 18014398509481982n,
};
const stringified = JSON.stringify(data, replacer);
console.log(stringified);
// {"number":1,"big":{"$bigint":"18014398509481982"}}
Sie können dann den reviver
Parameter von JSON.parse
verwenden, um sie zu handhaben:
const reviver = (key, value) =>
value !== null &&
typeof value === "object" &&
"$bigint" in value &&
typeof value.$bigint === "string"
? BigInt(value.$bigint)
: value;
const payload = '{"number":1,"big":{"$bigint":"18014398509481982"}}';
const parsed = JSON.parse(payload, reviver);
console.log(parsed);
// { number: 1, big: 18014398509481982n }
Hinweis: Obwohl es möglich ist, den Replacer von JSON.stringify()
generisch zu machen und BigInt-Werte für alle Objekte wie oben gezeigt korrekt zu serialisieren, muss der Reviver von JSON.parse()
mit Vorsicht eingesetzt werden, da die Serialisierung irreversibel ist: es ist nicht möglich, zwischen einem Objekt, das zufällig eine Eigenschaft namens $bigint
hat, und einem tatsächlichen BigInt zu unterscheiden.
Darüber hinaus erzeugt das obige Beispiel während des Ersetzens und Wiederherstellens ein gesamtes Objekt, was für gröÃere Objekte, die viele BigInts enthalten, Leistungs- oder Speicherimplikationen haben kann. Wenn Sie die Form der Nutzlast kennen, kann es besser sein, sie einfach als Strings zu serialisieren und sie anhand des Eigenschaftsschlüsselnamens wiederherzustellen.
Tatsächlich erlaubt JSON Zahlenliterale, die willkürlich lang sind; sie können nur in JavaScript nicht mit voller Präzision geparst werden. Wenn Sie mit einem anderen Programm in einer Sprache kommunizieren, die längere Ganzzahlen unterstützt (wie 64-Bit-Ganzzahlen), und Sie möchten das BigInt lieber als JSON-Zahl anstatt als JSON-String übertragen, siehe Lossless number serialization.
BigInt-KoerzierungViele eingebaute Operationen, die BigInts erwarten, zwingen ihre Argumente zuerst zu BigInts. Die Operation kann wie folgt zusammengefasst werden:
undefined
und null
werfen einen TypeError
.true
wird zu 1n
; false
wird zu 0n
.SyntaxError
. Die Syntax ist ein Teilmenge von Nummerische String-Literale, wobei Dezimalpunkte oder Exponenten-Indikatoren nicht erlaubt sind.TypeError
, um zu verhindern, dass unbeabsichtigte implizite Koerzierung zu einem Verlust der Genauigkeit führt.TypeError
.[Symbol.toPrimitive]()
(mit "number"
als Hinweis), valueOf()
, und toString()
Methoden, in dieser Reihenfolge. Das resultierende Primitiv wird dann in ein BigInt umgewandelt.Der beste Weg, um nahezu denselben Effekt in JavaScript zu erzielen, ist die Verwendung der BigInt()
Funktion: BigInt(x)
verwendet denselben Algorithmus, um x
zu konvertieren, mit der Ausnahme, dass Zahlen keinen TypeError
werfen, sondern zu BigInts konvertiert werden, wenn sie Ganzzahlen sind.
Beachten Sie, dass eingebaute Operationen, die BigInts erwarten, oft das BigInt nach der Koerzierung auf eine feste Breite kürzen. Dies schlieÃt BigInt.asIntN()
, BigInt.asUintN()
, und Methoden von BigInt64Array
und BigUint64Array
ein.
BigInt()
Gibt primitive Werte des Typs BigInt zurück. Wirft einen Fehler, wenn er mit new
aufgerufen wird.
BigInt.asIntN()
Begrenzt einen BigInt-Wert auf einen vorzeichenbehafteten Ganzzahlenwert und gibt diesen Wert zurück.
BigInt.asUintN()
Begrenzt einen BigInt-Wert auf einen nicht vorzeichenbehafteten Ganzzahlenwert und gibt diesen Wert zurück.
Diese Eigenschaften sind in BigInt.prototype
definiert und werden von allen BigInt
Instanzen geteilt.
BigInt.prototype.constructor
Die Konstruktionsfunktion, die das Instanzobjekt erstellt hat. Für BigInt
Instanzen ist der Anfangswert der BigInt
Konstruktor.
BigInt.prototype[Symbol.toStringTag]
Der Anfangswert der [Symbol.toStringTag]
Eigenschaft ist der String "BigInt"
. Diese Eigenschaft wird in Object.prototype.toString()
verwendet. Da jedoch BigInt
auch seine eigene toString()
Methode hat, wird diese Eigenschaft nicht verwendet, es sei denn, Sie rufen Object.prototype.toString.call()
mit einem BigInt als thisArg
auf.
BigInt.prototype.toLocaleString()
Gibt einen String mit einer sprachabhängigen Darstellung dieses BigInt-Werts zurück. Ãberschreibt die Object.prototype.toLocaleString()
Methode.
BigInt.prototype.toString()
Gibt einen String zurück, der diesen BigInt-Wert in der angegebenen Basis (Radix) repräsentiert. Ãberschreibt die Object.prototype.toString()
Methode.
BigInt.prototype.valueOf()
Gibt diesen BigInt-Wert zurück. Ãberschreibt die Object.prototype.valueOf()
Methode.
function isPrime(n) {
if (n < 2n) {
return false;
}
if (n % 2n === 0n) {
return n === 2n;
}
for (let factor = 3n; factor * factor <= n; factor += 2n) {
if (n % factor === 0n) {
return false;
}
}
return true;
}
// Takes a BigInt value as an argument, returns nth prime number as a BigInt value
function nthPrime(nth) {
let maybePrime = 2n;
let prime = 0n;
while (nth >= 0n) {
if (isPrime(maybePrime)) {
nth--;
prime = maybePrime;
}
maybePrime++;
}
return prime;
}
nthPrime(20n);
// 73n
Hinweis: Die isPrime()
Implementierung dient nur zur Demonstration. Für eine Anwendung in der realen Welt sollten Sie einen stark memoisierten Algorithmus wie das Sieb des Eratosthenes verwenden, um wiederholte Berechnungen zu vermeiden.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4