Photo by Eric Er on Unsplash

On this page

This chapter follows Type coercion and equality.

The number type is a double-precision floating-point format. Integers within a fixed range are exact; many decimal fractions are stored as nearby approximations. BigInt, added in ES2020, represents integers of arbitrary precision with an n suffix or the BigInt() constructor.

Number literals and special values

Integers and decimals share one type. Underscores between digits are allowed for readability (1_000_000). Exponent notation works as in other languages (6.02e23).

typeof 42; // "number"
typeof 3.14; // "number"
Number.MAX_VALUE; // largest finite number
Number.MIN_VALUE; // smallest positive subnormal (not the most negative number)

NaN means the result of an invalid numeric operation. Infinity and -Infinity come from overflow or division by zero. typeof NaN is "number".

Safe integers

A number stores at most 53 bits of significand. Integers from -(2**53 - 1) through 2**53 - 1 are safe: they round-trip through the format without ambiguity.

Number.MAX_SAFE_INTEGER; // 9007199254740991
Number.isSafeInteger(9007199254740991); // true
Number.isSafeInteger(9007199254740991 + 1); // false — not every integer above the max is representable

Literals with more digits than the format can represent are rounded when parsed:

99999999999999999 === 100000000000000000; // true

Use bigint when you need exact integers beyond that range or when doing currency-style math in whole minor units.

Binary fractions and rounding

0.1 and 0.2 are repeating binary fractions. Their sum is the closest representable value to 0.3, not the literal 0.3.

0.1 + 0.2; // 0.30000000000000004
0.1 + 0.2 === 0.3; // false

For money, store cents as integers or use a decimal library. For display, format with Intl.NumberFormat rather than assuming raw doubles print cleanly.

BigInt literals and operations

Append n to an integer literal or call BigInt(string) when the value comes from text:

42n;
BigInt("9007199254740992");

BigInt supports +, -, *, /, %, and ** with other bigints. Mixing bigint and number in one expression is a TypeError unless you convert explicitly:

1n + 2; // TypeError
Number(1n) + 2; // 3
1n + BigInt(2); // 3n

Division truncates toward zero for bigint, unlike number division which can yield fractions.

Parsing and conversion pitfalls

Number("") is 0. Number(" 3") is 3. Number("3px") is NaN. parseInt("3px", 10) is 3.

BigInt(1.9) truncates toward zero (1n). BigInt(undefined) throws. Prefer string input for large integers so you never pass through an already-rounded number.

When to choose which type

Need Prefer
Fractions, math functions, JSON APIs number
IDs and counters within safe range number (often)
Cryptography-sized integers, exact large IDs bigint
Bitwise operations on 32-bit flags number (operators truncate to 32 bits)

JSON does not standardize bigint serialization. Convert to string at API boundaries if you must exchange big integers.

Next: Strings and template literals.

Search articles

Type a word to search published articles.

Open the search page