Een complete gids voor JavaScript's BigInt, over functies, gebruik en toepassingen voor grote getallen. Overwin de beperkingen van JavaScript voor precieze berekeningen.
JavaScript BigInt: Grote Integer Aritmetiek Beheersen
JavaScript, hoewel een veelzijdige taal, heeft beperkingen bij het omgaan met zeer grote gehele getallen. Het standaard `Number`-type kan slechts gehele getallen tot een bepaalde limiet, bekend als `Number.MAX_SAFE_INTEGER`, nauwkeurig weergeven. Boven deze limiet worden berekeningen onnauwkeurig, wat leidt tot onverwachte resultaten. Dit is waar BigInt
te hulp schiet. Geïntroduceerd in ECMAScript 2020, is BigInt
een ingebouwd object dat een manier biedt om gehele getallen van willekeurige grootte weer te geven en te manipuleren, waarmee de beperkingen van het standaard `Number`-type worden overschreden.
De Noodzaak van BigInt Begrijpen
Voor BigInt
moesten JavaScript-ontwikkelaars vertrouwen op bibliotheken of aangepaste implementaties om grote integer-berekeningen uit te voeren. Deze oplossingen brachten vaak prestatie-overhead en verhoogde complexiteit met zich mee. De introductie van BigInt
bood een native en efficiënte manier om met grote gehele getallen te werken, wat mogelijkheden opende voor toepassingen in verschillende domeinen, waaronder:
- Cryptografie: Het veilig omgaan met grote priemgetallen is cruciaal voor cryptografische algoritmen.
- Financiële Berekeningen: Het nauwkeurig weergeven van grote monetaire waarden zonder verlies van precisie.
- Wetenschappelijke Berekeningen: Het uitvoeren van complexe berekeningen met extreem grote of kleine getallen.
- Hoge-Precisie Tijdstempels: Het weergeven van tijdstempels met nanoseconde-precisie.
- ID-Generatie: Het creëren van unieke en zeer grote identificatoren.
BigInt-waarden Creëren
Er zijn twee primaire manieren om BigInt
-waarden te creëren in JavaScript:
- Gebruik van de `BigInt()`-constructor: Deze constructor kan een getal, string of booleaanse waarde omzetten naar een
BigInt
. - Gebruik van het `n`-achtervoegsel: Het toevoegen van `n` aan een letterlijk geheel getal creëert een
BigInt
.
Voorbeelden:
Gebruik van de `BigInt()`-constructor:
const bigIntFromNumber = BigInt(12345678901234567890);
const bigIntFromString = BigInt("98765432109876543210");
const bigIntFromBoolean = BigInt(true); // Resulteert in 1n
const bigIntFromFalseBoolean = BigInt(false); // Resulteert in 0n
console.log(bigIntFromNumber); // Output: 12345678901234567890n
console.log(bigIntFromString); // Output: 98765432109876543210n
console.log(bigIntFromBoolean); // Output: 1n
console.log(bigIntFromFalseBoolean); // Output: 0n
Gebruik van het `n`-achtervoegsel:
const bigIntLiteral = 12345678901234567890n;
console.log(bigIntLiteral); // Output: 12345678901234567890n
Belangrijke opmerking: U kunt BigInt
- en Number
-waarden niet direct mengen in rekenkundige operaties. U moet ze expliciet naar hetzelfde type converteren voordat u berekeningen uitvoert. Pogingen om ze direct te mengen resulteren in een `TypeError`.
Rekenkundige Operaties met BigInt
BigInt
ondersteunt de meeste standaard rekenkundige operatoren, waaronder:
- Optellen (`+`)
- Aftrekken (`-`)
- Vermenigvuldigen (`*`)
- Delen (`/`)
- Rest (`%`)
- Machtsverheffen (`**`)
Voorbeelden:
const a = 12345678901234567890n;
const b = 98765432109876543210n;
const sum = a + b;
const difference = a - b;
const product = a * b;
const quotient = a / 2n; // Opmerking: Deling kapt af richting nul
const remainder = a % 7n;
const power = a ** 3n; // Machtsverheffen werkt zoals verwacht
console.log("Som:", sum); // Output: Sum: 111111111011111111100n
console.log("Verschil:", difference); // Output: Difference: -86419753208641975320n
console.log("Product:", product); // Output: Product: 1219326311370217957951669538098765432100n
console.log("Quotiënt:", quotient); // Output: Quotient: 6172839450617283945n
console.log("Rest:", remainder); // Output: Remainder: 5n
console.log("Macht:", power); // Output: Power: 187641281029182300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n
Belangrijke Overwegingen:
- Deling: Deling met
BigInt
-waarden kapt af richting nul. Dit betekent dat het decimale deel van het resultaat wordt weggegooid. Als u preciezere delingen nodig heeft, overweeg dan bibliotheken te gebruiken die willekeurige-precisie rekenkunde ondersteunen. - Unaire Plus Operator (+): De unaire plus-operator (+) kan niet worden gebruikt met
BigInt
-waarden omdat dit zou conflicteren met verouderde asm.js-code. Gebruik de `Number()`-conversiefunctie om een BigInt naar een Number te converteren als u een numerieke weergave nodig heeft (met het besef dat u precisie kunt verliezen). - Bitwise Operators:
BigInt
ondersteunt ook bitwise-operatoren zoals `&`, `|`, `^`, `~`, `<<`, en `>>`. Deze operatoren werken zoals verwacht op de binaire representatie van deBigInt
-waarden.
Vergelijkingsoperatoren
U kunt standaard vergelijkingsoperatoren (`==`, `!=`, `<`, `>`, `<=`, `>=`) gebruiken om BigInt
-waarden te vergelijken met andere BigInt
-waarden of zelfs met Number
-waarden. Wees echter bedacht op de mogelijkheid van typeconversie.
Voorbeelden:
const a = 10n;
const b = 20n;
const c = 10;
console.log(a == b); // Output: false
console.log(a != b); // Output: true
console.log(a < b); // Output: true
console.log(a > b); // Output: false
console.log(a <= b); // Output: true
console.log(a >= b); // Output: false
console.log(a == c); // Output: true (typeconversie)
console.log(a === c); // Output: false (geen typeconversie)
Beste Praktijk: Gebruik strikte gelijkheid (`===`) en strikte ongelijkheid (`!==`) om onverwachte typeconversie te vermijden bij het vergelijken van BigInt
- en Number
-waarden.
Converteren tussen BigInt en Number
Hoewel directe rekenkundige operaties tussen BigInt
en Number
niet zijn toegestaan, kunt u tussen de twee typen converteren. Wees u echter bewust van het mogelijke verlies van precisie bij het converteren van een BigInt
naar een Number
als de BigInt
-waarde `Number.MAX_SAFE_INTEGER` overschrijdt.
Voorbeelden:
const bigIntValue = 9007199254740991n; // Number.MAX_SAFE_INTEGER
const numberValue = Number(bigIntValue); // BigInt naar Number converteren
console.log(numberValue); // Output: 9007199254740991
const largerBigIntValue = 9007199254740992n; // Overschrijdt Number.MAX_SAFE_INTEGER
const largerNumberValue = Number(largerBigIntValue);
console.log(largerNumberValue); // Output: 9007199254740992 (kan onnauwkeurig zijn)
const numberToBigInt = BigInt(12345); // Number naar BigInt converteren
console.log(numberToBigInt); // Output: 12345n
Toepassingen en Voorbeelden
Cryptografie
Cryptografische algoritmen vertrouwen vaak op zeer grote priemgetallen voor beveiliging. BigInt
biedt een manier om deze getallen efficiënt weer te geven en te manipuleren.
// Voorbeeld: Een eenvoudig (onveilig) sleutelpaar genereren
function generateKeyPair() {
const p = 281n; // Een priemgetal
const q = 283n; // Een ander priemgetal
const n = p * q; // Modulus
const totient = (p - 1n) * (q - 1n); // Euler's totiëntfunctie
// Kies een e (publieke exponent) zodat 1 < e < totiënt en ggd(e, totiënt) = 1
const e = 17n;
// Bereken d (private exponent) zodat (d * e) % totiënt = 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("Publieke Sleutel:", keyPair.publicKey);
console.log("Private Sleutel:", keyPair.privateKey);
Opmerking: Dit is slechts een vereenvoudigd voorbeeld voor demonstratiedoeleinden. Echte cryptografie maakt gebruik van veel grotere priemgetallen en geavanceerdere algoritmen.
Financiële Berekeningen
Bij het omgaan met grote geldbedragen, vooral bij internationale transacties, is precisie cruciaal. BigInt
kan afrondingsfouten voorkomen en zorgen voor nauwkeurige berekeningen.
// Voorbeeld: Samengestelde rente berekenen
function calculateCompoundInterest(principal, rate, time) {
const principalBigInt = BigInt(principal * 100); // Omzetten naar centen
const rateBigInt = BigInt(rate * 10000); // Omzetten naar tienduizendsten van een procent
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% rentevoet
const time = 10; // 10 jaar
const finalAmount = calculateCompoundInterest(principal, rate, time);
console.log("Eindbedrag:", finalAmount); // Output: Final Amount: 1628894.6267774413 (ongeveer)
In dit voorbeeld converteren we de hoofdsom en de rentevoet naar BigInt
-waarden om afrondingsfouten tijdens de berekening te voorkomen. Het resultaat wordt vervolgens teruggeconverteerd naar een Number
voor weergave.
Werken met Grote ID's
In gedistribueerde systemen kan het genereren van unieke ID's over meerdere servers een uitdaging zijn. Met BigInt
kunt u zeer grote ID's creëren die waarschijnlijk niet zullen conflicteren.
// Voorbeeld: Een unieke ID genereren op basis van tijdstempel en server-ID
function generateUniqueId(serverId) {
const timestamp = BigInt(Date.now());
const serverIdBigInt = BigInt(serverId);
const random = BigInt(Math.floor(Math.random() * 1000)); // Voeg een beetje willekeur toe
// Combineer de waarden om een unieke ID te creëren
const uniqueId = (timestamp << 20n) + (serverIdBigInt << 10n) + random;
return uniqueId.toString(); // Retourneer als string voor eenvoudige verwerking
}
const serverId = 123; // Voorbeeld server-ID
const id1 = generateUniqueId(serverId);
const id2 = generateUniqueId(serverId);
console.log("Unieke ID 1:", id1);
console.log("Unieke ID 2:", id2);
BigInt en JSON
BigInt
-waarden worden niet native ondersteund door JSON. Een poging om een JavaScript-object met een BigInt
te serialiseren met `JSON.stringify()` resulteert in een `TypeError`. Om BigInt
-waarden te verwerken bij het werken met JSON, heeft u een paar opties:
- Converteren naar String: Converteer de
BigInt
naar een string voordat u serialiseert. Dit is de meest gebruikelijke en eenvoudige aanpak. - Aangepaste Serialisatie/Deserialisatie: Gebruik een aangepaste serialisatie/deserialisatie-functie om
BigInt
-waarden te verwerken.
Voorbeelden:
Converteren naar String:
const data = {
id: 12345678901234567890n,
name: "Example Data",
};
// Converteer BigInt naar string voor het serialiseren
data.id = data.id.toString();
const jsonData = JSON.stringify(data);
console.log(jsonData); // Output: {"id":"12345678901234567890","name":"Example Data"}
// Bij het deserialiseren moet u de string weer terug converteren naar een BigInt
const parsedData = JSON.parse(jsonData, (key, value) => {
if (key === "id") {
return BigInt(value);
}
return value;
});
console.log(parsedData.id); // Output: 12345678901234567890n
Aangepaste Serialisatie/Deserialisatie (met `replacer` en `reviver`):
const data = {
id: 12345678901234567890n,
name: "Example Data",
};
// Aangepaste serialisatie
const jsonData = JSON.stringify(data, (key, value) => {
if (typeof value === 'bigint') {
return value.toString();
} else {
return value;
}
});
console.log(jsonData);
// Aangepaste deserialisatie
const parsedData = JSON.parse(jsonData, (key, value) => {
if (typeof value === 'string' && /^[0-9]+$/.test(value)) { // controleer of het een getal en een string is
try {
return BigInt(value);
} catch(e) {
return value;
}
}
return value;
});
console.log(parsedData.id);
Browsercompatibiliteit
BigInt
wordt breed ondersteund in moderne browsers. Het is echter essentieel om de compatibiliteit voor oudere browsers of omgevingen te controleren. U kunt een tool zoals Can I use gebruiken om de browserondersteuning te verifiëren. Als u oudere browsers moet ondersteunen, kunt u overwegen een polyfill te gebruiken, maar wees u ervan bewust dat polyfills de prestaties kunnen beïnvloeden.
Prestatieoverwegingen
Hoewel BigInt
een krachtige manier biedt om met grote gehele getallen te werken, is het belangrijk om u bewust te zijn van de mogelijke prestatie-implicaties.
BigInt
-operaties kunnen langzamer zijn dan standaardNumber
-operaties.- Het converteren tussen
BigInt
enNumber
kan ook overhead met zich meebrengen.
Gebruik BigInt
daarom alleen wanneer dat nodig is, en optimaliseer uw code voor prestaties als u een groot aantal BigInt
-operaties uitvoert.
Conclusie
BigInt
is een waardevolle toevoeging aan JavaScript, die ontwikkelaars in staat stelt om met precisie grote integer-aritmetiek te hanteren. Door de functies, beperkingen en toepassingen te begrijpen, kunt u BigInt
benutten om robuuste en nauwkeurige applicaties te bouwen in verschillende domeinen, waaronder cryptografie, financiële berekeningen en wetenschappelijke berekeningen. Vergeet niet om rekening te houden met browsercompatibiliteit en prestatie-implicaties bij het gebruik van BigInt
in uw projecten.
Verder Onderzoek
- Mozilla Developer Network (MDN) - BigInt
- V8 Blog - BigInt: Willekeurige-Precisie Integers in JavaScript
Deze gids biedt een uitgebreid overzicht van BigInt
in JavaScript. Verken de gelinkte bronnen voor meer diepgaande informatie en geavanceerde technieken.