Deutsch

Ein Leitfaden zum BigInt-Typ in JavaScript, der dessen Funktionen, Verwendung und Anwendungen bei der Verarbeitung großer Ganzzahlen-Arithmetik abdeckt. Überwinden Sie die Grenzen von JavaScript und führen Sie komplexe Berechnungen präzise durch.

JavaScript BigInt: Große Ganzzahlen-Arithmetik meistern

JavaScript ist zwar eine vielseitige Sprache, hat aber Einschränkungen im Umgang mit sehr großen ganzen Zahlen. Der Standard-Datentyp `Number` kann ganze Zahlen nur bis zu einer bestimmten Grenze, bekannt als `Number.MAX_SAFE_INTEGER`, genau darstellen. Jenseits dieser Grenze werden Berechnungen ungenau, was zu unerwarteten Ergebnissen führt. Hier kommt BigInt zur Rettung. Eingeführt in ECMAScript 2020, ist BigInt ein eingebautes Objekt, das eine Möglichkeit bietet, ganze Zahlen beliebiger Größe darzustellen und zu manipulieren, was die Beschränkungen des Standard-`Number`-Typs überwindet.

Die Notwendigkeit von BigInt verstehen

Vor BigInt mussten sich JavaScript-Entwickler auf Bibliotheken oder benutzerdefinierte Implementierungen verlassen, um Berechnungen mit großen ganzen Zahlen durchzuführen. Diese Lösungen brachten oft einen Leistungs-Overhead und erhöhte Komplexität mit sich. Die Einführung von BigInt bot eine native und effiziente Möglichkeit, mit großen ganzen Zahlen zu arbeiten und eröffnete Möglichkeiten für Anwendungen in verschiedenen Bereichen, darunter:

BigInt-Werte erstellen

Es gibt zwei primäre Möglichkeiten, BigInt-Werte in JavaScript zu erstellen:

  1. Verwendung des `BigInt()`-Konstruktors: Dieser Konstruktor kann eine Zahl, eine Zeichenkette oder einen booleschen Wert in ein BigInt umwandeln.
  2. Verwendung des `n`-Suffixes: Das Anhängen von `n` an ein ganzzahliges Literal erzeugt ein BigInt.

Beispiele:

Verwendung des `BigInt()`-Konstruktors:


const bigIntFromNumber = BigInt(12345678901234567890);
const bigIntFromString = BigInt("98765432109876543210");
const bigIntFromBoolean = BigInt(true); // Ergibt 1n
const bigIntFromFalseBoolean = BigInt(false); // Ergibt 0n

console.log(bigIntFromNumber); // Ausgabe: 12345678901234567890n
console.log(bigIntFromString); // Ausgabe: 98765432109876543210n
console.log(bigIntFromBoolean); // Ausgabe: 1n
console.log(bigIntFromFalseBoolean); // Ausgabe: 0n

Verwendung des `n`-Suffixes:


const bigIntLiteral = 12345678901234567890n;
console.log(bigIntLiteral); // Ausgabe: 12345678901234567890n

Wichtiger Hinweis: Sie können BigInt- und Number-Werte nicht direkt in arithmetischen Operationen mischen. Sie müssen sie explizit in den gleichen Typ konvertieren, bevor Sie Berechnungen durchführen. Der Versuch, sie direkt zu mischen, führt zu einem `TypeError`.

Arithmetische Operationen mit BigInt

BigInt unterstützt die meisten der standardmäßigen arithmetischen Operatoren, einschließlich:

Beispiele:


const a = 12345678901234567890n;
const b = 98765432109876543210n;

const sum = a + b;
const difference = a - b;
const product = a * b;
const quotient = a / 2n; // Hinweis: Die Division rundet in Richtung Null ab
const remainder = a % 7n;
const power = a ** 3n; // Potenzierung funktioniert wie erwartet

console.log("Summe:", sum); // Ausgabe: Summe: 111111111011111111100n
console.log("Differenz:", difference); // Ausgabe: Differenz: -86419753208641975320n
console.log("Produkt:", product); // Ausgabe: Produkt: 1219326311370217957951669538098765432100n
console.log("Quotient:", quotient); // Ausgabe: Quotient: 6172839450617283945n
console.log("Restwert:", remainder); // Ausgabe: Restwert: 5n
console.log("Potenz:", power); // Ausgabe: Potenz: 187641281029182300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n

Wichtige Überlegungen:

Vergleichsoperatoren

Sie können Standard-Vergleichsoperatoren (`==`, `!=`, `<`, `>`, `<=`, `>=`) verwenden, um BigInt-Werte mit anderen BigInt-Werten oder sogar mit Number-Werten zu vergleichen. Seien Sie jedoch vorsichtig bezüglich der potenziellen Typumwandlung (Type Coercion).

Beispiele:


const a = 10n;
const b = 20n;
const c = 10;

