Number Methods
Numbers in JavaScript
JavaScript uses a single number type for both integers and floating-point values, based on the IEEE 754 double-precision format. This causes some famous quirks — but also a rich set of methods to work around them.
typeof 42; // "number"
typeof 3.14; // "number"
typeof NaN; // "number" — NaN is technically of type number
typeof Infinity; // "number"
Parsing Strings to Numbers
Number()
Converts a whole string to a number. Fails fast — returns NaN if any part is non-numeric:
Number("42"); // 42
Number("3.14"); // 3.14
Number(""); // 0
Number(" 42 "); // 42 (trims whitespace)
Number("42px"); // NaN
Number(true); // 1
Number(false); // 0
Number(null); // 0
Number(undefined); // NaN
parseInt(string, radix)
Parses from the start, stops at the first non-numeric character. Always pass the radix:
parseInt("42px", 10); // 42 — stops at 'p'
parseInt("3.9", 10); // 3 — truncates decimal
parseInt("0xff", 16); // 255 — hex
parseInt("101", 2); // 5 — binary
parseInt("hello", 10); // NaN — starts with non-numeric
Without the second argument, parseInt("08") was historically interpreted as octal in some engines, returning 0. Always write parseInt(str, 10) for decimal parsing.
parseFloat()
Parses decimal numbers from a string:
parseFloat("3.14abc"); // 3.14
parseFloat("3.14"); // 3.14
parseFloat("42"); // 42
parseFloat("abc"); // NaN
Checking Numbers
Number.isNaN() vs global isNaN()
Number.isNaN(NaN); // true
Number.isNaN("hello"); // false — does NOT coerce
Number.isNaN(undefined); // false
isNaN("hello"); // true — coerces to NaN first (misleading!)
isNaN(undefined); // true — coerces to NaN (misleading!)
Always use Number.isNaN() — the global isNaN() has unintuitive coercion behavior.
Number.isFinite() vs global isFinite()
Number.isFinite(42); // true
Number.isFinite(Infinity); // false
Number.isFinite(-Infinity); // false
Number.isFinite(NaN); // false
Number.isFinite("42"); // false — no coercion
isFinite("42"); // true — coerces "42" to 42 first
Again, prefer Number.isFinite().
Number.isInteger()
Number.isInteger(42); // true
Number.isInteger(42.0); // true — .0 is an integer
Number.isInteger(42.5); // false
Number.isInteger("42"); // false — no coercion
Number.isSafeInteger()
JavaScript can only safely represent integers up to 2^53 - 1:
Number.MAX_SAFE_INTEGER; // 9007199254740991
Number.MIN_SAFE_INTEGER; // -9007199254740991
Number.isSafeInteger(9007199254740991); // true
Number.isSafeInteger(9007199254740992); // false — precision lost
For larger integers, use BigInt:
const big = 9007199254740993n; // BigInt literal (n suffix)
Formatting Numbers
toFixed(decimals)
Returns a string with a fixed number of decimal places:
(3.14159).toFixed(2); // "3.14"
(3.1).toFixed(4); // "3.1000"
(3.7).toFixed(0); // "4" — rounds
// Common use: currency display
const price = 9.999;
`$${price.toFixed(2)}`; // "$10.00"
toFixed returns a string(1.5).toFixed(2) returns "1.50", not 1.50. Wrap with Number() if you need arithmetic on it.
toPrecision(digits)
Specifies total significant digits:
(123.456).toPrecision(5); // "123.46"
(0.000123).toPrecision(2); // "0.00012"
toString(radix)
Convert a number to a different base:
(255).toString(16); // "ff" — hex
(255).toString(2); // "11111111" — binary
(255).toString(8); // "377" — octal
(42).toString(); // "42" — decimal (default)
Intl.NumberFormat — Locale-Aware Formatting
For displaying numbers to users, use the Intl.NumberFormat API:
// Currency
new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" })
.format(1234567.89);
// "$1,234,567.89"
new Intl.NumberFormat("de-DE", { style: "currency", currency: "EUR" })
.format(1234567.89);
// "1.234.567,89 €"
// Compact notation
new Intl.NumberFormat("en", { notation: "compact" }).format(1_500_000);
// "1.5M"
// Percentage
new Intl.NumberFormat("en", { style: "percent" }).format(0.75);
// "75%"
Math Object
Common static methods on the global Math object:
Math.round(4.5); // 5 — rounds to nearest
Math.floor(4.9); // 4 — always rounds down
Math.ceil(4.1); // 5 — always rounds up
Math.trunc(4.9); // 4 — removes decimal (no rounding)
Math.trunc(-4.9); // -4 — note: different from floor for negatives
Math.abs(-5); // 5
Math.min(1, 2, 3); // 1
Math.max(1, 2, 3); // 3
Math.pow(2, 8); // 256
Math.sqrt(16); // 4
Math.cbrt(27); // 3 (cube root)
Math.log2(8); // 3
Math.log10(1000); // 3
Math.PI; // 3.141592653589793
Math.E; // 2.718281828459045
Random Numbers
Math.random(); // float between 0 (inclusive) and 1 (exclusive)
// Random integer between min and max (inclusive)
const randomInt = (min, max) =>
Math.floor(Math.random() * (max - min + 1)) + min;
randomInt(1, 6); // simulates a dice roll: 1-6
randomInt(0, 99); // 0-99
The Floating-Point Problem
0.1 + 0.2; // 0.30000000000000004 ← not 0.3!
This is not a JavaScript bug — it's how IEEE 754 floating-point arithmetic works in every language. Solutions:
// For display — round to sensible precision
(0.1 + 0.2).toFixed(2); // "0.30"
// For comparisons — use toBeCloseTo in tests, or epsilon check
Math.abs((0.1 + 0.2) - 0.3) < Number.EPSILON; // true
// For currency — work in cents (integers), never floats
const priceInCents = 199; // $1.99
const taxInCents = Math.round(priceInCents * 0.1); // 20 cents
const totalInCents = priceInCents + taxInCents; // 219 cents
const display = `$${(totalInCents / 100).toFixed(2)}`; // "$2.19"
Quick Reference
| Method | Purpose | Returns |
|---|---|---|
Number(val) | Convert to number | number |
parseInt(str, 10) | Parse integer from string | number |
parseFloat(str) | Parse float from string | number |
Number.isNaN(val) | Check if NaN (no coercion) | boolean |
Number.isFinite(val) | Check if finite (no coercion) | boolean |
Number.isInteger(val) | Check if integer | boolean |
num.toFixed(n) | Fixed decimal places | string |
num.toString(base) | Convert to base (hex, binary) | string |
Math.round/floor/ceil | Rounding | number |
Math.random() | Random 0–1 | number |