BigInt vs Number
BigInt is a special JavaScript numeric type that lets you work with integers of arbitrary length, without the 2^53 - 1 limit. A value is created by adding n at the end of a number or by calling the BigInt() function.
const big = 123456789012345678901234567890n;
const big2 = BigInt("123456789012345678901234567890");Theory
TL;DR
- Every ordinary number in JavaScript has type
Numberand is stored in IEEE 754 format (64-bit floating point). - Integers are represented exactly only up to
Number.MAX_SAFE_INTEGER === 9007199254740991(2^53 - 1); beyond that precision is lost. BigIntremoves that limit: the length of an integer is bounded only by memory.- It is created with an
nsuffixed literal (10n) or with the functionBigInt(10),BigInt("9007199254740995"). - It does not support fractions:
BigInt(1.5)throws aTypeError, and5n / 2ndiscards the fractional part. - It cannot be mixed with
Numberin arithmetic, does not work withMath, and is not serialisable byJSON.stringify().
Quick example
const a = 10n; // literal
const b = BigInt(10); // via the function
const c = BigInt("9007199254740995"); // from a string
console.log(a + b); // 20n
console.log(c + 1n); // 9007199254740996nThe problem with ordinary numbers
In JavaScript every ordinary number has type Number and is stored in IEEE 754 format (64-bit floating point). That means the language can represent integers exactly only up to:
Number.MAX_SAFE_INTEGER === 9007199254740991; // 2^53 - 1Once a number is larger, precision starts to disappear:
const num = 9007199254740991;
console.log(num + 1); // 9007199254740992, correct
console.log(num + 2); // 9007199254740992, wrongThe numbers have collapsed together: the engine can no longer tell
+1from+2, because neighbouring integers in this range have no separate representation.
BigInt solves exactly this problem:
const big = 9007199254740991n;
console.log(big + 1n); // 9007199254740992n
console.log(big + 2n); // 9007199254740993n, exactHow to create a BigInt
There are three ways, and none of them accepts a fraction:
const a = 10n; // literal
const b = BigInt(10); // via the function
const c = BigInt("9007199254740995"); // from a stringBigInt(1.5); // TypeError: Cannot convert 1.5 to a BigIntArithmetic with BigInt
The basic operators are supported, but all of them are integer operations:
const x = 5n;
const y = 2n;
console.log(x + y); // 7n
console.log(x - y); // 3n
console.log(x * y); // 10n
console.log(x / y); // 2n, the fractional part is dropped
console.log(x ** y); // 25nDivision always returns an integer, the remainder is simply discarded (
5n / 2nis2n, not2.5).
Number and BigInt cannot be mixed inside one arithmetic expression:
const big = 10n;
const num = 5;
console.log(big + num); // TypeError: Cannot mix BigInt and other typesAn explicit conversion is required:
console.log(big + BigInt(num)); // 15n
// or
console.log(Number(big) + num); // 15Comparison, unlike arithmetic, does work: loose comparison converts the type automatically.
10n == 10; // true, loose comparison
10n === 10; // false, strict comparison, the types differ
10n < 20; // trueThe Math functions are incompatible with BigInt:
Math.sqrt(4n); // TypeError: Cannot convert a BigInt value to a numberIf you need them, convert first: Math.sqrt(Number(4n)), remembering that on very large numbers this conversion loses precision again.
Number vs BigInt
| Feature | Number | BigInt |
|---|---|---|
| Type | floating point number | integer of arbitrary length |
| Maximum precision | up to 2^53 - 1 | unlimited |
| Fraction support | yes | no |
| Operations | standard | standard, but integer only |
| Compatibility | everywhere | since 2020 |
Use with JSON | yes | no, JSON.stringify() throws |
| Type coercion | compatible with everything | must be converted explicitly |
| When to pick it | ordinary numbers and fractions | very large integers |
Where BigInt is used
Storing large identifiers, for example from a database, where a 64-bit id does not fit into the safe Number range:
const userId = 183748917238479182374981273n;Cryptography, blockchain and finance, where rounding is unacceptable:
const balance = 999999999999999999999999999n;
const transfer = 250000000000000000000n;
console.log(balance - transfer); // computed exactlyThe same goes for counters with very large values, nanosecond timestamps, and any integer work where being off by one is not acceptable.
Common mistakes
- Mixing types in arithmetic.
10n + 5is aTypeError, not15n. Convert explicitly:10n + BigInt(5)orNumber(10n) + 5. - Expecting fractional division.
7n / 2ngives3n, the remainder is dropped silently, with no error at all. - Trying to build a
BigIntfrom a fraction.BigInt(1.5)throws aTypeError; round first:BigInt(Math.trunc(1.5)). JSON.stringify()over a structure containing aBigInt. It throwsTypeError: Do not know how to serialize a BigInt, so such values are sent as strings:String(id).- Confusing
==and===.10n == 10istrue, but10n === 10isfalse, because the types differ. - Calling
Mathwith aBigInt.Math.max(1n, 2n)andMath.sqrt(4n)both throw aTypeError. - Using
BigIntwhere it is not needed. It is slower thanNumberand has no fractions, so keepNumberfor ordinary calculations.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.