JavaScript by Example

Numbers

Every non-BigInt number in JavaScript is a 64-bit float - understanding the precision limits prevents hard-to-debug arithmetic bugs.

Every JavaScript number is a 64-bit IEEE 754 floating-point value. There is no separate integer type - which means integers above 2⁵³ lose precision, and decimal arithmetic has well-known rounding quirks.

The classic float trap: 0.1 + 0.2 does not equal 0.3. Compare floating-point numbers using a tolerance instead of strict equality.

console.log(0.1 + 0.2 === 0.3); // false
console.log(0.1 + 0.2); // 0.30000000000000004
 
// Safe float comparison
const a = 0.1 + 0.2;
const b = 0.3;
console.log(Math.abs(a - b) < Number.EPSILON); // true

Number.MAX_SAFE_INTEGER is the largest integer that can be represented exactly. Beyond it, incrementing no longer works reliably.

console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
 
const n = Number.MAX_SAFE_INTEGER;
console.log(n + 1 === n + 2); // true - precision lost

BigInt handles arbitrarily large integers exactly. Use the n suffix for literals. BigInt and Number cannot be mixed in arithmetic - you must convert explicitly.

const big = 9007199254740991n + 1n;
console.log(big); // 9007199254740992n
 
console.log(10n * 2n); // 20n
// console.log(10n + 1); // TypeError: Cannot mix BigInt and other types

In production

Never store monetary values as Number. Representing $19.99 as 19.99 and doing arithmetic on it will produce rounding errors that compound across transactions. Store money as integer cents (1999) or use a decimal library like decimal.js. Payment systems that let floats drift ship silent bugs that accounting finds months later.

Enjoyed this? Get more essays on software craft delivered to your inbox.

Subscribe free