BigInt
– це спеціальний числовий тип, який забезпечує підтримку цілих чисел довільної довжини.
Bigint створюється шляхом додавання n
до кінця цілочисельного літералу або викликом функції BigInt
, яка створює великі числа з рядків, чисел тощо.
const bigint = 1234567890123456789012345678901234567890n;
const sameBigint = BigInt("1234567890123456789012345678901234567890");
const bigintFromNumber = BigInt(10); // те саме що і 10n
Математичні оператори
BigInt
можна використовувати як звичайне число, наприклад:
alert(1n + 2n); // 3
alert(5n / 2n); // 2
Зверніть увагу: поділ 5/2
повертає результат, округлений до нуля, без десяткової частини. Усі операції над великими числами повертають великі числа.
Ми не можемо змішувати великі та звичайні числа:
alert(1n + 2); // Error: Cannot mix BigInt and other types
Ми повинні явно конвертувати їх, якщо потрібно: використовуючи BigInt()
або Number()
, наприклад:
let bigint = 1n;
let number = 2;
// число у велике число
alert(bigint + BigInt(number)); // 3
// велике число у число
alert(Number(bigint) + number); // 3
Операції перетворення завжди безшумні, ніколи не дають помилок, але якщо величе число занадто велике і не відповідає типу числа, то зайві біти будуть відрізані, тому ми повинні бути обережними, виконуючи таке перетворення.
Оператор унарний плюс +value
є добре відомим способом перетворення value
у число.
Щоб уникнути плутанини, він не підтримується на великих числах:
let bigint = 1n;
alert( +bigint ); // помилка
Тому ми повинні використовувати Number()
, щоб перетворити велике число в число.
Порівняння
Порівняння, такі як <
, >
, чудово працюють з великими та числами:
alert( 2n > 1n ); // true
alert( 2n > 1 ); // true
Зверніть увагу, оскільки числа та великі числа мають різні типи, вони можуть бути рівними ==
, але не строго рівними ===
:
alert( 1 == 1n ); // true
alert( 1 === 1n ); // false
Булеві операції
Всередині if
або інших логічних операцій великі числа поводяться як числа.
Наприклад, у if
величе число 0n
є хибним, інші значення є істинними:
if (0n) {
// ніколи не виконається
}
Логічні оператори, такі як ||
, &&
та інші також працюють з великими числами, подібно до чисел:
alert( 1n || 2 ); // 1 (1n вважається істинним)
alert( 0n || 2 ); // 2 (0n вважається хибним)
Поліфіли
Поліфілення великих чисел є складним. Причина в тому, що багато операторів в JavaScript, таких як +
, -
тощо, поводяться по-різному з великими числами порівняно зі звичайними числами.
Наприклад, поділ великих чисел завжди повертає велике число (за потреби округляється).
Щоб емулювати таку поведінку, поліфіл має проаналізувати код і замінити всі такі оператори своїми функціями. Але це громіздко і буде коштувати великої жертви в продуктивності.
Отже, добре відомого хорошого поліфілу не існує.
Проте, розробники бібліотеки JSBI пропонують рішення.
Ця бібліотека реалізує підтримку великих чисел, використовуючи власні методи. Ми можемо використовувати їх замість нативних великих чисел:
Операція | нативний BigInt |
JSBI |
---|---|---|
Створення from Number | a = BigInt(789) |
a = JSBI.BigInt(789) |
Додавання | c = a + b |
c = JSBI.add(a, b) |
Віднімання | c = a - b |
c = JSBI.subtract(a, b) |
… | … | … |
…А потім скористайтеся поліфілом (плагін для Babel), щоб перетворити виклики JSBI на нативні великі числа для тих браузерів, які їх підтримують.
Іншими словами, цей підхід припускає, що ми пишемо код на JSBI замість нативних великих чисел. Але JSBI всередині працює з числами як із великими числами, емулює їх відповідно до специфікації, тож код буде «готовий до великих чисел».
Ми можемо використовувати такий код JSBI «як є» для двигунців, які не підтримують великі числа, а для тих, які підтримують – поліфіл конвертуватиме виклики в нативні великі числа.