Skip to content

Türchen 14

Published: at 07:00 AMSuggest Changes

BigInt – Arbeiten mit großen Zahlen

In der Welt der Programmierung sind Zahlen ein grundlegendes Element. In JavaScript gibt es seit langem den Datentyp Number, der jedoch aufgrund seiner Implementierung als 64-Bit-Gleitkommazahl (nach dem IEEE 754 Standard) Grenzen hat. Insbesondere können ganzzahlige Werte nur bis zu einer bestimmten Größe exakt dargestellt werden. Mit der Einführung von BigInt in ES2020 hat JavaScript nun die Möglichkeit, mit ganzen Zahlen beliebiger Größe sicher zu arbeiten.

Warum BigInt?

Der Datentyp Number kann nur ganze Zahlen zwischen -(2^53 - 1) und 2^53 - 1 (das entspricht etwa ±9.007.199.254.740.991) exakt darstellen. Werte außerhalb dieses Bereichs können zu Präzisionsverlusten führen.

Beispiel:

const maxSafeInteger = Number.MAX_SAFE_INTEGER;
console.log(maxSafeInteger); // 9007199254740991

console.log(maxSafeInteger + 1); // 9007199254740992
console.log(maxSafeInteger + 2); // 9007199254740992  // Erwartet: 9007199254740993

Wie man sieht, führt die Addition von 1 und 2 zum gleichen Ergebnis, was zu unerwartetem Verhalten führen kann.

Numeric Separators

Um die Lesbarkeit des Artikels zu verbessern, möchte ich hier off toppic noch das Thema der “Numeric Separators” einstreuen. In ES12 wurden sie in JavaScript eingeführt und erhöhen die Lesbarkeit von numerischen Werten enorm. Hier werden, wie wir das von den Trennpunkten (.) gewöhnt sind, an den entsprechenden Stellen in einer Zahl ein Unterstrich (_) eingesetzt. Der Browser ignoriert diese Unterstriche jedoch. Sie erhöhen lediglich die Lesbarkeit für uns.

const a = 123456789;
const b = 123_456_789;
console.log(a === b); // true

Einführung in BigInt

BigInt ist ein neuer primitiver Datentyp, der ganze Zahlen beliebiger Größe repräsentiert. BigInt-Werte werden durch Anhängen eines n an das Ende der Zahl erzeugt.

Beispiel:

const bigIntValue = 1_234_567_890_123_456_789_012_345_678_901_234_567_890n;
console.log(bigIntValue); // 1234567890123456789012345678901234567890n

Alternativ kann man die BigInt-Funktion verwenden:

// Numeric Seperators funktionieren hier leider nicht.
const bigIntFromString = BigInt("1234567890123456789012345678901234567890");
console.log(bigIntFromString); // 1234567890123456789012345678901234567890n

Operationen mit BigInt

Man kann mit BigInt ähnlich wie mit normalen Zahlen rechnen, wobei einige Einschränkungen zu beachten sind.

Addition, Subtraktion, Multiplikation, Division:

const a = 12_345_678_901_234_567_890n;
const b = 98_765_432_109_876_543_210n;

console.log(a + b); // 111111111011111111100n
console.log(b - a); // 86419753208641975320n
console.log(a * b); // 1219326311370217952237463801111263526900n
console.log(b / a); // 8n

Hinweis zur Division:

Bei der Division von BigInt-Werten wird das Ergebnis immer auf die nächste ganze Zahl abgerundet.

console.log(10n / 3n); // 3n
console.log(10n / 4n); // 2n

Einschränkungen

Keine Vermischung von BigInt und Number:

BigInt und Number sind unterschiedliche Datentypen und können nicht direkt gemischt werden. Versuche, sie zu kombinieren, führen zu einem Fehler.

const bigIntValue = 10n;
const numberValue = 5;

console.log(bigIntValue + numberValue);
// TypeError: Cannot mix BigInt and other types

Um dies zu umgehen, muss man explizit konvertieren:

console.log(bigIntValue + BigInt(numberValue)); // 15n
console.log(Number(bigIntValue) + numberValue); // 15

Einsatz mit Math-Objekt:

Die Funktionen des Math-Objekts unterstützen BigInt nicht.

const bigIntValue = 16n;

console.log(Math.sqrt(bigIntValue));
// TypeError: Cannot convert a BigInt value to a number

Falls nötig, muss man BigInt in Number umwandeln:

console.log(Math.sqrt(Number(bigIntValue))); // 4

Achtung bei der Konvertierung:

Beim Konvertieren großer BigInt-Werte in Number kann es zu Präzisionsverlust kommen.

const bigIntValue = 123_456_789_012_345_678_901_234_567_890n;
const numberValue = Number(bigIntValue);

console.log(numberValue); // 1.2345678901234568e+29

Verwendung von BigInt mit Vergleichsoperatoren

BigInt-Werte können mit anderen BigInt- oder Number-Werten verglichen werden.