console.log(a == b);   // Ausgabe: false
console.log(a != b);   // Ausgabe: true
console.log(a < b);    // Ausgabe: true
console.log(a > b);    // Ausgabe: false
console.log(a <= b);   // Ausgabe: true
console.log(a >= b);   // Ausgabe: false

console.log(a == c);   // Ausgabe: true (Typumwandlung)
console.log(a === c);  // Ausgabe: false (keine Typumwandlung)

Best Practice: Verwenden Sie strikte Gleichheit (`===`) und strikte Ungleichheit (`!==`), um unerwartete Typumwandlungen beim Vergleich von BigInt- und Number-Werten zu vermeiden.

Konvertierung zwischen BigInt und Number

Obwohl direkte arithmetische Operationen zwischen BigInt und Number nicht erlaubt sind, können Sie zwischen den beiden Typen konvertieren. Seien Sie sich jedoch des potenziellen Präzisionsverlusts bewusst, wenn Sie ein BigInt in eine Number umwandeln, falls der BigInt-Wert `Number.MAX_SAFE_INTEGER` überschreitet.

Beispiele:


const bigIntValue = 9007199254740991n; // Number.MAX_SAFE_INTEGER
const numberValue = Number(bigIntValue); // Konvertierung von BigInt zu Number
console.log(numberValue); // Ausgabe: 9007199254740991

const largerBigIntValue = 9007199254740992n; // Überschreitet Number.MAX_SAFE_INTEGER
const largerNumberValue = Number(largerBigIntValue);
console.log(largerNumberValue); // Ausgabe: 9007199254740992 (kann ungenau sein)

const numberToBigInt = BigInt(12345); // Konvertierung von Number zu BigInt
console.log(numberToBigInt); // Ausgabe: 12345n

Anwendungsfälle und Beispiele

Kryptographie

Kryptographische Algorithmen verlassen sich oft auf sehr große Primzahlen für die Sicherheit. BigInt bietet eine Möglichkeit, diese Zahlen effizient darzustellen und zu manipulieren.


// Beispiel: Generierung eines einfachen (unsicheren) Schlüsselpaars
function generateKeyPair() {
  const p = 281n; // Eine Primzahl
  const q = 283n; // Eine weitere Primzahl
  const n = p * q; // Modul
  const totient = (p - 1n) * (q - 1n); // Eulersche Phi-Funktion

  // Wähle ein e (öffentlicher Exponent), sodass 1 < e < totient und ggT(e, totient) = 1
  const e = 17n;

  // Berechne d (privater Exponent), sodass (d * e) % totient = 1
  let d = 0n;
  for (let i = 1n; i < totient; i++) {
    if ((i * e) % totient === 1n) {
      d = i;
      break;
    }
  }

  return {
    publicKey: { n, e },
    privateKey: { n, d },
  };
}

const keyPair = generateKeyPair();
console.log("Öffentlicher Schlüssel:", keyPair.publicKey);
console.log("Privater Schlüssel:", keyPair.privateKey);

Hinweis: Dies ist nur ein vereinfachtes Beispiel zu Demonstrationszwecken. In der realen Kryptographie werden weitaus größere Primzahlen und anspruchsvollere Algorithmen verwendet.

Finanzberechnungen

Beim Umgang mit großen Geldbeträgen, insbesondere bei internationalen Transaktionen, ist Präzision entscheidend. BigInt kann Rundungsfehler verhindern und genaue Berechnungen sicherstellen.


// Beispiel: Berechnung von Zinseszinsen
function calculateCompoundInterest(principal, rate, time) {
  const principalBigInt = BigInt(principal * 100); // In Cent umrechnen
  const rateBigInt = BigInt(rate * 10000);       // In Zehntausendstel eines Prozents umrechnen
  const timeBigInt = BigInt(time);

  let amount = principalBigInt;
  for (let i = 0n; i < timeBigInt; i++) {
    amount = amount * (10000n + rateBigInt) / 10000n;
  }

  const amountInDollars = Number(amount) / 100;
  return amountInDollars;
}

const principal = 1000000; // $1.000.000
const rate = 0.05;    // 5% Zinssatz
const time = 10;     // 10 Jahre

const finalAmount = calculateCompoundInterest(principal, rate, time);
console.log("Endbetrag:", finalAmount); // Ausgabe: Endbetrag: 1628894.6267774413 (ungefähr)

In diesem Beispiel konvertieren wir den Kapitalbetrag und den Zinssatz in BigInt-Werte, um Rundungsfehler während der Berechnung zu vermeiden. Das Ergebnis wird dann zur Anzeige wieder in eine Number umgewandelt.

Arbeiten mit großen IDs

In verteilten Systemen kann die Generierung eindeutiger IDs über mehrere Server hinweg eine Herausforderung sein. Die Verwendung von BigInt ermöglicht es Ihnen, sehr große IDs zu erstellen, bei denen Kollisionen unwahrscheinlich sind.


