Slovenščina

Celovit vodnik po tipu BigInt v JavaScriptu, ki pokriva njegove lastnosti, uporabo in aplikacije pri delu z velikimi celimi števili. Premagajte omejitve in izvajajte natančne izračune.

JavaScript BigInt: Obvladovanje aritmetike velikih celih števil

JavaScript je vsestranski jezik, vendar ima omejitve pri delu z zelo velikimi celimi števili. Standardni tip `Number` lahko natančno predstavlja cela števila le do določene meje, znane kot `Number.MAX_SAFE_INTEGER`. Nad to mejo postanejo izračuni nenatančni, kar vodi do nepričakovanih rezultatov. Tu na pomoč priskoči BigInt. BigInt, predstavljen v ECMAScript 2020, je vgrajen objekt, ki omogoča predstavitev in manipulacijo celih števil poljubne velikosti, s čimer presega omejitve standardnega tipa `Number`.

Razumevanje potrebe po BigInt

Pred uvedbo BigInt so se morali razvijalci v JavaScriptu zanašati na knjižnice ali lastne implementacije za obdelavo izračunov z velikimi celimi števili. Te rešitve so pogosto prinašale dodatno obremenitev za zmogljivost in povečano kompleksnost. Uvedba BigInt je zagotovila izviren in učinkovit način za delo z velikimi celimi števili, kar je odprlo možnosti za uporabo na različnih področjih, vključno z:

Ustvarjanje vrednosti BigInt

V JavaScriptu obstajata dva glavna načina za ustvarjanje vrednosti BigInt:

  1. Uporaba konstruktorja `BigInt()`: Ta konstruktor lahko pretvori število, niz ali logično vrednost v BigInt.
  2. Uporaba pripone `n`: Dodajanje pripone `n` na konec celega števila ustvari BigInt.

Primeri:

Uporaba konstruktorja `BigInt()`:


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

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

Uporaba pripone `n`:


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

Pomembna opomba: V aritmetičnih operacijah ne morete neposredno mešati vrednosti BigInt in Number. Pred izvajanjem izračunov jih morate eksplicitno pretvoriti v isti tip. Poskus neposrednega mešanja bo povzročil napako `TypeError`.

Aritmetične operacije z BigInt

BigInt podpira večino standardnih aritmetičnih operatorjev, vključno z:

Primeri:


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

const sum = a + b;
const difference = a - b;
const product = a * b;
const quotient = a / 2n; // Opomba: Deljenje zaokroži proti ničli
const remainder = a % 7n;
const power = a ** 3n; // Potenciranje deluje po pričakovanjih

console.log("Vsota:", sum); // Izhod: Vsota: 111111111011111111100n
console.log("Razlika:", difference); // Izhod: Razlika: -86419753208641975320n
console.log("Zmnožek:", product); // Izhod: Zmnožek: 1219326311370217957951669538098765432100n
console.log("Količnik:", quotient); // Izhod: Količnik: 6172839450617283945n
console.log("Ostanek:", remainder); // Izhod: Ostanek: 5n
console.log("Potenca:", power); // Izhod: Potenca: 187641281029182300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n

Pomembni premisleki:

Primerjalni operatorji

Za primerjavo vrednosti BigInt z drugimi vrednostmi BigInt ali celo z vrednostmi Number lahko uporabite standardne primerjalne operatorje (`==`, `!=`, `<`, `>`, `<=`, `>=`). Vendar bodite pozorni na možnost prisilne pretvorbe tipov (type coercion).

Primeri:


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

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

console.log(a == c);   // Izhod: true (prisilna pretvorba tipa)
console.log(a === c);  // Izhod: false (ni prisilne pretvorbe tipa)

Dobra praksa: Uporabljajte strogo enakost (`===`) in strogo neenakost (`!==`), da se izognete nepričakovani prisilni pretvorbi tipov pri primerjanju vrednosti BigInt in Number.

Pretvarjanje med BigInt in Number

Čeprav neposredne aritmetične operacije med BigInt in Number niso dovoljene, lahko med obema tipoma pretvarjate. Vendar se zavedajte možnosti izgube natančnosti pri pretvorbi BigInt v Number, če vrednost BigInt presega `Number.MAX_SAFE_INTEGER`.

Primeri:


const bigIntValue = 9007199254740991n; // Number.MAX_SAFE_INTEGER
const numberValue = Number(bigIntValue); // Pretvarjanje BigInt v Number
console.log(numberValue); // Izhod: 9007199254740991

const largerBigIntValue = 9007199254740992n; // Presega Number.MAX_SAFE_INTEGER
const largerNumberValue = Number(largerBigIntValue);
console.log(largerNumberValue); // Izhod: 9007199254740992 (lahko je nenatančno)

const numberToBigInt = BigInt(12345); // Pretvarjanje Number v BigInt
console.log(numberToBigInt); // Izhod: 12345n

Primeri uporabe

Kriptografija

Kriptografski algoritmi se za varnost pogosto zanašajo na zelo velika praštevila. BigInt omogoča učinkovito predstavitev in manipulacijo teh števil.


