BigInt

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2020.

BigInt-Werte repräsentieren Ganzzahlen, die zu groß oder zu klein sind, um durch den number-Basisdatentyp dargestellt zu werden.

Beschreibung

Ein BigInt-Wert, manchmal einfach nur BigInt genannt, ist ein bigint-Basisdatentyp, der erstellt wird, indem man ein n an das Ende eines Ganzzahl-Literals anfügt oder indem man die BigInt()-Funktion (ohne den new-Operator) aufruft und ihr einen Ganzzahl- oder String-Wert gibt.

js
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 Number-Werten ähnlich, unterscheiden sich jedoch in einigen wichtigen Punkten: Ein BigInt-Wert kann nicht mit Methoden des eingebauten Math-Objekts verwendet werden und kann nicht in Operationen mit einem Number-Wert gemischt werden; sie müssen in denselben Typ umgewandelt werden. Seien Sie vorsichtig bei der Umwandlung von Werten hin und her, da die Präzision eines BigInt-Wertes verloren gehen kann, wenn er in einen Number-Wert umgewandelt wird.

Typinformationen

Wenn man typeof auf einen BigInt-Wert (bigint-Basisdatentyp) anwendet, erhält man "bigint":

js
typeof 1n === "bigint"; // true
typeof BigInt("1") === "bigint"; // true

Ein BigInt-Wert kann auch in einem Object eingepackt werden:

js
typeof Object(1n) === "object"; // true

Operatoren

Die meisten Operatoren unterstützen BigInts, jedoch erlauben die meisten es nicht, Operanden gemischter Typen zu verwenden — beide Operanden müssen BigInt oder keiner sein:

Die boolesche Rückgabe der Operatoren erlaubt das Mischen von Numbers und BigInts als Operanden:

Einige Operatoren unterstützen BigInt überhaupt nicht:

Sonderfälle:

  • Addition (+) mit einem String und einem BigInt gibt einen String zurück.
  • Division (/) schneidet Nachkommastellen in Richtung Null ab, da BigInt keine Bruchmengen darstellen kann.
js
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 lose so:

js
0n === 0; // false
0n == 0; // true

Ein Number-Wert und ein BigInt-Wert können wie gewöhnlich verglichen werden:

js
1n < 2; // true
2n > 1; // true
2 > 2; // false
2n > 2; // false
2n >= 2; // true

BigInt-Werte und Number-Werte können in Arrays gemischt und sortiert werden:

js
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-eingepackten BigInt-Werten wie bei anderen Objekten nur Gleichheit anzeigen, wenn dieselbe Objektinstanz verglichen wird:

js
Object(0n) === 0n; // false
Object(0n) === Object(0n); // false

const o = Object(0n);
o === o; // true

Da die Umwandlung zwischen Number-Werten und BigInt-Werten zum Verlust der Genauigkeit führen kann, werden folgende Empfehlungen gegeben:

  • Verwenden Sie einen BigInt-Wert nur, wenn Werte größer als 253 vernünftigerweise erwartet werden.
  • Vermeiden Sie das Umwandeln zwischen BigInt-Werten und Number-Werten.

Konditionen

Ein BigInt-Wert folgt denselben Umwandlungsregeln wie Numbers, wenn:

  • er in einen Boolean umgewandelt wird: über die Boolean-Funktion;
  • bei Verwendung mit logischen Operatoren ||, && und !; oder
  • innerhalb eines konditionalen Tests wie einer if-Anweisung.

Nur 0n ist falsch; alles andere ist wahr.

js
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 in der Ausführungszeit und sind daher anfällig für Timing-Angriffe. JavaScript BigInts könnten daher für die Verwendung in der Kryptografie gefährlich sein, ohne mildernde Maßnahmen zu ergreifen. Ein sehr generisches Beispiel: Ein Angreifer könnte die Zeitdifferenz zwischen 101n ** 65537n und 17n ** 9999n messen und die Größe von Geheimnissen, wie private Schlüssel, basierend auf der vergangenen Zeit ableiten. Wenn Sie dennoch BigInts verwenden müssen, werfen Sie einen Blick auf die Timing Attack FAQ für allgemeine Ratschläge zu diesem Thema.

Verwendung innerhalb von JSON

Die Verwendung von JSON.stringify() mit einem BigInt-Wert führt zu einem TypeError, da BigInt-Werte standardmäßig nicht in JSON serialisiert werden. JSON.stringify() lässt jedoch ausdrücklich eine Hintertür für BigInt-Werte offen: Es versucht, die toJSON()-Methode des BigInts aufzurufen. (Dies tut es für keine anderen Basisdatentypen.) Deshalb können Sie Ihre eigene toJSON()-Methode implementieren (dies ist einer der wenigen Fälle, in denen das Patchen von eingebauten Objekten nicht ausdrücklich abgeraten wird):

js
BigInt.prototype.toJSON = function () {
  return { $bigint: this.toString() };
};

Statt einen Fehler zu werfen, produziert JSON.stringify() jetzt einen String wie diesen:

js
console.log(JSON.stringify({ a: 1n }));
// {"a":{"$bigint":"1"}}

