BigInt

BigInt — примитивный тип для работы с целыми числами произвольной длины, без ограничения Number.MAX_SAFE_INTEGER.

Зачем нужно

Number точно представляет целые числа только до 2^53 - 1 (9 007 199 254 740 991). Для ID из баз данных, криптографии, финансовых расчётов с большими суммами нужен BigInt.

Где используется

  • ID из баз данных (Snowflake ID в Twitter/Discord)
  • Криптографические вычисления
  • Точные финансовые расчёты с большими числами
  • Работа с timestamp в наносекундах

Предпосылки

Number, Типы данных

Создание BigInt

// Литерал — суффикс n
const big = 9007199254740991n;
const huge = 123456789012345678901234567890n;

// Функция BigInt
const fromNumber = BigInt(42);        // 42n
const fromString = BigInt('9007199254740991'); // 9007199254740991n

// BigInt НЕ конструктор
// const x = new BigInt(42); // TypeError!

// Проблема Number
console.log(9007199254740991 + 1); // 9007199254740992
console.log(9007199254740991 + 2); // 9007199254740992 — потеря!

// BigInt точен
console.log(9007199254740991n + 1n); // 9007199254740992n
console.log(9007199254740991n + 2n); // 9007199254740993n — точно!

Операции

const a = 100n;
const b = 30n;

// Арифметика
a + b;   // 130n
a - b;   // 70n
a * b;   // 3000n
a / b;   // 3n (целочисленное деление, дробная часть отбрасывается!)
a % b;   // 10n
a ** 3n; // 1000000n

// Сравнение
10n === 10n; // true
10n === 10;  // false (разные типы!)
10n == 10;   // true (нестрогое сравнение)
10n > 5;     // true (сравнение с Number работает)
10n < 20;    // true

// Унарные
-10n;   // -10n
// +10n; // TypeError! Унарный + не поддерживается

// Логические
!0n;    // true (0n — falsy)
!1n;    // false (1n — truthy)

Ограничения

// Нельзя смешивать с Number в арифметике
// 10n + 5; // TypeError: Cannot mix BigInt and other types

// Решение: явное преобразование
10n + BigInt(5);  // 15n
Number(10n) + 5;  // 15 (может потерять точность!)

// Нельзя использовать с Math
// Math.sqrt(4n); // TypeError

// Нельзя использовать дробные числа
// BigInt(1.5); // RangeError

// JSON.stringify не поддерживает BigInt
// JSON.stringify({ id: 42n }); // TypeError

// Решение для JSON
const data = { id: 42n };
JSON.stringify(data, (key, value) =>
  typeof value === 'bigint' ? value.toString() : value
); // '{"id":"42"}'

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

ID из базы данных

// Snowflake ID (Discord, Twitter) не влезает в Number
const discordId = '1234567890123456789';
console.log(Number(discordId));  // 1234567890123456800 — потеря!
console.log(BigInt(discordId));  // 1234567890123456789n — точно

// Работа с API
async function getUser(id) {
  // Передаём как строку в URL
  const response = await fetch(`/api/users/${id.toString()}`);
  const data = await response.json();
  // Парсим обратно
  data.id = BigInt(data.id);
  return data;
}

Факториал больших чисел

function factorial(n) {
  let result = 1n;
  for (let i = 2n; i <= n; i++) {
    result *= i;
  }
  return result;
}

console.log(factorial(50n));
// 30414093201713378043612608166979581188299763898377856820553615673507270386838265
// Number не смог бы это представить

Частые ошибки

1. Смешивание типов

// const result = 10n + 5; // TypeError
const result = 10n + BigInt(5); // 15n

2. Деление отбрасывает дробь

console.log(7n / 2n); // 3n (не 3.5n!)

3. JSON сериализация

// Добавь toJSON в прототип или используй replacer
BigInt.prototype.toJSON() = function {
  return this.toString();
};

Практика

  1. Вычисли 2n ** 100n и убедись, что Number не справляется
  2. Напиши функцию факториала для BigInt
  3. Реализуй безопасный парсинг больших ID из JSON-строки

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

Ресурсы


🎓 Источник: 💻 Новое в JavaScript ES.Next, ES2020...ES6

  • 📅 2019-12-03 · YouTube
  • Тезисы: BigInt появился в ES2020. Литерал n суффикс. Нельзя смешивать с Number в одной операции — TypeError. JSON не умеет BigInt — нужен toString