Latviešu

Visaptverošs ceļvedis par JavaScript BigInt tipu, tā funkcijām, lietojumu un pielietojumu lielu skaitļu aritmētikā. Mācieties pārvarēt JavaScript ierobežojumus un veikt precīzus aprēķinus.

JavaScript BigInt: Lielu veselu skaitļu aritmētikas apgūšana

JavaScript, lai arī ir daudzpusīga valoda, saskaras ar ierobežojumiem, strādājot ar ļoti lieliem veseliem skaitļiem. Standarta `Number` tips var precīzi attēlot veselus skaitļus tikai līdz noteiktai robežai, kas pazīstama kā `Number.MAX_SAFE_INTEGER`. Pārsniedzot šo robežu, aprēķini kļūst neprecīzi, radot neparedzētus rezultātus. Šeit talkā nāk BigInt. Ieviests ECMAScript 2020, BigInt ir iebūvēts objekts, kas nodrošina veidu, kā attēlot un manipulēt ar patvaļīga izmēra veseliem skaitļiem, pārsniedzot standarta `Number` tipa ierobežojumus.

Izpratne par BigInt nepieciešamību

Pirms BigInt ieviešanas JavaScript izstrādātājiem bija jāpaļaujas uz bibliotēkām vai pielāgotām implementācijām, lai veiktu aprēķinus ar lieliem veseliem skaitļiem. Šādi risinājumi bieži vien radīja veiktspējas zudumus un palielināja sarežģītību. BigInt ieviešana nodrošināja dabisku un efektīvu veidu, kā strādāt ar lieliem veseliem skaitļiem, paverot iespējas lietojumiem dažādās jomās, tostarp:

BigInt vērtību izveide

JavaScript ir divi galvenie veidi, kā izveidot BigInt vērtības:

  1. Izmantojot `BigInt()` konstruktoru: Šis konstruktors var pārvērst skaitli, virkni vai Būla vērtību par BigInt.
  2. Izmantojot sufiksu `n`: Pievienojot `n` vesela skaitļa literālim, tiek izveidots BigInt.

Piemēri:

Izmantojot `BigInt()` konstruktoru:


const bigIntFromNumber = BigInt(12345678901234567890);
const bigIntFromString = BigInt("98765432109876543210");
const bigIntFromBoolean = BigInt(true); // Rezultāts ir 1n
const bigIntFromFalseBoolean = BigInt(false); // Rezultāts ir 0n

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

Izmantojot sufiksu `n`:


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

Svarīga piezīme: Jūs nevarat tieši sajaukt BigInt un Number vērtības aritmētiskās operācijās. Pirms aprēķinu veikšanas tās ir skaidri jāpārvērš vienā tipā. Mēģinājums tās sajaukt tieši izraisīs `TypeError`.

BigInt aritmētiskās operācijas

BigInt atbalsta lielāko daļu standarta aritmētisko operatoru, tostarp:

Piemēri:


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

const sum = a + b;
const difference = a - b;
const product = a * b;
const quotient = a / 2n; // Piezīme: Dalīšana noapaļo uz nulles pusi
const remainder = a % 7n;
const power = a ** 3n; // Kāpināšana darbojas kā paredzēts

console.log("Summa:", sum); // Izvade: Summa: 111111111011111111100n
console.log("Starpība:", difference); // Izvade: Starpība: -86419753208641975320n
console.log("Reizinājums:", product); // Izvade: Reizinājums: 1219326311370217957951669538098765432100n
console.log("Dalījums:", quotient); // Izvade: Dalījums: 6172839450617283945n
console.log("Atlikums:", remainder); // Izvade: Atlikums: 5n
console.log("Kāpinājums:", power); // Izvade: Kāpinājums: 187641281029182300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n

Svarīgi apsvērumi:

Salīdzināšanas operatori

Jūs varat izmantot standarta salīdzināšanas operatorus (`==`, `!=`, `<`, `>`, `<=`, `>=`), lai salīdzinātu BigInt vērtības ar citām BigInt vērtībām vai pat ar Number vērtībām. Tomēr esiet uzmanīgi ar iespējamo tipu piespiedu pārveidošanu.

