W3docs

JavaScript BigInt

Изучите JavaScript BigInt: создание и использование целых чисел произвольной точности, арифметика, сравнение, преобразование типов и практические примеры.

Введение в JavaScript BigInt

BigInt — это встроенный примитивный тип JavaScript, представляющий целые числа произвольного размера — числа, значительно превышающие то, что может точно хранить обычный тип Number. В этом руководстве объясняется, зачем нужен BigInt, как его создавать и использовать, в каких задачах он незаменим (финансы, криптография, крупные вычисления), а также описаны типичные ловушки.

Почему появился BigInt

Тип Number в JavaScript — это 64-битное число с плавающей точкой. Он может точно представлять целые числа лишь до Number.MAX_SAFE_INTEGER, равного 2^53 - 1 (9007199254740991). При выходе за этот предел обычная арифметика молча теряет точность:

javascript— editable

Если вам нужны точные целые числа большего размера — идентификаторы из базы данных, суммы в наименьших денежных единицах, криптографические ключи, факториалы — BigInt является правильным решением.

Понимание BigInt в JavaScript

BigInt — это отдельный примитивный тип, отличный от Number. Оператор typeof возвращает "bigint", и у него собственные правила арифметики.

Синтаксис и создание

Создать BigInt можно, добавив n в конец целочисленного литерала, или вызвав функцию BigInt() с числом или строкой в качестве аргумента.

javascript— editable

Используйте строковую форму, когда значение поступает из пользовательского ввода или превышает то, что числовой литерал может безопасно выразить. Передача нецелого числа (например, BigInt(1.5)) вызывает ошибку RangeError.

Базовые операции с BigInt

BigInt поддерживает те же арифметические операторы, что и Number, однако оба операнда должны быть типа BigInt. Деление усекается в сторону нуля — дробной части нет.

javascript— editable

Обратите внимание: first / second равно 2n, а не 2.5 — деление BigInt отбрасывает остаток, не возвращая дробного значения.

Сравнение BigInt и Number

Несмотря на то что это разные типы, BigInt и Number можно сравнивать с помощью операторов отношения и оператора нестрогого равенства ==. Только строгое равенство === различает типы, поскольку проверяет и тип тоже.

javascript— editable

Подробнее о различиях между == и === см. в разделе операторы сравнения.

Ограничения и приведение типов

При всей своей мощи BigInt имеет ряд ограничений по сравнению со стандартным типом Number:

  • Нет неявного приведения в арифметике: нельзя складывать, умножать и т. д. BigInt и Number напрямую — это вызовет TypeError. Предварительно преобразуйте один из операндов.
  • Математические функции: стандартные методы Math (например, Math.sqrt(), Math.floor()) не принимают аргументы типа BigInt и выбросят исключение.
  • Нет унарного плюса: +10n вызывает ошибку — используйте вместо него Number(10n).
  • JSON: JSON.stringify не может сериализовать BigInt и выбросит TypeError; предварительно преобразуйте значение в строку самостоятельно.
  • Явное преобразование: для преобразования между типами используйте Number(bigint) или BigInt(number). Преобразование в Number может потерять точность для очень больших значений.
javascript— editable

Практическое применение BigInt

Способность BigInt точно работать с большими числами делает его незаменимым в финансовых вычислениях, криптографии и крупномасштабных вычислениях.

Финансовые вычисления

В финансовых приложениях BigInt помогает избежать ошибок округления, связанных с числами с плавающей точкой.

javascript— editable

Этот пример демонстрирует использование BigInt для высокоточных арифметических вычислений в финансовом контексте, обеспечивая точность транзакций.

Информация

BigInt — незаменимый инструмент в криптографии, играющий ключевую роль в генерации больших простых чисел. Эти числа лежат в основе механизмов безопасности алгоритмов шифрования, обеспечивая надёжную защиту данных.

Высокопроизводительные вычисления

Следующий пример демонстрирует использование BigInt при перемножении матриц для обработки данных большого масштаба с обеспечением точности и эффективности. Мы рассмотрим полную реализацию функции умножения матриц с использованием BigInt. Она включает инициализацию матриц, заполнение их значениями BigInt и выполнение умножения. Вот пошаговый реальный пример:

Шаг 1: Инициализация матрицы

Сначала создадим функцию для инициализации матрицы заданных размеров с нулевыми значениями BigInt.

function initializeMatrix(rows, cols) {
  let matrix = new Array(rows);
  for (let i = 0; i < rows; i++) {
    matrix[i] = new Array(cols).fill(0n);
  }
  return matrix;
}

Шаг 2: Функция умножения матриц

Далее определим функцию для выполнения умножения матриц. Обе входные матрицы должны содержать значения BigInt, и результирующая матрица также будет содержать значения BigInt.

function multiplyMatrices(matrixA, matrixB) {
  if (matrixA[0].length !== matrixB.length) {
    throw new Error('Number of columns in Matrix A must equal number of rows in Matrix B');
  }

  let resultMatrix = initializeMatrix(matrixA.length, matrixB[0].length);

  for (let i = 0; i < matrixA.length; i++) {
    for (let j = 0; j < matrixB[0].length; j++) {
      let sum = 0n;
      for (let k = 0; k < matrixA[0].length; k++) {
        sum += matrixA[i][k] * matrixB[k][j];
      }
      resultMatrix[i][j] = sum;
    }
  }
  return resultMatrix;
}

Шаг 3: Пример матриц и умножение

Наконец, создадим несколько примеров матриц и выполним умножение. Матрицы заполнены значениями BigInt.

javascript— editable

Объяснение результата

