64-битный тип Number
в JavaScript вполне подходит для большинства целей, но если вам нужны очень большие числа или больше десятичных разрядов, чем он может представить, вам может прийти на помощь тип BigNumber
из библиотеки math.js. В этой статье я покажу тип BigNumber
в действии.
Этот проект состоит из файла HTML, файла JavaScript и файла CSS, которые находятся в репозитории itHub. Я также включил минимизированную версию библиотеки math.js, math.min.js.
Ограничения числового типа JavaScript
Тип JavaScript Number
подходит для большинства целей как с точки зрения наибольшего и наименьшего числа, так и с максимальным количеством знаков после запятой. Однако он ограничен тем, сколько вы можете втиснуть в 64 бита, поэтому, прежде чем перейти к основной теме этой статьи, math.js BigNumber
, я кратко расскажу, каковы ограничения типа JavaScript Number
.
JavaScript предоставляет нам пару констант, Number.MAX_SAFE_INTEGER
и Number.MIN_SAFE_INTEGER
, а также метод под названием Number.isSafeInteger
, который позволяет нам проверить, не думаем ли мы, что можем наткнуться на опасную территорию с очень большими числами.
Первая часть кода JavaScript, прилагаемая к этой статье, показывает использование этих констант и методов.
В onload
есть три вызова функций, второй и третий пока закомментированы. После onload
идет короткая функция, которая записывает текст прямо на веб-страницу.
В safeIntegers
мы просто выводим Number.MAX_SAFE_INTEGER
и Number.MIN_SAFE_INTEGER
перед созданием нескольких констант для проверки безопасности. Затем выводится каждый из них, за которым следует результат вызова Number.isSafeInteger
с ним. Если вы откроете mathjsbignumber.htm в своем браузере, вы увидите это.
Тип JavaScript BigInt
В JavaScript есть собственное частичное решение проблемы ограничений Number
, тип BigInt
. Как следует из названия, это целочисленный тип, а не вещественный или с плавающей запятой, и он несовместим с методами Math
. Поэтому его полезность ограничена, но в следующем методе я кратко покажу его использование.
Во-первых, мы создаем пару BigInts
— здесь это делается путем добавления к числу суффикса n
, но вы также можете вызвать конструктор BigInt
, например:
const bigNo = BigInt(9007199254740992);
Вызов typeof
для BigInt
возвращает bigint
, а затем печатаются две константы. Затем мы делим 3n
на 2n
просто для того, чтобы продемонстрировать, что это целочисленный тип; результатом будет 1 с потерей десятичной части. Наконец, просто как напоминание о том, что методы Math
не работают на BigInts
, я попробовал его с Math.min
и Math.sign
. Оба они будут вызывать ошибки, поэтому эти фрагменты кода находятся в блоках try/catch.
Если вы прокрутите вверх до функции onload
, закомментируете safeIntegers();
, раскомментируете BigInts();
и обновите веб-страницу, вы увидите этот вывод.
Интересно видеть сообщения об ошибках: методы Math
пытаются преобразовать аргументы в типы Number
, но терпят неудачу. Это так же хорошо, как если бы они потеряли точность.
Должен сказать, что меня совсем не впечатлил тип BigInt
. Это довольно хромая попытка со слишком большим количеством ограничений, чтобы воспринимать ее всерьез.
Основная особенность: тип math.js BigNumber
Тип BigNumber
библиотеки math.js может представлять действительные числа или числа с плавающей запятой и может использоваться с методами библиотеки. В финальной функции я покажу ее в использовании.
Во-первых, я создал BigNumber
с размером наблюдаемой вселенной в километрах и вывел значение с фиксированной нотацией; это отформатирует вывод полностью, а не 8.8e+26
. (Очевидно, что световые годы были бы более разумной единицей, но это только для демонстрационных целей.)
Затем мы выполняем несколько операций над BigNumbers
с помощью методов math.js, чего нельзя сделать с помощью методов JavaScript BigInts
и Math
, как мы только что видели.
Следующие несколько строк кода демонстрируют, как изменить точность BigNumbers
, в данном случае с квадратным корнем из 2, которое является иррациональным числом. По умолчанию используется 64 значащих цифры, но здесь я также использую 32 и 128. Использование BigNumbers
значительно медленнее, чем тип Number
, тем медленнее, чем больше цифр, поэтому важно использовать только ту точность, которая вам нужна. Обратите внимание, что даже при значении 32 у нас все еще примерно в два раза больше точных знаков после запятой, чем у типа Number
.
Наконец, я создал пару констант для очень маленьких и очень больших чисел. Первая — это планковская длина (в метрах), которую я не буду здесь описывать, но вы можете прочитать статью в Википедии. Достаточно сказать, что это очень-очень мало!
Второе число — это количество атомов во Вселенной. Обозначение 1e+80
означает 10^80 и является приблизительным. Очевидно!
Закомментируйте BigInts();
в onload
, раскомментируйте BigNumbers();
и перезагрузите страницу. Это результат, несколько обрезанный. Очень длинные числа идут намного дальше вправо.
Эта статья и исходный код представляют собой лишь введение в тему с несколькими примерами, но должны помочь вам начать работу. Это краткое изложение использования типа BigNumber
библиотеки math.js.
- Создайте
BigNumber
сmath.bignumber(880000000000000000000000000)
илиmath.bignumber(1e+80)
- Установите минимальное количество значащих цифр, необходимое для оптимальной эффективности.
- Используйте любой из методов библиотеки math.js с
BigNumbers
: они распознают, когда вы передаетеBigNumber
аргументов, и вернутBigNumber
- Используйте
math.format . . . {notation: ‘fixed’}
, если вы хотите видеть все цифры, а не что-то вроде8.8e+26
Эта статья ранее публиковалась на моем сайте CodeDrome