Piemēri:


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

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

console.log(a == c);   // Izvade: true (tipu piespiedu pārveidošana)
console.log(a === c);  // Izvade: false (nav tipu piespiedu pārveidošanas)

Labākā prakse: Izmantojiet stingro vienādību (`===`) un stingro nevienādību (`!==`), lai izvairītos no neparedzētas tipu piespiedu pārveidošanas, salīdzinot BigInt un Number vērtības.

Konvertēšana starp BigInt un Number

Lai gan tiešas aritmētiskās operācijas starp BigInt un Number nav atļautas, jūs varat konvertēt starp abiem tipiem. Tomēr apzinieties iespējamo precizitātes zudumu, konvertējot BigInt uz Number, ja BigInt vērtība pārsniedz `Number.MAX_SAFE_INTEGER`.

Piemēri:


const bigIntValue = 9007199254740991n; // Number.MAX_SAFE_INTEGER
const numberValue = Number(bigIntValue); // Pārvērš BigInt par Number
console.log(numberValue); // Izvade: 9007199254740991

const largerBigIntValue = 9007199254740992n; // Pārsniedz Number.MAX_SAFE_INTEGER
const largerNumberValue = Number(largerBigIntValue);
console.log(largerNumberValue); // Izvade: 9007199254740992 (var būt neprecīzs)

const numberToBigInt = BigInt(12345); // Pārvērš Number par BigInt
console.log(numberToBigInt); // Izvade: 12345n

Lietošanas gadījumi un piemēri

Kriptogrāfija

Kriptogrāfijas algoritmi bieži paļaujas uz ļoti lieliem pirmskaitļiem drošības nodrošināšanai. BigInt nodrošina veidu, kā efektīvi attēlot un manipulēt ar šiem skaitļiem.


