BigInt
– это специальный числовой тип, который предоставляет возможность работать с целыми числами произвольной длины.
Чтобы создать значение типа BigInt
, необходимо добавить n
в конец числового литерала или вызвать функцию BigInt
, которая создаст число типа BigInt
из переданного аргумента. Аргументом может быть число, строка и др.
const bigint = 1234567890123456789012345678901234567890n;
const sameBigint = BigInt("1234567890123456789012345678901234567890");
const bigintFromNumber = BigInt(10); // то же самое, что и 10n
Математические операторы
BigInt
можно использовать как обычные числа, к примеру:
alert(1n + 2n); // 3
alert(5n / 2n); // 2
Обратите внимание: операция деления 5/2
возвращает округлённый результат, без дробной части. Все операции с числами типа bigint
возвращают bigint
.
В математических операциях мы не можем смешивать bigint
и обычные числа:
alert(1n + 2); // Error: Cannot mix BigInt and other types
Мы должны явно их конвертировать: используя либо BigInt()
, либо Number()
, например:
let bigint = 1n;
let number = 2;
// конвертируем number в bigint
alert(bigint + BigInt(number)); // 3
// конвертируем `bigint` в number
alert(Number(bigint) + number); // 3
Конвертирование bigint
в число всегда происходит неявно и без генерации ошибок, но если значение bigint
слишком велико и не подходит под тип number
, то дополнительные биты будут отброшены, так что следует быть осторожными с такими преобразованиями.
BigInt
числам нельзя применить унарный оператор +
Унарный оператор +value
является хорошо известным способом конвертировать произвольное значение value
в число.
Данный оператор не поддерживается при работе с BigInt
числами:
let bigint = 1n;
alert( +bigint ); // Ошибка!
Мы должны использовать Number()
для преобразования bigint
к number
.
Операции сравнения
Операции сравнения, такие как <
, >
, работают с bigint
и обычными числами как обычно:
alert( 2n > 1n ); // true
alert( 2n > 1 ); // true
Пожалуйста, обратите внимание, что обычные и bigint
числа принадлежат к разным типам, они могут быть равны только при нестрогом сравнении ==
:
alert( 1 == 1n ); // true
alert( 1 === 1n ); // false
Логические операции
В if
или любом другом логическом операторе bigint
число ведёт себя как обычное число.
К примеру, в if
bigint
0n
преобразуется в false
, другие значения преобразуются в true
:
if (0n) {
// никогда не выполнится
}
Логические операторы ||
, &&
и другие также работают с bigint
числами как с обычными числами:
alert( 1n || 2 ); // 1
alert( 0n || 2 ); // 2
Полифилы
Создание полифила для BigInt
– достаточно непростая задача. Причина в том, что многие операторы в JavaScript, такие как +
, -
и др., ведут себя по-разному с bigint
по сравнению с обычными числами.
К примеру, деление bigint
числа всегда возвращает bigint
(округлённое при необходимости).
Чтобы эмулировать такое поведение, полифил должен будет проанализировать код и заменить все такие операторы на свои вызовы. Такая реализация будет тяжеловесной, не очень хорошей с точки зрения производительности.
Вот почему на данный момент нет хорошо реализованного полифила.
��уществует обратное решение, предложеное разработчиками библиотеки JSBI.
Эта библиотека реализует большие числа, используя собственные методы. Мы можем использовать их вместо встроенных BigInt
:
Операция | Встроенный BigInt |
JSBI |
---|---|---|
Создание из 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 на встроенные Bigint
для браузеров, которые их поддерживают.
Другими словами, данный подход предлагает использовать JSBI вместо встроенных BigInt
. JSBI внутри себя работает с числами как с BigInt
, эмулирует ��х с соблюдением всех требований спецификации. Таким образом, мы можем выполнять JSBI-код в интерпретаторах, которые не поддерживают Bigint
, а для тех, которые поддерживают – полифил преобразует вызовы в обычные Bigint
.
Комментарии
<code>
, для нескольких строк кода — тег<pre>
, если больше 10 строк — ссылку на песочницу (plnkr, JSBin, codepen…)