Eesti

Põhjalik juhend JavaScripti BigInt-tüübi kohta, mis hõlmab selle omadusi, kasutamist ja rakendusi suurte täisarvude aritmeetikas. Õppige, kuidas ületada JavaScripti piiranguid ja sooritada keerulisi arvutusi täpselt.

JavaScript BigInt: suurte täisarvude aritmeetika meisterlik valdamine

Kuigi JavaScript on mitmekülgne keel, on sellel piirangud väga suurte täisarvudega tegelemisel. Standardne `Number` tüüp suudab täpselt esitada täisarve ainult teatud piirini, mida tuntakse kui `Number.MAX_SAFE_INTEGER`. Sellest piirist kaugemal muutuvad arvutused ebatäpseks, mis viib ootamatute tulemusteni. Siin tulebki appi BigInt. ECMAScript 2020-s tutvustatud BigInt on sisseehitatud objekt, mis pakub viisi suvalise suurusega täisarvude esitamiseks ja nendega manipuleerimiseks, ületades standardse `Number` tüübi piiranguid.

Mõistes BigInt'i vajalikkust

Enne BigInt'i pidid JavaScripti arendajad suurte täisarvude arvutuste käsitlemiseks toetuma teekidele või kohandatud lahendustele. Nende lahendustega kaasnesid sageli jõudluse lisakulu ja suurenenud keerukus. BigInt'i kasutuselevõtt pakkus natiivse ja tõhusa viisi suurte täisarvudega töötamiseks, avades võimalusi rakendustele erinevates valdkondades, sealhulgas:

BigInt väärtuste loomine

JavaScriptis on kaks peamist viisi BigInt väärtuste loomiseks:

  1. Kasutades `BigInt()` konstruktorit: See konstruktor saab teisendada arvu, sõne või tõeväärtuse BigInt'iks.
  2. Kasutades `n` järelliidet: `n`-i lisamine täisarvu literaalile loob BigInt'i.

Näited:

Kasutades `BigInt()` konstruktorit:


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

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

Kasutades `n` järelliidet:


const bigIntLiteral = 12345678901234567890n;
console.log(bigIntLiteral); // Väljund: 12345678901234567890n

Oluline märkus: Te ei saa aritmeetilistes tehetes otse segada BigInt ja Number väärtusi. Enne arvutuste tegemist peate need selgesõnaliselt teisendama samasse tüüpi. Nende otse segamine põhjustab `TypeError` vea.

BigInt aritmeetilised tehted

BigInt toetab enamikku standardsetest aritmeetilistest operaatoritest, sealhulgas:

Näited:


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

const sum = a + b;
const difference = a - b;
const product = a * b;
const quotient = a / 2n; // Märkus: Jagamine kärbib nulli suunas
const remainder = a % 7n;
const power = a ** 3n; // Astendamine töötab ootuspäraselt

console.log("Summa:", sum); // Väljund: Summa: 111111111011111111100n
console.log("Vahe:", difference); // Väljund: Vahe: -86419753208641975320n
console.log("Korrutis:", product); // Väljund: Korrutis: 1219326311370217957951669538098765432100n
console.log("Jagatis:", quotient); // Väljund: Jagatis: 6172839450617283945n
console.log("Jääk:", remainder); // Väljund: Jääk: 5n
console.log("Aste:", power); // Väljund: Aste: 187641281029182300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n

Olulised kaalutlused:

Võrdlusoperaatorid

Saate kasutada standardseid võrdlusoperaatoreid (`==`, `!=`, `<`, `>`, `<=`, `>=`), et võrrelda BigInt väärtusi teiste BigInt väärtustega või isegi Number väärtustega. Siiski olge teadlik võimalikust tüübisundlusest.

Näited:


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

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

console.log(a == c);   // Väljund: true (tüübisundlus)
console.log(a === c);  // Väljund: false (tüübisundlust ei toimu)

Parim praktika: Kasutage ranget võrdsust (`===`) ja ranget mittevõrdsust (`!==`), et vältida ootamatut tüübisundlust BigInt ja Number väärtuste võrdlemisel.

Teisendamine BigInt'i ja Number'i vahel

Kuigi otsesed aritmeetilised tehted BigInt ja Number vahel ei ole lubatud, saate nende kahe tüübi vahel teisendada. Siiski olge teadlik võimalikust täpsuse kaost, kui teisendate BigInt'i Number'iks ja BigInt väärtus ületab `Number.MAX_SAFE_INTEGER`.

Näited:


const bigIntValue = 9007199254740991n; // Number.MAX_SAFE_INTEGER
const numberValue = Number(bigIntValue); // BigInt'i teisendamine Number'iks
console.log(numberValue); // Väljund: 9007199254740991

const largerBigIntValue = 9007199254740992n; // Ületab Number.MAX_SAFE_INTEGER
const largerNumberValue = Number(largerBigIntValue);
console.log(largerNumberValue); // Väljund: 9007199254740992 (võib olla ebatäpne)

const numberToBigInt = BigInt(12345); // Number'i teisendamine BigInt'iks
console.log(numberToBigInt); // Väljund: 12345n

Kasutusjuhud ja näited

Krüptograafia

Krüptograafilised algoritmid toetuvad turvalisuse tagamiseks sageli väga suurtele algarvudele. BigInt pakub viisi nende arvude tõhusaks esitamiseks ja nendega manipuleerimiseks.


