Money, IDs and user input all hit the edges of floating point sooner or later.
Every number is a 64-bit IEEE-754 double. There is no separate integer type, so 1 and 1.0 are the same value. Integers are exact up to Number.MAX_SAFE_INTEGER (2^53 − 1); beyond that, adjacent integers can't all be represented.
Decimal fractions are approximations: 0.1 + 0.2 is 0.30000000000000004. For money, compute in integer cents (or use a decimal library) and only format at the end.
Special values: Infinity, -Infinity and NaN ("not a number"), which results from invalid math like 0 / 0 or Number("abc").
Converting text to numbers:
Number("42")converts the whole string and returnsNaNif anything is left over.parseInt("42px", 10)andparseFloatread a leading number and ignore the rest. Always pass the radix toparseInt.
Useful helpers: Number.isInteger, Number.isFinite, Math.round/floor/ceil/trunc, Math.max/min, Math.random() (0 inclusive to 1 exclusive). n.toFixed(2) rounds for display and returns a string.
For display to humans use Intl.NumberFormat, which handles separators, currencies and locales: new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(1234.5) gives "$1,234.50".
When you need exact integers larger than 2^53 — database IDs, cryptography — use BigInt: write 123n or BigInt("123"). BigInts can't be mixed with numbers in arithmetic (1n + 1 throws), so convert explicitly. Numeric separators (1_000_000) work for both.
Example
console.log(0.1 + 0.2); // 0.30000000000000004
console.log((0.1 + 0.2).toFixed(2)); // "0.30" (a string)
console.log(Number("12px")); // NaN
console.log(parseInt("12px", 10)); // 12
console.log(Number.isNaN(0 / 0)); // true
const priceCents = 1999 * 3; // compute money in integers
const fmt = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" });
console.log(fmt.format(priceCents / 100)); // "$59.97"
console.log(Number.MAX_SAFE_INTEGER + 2); // 9007199254740992 (wrong!)
console.log(9007199254740991n + 2n); // 9007199254740993n
const big = 1_000_000n * BigInt(3); // convert before mixing
console.log(big); // 3000000nRemember
- All numbers are doubles: fractions are approximate, integers are safe up to 2^53 − 1
Number()is strict,parseInt(str, 10)reads a numeric prefix- Format for people with
Intl.NumberFormat; use BigInt for huge exact integers
Watch out for
- Treating the result of
toFixedas a number — it is a string.