Wenn Sie BigInt.prototype nicht patchen möchten, können Sie den replacer-Parameter von JSON.stringify verwenden, um BigInt-Werte zu serialisieren:

js
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"}}

Anschließend können Sie mit dem reviver-Parameter von JSON.parse mit ihnen umgehen:

js
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: Während es möglich ist, den Replacer von JSON.stringify() allgemein zu machen und BigInt-Werte für alle Objekte korrekt zu serialisieren, muss der Reviver von JSON.parse() mit Vorsicht verwendet 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 beim Ersetzen und Wiederherstellen ein ganzes Objekt, was für größere Objekte, die viele BigInts enthalten, Leistungs- oder Speicherimplikationen haben kann. Wenn Sie die Struktur des Payloads kennen, ist es möglicherweise besser, sie einfach als Strings zu serialisieren und sie basierend auf dem Namen des Eigenschaftsschlüssels wiederherzustellen.

Tatsächlich erlaubt JSON Zahlenliterale beliebiger Länge; sie können jedoch in JavaScript nicht mit voller Genauigkeit geparst werden. Wenn Sie mit einem anderen Programm in einer Sprache kommunizieren, die längere Ganzzahlen (wie 64-Bit-Ganzzahlen) unterstützt, und Sie das BigInt als JSON-Zahl anstelle eines JSON-Strings übertragen möchten, siehe Lossless number serialization.

BigInt-Umwandlung

Viele eingebaute Operationen, die BigInts erwarten, wandeln ihre Argumente zuerst in BigInts um. Die Operation kann wie folgt zusammengefasst werden:

  • BigInts werden unverändert zurückgegeben.
  • undefined und null werfen einen TypeError.
  • true wird in 1n umgewandelt; false wird in 0n umgewandelt.
  • Zeichenketten werden durch Parsen als Integer-Literal konvertiert. Jegliches Parsingversagen führt zu einem SyntaxError. Die Syntax ist ein Teilmenge von String-Zahlliteralen, wobei Dezimalpunkte oder Exponentenzeichen nicht erlaubt sind.
  • Numbers werfen einen TypeError, um unbeabsichtigte implizite Umwandlungen, die zu einem Verlust der Genauigkeit führen, zu verhindern.
  • Symbole werfen einen TypeError.
  • Objekte werden zuerst in einen primitiven Typ umgewandelt, indem ihre [Symbol.toPrimitive]() (mit "number" als Hinweis), valueOf() und toString()-Methoden in dieser Reihenfolge aufgerufen werden. Der resultierende primitive Wert wird dann in ein BigInt konvertiert.

Der beste Weg, um fast denselben Effekt in JavaScript zu erzielen, ist über die BigInt()-Funktion: BigInt(x) verwendet denselben Algorithmus, um x zu konvertieren, mit der Ausnahme, dass Numbers keinen TypeError werfen, sondern in BigInts konvertiert werden, wenn sie Ganzzahlen sind.

Beachten Sie, dass eingebaute Operationen, die BigInts erwarten, BigInts oft nach der Umwandlung auf eine feste Breite kürzen. Dazu gehören BigInt.asIntN(), BigInt.asUintN(), und Methoden von BigInt64Array und BigUint64Array.

Konstruktor

BigInt()

Gibt primitive Werte vom Typ BigInt zurück. Wirft einen Fehler, wenn mit new aufgerufen.

Statische Methoden

BigInt.asIntN()

Klemmt einen BigInt-Wert auf einen vorzeichenbehafteten Integerwert und gibt diesen Wert zurück.

BigInt.asUintN()

Klemmt einen BigInt-Wert auf einen nicht vorzeichenbehafteten Integerwert und gibt diesen Wert zurück.

Instanz-Eigenschaften

Diese Eigenschaften sind auf BigInt.prototype definiert und werden von allen BigInt-Instanzen geteilt.

BigInt.prototype.constructor

Die Konstruktorfunktion, die das Instanzobjekt erstellt hat. Für BigInt-Instanzen ist der Anfangswert der BigInt-Konstruktor.

BigInt.prototype[Symbol.toStringTag]

Der Ausgangswert der [Symbol.toStringTag]-Eigenschaft ist der String "BigInt". Diese Eigenschaft wird in Object.prototype.toString() verwendet. Da BigInt jedoch 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.

Instanz-Methoden

BigInt.prototype.toLocaleString()

Gibt einen String mit einer sprachsensitiven Darstellung dieses BigInt-Wertes zurück. Überschreibt die Object.prototype.toLocaleString()-Methode.

BigInt.prototype.toString()

Gibt einen String zurück, der diesen BigInt-Wert im angegebenen Radix (Basis) darstellt. Überschreibt die Object.prototype.toString()-Methode.

BigInt.prototype.valueOf()

Gibt diesen BigInt-Wert zurück. Überschreibt die Object.prototype.valueOf()-Methode.

Beispiele

Primzahlen berechnen

js
// Returns true if the passed BigInt value is a prime number
function isPrime(p) {
  for (let i = 2n; i * i <= p; i++) {
    if (p % i === 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

Spezifikationen

Specification
ECMAScript® 2025 Language Specification
# sec-bigint-objects

Browser-Kompatibilität

Siehe auch