// Näide: Lihtsa (ebaturvalise) võtmepaari genereerimine
function generateKeyPair() {
  const p = 281n; // Algarv
  const q = 283n; // Teine algarv
  const n = p * q; // Moodul
  const totient = (p - 1n) * (q - 1n); // Euleri totient-funktsioon

  // Valige e (avalik eksponent) nii, et 1 < e < totient ja gcd(e, totient) = 1
  const e = 17n;

  // Arvutage d (privaatne eksponent) nii, et (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("Avalik võti:", keyPair.publicKey);
console.log("Privaatne võti:", keyPair.privateKey);

Märkus: See on lihtsustatud näide ainult demonstreerimiseks. Reaalses krüptograafias kasutatakse palju suuremaid algarve ja keerukamaid algoritme.

Finantsarvutused

Suurte rahasummadega tegelemisel, eriti rahvusvahelistes tehingutes, on täpsus ülioluline. BigInt aitab vältida ümardamisvigu ja tagab täpsed arvutused.


// Näide: liitintressi arvutamine
function calculateCompoundInterest(principal, rate, time) {
  const principalBigInt = BigInt(principal * 100); // Teisenda sentideks
  const rateBigInt = BigInt(rate * 10000);       // Teisenda protsendi kümnendtuhandikeks
  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% intressimäär
const time = 10;     // 10 aastat

const finalAmount = calculateCompoundInterest(principal, rate, time);
console.log("Lõppsumma:", finalAmount); // Väljund: Lõppsumma: 1628894.6267774413 (ligikaudu)

Selles näites teisendame põhiosa ja intressimäära BigInt väärtusteks, et vältida ümardamisvigu arvutuse käigus. Tulemus teisendatakse seejärel kuvamiseks tagasi Number'iks.

Suurte ID-dega töötamine

Hajussüsteemides võib unikaalsete ID-de genereerimine mitme serveri vahel olla keeruline. BigInt'i kasutamine võimaldab luua väga suuri ID-sid, mille kokkupõrge on ebatõenäoline.


// Näide: Unikaalse ID genereerimine ajatempli ja serveri ID alusel
function generateUniqueId(serverId) {
  const timestamp = BigInt(Date.now());
  const serverIdBigInt = BigInt(serverId);
  const random = BigInt(Math.floor(Math.random() * 1000)); // Lisa natuke juhuslikkust

  // Kombineeri väärtused unikaalse ID loomiseks
  const uniqueId = (timestamp << 20n) + (serverIdBigInt << 10n) + random;
  return uniqueId.toString(); // Tagasta sõnena lihtsamaks käsitlemiseks
}

const serverId = 123; // Näide serveri ID-st
const id1 = generateUniqueId(serverId);
const id2 = generateUniqueId(serverId);

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

BigInt ja JSON

JSON ei toeta BigInt väärtusi natiivselt. Kui proovite serialiseerida JavaScripti objekti, mis sisaldab BigInt'i, kasutades `JSON.stringify()`, tulemuseks on `TypeError`. BigInt väärtuste käsitlemiseks JSON-iga töötades on teil paar võimalust:

  1. Teisenda sõneks: Teisendage BigInt enne serialiseerimist sõneks. See on kõige levinum ja otsekohesem lähenemine.
  2. Kohandatud serialiseerimine/deserialiseerimine: Kasutage BigInt väärtuste käsitlemiseks kohandatud serialiseerimis-/deserialiseerimisfunktsiooni.

Näited:

Sõneks teisendamine:


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

// Teisenda BigInt sõneks enne serialiseerimist
data.id = data.id.toString();

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

// Deserialiseerimisel peate sõne tagasi BigInt'iks teisendama
const parsedData = JSON.parse(jsonData, (key, value) => {
  if (key === "id") {
    return BigInt(value);
  }
  return value;
});

console.log(parsedData.id); // Väljund: 12345678901234567890n

Kohandatud serialiseerimine/deserialiseerimine (kasutades `replacer`'it ja `reviver`'it):


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

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

console.log(jsonData);

// Kohandatud deserialiseerimine
const parsedData = JSON.parse(jsonData, (key, value) => {
    if (typeof value === 'string' && /^[0-9]+$/.test(value)) { //kontrolli, kas see on number ja sõne
      try {
        return BigInt(value);
      } catch(e) {
          return value;
      }
    }
    return value;
});

console.log(parsedData.id);

Brauserite ühilduvus

BigInt on laialdaselt toetatud kaasaegsetes brauserites. Siiski on oluline kontrollida ühilduvust vanemate brauserite või keskkondade jaoks. Brauseri toe kontrollimiseks saate kasutada tööriista nagu Can I use. Kui peate toetama vanemaid brausereid, võiksite kaaluda polüfilli kasutamist, kuid olge teadlik, et polüfillid võivad mõjutada jõudlust.

Jõudlusega seotud kaalutlused

Kuigi BigInt pakub võimsat viisi suurte täisarvudega töötamiseks, on oluline olla teadlik võimalikest jõudlusmõjudest.

Seetõttu kasutage BigInt'i ainult siis, kui see on vajalik, ja optimeerige oma koodi jõudluse osas, kui teete suurt hulka BigInt tehteid.

Kokkuvõte

BigInt on väärtuslik lisa JavaScriptile, mis võimaldab arendajatel käsitleda suurt täisarvude aritmeetikat täpselt. Mõistes selle omadusi, piiranguid ja kasutusjuhte, saate BigInt'i abil luua vastupidavaid ja täpseid rakendusi erinevates valdkondades, sealhulgas krüptograafias, finantsarvutustes ja teadusarvutustes. Pidage meeles, et oma projektides BigInt'i kasutamisel tuleb arvestada brauserite ühilduvuse ja jõudlusmõjudega.

Edasine uurimine

See juhend annab põhjaliku ülevaate BigInt'ist JavaScriptis. Sügavama teabe ja täpsemate tehnikate saamiseks uurige lingitud ressursse.