// Piemērs: Vienkārša (nedroša) atslēgu pāra ģenerēšana
function generateKeyPair() {
  const p = 281n; // Pirmskaitlis
  const q = 283n; // Cits pirmskaitlis
  const n = p * q; // Modulis
  const totient = (p - 1n) * (q - 1n); // Eilera totienta funkcija

  // Izvēlas e (publisko eksponentu) tā, lai 1 < e < totient un gcd(e, totient) = 1
  const e = 17n;

  // Aprēķina d (privāto eksponentu) tā, lai (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("Publiskā atslēga:", keyPair.publicKey);
console.log("Privātā atslēga:", keyPair.privateKey);

Piezīme: Šis ir vienkāršots piemērs tikai demonstrācijas nolūkiem. Reālajā kriptogrāfijā tiek izmantoti daudz lielāki pirmskaitļi un sarežģītāki algoritmi.

Finanšu aprēķini

Strādājot ar lielām naudas summām, īpaši starptautiskos darījumos, precizitāte ir kritiski svarīga. BigInt var novērst noapaļošanas kļūdas un nodrošināt precīzus aprēķinus.


// Piemērs: Salikto procentu aprēķināšana
function calculateCompoundInterest(principal, rate, time) {
  const principalBigInt = BigInt(principal * 100); // Pārvērš centos
  const rateBigInt = BigInt(rate * 10000);       // Pārvērš desmittūkstošdaļās procenta
  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% procentu likme
const time = 10;     // 10 gadi

const finalAmount = calculateCompoundInterest(principal, rate, time);
console.log("Gala summa:", finalAmount); // Izvade: Gala summa: 1628894.6267774413 (aptuveni)

Šajā piemērā mēs pārvēršam pamatsummu un likmi par BigInt vērtībām, lai izvairītos no noapaļošanas kļūdām aprēķina laikā. Pēc tam rezultāts tiek pārvērsts atpakaļ par Number, lai to attēlotu.

Darbs ar lieliem ID

Izkliedētās sistēmās unikālu ID ģenerēšana vairākos serveros var būt izaicinājums. Izmantojot BigInt, var izveidot ļoti lielus ID, kuriem ir maza sadursmes iespējamība.


// Piemērs: Unikāla ID ģenerēšana, balstoties uz laikspiedolu un servera ID
function generateUniqueId(serverId) {
  const timestamp = BigInt(Date.now());
  const serverIdBigInt = BigInt(serverId);
  const random = BigInt(Math.floor(Math.random() * 1000)); // Pievieno nedaudz nejaušības

  // Apvieno vērtības, lai izveidotu unikālu ID
  const uniqueId = (timestamp << 20n) + (serverIdBigInt << 10n) + random;
  return uniqueId.toString(); // Atgriež kā virkni ērtai apstrādei
}

const serverId = 123; // Piemēra servera ID
const id1 = generateUniqueId(serverId);
const id2 = generateUniqueId(serverId);

console.log("Unikālais ID 1:", id1);
console.log("Unikālais ID 2:", id2);

BigInt un JSON

JSON dabiski neatbalsta BigInt vērtības. Mēģinot serializēt JavaScript objektu, kas satur BigInt, izmantojot `JSON.stringify()`, radīsies `TypeError`. Lai apstrādātu BigInt vērtības, strādājot ar JSON, jums ir dažas iespējas:

  1. Pārvērst par virkni: Pirms serializācijas pārvērsiet BigInt par virkni. Šī ir visizplatītākā un vienkāršākā pieeja.
  2. Pielāgota serializācija/deserializācija: Izmantojiet pielāgotu serializācijas/deserializācijas funkciju, lai apstrādātu BigInt vērtības.

Piemēri:

Pārvēršana par virkni:


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

// Pārvērš BigInt par virkni pirms serializācijas
data.id = data.id.toString();

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

// Deserializējot, jums būs jāpārvērš virkne atpakaļ par BigInt
const parsedData = JSON.parse(jsonData, (key, value) => {
  if (key === "id") {
    return BigInt(value);
  }
  return value;
});

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

Pielāgota serializācija/deserializācija (izmantojot `replacer` un `reviver`):


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

// Pielāgota serializācija
const jsonData = JSON.stringify(data, (key, value) => {
  if (typeof value === 'bigint') {
    return value.toString();
  } else {
    return value;
  }
});

console.log(jsonData);

// Pielāgota deserializācija
const parsedData = JSON.parse(jsonData, (key, value) => {
    if (typeof value === 'string' && /^[0-9]+$/.test(value)) { //pārbauda, vai tā ir virkne, kas satur tikai ciparus
      try {
        return BigInt(value);
      } catch(e) {
          return value;
      }
    }
    return value;
});

console.log(parsedData.id);

Pārlūku saderība

BigInt ir plaši atbalstīts modernajos pārlūkos. Tomēr ir svarīgi pārbaudīt saderību ar vecākām pārlūkprogrammām vai vidēm. Jūs varat izmantot rīku, piemēram, Can I use, lai pārbaudītu pārlūku atbalstu. Ja jums jāatbalsta vecākas pārlūkprogrammas, varat apsvērt polyfill izmantošanu, taču ņemiet vērā, ka polyfill var ietekmēt veiktspēju.

Veiktspējas apsvērumi

Lai gan BigInt nodrošina jaudīgu veidu, kā strādāt ar lieliem veseliem skaitļiem, ir svarīgi apzināties iespējamo ietekmi uz veiktspēju.

Tāpēc izmantojiet BigInt tikai tad, kad tas ir nepieciešams, un optimizējiet savu kodu veiktspējai, ja veicat lielu skaitu BigInt operāciju.

Noslēgums

BigInt ir vērtīgs papildinājums JavaScript, kas ļauj izstrādātājiem precīzi veikt lielu veselu skaitļu aritmētiku. Izprotot tā funkcijas, ierobežojumus un lietošanas gadījumus, jūs varat izmantot BigInt, lai izveidotu stabilas un precīzas lietojumprogrammas dažādās jomās, tostarp kriptogrāfijā, finanšu aprēķinos un zinātniskajā skaitļošanā. Atcerieties ņemt vērā pārlūku saderību un veiktspējas ietekmi, izmantojot BigInt savos projektos.

Tālākai izpētei

Šis ceļvedis sniedz visaptverošu pārskatu par BigInt JavaScript valodā. Izpētiet saistītos resursus, lai iegūtu padziļinātu informāciju un progresīvas tehnikas.