BigInt: работа с числами больше Number.MAX_SAFE_INTEGER
Когда обычных чисел недостаточно 🚨
Представь, что ты работаешь с финансовой системой, где суммы могут достигать астрономических значений. Или разрабатываешь криптографический алгоритм, требующий операций с гигантскими числами. В JavaScript стандартный тип Number имеет ограничение:
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
Выше этого порога начинаются неточности из-за особенностей хранения чисел в памяти. Попробуем:
console.log(9007199254740991 + 1); // 9007199254740992 (корректно)
console.log(9007199254740991 + 2); // 9007199254740992 (ошибка!)
BigInt в деле 🛠️
Для таких случаев в ES2020 появился тип BigInt. Создаётся он двумя способами:
1. Добавлением n в конец числа:
const bigNum = 9007199254740993n;
2. Через конструктор BigInt():
const sameBigNum = BigInt("9007199254740993");
🔥 Важно: BigInt нельзя смешивать с обычными числами в операциях. Сначала приводите типы!
const regularNum = 10;
console.log(bigNum + BigInt(regularNum)); // Корректно
console.log(bigNum + regularNum); // TypeError
Магия операций ✨
С BigInt доступны все стандартные арифметические операции:
const a = 123456789012345678901234567890n;
const b = 987654321098765432109876543210n;
// Умножение космических масштабов
console.log(a * b); // 121932631137021795223746380111126352690700321792900n
// Деление с остатком
console.log(b / a); // 8n (целочисленное деление)
Практические примеры из реального мира 🌍
Пример 1: Криптография
function generateLargePrime(bits) {
let candidate = BigInt(Math.pow(2, bits)) - 1n;
while (!isPrime(candidate)) {
candidate -= 2n;
}
return candidate;
}
// Упрощённая проверка на простоту (для демонстрации)
function isPrime(n) {
for (let i = 2n; i * i <= n; i += 1n) {
if (n % i === 0n) return false;
}
return n > 1n;
}
Пример 2: Финансовые расчёты
const nationalDebtUSD = 31400000000000n; // 31.4 триллиона
const populationUSA = 331000000n;
const debtPerPerson = nationalDebtUSD / populationUSA;
console.log(`Долг на каждого американца: $${debtPerPerson}`); // ~$94864
Ограничения и подводные камни ⚠️
1. Нет поддержки в JSON:
const data = { bigValue: 100n };
JSON.stringify(data); // TypeError
2. Нельзя использовать с Math:
Math.sqrt(16n); // TypeError
3. Строгое равенство:
console.log(0n === 0); // false (разные типы)
console.log(0n == 0); // true (неявное приведение)
Производительность ⚡
Операции с BigInt в среднем на 40-60% медленнее обычных числовых операций. Для критичных к скорости вычислений сценариев стоит проводить бенчмарки:
console.time("BigInt");
let bigSum = 0n;
for (let i = 0n; i < 1000000n; i++) {
bigSum += i;
}
console.timeEnd("BigInt"); // ~150ms
console.time("Number");
let numSum = 0;
for (let i = 0; i < 1000000; i++) {
numSum += i;
}
console.timeEnd("Number"); // ~5ms
Когда использовать BigInt? 🤔
Идеальные сценарии:
- Работа с банковскими транзакциями высокой точности
- Криптографические алгоритмы
- ID из внешних систем (например, Twitter snowflake)
- Научные вычисления с астрономическими числами
💡 Профессиональный совет: начинайте с обычных чисел и переходите на BigInt только при явной необходимости выйти за пределы
Number.MAX_SAFE_INTEGER.