Skip to main content

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.

javascript
const big = 123456789012345678901234567890n; const big2 = BigInt("123456789012345678901234567890");

Theory

TL;DR

  • Every ordinary number in JavaScript has type Number and 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.
  • BigInt removes that limit: the length of an integer is bounded only by memory.
  • It is created with an n suffixed literal (10n) or with the function BigInt(10), BigInt("9007199254740995").
  • It does not support fractions: BigInt(1.5) throws a TypeError, and 5n / 2n discards the fractional part.
  • It cannot be mixed with Number in arithmetic, does not work with Math, and is not serialisable by JSON.stringify().

Quick example

javascript
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); // 9007199254740996n

The 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:

javascript
Number.MAX_SAFE_INTEGER === 9007199254740991; // 2^53 - 1

Once a number is larger, precision starts to disappear:

javascript
const num = 9007199254740991; console.log(num + 1); // 9007199254740992, correct console.log(num + 2); // 9007199254740992, wrong

The numbers have collapsed together: the engine can no longer tell +1 from +2, because neighbouring integers in this range have no separate representation.

BigInt solves exactly this problem:

javascript
const big = 9007199254740991n; console.log(big + 1n); // 9007199254740992n console.log(big + 2n); // 9007199254740993n, exact

How to create a BigInt

There are three ways, and none of them accepts a fraction:

javascript
const a = 10n; // literal const b = BigInt(10); // via the function const c = BigInt("9007199254740995"); // from a string
javascript
BigInt(1.5); // TypeError: Cannot convert 1.5 to a BigInt

Arithmetic with BigInt

The basic operators are supported, but all of them are integer operations:

javascript
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); // 25n

Division always returns an integer, the remainder is simply discarded (5n / 2n is 2n, not 2.5).

Number and BigInt cannot be mixed inside one arithmetic expression:

javascript
const big = 10n; const num = 5; console.log(big + num); // TypeError: Cannot mix BigInt and other types

An explicit conversion is required:

javascript
console.log(big + BigInt(num)); // 15n // or console.log(Number(big) + num); // 15

Comparison, unlike arithmetic, does work: loose comparison converts the type automatically.

javascript
10n == 10; // true, loose comparison 10n === 10; // false, strict comparison, the types differ 10n < 20; // true

The Math functions are incompatible with BigInt:

javascript
Math.sqrt(4n); // TypeError: Cannot convert a BigInt value to a number

If you need them, convert first: Math.sqrt(Number(4n)), remembering that on very large numbers this conversion loses precision again.

Number vs BigInt

FeatureNumberBigInt
Typefloating point numberinteger of arbitrary length
Maximum precisionup to 2^53 - 1unlimited
Fraction supportyesno
Operationsstandardstandard, but integer only
Compatibilityeverywheresince 2020
Use with JSONyesno, JSON.stringify() throws
Type coercioncompatible with everythingmust be converted explicitly
When to pick itordinary numbers and fractionsvery 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:

javascript
const userId = 183748917238479182374981273n;

Cryptography, blockchain and finance, where rounding is unacceptable:

javascript
const balance = 999999999999999999999999999n; const transfer = 250000000000000000000n; console.log(balance - transfer); // computed exactly

The 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 + 5 is a TypeError, not 15n. Convert explicitly: 10n + BigInt(5) or Number(10n) + 5.
  • Expecting fractional division. 7n / 2n gives 3n, the remainder is dropped silently, with no error at all.
  • Trying to build a BigInt from a fraction. BigInt(1.5) throws a TypeError; round first: BigInt(Math.trunc(1.5)).
  • JSON.stringify() over a structure containing a BigInt. It throws TypeError: Do not know how to serialize a BigInt, so such values are sent as strings: String(id).
  • Confusing == and ===. 10n == 10 is true, but 10n === 10 is false, because the types differ.
  • Calling Math with a BigInt. Math.max(1n, 2n) and Math.sqrt(4n) both throw a TypeError.
  • Using BigInt where it is not needed. It is slower than Number and has no fractions, so keep Number for ordinary calculations.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.