Повний посібник з JavaScript BigInt: призначення, операції, розширені техніки та реальні застосування для обробки довільно великих чисел.
Операції з JavaScript BigInt: математичні обчислення з великими числами
Історично JavaScript мав проблеми з точним представленням дуже великих цілих чисел через те, що його тип Number є 64-бітним двійковим форматом з подвійною точністю (IEEE 754). Це обмеження стає проблематичним у сценаріях, що вимагають точності, яка перевищує можливості Number, таких як криптографія, фінансові розрахунки або наукове моделювання. Зустрічайте BigInt, новий примітивний тип даних у JavaScript, призначений для представлення цілих чисел довільної довжини.
Що таке BigInt?
BigInt — це вбудований об'єкт, який надає спосіб представлення цілих чисел, більших за 253 - 1, що є максимальним безпечним цілим числом, яке тип Number у JavaScript може точно представити. Без BigInt виконання обчислень із числами, що перевищують цю межу, може призвести до втрати точності та неправильних результатів. BigInt вирішує цю проблему, дозволяючи працювати з довільно великими цілими числами без втрати точності.
Створення BigInt
Створити BigInt можна двома способами:
- Додавши
nв кінець цілочисельного літерала. - Викликавши конструктор
BigInt().
Ось кілька прикладів:
const bigIntLiteral = 123456789012345678901234567890n;
const bigIntConstructor = BigInt(123456789012345678901234567890);
const bigIntFromString = BigInt("123456789012345678901234567890");
console.log(bigIntLiteral); // Вивід: 123456789012345678901234567890n
console.log(bigIntConstructor); // Вивід: 123456789012345678901234567890n
console.log(bigIntFromString); // Вивід: 123456789012345678901234567890n
Зауважте, що ви можете створити BigInt з числа, рядка, що представляє число, або безпосередньо як літерал BigInt. Спроба створити BigInt з числа з рухомою комою призведе до RangeError.
Основні операції з BigInt
BigInt підтримує більшість стандартних арифметичних операторів, включно з додаванням, відніманням, множенням, діленням та остачею від ділення.
Арифметичні оператори
Ось як використовувати основні арифметичні оператори з BigInt:
const a = 10n;
const b = 5n;
console.log(a + b); // Вивід: 15n (Додавання)
console.log(a - b); // Вивід: 5n (Віднімання)
console.log(a * b); // Вивід: 50n (Множення)
console.log(a / b); // Вивід: 2n (Ділення - округлює в бік нуля)
console.log(a % b); // Вивід: 0n (Остача від ділення)
console.log(a ** b); // Вивід: 100000n (Піднесення до степеня)
Важливе зауваження: Не можна змішувати BigInt та Number в арифметичних операціях. Це призведе до TypeError. Ви повинні явно перетворити Number на BigInt перед виконанням операції.
const bigInt = 10n;
const number = 5;
// console.log(bigInt + number); // Викидає TypeError
console.log(bigInt + BigInt(number)); // Вивід: 15n (Правильно)
Оператори порівняння
BigInt можна порівнювати за допомогою стандартних операторів порівняння:
const a = 10n;
const b = 5n;
console.log(a > b); // Вивід: true
console.log(a < b); // Вивід: false
console.log(a >= b); // Вивід: true
console.log(a <= b); // Вивід: false
console.log(a === b); // Вивід: false
console.log(a !== b); // Вивід: true
console.log(a == BigInt(10)); // Вивід: true
console.log(a === BigInt(10)); // Вивід: true
console.log(a == 10); // Вивід: true
console.log(a === 10); // Вивід: false
Хоча ви можете використовувати нестрогу рівність (==) для порівняння BigInt з Number, зазвичай рекомендується використовувати строгу рівність (===) та явно перетворювати Number на BigInt для ясності та уникнення несподіваного приведення типів.
Побітові оператори
BigInt також підтримують побітові оператори:
const a = 10n; // 1010 у двійковій системі
const b = 3n; // 0011 у двійковій системі
console.log(a & b); // Вивід: 2n (Побітове І)
console.log(a | b); // Вивід: 11n (Побітове АБО)
console.log(a ^ b); // Вивід: 9n (Побітове виключне АБО)
console.log(~a); // Вивід: -11n (Побітове НЕ - доповняльний код)
console.log(a << b); // Вивід: 80n (Зсув вліво)
console.log(a >> b); // Вивід: 1n (Зсув вправо)
console.log(a >>> b); // Викидає TypeError (Беззнаковий зсув вправо не підтримується для BigInt)
Зауважте, що оператор беззнакового зсуву вправо (>>>) не підтримується для BigInt, оскільки BigInt завжди є знаковими.
Розширені техніки роботи з BigInt
Робота з бібліотеками
Хоча BigInt надає базові будівельні блоки для арифметики з великими числами, використання спеціалізованих бібліотек може значно підвищити продуктивність та надати додаткові функціональні можливості для складніших операцій. Ось декілька вартих уваги бібліотек:
- jsbn: Швидка, портативна реалізація математики з великими числами на чистому JavaScript.
- BigInteger.js: Ще одна популярна бібліотека, що пропонує повний набір арифметичних та побітових операцій над цілими числами довільної довжини.
- elliptic: Спеціально розроблена для криптографії на еліптичних кривих, яка значною мірою покладається на арифметику BigInt.
Ці бібліотеки часто надають оптимізовані алгоритми та спеціалізовані функції, які можуть бути критично важливими для чутливих до продуктивності застосунків.
Аспекти продуктивності
Хоча BigInt дозволяє довільну точність, важливо пам'ятати про його вплив на продуктивність. Операції з BigInt зазвичай повільніші, ніж операції з Number, оскільки вони вимагають більше пам'яті та обчислювальних ресурсів. Тому важливо використовувати BigInt тільки за необхідності та оптимізувати свій код для підвищення продуктивності.
Ось кілька порад для оптимізації продуктивності BigInt:
- Уникайте непотрібних перетворень: Мінімізуйте кількість перетворень між Number та BigInt.
- Використовуйте ефективні алгоритми: Обирайте алгоритми, оптимізовані для арифметики з великими числами. Бібліотеки, такі як jsbn та BigInteger.js, часто надають високооптимізовані реалізації.
- Профілюйте свій код: Використовуйте інструменти профілювання JavaScript для виявлення вузьких місць продуктивності та оптимізації вашого коду.
Типова безпека
TypeScript надає відмінну підтримку для BigInt, дозволяючи забезпечити типову безпеку та запобігти помилкам, пов'язаним зі змішуванням BigInt та Number. Ви можете явно оголошувати змінні як 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)); // Вивід: 30n
// console.log(addBigInts(10, 20)); // TypeScript видасть помилку
Використовуючи систему типів TypeScript, ви можете виявляти потенційні помилки на ранніх етапах процесу розробки та підвищувати надійність вашого коду.
Реальні застосування BigInt
BigInt є незамінними в різних сферах, де точна обробка великих цілих чисел має вирішальне значення. Розглянемо деякі основні застосування:
Криптографія
Криптографія значною мірою покладається на великі прості числа та складні математичні операції, що вимагають довільної точності. BigInt незамінні для реалізації криптографічних алгоритмів, таких як RSA, ECC (криптографія на еліптичних кривих) та обмін ключами Діффі-Геллмана.
Приклад: шифрування RSA
RSA включає генерацію великих простих чисел та виконання модулярного піднесення до степеня з великими цілими числами. BigInt використовуються для представлення цих простих чисел та виконання необхідних обчислень без втрати точності. Безпека RSA залежить від складності факторизації великих чисел, що робить BigInt критично важливим для її реалізації.
Фінансові розрахунки
Фінансові розрахунки часто включають обробку великих грошових сум або виконання складних обчислень з високою точністю. BigInt можна використовувати для точного представлення грошових значень та уникнення помилок округлення, які можуть виникнути при використанні чисел з рухомою комою. Це особливо важливо в таких застосунках, як бухгалтерські системи, банківське програмне забезпечення та фінансове моделювання.
Приклад: розрахунок відсотків за великою позикою
При розрахунку відсотків за великою позикою навіть невеликі помилки округлення можуть накопичуватися з часом і призводити до значних розбіжностей. Використання BigInt для представлення основної суми, процентної ставки та інших відповідних значень гарантує точність та надійність розрахунків.
Наукові обчислення
Наукове моделювання та обчислення часто включають обробку надзвичайно великих або малих чисел. BigInt можна використовувати для точного представлення цих чисел та виконання необхідних обчислень без втрати точності. Це особливо важливо в таких галузях, як астрономія, фізика та хімія, де точність є першочерговою.
Приклад: обчислення кількості атомів у молі
Число Авогадро (приблизно 6.022 x 1023) представляє кількість атомів у молі речовини. Це число значно перевищує межу безпечних цілих чисел для типу Number в JavaScript. Використання BigInt дозволяє точно представляти число Авогадро та виконувати обчислення з ним без втрати точності.
Високоточні часові мітки
У розподілених системах або високочастотних трейдингових застосунках точні часові мітки є важливими для підтримки узгодженості даних та правильного впорядкування подій. BigInt можна використовувати для представлення часових міток з точністю до наносекунд або навіть пікосекунд, забезпечуючи точне впорядкування подій навіть у сценаріях з надзвичайно високою частотою подій.
Технологія блокчейн
Технологія блокчейн значною мірою покладається на криптографічні операції та арифметику з великими числами. BigInt використовуються для представлення ідентифікаторів транзакцій, хешів блоків та інших криптографічних значень з високою точністю. Вони також використовуються в смарт-контрактах для виконання складних обчислень та забезпечення фінансових правил без використання чисел з рухомою комою.
Приклад: смарт-контракти Ethereum
Смарт-контракти Ethereum часто включають складні фінансові розрахунки та управління цифровими активами. Використання BigInt гарантує точне виконання цих розрахунків та представлення вартості активів без помилок округлення.
Сумісність з браузерами
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); // викличе помилку діапазону (range error)
Підводні камені та міркування
Хоча BigInt неймовірно корисні, слід пам'ятати про певні підводні камені:
- Помилки типів: Пам'ятайте, що BigInt не можна безпосередньо змішувати з Number в арифметичних операціях.
- Продуктивність: Операції з BigInt повільніші, ніж стандартні операції з Number.
- Втрата точності: Перетворення дуже великих BigInt в Number може призвести до втрати точності через обмеження типу Number.
- Відсутність підтримки в стандартній бібліотеці: Не всі стандартні методи JavaScript безпосередньо сумісні з BigInt. Можливо, вам доведеться реалізовувати власні функції або використовувати бібліотеки, які явно підтримують BigInt.
- Пріоритет операторів: Будьте уважні до пріоритету операторів при використанні побітових операторів з BigInt.
Висновок
BigInt — це потужне доповнення до JavaScript, яке дозволяє розробникам працювати з довільно великими цілими числами без втрати точності. Ця можливість є важливою в різних сферах, включаючи криптографію, фінансові розрахунки, наукові обчислення та технологію блокчейн. Розуміючи основи операцій з BigInt, аспекти продуктивності та реальні застосування, розробники можуть використовувати цей тип даних для створення більш надійних і стабільних застосунків, що вимагають точної обробки великих чисел. Хоча існують певні міркування щодо продуктивності та типів, переваги використання BigInt за необхідності є значними.
Оскільки JavaScript продовжує розвиватися, BigInt, безсумнівно, відіграватиме все більш важливу роль, дозволяючи розробникам вирішувати складні проблеми, що вимагають арифметики довільної точності. Світ все більше покладається на обчислення, і точність є першочерговою.
Вважайте цей вичерпний посібник відправною точкою, заглиблюйтесь у бібліотеки та досліджуйте творчі способи застосування BigInt у ваших проєктах.