Пълно ръководство за JavaScript BigInt, обхващащо предназначение, операции, напреднали техники и реални приложения за работа с произволно големи числа.
Операции с JavaScript BigInt: Изчисления с големи числа
Исторически JavaScript се е затруднявал да представя много големи цели числа точно, тъй като неговият тип Number е 64-битов бинарен формат с двойна прецизност (IEEE 754). Това ограничение става проблематично в сценарии, изискващи по-висока точност от тази, която Number може да предложи, като криптография, финансови изчисления или научни симулации. Тук идва BigInt, нов примитивен тип данни в JavaScript, предназначен да представя цели числа с произволна дължина.
Какво е BigInt?
BigInt е вграден обект, който предоставя начин за представяне на цели числа, по-големи от 253 - 1, което е максималното безопасно цяло число, което типът Number на JavaScript може точно да представи. Без BigInt, извършването на изчисления с числа, надвишаващи този лимит, може да доведе до загуба на точност и неправилни резултати. BigInt решава този проблем, като ви позволява да работите с произволно големи цели числа, без да губите точност.
Създаване на BigInts
Можете да създадете BigInt по два начина:
- Чрез добавяне на
nв края на целочислен литерал. - Чрез извикване на конструктора
BigInt().
Ето няколко примера:
const bigIntLiteral = 123456789012345678901234567890n;
const bigIntConstructor = BigInt(123456789012345678901234567890);
const bigIntFromString = BigInt("123456789012345678901234567890");
console.log(bigIntLiteral); // Output: 123456789012345678901234567890n
console.log(bigIntConstructor); // Output: 123456789012345678901234567890n
console.log(bigIntFromString); // Output: 123456789012345678901234567890n
Имайте предвид, че можете да създадете BigInt от число, низ, представляващ число, или директно като BigInt литерал. Опитът за създаване на BigInt от число с плаваща запетая ще доведе до RangeError.
Основни операции с BigInt
BigInt поддържа повечето от стандартните аритметични оператори, включително събиране, изваждане, умножение, деление и модул.
Аритметични оператори
Ето как да използвате основните аритметични оператори с BigInt:
const a = 10n;
const b = 5n;
console.log(a + b); // Output: 15n (Събиране)
console.log(a - b); // Output: 5n (Изваждане)
console.log(a * b); // Output: 50n (Умножение)
console.log(a / b); // Output: 2n (Деление - пресича към нула)
console.log(a % b); // Output: 0n (Модул)
console.log(a ** b); // Output: 100000n (Степенуване)
Важна забележка: Не можете да смесвате BigInts с Numbers в аритметични операции. Това ще доведе до TypeError. Трябва изрично да конвертирате Number в BigInt, преди да извършите операцията.
const bigInt = 10n;
const number = 5;
// console.log(bigInt + number); // Хвърля TypeError
console.log(bigInt + BigInt(number)); // Output: 15n (Коректно)
Оператори за сравнение
BigInts могат да бъдат сравнявани с помощта на стандартните оператори за сравнение:
const a = 10n;
const b = 5n;
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 === b); // Output: false
console.log(a !== b); // Output: true
console.log(a == BigInt(10)); // Output: true
console.log(a === BigInt(10)); // Output: true
console.log(a == 10); // Output: true
console.log(a === 10); // Output: false
Въпреки че можете да използвате свободно равенство (==) за сравняване на BigInt с Number, като цяло се препоръчва да използвате стриктно равенство (===) и изрично да конвертирате Number в BigInt за яснота и за да избегнете неочаквано принудително преобразуване на тип.
Побитови оператори
BigInts също поддържат побитови оператори:
const a = 10n; // 1010 в двоичен код
const b = 3n; // 0011 в двоичен код
console.log(a & b); // Output: 2n (Побитово И)
console.log(a | b); // Output: 11n (Побитово ИЛИ)
console.log(a ^ b); // Output: 9n (Побитово ИЗКЛЮЧВАЩО ИЛИ)
console.log(~a); // Output: -11n (Побитово НЕ - допълнение до две)
console.log(a << b); // Output: 80n (Ляв шифт)
console.log(a >> b); // Output: 1n (Десен шифт)
console.log(a >>> b); // Хвърля TypeError (Неподдържан беззнаков десен шифт за BigInt)
Имайте предвид, че операторът за беззнаков десен шифт (>>>) не се поддържа за BigInts, тъй като BigInts винаги са със знак.
Разширени техники с BigInt
Работа с библиотеки
Въпреки че BigInt предоставя основните градивни елементи за аритметика с големи числа, използването на специализирани библиотеки може значително да подобри производителността и да предостави допълнителни функционалности за по-сложни операции. Ето няколко забележителни библиотеки:
- jsbn: Бърза, преносима имплементация на математика с големи числа в чист JavaScript.
- BigInteger.js: Друга популярна библиотека, предлагаща изчерпателен набор от аритметични и побитови операции върху цели числа с произволна дължина.
- elliptic: Специално проектирана за криптография с елиптични криви, която силно разчита на аритметиката с BigInt.
Тези библиотеки често предоставят оптимизирани алгоритми и специализирани функции, които могат да бъдат от решаващо значение за чувствителни към производителността приложения.
Съображения за производителността
Въпреки че BigInt позволява произволна точност, важно е да сте наясно с последиците му за производителността. Операциите с BigInt като цяло са по-бавни от операциите с Number, тъй като изискват повече памет и изчислителни ресурси. Затова е от решаващо значение да използвате BigInt само когато е необходимо и да оптимизирате кода си за производителност.
Ето няколко съвета за оптимизиране на производителността на BigInt:
- Избягвайте ненужни преобразувания: Минимизирайте броя на преобразуванията между Numbers и BigInts.
- Използвайте ефективни алгоритми: Изберете алгоритми, които са оптимизирани за аритметика с големи числа. Библиотеки като jsbn и BigInteger.js често предоставят силно оптимизирани имплементации.
- Профилирайте кода си: Използвайте инструменти за профилиране на JavaScript, за да идентифицирате тесните места в производителността и да оптимизирате кода си съответно.
Типова безопасност
TypeScript осигурява отлична поддръжка за BigInt, което ви позволява да наложите типова безопасност и да предотвратите грешки, свързани със смесването на BigInts с Numbers. Можете изрично да декларирате променливи като BigInt, за да гарантирате, че те съдържат само стойности на BigInt.
let bigIntValue: bigint = 12345678901234567890n;
// bigIntValue = 5; // TypeScript ще хвърли грешка, защото се опитвате да присвоите число на bigint.
console.log(bigIntValue);
function addBigInts(a: bigint, b: bigint): bigint {
return a + b;
}
console.log(addBigInts(10n, 20n)); // Output: 30n
// console.log(addBigInts(10, 20)); // TypeScript ще хвърли грешка
Чрез използване на системата за типове на TypeScript можете да хванете потенциални грешки в ранен етап от процеса на разработка и да подобрите надеждността на кода си.
Приложения на BigInt в реалния свят
BigInts са от съществено значение в различни области, където е от решаващо значение прецизното обработване на големи цели числа. Нека разгледаме някои от най-известните приложения:
Криптография
Криптографията силно разчита на големи прости числа и сложни математически операции, които изискват произволна точност. BigInts са незаменими за имплементиране на криптографски алгоритми като RSA, ECC (криптография с елиптични криви) и обмен на ключове Diffie-Hellman.
Пример: RSA криптиране
RSA включва генериране на големи прости числа и извършване на модулно степенуване с големи цели числа. BigInts се използват за представяне на тези прости числа и за извършване на необходимите изчисления без загуба на точност. Сигурността на RSA зависи от трудността при факторизирането на големи числа, което прави BigInts решаващи за неговото изпълнение.
Финансови изчисления
Финансовите изчисления често включват обработка на големи суми пари или извършване на сложни изчисления с висока точност. BigInts могат да се използват за точно представяне на парични стойности и избягване на грешки при закръгляване, които могат да възникнат при използване на числа с плаваща запетая. Това е особено важно в приложения като счетоводни системи, банков софтуер и финансово моделиране.
Пример: Изчисляване на лихвата по голям заем
При изчисляване на лихвата по голям заем, дори малки грешки при закръгляване могат да се натрупат с течение на времето и да доведат до значителни несъответствия. Използването на BigInts за представяне на главницата, лихвения процент и други свързани стойности гарантира, че изчисленията са точни и надеждни.
Научни изчисления
Научните симулации и изчисления често включват работа с изключително големи или малки числа. BigInts могат да се използват за точно представяне на тези числа и извършване на необходимите изчисления без загуба на точност. Това е особено важно в области като астрономията, физиката и химията, където точността е от първостепенно значение.
Пример: Изчисляване на броя на атомите в мол
Числото на Авогадро (приблизително 6.022 x 1023) представлява броя на атомите в един мол вещество. Това число е далеч извън безопасния лимит за цели числа на типа Number в JavaScript. Използването на BigInts ви позволява точно да представите числото на Авогадро и да извършвате изчисления, включващи го, без да губите точност.
Времеви клейма с висока точност
В разпределени системи или приложения за високочестотна търговия, точните времеви клейма са от съществено значение за поддържане на съгласуваност на данните и правилно подреждане на събитията. BigInts могат да се използват за представяне на времеви клейма с наносекундна или дори пикосекундна точност, гарантирайки, че събитията са подредени точно, дори в сценарии с изключително високи скорости на събития.
Блокчейн технология
Блокчейн технологията силно разчита на криптографски операции и аритметика с големи числа. BigInts се използват за представяне на ID на транзакции, хешове на блокове и други криптографски стойности с висока точност. Те също така се използват в смарт договори за извършване на сложни изчисления и налагане на финансови правила, без да се разчита на числа с плаваща запетая.
Пример: Смарт договори на Ethereum
Смарт договорите на Ethereum често включват сложни финансови изчисления и управление на цифрови активи. Използването на BigInts гарантира, че тези изчисления се извършват точно и че стойностите на активите се представят без грешки при закръгляване.
Съвместимост с браузъри
BigInt има отлична поддръжка в съвременните браузъри, включително Chrome, Firefox, Safari и Edge. Въпреки това е от съществено значение да се вземе предвид съвместимостта с браузърите, когато се разработват приложения, които трябва да поддържат по-стари браузъри. Можете да използвате полифили или транспилери като Babel, за да осигурите поддръжка на BigInt за по-стари браузъри. Много по-стари браузъри нямат нативна поддръжка на BigInt, но са налични полифили за добавяне на функционалност. Проверете уебсайта CanIUse за актуализирана таблица.
Например, Babel може да транспилира вашия код, използващ BigInt, в еквивалентен код, който работи дори в по-стари Javascript енджини.
Преобразуване към и от други типове
Преобразуването между BigInt и други типове JavaScript изисква изрично преобразуване. Ето правилата:
- Към Number: Използвайте
Number(bigIntValue). Бъдете внимателни, тъй като това може да доведе до загуба на точност, ако BigInt е твърде голям. - Към String: Използвайте
String(bigIntValue). Това като цяло е безопасно и предоставя низово представяне на BigInt. - От Number: Използвайте
BigInt(numberValue). Това се препоръчва само за цели числа. Числа с плаваща запетая, подадени на конструктора BigInt, ще хвърлят RangeError. - От String: Използвайте
BigInt(stringValue). Низът трябва да представлява цяло число, в противен случай ще възникне SyntaxError.
let bigIntVal = 123456789012345678901234567890n;
let numVal = Number(bigIntVal); // Потенциално загуба на точност при конвертиране
let strVal = String(bigIntVal); // Безопасно конвертиране към низ
console.log(numVal); // Показва загуба на точност.
console.log(strVal);
let newBigInt = BigInt(100); // Създава от цяло число Number
console.log(newBigInt);
let newBigIntFromString = BigInt("98765432109876543210"); // от низ
console.log(newBigIntFromString);
// BigInt(3.14); // ще предизвика грешка от обхват
Капани и съображения
Въпреки че BigInts са изключително полезни, трябва да сте наясно с някои капани:
- Грешки от тип: Не забравяйте, че BigInts не могат да се смесват директно с Numbers в аритметични операции.
- Производителност: Операциите с BigInt са по-бавни от стандартните операции с Number.
- Загуба на точност: Преобразуването на много големи BigInts в Numbers може да доведе до загуба на точност поради ограниченията на типа Number.
- Липса на поддръжка от стандартна библиотека: Не всички стандартни методи на JavaScript са директно съвместими с BigInts. Може да се наложи да имплементирате потребителски функции или да използвате библиотеки, които изрично поддържат BigInts.
- Приоритет на операторите: Внимавайте за приоритета на операторите, когато използвате побитови оператори с BigInts.
Заключение
BigInt е мощно допълнение към JavaScript, което позволява на разработчиците да работят с произволно големи цели числа без загуба на точност. Тази възможност е от съществено значение в различни области, включително криптография, финансови изчисления, научни изчисления и блокчейн технология. Чрез разбиране на основите на операциите с BigInt, съображенията за производителност и приложенията в реалния свят, разработчиците могат да използват този тип данни, за да изграждат по-стабилни и надеждни приложения, които изискват прецизно обработване на големи числа. Въпреки че има някои съображения за производителността и типа, ползите от използването на BigInt, когато е необходимо, са значителни.
Тъй като JavaScript продължава да се развива, BigInt без съмнение ще играе все по-важна роля в даването на възможност на разработчиците да се справят със сложни проблеми, които изискват аритметика с произволна точност. Светът разчита все повече на изчисленията и точността е от първостепенно значение.
Считайте това изчерпателно ръководство за отправна точка, потопете се по-дълбоко в библиотеките и проучете креативни начини да приложите BigInt във вашите проекти.