In short
JavaScript number methods help you round, check and format numbers. Learn toFixed, toPrecision, Number.isInteger, BigInt, and how to format currency with Intl.NumberFormat.
JavaScript number methods help you round, check and format numbers. Learn toFixed, toPrecision, Number.isInteger, BigInt, and how to format currency with Intl.NumberFormat.
Number methods for turning numbers into strings
Every number in JavaScript comes with built-in methods: small functions you call with a dot, like price.toFixed(2). You met toFixed briefly in the Numbers and Math lesson. Here are the main methods that turn a number into a string:
| Method | What it does | Example | Result |
|---|---|---|---|
toString() | Number to string | (42).toString() | "42" |
toString(base) | Number in another base | (255).toString(16) | "ff" |
toFixed(digits) | Fixed number of decimals | (3.14159).toFixed(2) | "3.14" |
toPrecision(digits) | Fixed number of significant digits | (123.456).toPrecision(4) | "123.5" |
toLocaleString() | Formatted for a language and region | (1234.5).toLocaleString("en-US") | "1,234.5" |
All of them return a string, not a number. That is perfect for showing values on a page, but you should do your maths before you format.
const price = 19.999;
console.log(price.toFixed(2)); // Output: 20.00
console.log(price.toFixed(0)); // Output: 20
console.log((5).toFixed(2)); // Output: 5.00
console.log((123.456).toPrecision(2)); // Output: 1.2e+2
console.log((0.000123).toPrecision(2)); // Output: 0.00012
console.log((5).toString(2)); // Output: 101 (binary)
console.log((255).toString(16)); // Output: ff (hexadecimal, used in CSS colours)
console.log(typeof price.toFixed(2)); // Output: string
toFixed counts digits after the decimal point. toPrecision counts significant digits (all the meaningful digits from the first non-zero one), and may switch to scientific notation like 1.2e+2, which means 1.2 × 10². The brackets around (5) are needed because 5.toFixed() would confuse JavaScript: it would think the dot is a decimal point.
Common mistake: Adding formatted values.
price.toFixed(2) + 1gives"20.001", becausetoFixedreturned a string and+joins text. Calculate with numbers first, format at the very end.
Checking numbers: Number.isInteger, Number.isNaN and Number.isFinite
The Number object also has static methods, which you call on Number itself rather than on a value. They answer yes/no questions about a value:
| Method | Returns true when | Example |
|---|---|---|
Number.isInteger(x) | x is a whole number | Number.isInteger(4.0) is true |
Number.isNaN(x) | x is exactly NaN | Number.isNaN(NaN) is true |
Number.isFinite(x) | x is a real number, not Infinity or NaN | Number.isFinite(10 / 0) is false |
Number.isSafeInteger(x) | x is a whole number in the safe range | Number.isSafeInteger(2 ** 53) is false |
Older global versions, isNaN() and isFinite(), also exist, but they convert the value to a number first, which causes surprises. The Number. versions never convert:
console.log(isNaN("hello")); // Output: true (converted "hello" to NaN first)
console.log(Number.isNaN("hello")); // Output: false (it's a string, not NaN)
console.log(isFinite("42")); // Output: true
console.log(Number.isFinite("42")); // Output: false (a string is not a number)
// Checking a quantity typed into a form
const input = "3";
const quantity = Number(input);
if (Number.isInteger(quantity) && quantity > 0) {
console.log(`Adding ${quantity} items`);
} else {
console.log("Please enter a whole number above 0");
}
// Output: Adding 3 items
With "2.5" or "abc" in input, you would see the error message instead.
Number.MAX_SAFE_INTEGER and BigInt for very large numbers
Normal JavaScript numbers can store whole numbers exactly only up to Number.MAX_SAFE_INTEGER, which is 9007199254740991 (about 9 quadrillion). Above that, numbers lose precision and maths goes quietly wrong:
console.log(Number.MAX_SAFE_INTEGER); // Output: 9007199254740991
console.log(9007199254740992 === 9007199254740993); // Output: true (!)
console.log(Number.MAX_SAFE_INTEGER + 2); // Output: 9007199254740992
For bigger whole numbers, use BigInt, a separate number type for whole numbers of any size. Create one by adding n to the end of a number, or with BigInt():
const big = 9007199254740993n;
console.log(big + 2n); // Output: 9007199254740995n
console.log(typeof big); // Output: bigint
const fromText = BigInt("123456789012345678901234567890");
console.log(fromText * 2n); // Output: 246913578024691357802469135780n
console.log(7n / 2n); // Output: 3n (decimals are cut off)
console.log(10n === 10); // Output: false (different types)
console.log(10n == 10); // Output: true
// console.log(10n + 5); // TypeError: Cannot mix BigInt and other types
console.log(10n + BigInt(5)); // Output: 15n
console.log(Number(10n) + 5); // Output: 15
The rules for BigInt are simple but strict:
- BigInts hold only whole numbers. Division drops the decimal part.
- You cannot mix BigInt and normal numbers in maths; convert one side with
BigInt()orNumber(). Mathmethods likeMath.rounddo not accept BigInts.JSON.stringifythrows an error on BigInts, so convert them to strings before sending them to a server.
You will need BigInt for things like very large IDs from databases, or precise maths on huge whole numbers. For prices and everyday counting, normal numbers are the right choice.
Formatting currency, percent and compact numbers with Intl.NumberFormat
People in different countries write numbers differently. In the US one thousand and a half is 1,000.5; in Germany it is 1.000,5. Intl.NumberFormat is the browser's built-in formatter that knows these rules. You give it a locale (a language and region code like "en-US") and options, and it creates a reusable formatter.
const usd = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" });
const eur = new Intl.NumberFormat("de-DE", { style: "currency", currency: "EUR" });
const inr = new Intl.NumberFormat("en-IN", { style: "currency", currency: "INR" });
console.log(usd.format(1234.5)); // Output: $1,234.50
console.log(eur.format(1234.5)); // Output: 1.234,50 €
console.log(inr.format(123456)); // Output: ₹1,23,456.00
The formatter adds the currency symbol, the right separators and the right number of decimals for that currency. The currency option uses three-letter codes like "USD", "EUR" or "GBP".
The style option has other useful values too:
const percent = new Intl.NumberFormat("en-US", { style: "percent", maximumFractionDigits: 1 });
console.log(percent.format(0.256)); // Output: 25.6%
const compact = new Intl.NumberFormat("en-US", { notation: "compact" });
console.log(compact.format(15300)); // Output: 15K
console.log(compact.format(2500000)); // Output: 2.5M
const longCompact = new Intl.NumberFormat("en-US", { notation: "compact", compactDisplay: "long" });
console.log(longCompact.format(1234567)); // Output: 1.2 million
const speed = new Intl.NumberFormat("en-US", { style: "unit", unit: "kilometer-per-hour" });
console.log(speed.format(50)); // Output: 50 km/h
Notice that "percent" expects a fraction: 0.256 becomes 25.6%. Compact notation is great for follower counts and view numbers on social media style pages.
| Option | Example values | What it controls |
|---|---|---|
style | "decimal", "currency", "percent", "unit" | The kind of number |
currency | "USD", "EUR", "JPY" | Which currency (needed for "currency") |
minimumFractionDigits / maximumFractionDigits | 0 to 20 | How many decimals |
notation | "standard", "compact", "scientific" | Short forms like 15K |
unit | "kilogram", "liter", "percent" | The unit (needed for "unit") |
Quick formatting with toLocaleString
If you only need to format one number, toLocaleString() takes the same locale and options directly, without creating a formatter first:
const visitors = 1234567.891;
console.log(visitors.toLocaleString("en-US")); // Output: 1,234,567.891
console.log(visitors.toLocaleString("de-DE")); // Output: 1.234.567,891
console.log(visitors.toLocaleString("en-US", { maximumFractionDigits: 0 })); // Output: 1,234,568
const price = 49.9;
console.log(price.toLocaleString("en-GB", { style: "currency", currency: "GBP" })); // Output: £49.90
console.log(visitors.toLocaleString()); // Output: depends on the visitor's own settings
If you leave out the locale, the browser uses the visitor's own language settings, which is often exactly what you want.
Tip: When you format many numbers the same way, such as every price in a product list, create one
Intl.NumberFormatand reuse itsformatmethod. It is faster than callingtoLocaleStringwith options each time.
Practice exercise
Make a small sales summary. Start with const sales = [1299.5, 349.99, 89, 2450];. Use reduce (or a loop) to get the total, then log it as US dollars and as euros in German format. Also log the average with toFixed(2), and log the total in compact form, like 4.2K.
Hint: create two currency formatters and one with notation: "compact". Do all the adding and dividing with plain numbers before you call format.
Key takeaways
toFixed,toPrecision,toStringandtoLocaleStringall return strings, so format at the end.- Use
Number.isInteger,Number.isNaNandNumber.isFinite; they never convert the value first. - Whole numbers are exact only up to
Number.MAX_SAFE_INTEGER; use BigInt (123n) beyond that, and never mix it with normal numbers. Intl.NumberFormatformats currency, percentages, units and compact numbers for any locale.