console.log(10n > 5n); // true
console.log(10n === 10); // false (unterschiedliche Typen)
console.log(10n == 10); // true (Typumwandlung)

console.log(10n >= 10); // true
console.log(10n <= 10); // true

BigInt und JSON

BigInt-Werte können nicht direkt in JSON serialisiert werden.

const bigIntValue = 12_345_678_901_234_567_890n;
const obj = { value: bigIntValue };

console.log(JSON.stringify(obj));
// TypeError: Do not know how to serialize a BigInt

Um dies zu umgehen, muss man den BigInt-Wert konvertieren, z. B. in einen String:

const obj = { value: bigIntValue.toString() };
console.log(JSON.stringify(obj)); // {"value":"12345678901234567890"}

Praktische Anwendungsfälle

1. Kryptographie und Hashing

In kryptographischen Verfahren, etwa bei der Implementierung von RSA, werden sehr große Primzahlen verwendet. Diese Zahlen liegen oft weit außerhalb des sicheren Bereichs für normale JavaScript-Number-Werte. Mit BigInt kann man solche Berechnungen direkt in JavaScript durchführen:

// Beispiel: Multiplikation sehr großer Primzahlen (vereinfachtes Beispiel)
// In der Praxis würden diese Zahlen noch viel größer und zufällig generiert sein.
const prime1 =  1_298_074_214_633_706_907_132_624_082_305_027n;
const prime2 =  3_750_809_578_651_072_525_849_623_921_260_295n;

// Multiplikation für RSA-Schlüsselberechnung:
const product = prime1 * prime2;
console.log('Produkt aus zwei großen Primzahlen:', product.toString());
// Ohne BigInt wäre diese Berechnung nicht exakt möglich.

Dieses vereinfachte Beispiel zeigt, wie man mit BigInt große Zahlen handhaben kann, die in kryptographischen Algorithmen üblich sind.

2. Arithmetik mit großen Zahlen (Finanzberechnungen)

Stell dir vor, du entwickelst eine Anwendung für Finanztransaktionen, bei der exakte Berechnungen mit sehr großen Beträgen nötig sind (etwa Zinsen auf riesige Geldsummen oder wissenschaftliche Simulationen mit großen Messwerten). Gleitkommazahlen könnten Präzisionsverluste verursachen. BigInt gewährleistet exakte ganzzahlige Berechnungen:

// Beispiel: Berechnung von Zinsen auf sehr große Beträge
const principal = 99_999_999_999_999_999_999_999n; // Sehr großer Betrag
const rate = 5n; // 5% Zinsen
const time = 2n; // 2 Jahre

// Einfache Zinsberechnung: Zinsen = (Hauptbetrag * Zinssatz * Zeit) / 100
const interest = (principal * rate * time) / 100n;
console.log('Zinsen auf sehr großen Betrag:', interest.toString());
// Keine Rundungsfehler, da ganzzahlige Arithmetik verwendet wird.

Hier wird garantiert, dass auch bei sehr großen Werten keine Präzision verloren geht, was für finanzielle oder wissenschaftliche Berechnungen von entscheidender Bedeutung ist.

3. Arbeit mit 64-Bit-Datei-IDs

In einigen Betriebssystemen oder Dateisystemen werden 64-Bit-Datei-IDs verwendet, die nicht in eine normale JavaScript-Number passen, da der sichere Integer-Bereich dort überschritten wird. Mit BigInt kann man diese IDs exakt verarbeiten:

// Beispiel: Eine 64-Bit-Datei-ID, die größer als Number.MAX_SAFE_INTEGER ist
const fileId = 18_446_744_073_709_551_615n; // 2^64 - 1 (max. 64-Bit Wert)

// Speicherung, Vergleich oder Weitergabe dieser ID ohne Präzisionsverlust
function isValidFileId(id) {
  // Prüfe, ob die ID in einem bestimmten Bereich liegt
  const maxFileId = 2n**64n - 1n; // Maximaler 64-Bit Wert
  return id <= maxFileId;
}

console.log(isValidFileId(fileId)); // true

Hier kann man Datei-IDs sicher vergleichen, sortieren oder validieren, ohne befürchten zu müssen, dass JavaScript den Wert ungenau repräsentiert.

Fazit

BigInt erweitert JavaScript um die Fähigkeit, mit ganzen Zahlen beliebiger Größe zu arbeiten, ohne Präzisionsverlust zu riskieren. Obwohl es einige Einschränkungen gibt, insbesondere bei der Interaktion mit Number und dem Math-Objekt, bietet BigInt eine wertvolle Ergänzung für Entwickler, die mit großen Zahlen arbeiten müssen.

Experimentiere mit BigInt in deinem nächsten Projekt und entdecke, wie es dir hilft, präzise Berechnungen mit großen Zahlen durchzuführen!


Previous Post
Türchen 15
Next Post
Türchen 13