JavaScript basicsNumbers in plain wordsOne tool at a time
Number
Toolbox
JavaScript has one main number type for whole numbers and decimals alike. This guide shows how to check numbers, turn text into numbers, round them, do maths, avoid decimal surprises and show them nicely as money, with a small example for each that you can run.
Key terms in plain words
Never written code before? Start here. Every word below shows up later on this page, and each one comes with an everyday comparison. Underlined words in the modules link back to these cards.
25 terms in 5 groups. Hover an underlined word anywhere on the page for a quick reminder, or click it to jump here.
What a number is
Think of JavaScript as a shop counter with a till. Numbers are the amounts that go through it, and a few odd slips can come out of it too.
- Number
- Think of it as any amount the till can ring up
- JavaScript has one kind of number for everything, whether it has a decimal point or not. Prices, counts and percentages all use it.
- For example
450and7.5are both numbers. - Type
- Think of it as the label on a drawer of the till: coins, notes or receipts
- The kind of value something is, such as a number or a piece of text.
typeoftells you the type, and it matters because the same symbol can behave differently on different types. - For example
typeof 7.5gives"number". - Whole number (integer)
- Think of it as an amount in full rupees with no paise
- A number with nothing after the decimal point, such as 5, 0 or -12. Programmers call it an integer.
Number.isIntegerchecks for one. - Decimal
- Think of it as an amount with paise after the point
- A number with a part after the decimal point, such as 4.5 or 0.25. Decimals are where rounding and tiny storage errors come in.
- NaN
- Think of it as a till receipt that just reads "error"
- Short for "not a number". It is what you get from maths that makes no sense, such as multiplying a word. Oddly, NaN is never equal to anything, even itself, so check for it with
Number.isNaN. - For example
"abc" * 2givesNaN. - Infinity
- Think of it as a total too big for any till to show
- A special value bigger than every other number. You get it by dividing by zero or going past the largest number JavaScript can hold. There is a minus version too.
- For example
10 / 0givesInfinity.
Turning text into numbers
What a customer types into a form arrives as text, even when it looks like an amount. You have to turn it into a number first.
- String
- Think of it as a price written on a sticky note, which the till can't add up yet
- Programmers call text a string. A form field always gives you a string, even "42", and adding strings joins them instead of summing them, so
"7" + 1gives"71". - Converting
- Think of it as the cashier reading the note and keying the amount into the till
- Turning a value of one type into another, here text into a number.
Number(text)converts the whole thing and gives NaN if any of it is junk. - For example
Number("42")gives42. - parseInt and parseFloat
- Think of it as a cashier who reads the digits on the note and ignores the scribble after them
- They read a number from the start of some text and stop at the first character that isn't part of it, so "42px" gives 42. parseInt reads whole numbers and parseFloat reads decimals. Always give parseInt a 10, so it counts in ordinary tens.
- For example
parseInt("42px", 10)gives42. - True or false
- Think of it as the green or red light on a card machine
- The answer from a check is one of two values: true or false. Programmers call this a boolean. Every
is...check on this page gives one.
Rounding and everyday maths
The sums a shop does all day: rounding totals, splitting change and picking a lucky number.
- Rounding
- Think of it as the shop rounding ₹99.60 up to ₹100
- Turning a decimal into a nearby whole number, or into fewer decimal places.
Math.roundgoes to the nearest one, andtoFixedrounds to a set number of decimals but hands back text. - For example
Math.round(4.567)gives5. - floor, ceil and trunc
- Think of it as always rounding down, always rounding up, or just tearing off the paise
Math.flooralways goes down,Math.ceilalways goes up, andMath.truncsimply cuts the decimals off. They only disagree with negative numbers, where down means further from zero.- For example
Math.floor(-4.5)is -5,Math.trunc(-4.5)is -4. - Math
- Think of it as the calculator kept next to the till
- A built-in set of maths tools that every JavaScript program has. You use them by writing
Math.and the tool's name, such asMath.maxfor the biggest of some numbers. - Remainder (%)
- Think of it as the coins left over after sharing a pile out evenly
- What is left after dividing as many whole times as you can.
17 % 5is 2. If a number divided by 2 leaves 0, it is even. - Power and square root
- Think of it as doubling the stock again and again, or working backwards to where it started
- A power multiplies a number by itself several times:
2 ** 10is 2 times itself ten times, 1024. A square root goes the other way: the square root of 81 is 9, because 9 times 9 is 81. - Random number
- Think of it as a lucky draw slip pulled from a box at the counter
Math.random()gives an unpredictable decimal from 0 up to just below 1. Stretch it, round it down and shift it to get a whole number in any range, such as a dice roll.- Array and spread
- Think of it as tipping a bag of coins out onto the counter one by one
- An array is a list of values in square brackets. Three dots in front of it, called spread, pour the items out separately, which is how you pass a whole list to a tool like
Math.max. - For example
Math.max(...[40, 75, 12])gives75.
Keeping money exact
Why a till that works in decimals can be off by a fraction, and how to stop that from costing anyone a paisa.
- Binary
- Think of it as a till that can only count in ones and zeros
- Computers store every number as a string of 1s and 0s. Some simple decimals, such as 0.1, can't be written exactly that way, just as 1/3 never ends when written as a decimal.
- Floating point error
- Think of it as a scale that's off by a grain of sugar
- The tiny mistake left over when a decimal can't be stored exactly. It is why
0.1 + 0.2shows 0.30000000000000004. Compare decimals by checking the gap is smaller thanNumber.EPSILONrather than using ===. - Smallest unit (paise)
- Think of it as counting the coins in the drawer instead of estimating the rupees
- Store money as whole paise (or cents) instead of rupees with decimals. Whole numbers add up exactly, so nothing goes missing. Divide by 100 only when you show the amount.
- For example ₹4.50 is stored as
450paise. - BigInt
- Think of it as a bank vault ledger for amounts too big for the shop till
- Ordinary numbers stay exact only up to about 9 quadrillion. Past that, digits quietly go wrong. A BigInt is a separate kind of whole number, written with an
non the end, that stays exact at any size. - For example
9007199254740993n + 1ngives9007199254740994n.
Showing numbers to people
Printing amounts on the receipt the way a customer in that country expects to read them.
- Locale
- Think of it as the country setting on the receipt printer
- A short code for a language and region, such as en-IN for English in India or en-US for the United States. It decides where commas go and how currency is written.
- Thousands separator
- Think of it as the commas printed in a long total so it's easy to read
- Commas or spaces that split a long number into groups. India groups by lakhs and crores (12,34,567), while the US groups in threes (1,234,567).
- Formatter (Intl.NumberFormat)
- Think of it as a stamp set up once for rupees, then pressed on every receipt
- A reusable tool that turns numbers into display text: currency, percent or short forms like 2.4M. Build it once with your locale and options, then call its
formatas often as you like. - For example
₹12,34,567.89comes from an en-IN currency formatter. - Currency
- Think of it as the ₹ or $ sign printed in front of the amount
- The money a number stands for. A formatter set to a currency adds the right symbol and the usual two decimal places for you.
Make and check
Write numbers, meet the special values NaN and Infinity, and test what kind of number you have.
In JavaScript, 7 and 7.5 are the same type: number. There are also a few special values. Infinity is what you get past the biggest number, and NaN, short for "not a number", is the answer to maths that makes no sense.
const price = 450;
const rate = 7.5;
const big = 1_000_000; // underscores only help you read it
const tiny = 2.5e-3; // 0.0025 in science notation
console.log(typeof price, typeof rate); // whole or decimal, both are "number"
console.log(big, tiny);
console.log(10 / 0, -10 / 0); // dividing by zero gives Infinity
console.log(0 / 0, "abc" * 2); // NaN means "not a number"
Easy way to remember: NaN is still of type number. It just means the maths went wrong somewhere earlier.
$ node make.js number number 1000000 0.0025 Infinity -Infinity NaN NaN
Checks for a whole number with no decimals.
See the exampleChecks for a real, countable number. Not NaN, not Infinity.
See the exampleThe older check. It converts text first, so "hello" counts.
See the exampleconsole.log(Number.isInteger(5), Number.isInteger(5.5));
console.log(Number.isFinite(42), Number.isFinite(Infinity));
// NaN is the only value that is not equal to itself
console.log(NaN === NaN);
console.log(Number.isNaN(NaN)); // the reliable check
console.log(isNaN("hello")); // older isNaN converts first: true
console.log(Number.isNaN("hello")); // Number.isNaN does not: false
Why it matters: NaN is never equal to anything, not even itself, so x === NaN is always false. Use Number.isNaN(x).
$ node check.js true false true false false true true false
Text to number
Turn what a person typed into a real number, and catch it when they typed something else.
| Input | Number(x) | parseInt(x, 10) | parseFloat(x) |
|---|---|---|---|
"42" | 42 | 42 | 42 |
"4.5" | 4.5 | 4 | 4.5 |
"42px" | NaN | 42 | 42 |
"" | 0 | NaN | NaN |
"abc" | NaN | NaN | NaN |
Converts the whole value. Any junk gives NaN.
See the exampleReads a whole number from the start, stopping at junk. Always pass 10.
See the exampleReads a decimal number from the start.
See the exampleA short way to write Number(x).
See the exampleconsole.log(Number("42"), Number("4.5"), Number("")); // empty text becomes 0
console.log(Number("42px")); // any junk gives NaN
console.log(parseInt("42px", 10)); // reads digits until it hits junk
console.log(parseInt("08", 10), parseInt("ff", 16)); // always pass the base
console.log(parseFloat("3.14 metres"));
console.log(+"7" + 1, "7" + 1); // + in front converts; + between joins text
const qty = Number("abc");
console.log(Number.isNaN(qty) ? "please enter a number" : qty);
Rule of thumb: use Number for form fields, since it rejects junk. Use parseInt or parseFloat only when you expect units like "px" on the end.
$ node parse.js 42 4.5 0 NaN 42 8 255 3.14 8 71 please enter a number
Round it
Round up, round down, cut off decimals, or show a fixed number of decimal places.
| Value | round | floor | ceil | trunc |
|---|---|---|---|---|
4.567 | 5 | 4 | 5 | 4 |
4.5 | 5 | 4 | 5 | 4 |
-4.5 | -4 | -5 | -4 | -4 |
Always down, towards minus infinity.
See the exampleAlways up.
See the exampleRounds to that many decimals for display.
See the exampleconst n = 4.567;
console.log(Math.round(n), Math.floor(n), Math.ceil(n), Math.trunc(n));
console.log(Math.floor(-4.5), Math.trunc(-4.5)); // floor goes down, trunc cuts off
console.log(n.toFixed(2)); // "4.57": a string with 2 decimals
console.log(n.toFixed(0), typeof n.toFixed(2));
console.log(Number(n.toFixed(1))); // back to a number
console.log((1234.5678).toPrecision(3)); // 3 significant digits
Watch for this: toFixed gives you text, not a number. Wrap it in Number() if you need to keep calculating.
$ node round.js 5 4 5 4 -5 -4 4.57 5 string 4.6 1.23e+3
Math toolbox
Find the biggest and smallest, powers and roots, remainders and random numbers.
Picks the biggest or smallest. Spread an array into it.
See the exampleRemoves the minus sign.
See the exampleThe square root.
See the exampleThe remainder after dividing. Great for even or odd checks.
See the exampleconsole.log(Math.max(3, 9, 1), Math.min(3, 9, 1));
console.log(Math.max(...[40, 75, 12])); // spread an array in
console.log(Math.abs(-8), 2 ** 10, Math.sqrt(81));
console.log(17 % 5, 10 % 2 === 0); // remainder; checks even numbers
// a whole random number between min and max, both included
const randomInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
const roll = randomInt(1, 6);
console.log(roll >= 1 && roll <= 6);
The pattern: for a random whole number between min and max, scale random, floor it, then shift it up by min.
$ node math.js 9 1 75 8 1024 9 2 true true
Decimal gotchas
Understand why 0.1 + 0.2 is not 0.3, handle money safely and use BigInt for huge whole numbers.
Computers store decimals in binary, and some simple decimals like 0.1 cannot be stored exactly, the same way 1/3 never ends in decimal. The error is tiny, but it shows up when you compare.
| Problem | Fix |
|---|---|
| Comparing decimals | check the gap is below Number.EPSILON |
| Adding money | count whole paise or cents, divide only for display |
| Whole numbers above 9 quadrillion | use BigInt, written with an n on the end |
console.log(0.1 + 0.2); // tiny error from how decimals are stored
console.log(0.1 + 0.2 === 0.3);
const close = (a, b) => Math.abs(a - b) < Number.EPSILON;
console.log(close(0.1 + 0.2, 0.3)); // compare with a tiny allowed gap
// for money, count the smallest unit (paise) as whole numbers
const paise = 10 + 20; // ₹0.10 + ₹0.20
console.log(paise / 100);
console.log(Number.MAX_SAFE_INTEGER);
console.log(9007199254740993); // too big: the last digit is lost
console.log(9007199254740993n + 1n); // BigInt, with n, stays exact
Rule of thumb: never store money as rupees with decimals. Store paise as a whole number and format it at the very end.
$ node gotchas.js 0.30000000000000004 false true 0.3 9007199254740991 9007199254740992 9007199254740994n
Show it nicely
Format numbers for people: thousands separators, currency, percent and short forms like 2.4M.
Picture it: formatting
1234567.891Intl.NumberFormat("en-IN", { currency })₹12,34,567.89The number stays the same. Only how it looks changes.Adds separators the way that country writes numbers.
See the exampleconst amount = 1234567.891;
console.log(amount.toLocaleString("en-IN")); // Indian grouping: lakhs and crores
console.log(amount.toLocaleString("en-US"));
const inr = new Intl.NumberFormat("en-IN", { style: "currency", currency: "INR" });
console.log(inr.format(amount));
const usd = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" });
console.log(usd.format(amount));
const pct = new Intl.NumberFormat("en-IN", { style: "percent", maximumFractionDigits: 1 });
console.log(pct.format(0.1834));
const short = new Intl.NumberFormat("en-US", { notation: "compact" });
console.log(short.format(1500), short.format(2_400_000));
Why it matters: en-IN groups by lakhs and crores while en-US groups by thousands. Make the formatter once and call format as often as you like.
$ node format.js 12,34,567.891 1,234,567.891 ₹12,34,567.89 $1,234,567.89 18.3% 1.5K 2.4M
All together
Split a restaurant bill with tax between friends, down to the last paisa.
Splitting ₹859.43 three ways does not divide evenly. This example works in whole paise so nothing gets lost, then hands the leftover paise to the first people so the shares still add up to the total.
// split a restaurant bill fairly, working in paise so nothing is lost
const items = [
{ name: "Paneer tikka", price: 349.0 },
{ name: "Dal makhani", price: 289.5 },
{ name: "Naan x4", price: 180.0 },
];
const people = 3;
const GST = 0.05;
const toPaise = (rupees) => Math.round(rupees * 100);
const subtotal = items.reduce((sum, item) => sum + toPaise(item.price), 0);
const tax = Math.round(subtotal * GST);
const total = subtotal + tax;
// share out the paise, and give any leftover to the first people
const base = Math.floor(total / people);
const leftover = total % people;
const shares = Array.from({ length: people }, (_, i) => base + (i < leftover ? 1 : 0));
const inr = new Intl.NumberFormat("en-IN", { style: "currency", currency: "INR" });
console.log("total", inr.format(total / 100));
console.log(shares.map((p) => inr.format(p / 100)).join(" | "));
console.log("adds up:", shares.reduce((a, b) => a + b) === total);
What each part uses: whole paise from module 05, Math.round and Math.floor from 03, the remainder operator from 04, and Intl.NumberFormat from 06.
$ node bill.js total ₹859.43 ₹286.48 | ₹286.48 | ₹286.47 adds up: true
# save any example as a file and run it with Node 22 $ node bill.js # or paste it into your browser console with F12
Which one do I need?
Start from what you want to do, then read across to the tool and what it gives back.
| I want to | Use | You get |
|---|---|---|
| Check for a whole number | Number.isInteger(n) | true or false |
| Check for NaN | Number.isNaN(n) | true or false |
| Turn text into a number | Number(text) | a number or NaN |
| Read "42px" as 42 | parseInt(text, 10) | a number |
| Round to nearest | Math.round(n) | a whole number |
| Show 2 decimals | n.toFixed(2) | a string |
| Find the biggest | Math.max(...list) | a number |
| Check even or odd | n % 2 === 0 | true or false |
| Random from 1 to 6 | Math.floor(Math.random() * 6) + 1 | a whole number |
| Compare decimals | Math.abs(a - b) < Number.EPSILON | true or false |
| Huge exact numbers | 123n | a BigInt |
| Show as rupees | Intl.NumberFormat("en-IN", { style: "currency", currency: "INR" }) | a formatter |