// Beispiel: Generierung einer eindeutigen ID basierend auf Zeitstempel und Server-ID
function generateUniqueId(serverId) {
  const timestamp = BigInt(Date.now());
  const serverIdBigInt = BigInt(serverId);
  const random = BigInt(Math.floor(Math.random() * 1000)); // Füge etwas Zufälligkeit hinzu

  // Kombiniere die Werte, um eine eindeutige ID zu erstellen
  const uniqueId = (timestamp << 20n) + (serverIdBigInt << 10n) + random;
  return uniqueId.toString(); // Als String zurückgeben für einfache Handhabung
}

const serverId = 123; // Beispiel-Server-ID
const id1 = generateUniqueId(serverId);
const id2 = generateUniqueId(serverId);

console.log("Eindeutige ID 1:", id1);
console.log("Eindeutige ID 2:", id2);

BigInt und JSON

BigInt-Werte werden von JSON nicht nativ unterstützt. Der Versuch, ein JavaScript-Objekt, das ein BigInt enthält, mit `JSON.stringify()` zu serialisieren, führt zu einem `TypeError`. Um BigInt-Werte bei der Arbeit mit JSON zu handhaben, haben Sie mehrere Möglichkeiten:

  1. In einen String konvertieren: Konvertieren Sie das BigInt vor der Serialisierung in einen String. Dies ist der gebräuchlichste und einfachste Ansatz.
  2. Benutzerdefinierte Serialisierung/Deserialisierung: Verwenden Sie eine benutzerdefinierte Serialisierungs-/Deserialisierungsfunktion, um BigInt-Werte zu behandeln.

Beispiele:

In einen String konvertieren:


const data = {
  id: 12345678901234567890n,
  name: "Example Data",
};

// BigInt vor der Serialisierung in einen String umwandeln
data.id = data.id.toString();

const jsonData = JSON.stringify(data);
console.log(jsonData); // Ausgabe: {"id":"12345678901234567890","name":"Example Data"}

// Beim Deserialisieren müssen Sie den String wieder in ein BigInt umwandeln
const parsedData = JSON.parse(jsonData, (key, value) => {
  if (key === "id") {
    return BigInt(value);
  }
  return value;
});

console.log(parsedData.id); // Ausgabe: 12345678901234567890n

Benutzerdefinierte Serialisierung/Deserialisierung (mit `replacer` und `reviver`):


const data = {
  id: 12345678901234567890n,
  name: "Example Data",
};

// Benutzerdefinierte Serialisierung
const jsonData = JSON.stringify(data, (key, value) => {
  if (typeof value === 'bigint') {
    return value.toString();
  } else {
    return value;
  }
});

console.log(jsonData);

// Benutzerdefinierte Deserialisierung
const parsedData = JSON.parse(jsonData, (key, value) => {
    if (typeof value === 'string' && /^[0-9]+$/.test(value)) { // prüfen, ob es eine Zahl und ein String ist
      try {
        return BigInt(value);
      } catch(e) {
          return value;
      }
    }
    return value;
});

console.log(parsedData.id);

Browserkompatibilität

BigInt wird von modernen Browsern weitgehend unterstützt. Es ist jedoch unerlässlich, die Kompatibilität für ältere Browser oder Umgebungen zu überprüfen. Sie können ein Tool wie Can I use verwenden, um die Browserunterstützung zu verifizieren. Wenn Sie ältere Browser unterstützen müssen, könnten Sie die Verwendung eines Polyfills in Betracht ziehen, aber seien Sie sich bewusst, dass Polyfills die Leistung beeinträchtigen können.

Leistungsaspekte

Obwohl BigInt eine leistungsstarke Möglichkeit bietet, mit großen ganzen Zahlen zu arbeiten, ist es wichtig, sich der potenziellen Auswirkungen auf die Leistung bewusst zu sein.

Verwenden Sie BigInt daher nur bei Bedarf und optimieren Sie Ihren Code auf Leistung, wenn Sie eine große Anzahl von BigInt-Operationen durchführen.

Fazit

BigInt ist eine wertvolle Ergänzung zu JavaScript, die es Entwicklern ermöglicht, Arithmetik mit großen ganzen Zahlen präzise durchzuführen. Indem Sie seine Funktionen, Einschränkungen und Anwendungsfälle verstehen, können Sie BigInt nutzen, um robuste und genaue Anwendungen in verschiedenen Bereichen zu erstellen, einschließlich Kryptographie, Finanzberechnungen und wissenschaftlichem Rechnen. Denken Sie daran, die Browserkompatibilität und die Auswirkungen auf die Leistung zu berücksichtigen, wenn Sie BigInt in Ihren Projekten verwenden.

Weiterführende Informationen

Dieser Leitfaden bietet einen umfassenden Überblick über BigInt in JavaScript. Erkunden Sie die verlinkten Ressourcen für weiterführende Informationen und fortgeschrittene Techniken.