// Primer: Generiranje preprostega (nevarnega) para ključev
function generateKeyPair() {
  const p = 281n; // Praštevilo
  const q = 283n; // Drugo praštevilo
  const n = p * q; // Modul
  const totient = (p - 1n) * (q - 1n); // Eulerjeva totient funkcija

  // Izberemo e (javni eksponent), tako da je 1 < e < totient in gcd(e, totient) = 1
  const e = 17n;

  // Izračunamo d (zasebni eksponent), tako da je (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("Javni ključ:", keyPair.publicKey);
console.log("Zasebni ključ:", keyPair.privateKey);

Opomba: To je poenostavljen primer samo za demonstracijo. Kriptografija v resničnem svetu uporablja veliko večja praštevila in bolj sofisticirane algoritme.

Finančni izračuni

Pri delu z velikimi vsotami denarja, zlasti pri mednarodnih transakcijah, je natančnost ključnega pomena. BigInt lahko prepreči napake pri zaokroževanju in zagotovi natančne izračune.


// Primer: Izračun obrestno-obrestnega računa
function calculateCompoundInterest(principal, rate, time) {
  const principalBigInt = BigInt(principal * 100); // Pretvorba v cente
  const rateBigInt = BigInt(rate * 10000);       // Pretvorba v desettisočinke odstotka
  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% obrestna mera
const time = 10;     // 10 let

const finalAmount = calculateCompoundInterest(principal, rate, time);
console.log("Končni znesek:", finalAmount); // Izhod: Končni znesek: 1628894.6267774413 (približno)

V tem primeru glavnico in obrestno mero pretvorimo v vrednosti BigInt, da se izognemo napakam pri zaokroževanju med izračunom. Rezultat se nato za prikaz pretvori nazaj v Number.

Delo z velikimi ID-ji

V porazdeljenih sistemih je generiranje edinstvenih ID-jev na več strežnikih lahko izziv. Z uporabo BigInt lahko ustvarite zelo velike ID-je, za katere je malo verjetno, da bi prišlo do kolizije.


// Primer: Generiranje edinstvenega ID-ja na podlagi časovnega žiga in ID-ja strežnika
function generateUniqueId(serverId) {
  const timestamp = BigInt(Date.now());
  const serverIdBigInt = BigInt(serverId);
  const random = BigInt(Math.floor(Math.random() * 1000)); // Dodajanje malo naključnosti

  // Združevanje vrednosti za ustvarjanje edinstvenega ID-ja
  const uniqueId = (timestamp << 20n) + (serverIdBigInt << 10n) + random;
  return uniqueId.toString(); // Vračanje kot niz za lažje upravljanje
}

const serverId = 123; // Primer ID-ja strežnika
const id1 = generateUniqueId(serverId);
const id2 = generateUniqueId(serverId);

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

BigInt in JSON

Vrednosti BigInt niso izvorno podprte v formatu JSON. Poskus serializacije objekta JavaScript, ki vsebuje BigInt, z uporabo `JSON.stringify()` bo povzročil napako `TypeError`. Za obravnavo vrednosti BigInt pri delu z JSON imate na voljo nekaj možnosti:

  1. Pretvorba v niz: Pred serializacijo pretvorite BigInt v niz. To je najpogostejši in najpreprostejši pristop.
  2. Serializacija/deserializacija po meri: Uporabite funkcijo za serializacijo/deserializacijo po meri za obravnavo vrednosti BigInt.

Primeri:

Pretvarjanje v niz:


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

// Pretvorba BigInt v niz pred serializacijo
data.id = data.id.toString();

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

// Pri deserializaciji boste morali niz pretvoriti nazaj v BigInt
const parsedData = JSON.parse(jsonData, (key, value) => {
  if (key === "id") {
    return BigInt(value);
  }
  return value;
});

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

Serializacija/deserializacija po meri (z uporabo `replacer` in `reviver`):


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

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

console.log(jsonData);

// Deserializacija po meri
const parsedData = JSON.parse(jsonData, (key, value) => {
    if (typeof value === 'string' && /^[0-9]+$/.test(value)) { // preveri, ali je število in niz
      try {
        return BigInt(value);
      } catch(e) {
          return value;
      }
    }
    return value;
});

console.log(parsedData.id);

Združljivost z brskalniki

BigInt je široko podprt v sodobnih brskalnikih. Vendar je ključnega pomena, da preverite združljivost za starejše brskalnike ali okolja. Za preverjanje podpore brskalnikov lahko uporabite orodje, kot je Can I use. Če morate podpirati starejše brskalnike, lahko razmislite o uporabi polyfill-a, vendar se zavedajte, da lahko polyfill-i vplivajo na zmogljivost.

Premisleki o zmogljivosti

Čeprav BigInt ponuja zmogljiv način za delo z velikimi celimi števili, je pomembno, da se zavedate morebitnih posledic za zmogljivost.

Zato uporabljajte BigInt samo, kadar je to nujno potrebno, in optimizirajte svojo kodo za zmogljivost, če izvajate veliko število operacij z BigInt.

Zaključek

BigInt je dragocen dodatek k JavaScriptu, ki razvijalcem omogoča natančno obravnavo aritmetike velikih celih števil. Z razumevanjem njegovih lastnosti, omejitev in primerov uporabe lahko izkoristite BigInt za izgradnjo robustnih in natančnih aplikacij na različnih področjih, vključno s kriptografijo, finančnimi izračuni in znanstvenim računanjem. Ne pozabite upoštevati združljivosti z brskalniki in posledic za zmogljivost pri uporabi BigInt v svojih projektih.

Nadaljnje raziskovanje

Ta vodnik ponuja celovit pregled BigInt v JavaScriptu. Raziščite povezane vire za podrobnejše informacije in napredne tehnike.