Этот пример перемножает две матрицы 2x2, заполненные значениями BigInt. Результатом будет новая матрица, каждый элемент которой является итогом применения правил умножения матриц к значениям BigInt. Вот как выглядит умножение:

  • Result[0][0] = (1n * 2n) + (2n * 1n) = 2n + 2n = 4n
  • Result[0][1] = (1n * 0n) + (2n * 2n) = 0n + 4n = 4n
  • Result[1][0] = (3n * 2n) + (4n * 1n) = 6n + 4n = 10n
  • Result[1][1] = (3n * 0n) + (4n * 2n) = 0n + 8n = 8n

Этот пример демонстрирует, как BigInt можно использовать для работы с большими числами в сложных вычислениях, таких как умножение матриц, обеспечивая точность и производительность в JavaScript-приложениях, требующих численных вычислений большого масштаба.

Внимание

Используйте BigInt взвешенно, так как он может снижать производительность из-за более высоких требований к памяти и вычислительным ресурсам по сравнению со стандартными числами. Применяйте его только тогда, когда это действительно необходимо для работы с очень большими целыми числами.

Лучшие практики использования BigInt в JavaScript

При включении BigInt в свои JavaScript-проекты учитывайте следующие рекомендации для оптимизации производительности и поддерживаемости:

  1. Согласованность типов данных: избегайте смешивания BigInt с другими числовыми типами. Приведение между BigInt и Number может привести к ошибкам или непредсказуемому поведению. Убедитесь, что все операнды в вычислениях имеют тип BigInt там, где это необходимо.
  2. Уместность применения: используйте BigInt только при работе с числами, выходящими за пределы безопасного диапазона для стандартных чисел JavaScript. Избыточное использование BigInt может привести к накладным расходам по производительности.
  3. Использование памяти: несмотря на то что BigInt может обрабатывать очень большие числа, учитывайте потребление памяти в ваших приложениях, особенно в средах с ограниченными ресурсами.
  4. Проверка совместимости: перед использованием BigInt проверьте совместимость с целевой средой JavaScript, так как старые браузеры или некоторые движки JavaScript могут не поддерживать его.
  5. Эффективные алгоритмы: при выполнении операций с BigInt, особенно в циклах или рекурсивных функциях, оптимизируйте алгоритмы для минимизации влияния на производительность.

Понимание полифилов для BigInt в JavaScript

Тип BigInt в JavaScript необходим для работы с очень большими целыми числами, однако он поддерживается не во всех средах. Для обеспечения совместимости с различными браузерами и движками JavaScript, особенно старыми, использование полифила для BigInt может быть практичным решением.

Что такое полифил?

Полифил — это метод реализации функций в браузерах, которые не поддерживают их нативно. Он включает подключение скрипта, добавляющего недостающую функциональность в среду JavaScript браузера, что позволяет разработчикам использовать современные возможности, не дожидаясь перехода всех пользователей на поддерживающие их браузеры.

Полифил для BigInt

Поскольку BigInt является относительно новым дополнением к JavaScript, не все среды его поддерживают. Полифил позволяет использовать BigInt в таких неподдерживаемых средах, имитируя его функциональность. Это может быть критически важно для приложений, требующих высокоточных вычислений в средах, где обновление до последней версии браузера невозможно.

Реализация полифила BigInt

Реализация полифила BigInt предполагает создание или подключение библиотеки, имитирующей поведение BigInt. Вот простая концептуальная демонстрация того, как может быть организована оболочка полифила:

// Conceptual demonstration only. A true BigInt polyfill is complex and impractical.
// This example uses Number conversion internally for simplicity and is not suitable 
// for production large-integer handling.
if (typeof BigInt === "undefined") {
    window.BigInt = function(value) {
        return {
            value: value,
            toString: function() { return value + "n"; },
            add: function(other) { return BigInt(Number(this.value) + Number(other.value)); },
            subtract: function(other) { return BigInt(Number(this.value) - Number(other.value)); }
        };
    };
}

Ограничения полифилов для BigInt

Хотя полифилы могут обеспечивать обратную совместимость, они не являются полноценной заменой нативных реализаций:

  • Производительность: полифилы не могут сравниться по производительности с нативными операциями BigInt, так как реализованы на JavaScript, а не на низкоуровневом коде, оптимизированном производителями браузеров.
  • Сложность: точное воспроизведение всех аспектов такой сложной функции, как BigInt, представляет значительную сложность и может привести к ошибкам или несоответствиям.
  • Поддержка: поддержание полифила в актуальном состоянии с учётом изменений в официальной спецификации BigInt требует постоянного обслуживания.
Информация

Рассмотрите возможность использования полифила BigInt для обеспечения совместимости со старыми браузерами, не поддерживающими BigInt нативно. Однако помните, что полифилы могут не обеспечивать ту же производительность, что и нативные реализации, и должны рассматриваться как временное решение до тех пор, пока нативная поддержка не станет более повсеместной.

Заключение

BigInt позволяет JavaScript представлять целые числа любого размера с полной точностью, заполняя пробел, оставленный 53-битным безопасным пределом типа Number. Используйте его всякий раз, когда целое число может превысить Number.MAX_SAFE_INTEGER — большие идентификаторы из баз данных, суммы в наименьших денежных единицах, криптографические значения и математика с большими числами — но оставляйте Number для повседневных вычислений, где важны дроби и методы Math. Помните главное правило: никогда не смешивайте BigInt и Number в арифметике без явного преобразования.

Связанные темы

  • JavaScript Numbers — стандартный числовой тип и его предел безопасных целых чисел.
  • JavaScript Math — математические вспомогательные функции (которые работают с Number, но не с BigInt).
  • JavaScript Data Types — место bigint среди примитивов.
  • Comparison Operators — поведение == и ===, описанное выше.

Практика

Практика
Каков правильный способ создания BigInt в JavaScript?
Каков правильный способ создания BigInt в JavaScript?
Was this page helpful?