Numbers & Math

Reviewed & published by Brayan K

Prices, scores, percentages, coordinates, timers — numbers run through every app. JavaScript has just one number type for integers and decimals alike, which is convenient until you hit the famous 0.1 + 0.2 surprise.

Part of the free JavaScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

This lesson covers arithmetic, rounding, the Math object, conversions, and how to handle precision like a professional.

What You'll Learn in This Lesson

📐 Real-World Analogy: Think of a kitchen scale that only shows two decimal places:

🧠 Arithmetic & the Modulo Operator

The basic operators are + - * /, plus % (remainder) and ** (exponent). The remainder operator is the secret behind "is this even?" and "wrap around a clock":

⚠️ The Floating-Point Gotcha

Every JavaScript number is a 64-bit float, so some decimals can't be stored exactly. This is not a bug in your code — it happens in nearly every programming language:

🔘 Rounding the Right Way

Different jobs need different rounding. Pick deliberately — the wrong one silently corrupts totals:

Note the negative trap: Math.floor(-4.7) is -5 because floor always moves toward negative infinity, while Math.trunc just deletes the fractional part.

🧮 The Math Object & Random Numbers

Math is a built-in toolbox of static helpers. You don't create it — you call methods on it directly. Random integers are the most-asked-for recipe:

🔁 Converting Strings to Numbers

User input always arrives as text. Convert it carefully — the method you choose changes the result:

🚫 NaN, Infinity & Safe Checks

Two special numeric values appear when math goes sideways. Knowing how to detect them prevents hard-to-trace bugs:

// Average a list of scores
const scores = [88, 92, 79, 95, 100];
const total = scores.reduce((sum, s) => sum + s, 0);
const average = total / scores.length;
console.log("Average:", average.toFixed(1));
console.log("Highest:", Math.max(...scores));
console.log("Lowest:", Math.min(...scores));

// Money safely with integer cents
const priceCents = 1999;     // $19.99
const taxCents = Math.round(priceCents * 0.2);
const totalCents = priceCents + taxCents;
console.log("Total: $" + (totalCents / 100).toFixed(2));

// Random in a range
function randInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log("Random 1-100 valid?", (() => {
  const r = randInt(1, 100);
  return r >= 1 && r <= 100;
})());

// Even / odd
console.log("Is 42 even?", 42 % 2 === 0);

// Try it: write a celsiusToFahrenheit(c) function and round the result!
// 🎯 YOUR TURN — replace each ___ using the hint beside it.

const price = 12.3456;

// 1) Two decimal places, as a STRING — the one to use for money.
console.log("Fixed 2:", price.___(2));      // 👉 replace ___ with toFixed

// 2) Nearest whole number.
console.log("Rounded:", Math.___(price));   // 👉 replace ___ with round

// 3) Always up, then always down.
console.log("Up:", Math.___(price));        // 👉 replace ___ with ceil
console.log("Down:", Math.floor(price));

// Binary floating point, not a bug: 0.1 and 0.2 have no exact binary form.
console.log("0.1 + 0.2 =", 0.1 + 0.2);

// 4) So compare with a tolerance instead of ===.
console.log("Close enough?", Math.___(0.1 + 0.2 - 0.3) < Number.EPSILON);  // 👉 replace ___ with abs

const typed = "42";
console.log("parseInt:", parseInt(typed, 10) + 1);
console.log("Number():", Number("3.5") * 2);
console.log("Not a number:", Number("twelve"));

// 5) NaN is not equal to anything, including itself. Ask properly.
console.log("Is it NaN?", Number.___(Number("twelve")));   // 👉 replace ___ with isNaN

console.log("Safe max:", Number.MAX_SAFE_INTEGER);
console.log("Integer?", Number.isInteger(7.0), Number.isInteger(7.5));

// ✅ Expected output:
// Fixed 2: 12.35
// Rounded: 12
// Up: 13
// Down: 12
// 0.1 + 0.2 = 0.30000000000000004
// Close enough? true
// parseInt: 43
// Number(): 7
// Not a number: NaN
// Is it NaN? true
// Safe max: 9007199254740991
// Integer? true false

🧩 Reorder Challenge

These lines should compute a price with 20% tax and print it as currency. They are scrambled — reorder them so the log is $24.00.

C → A → D → B

Why: the base price (C) must exist before tax is computed from it (A). The total (D) adds the two together, and only then can it be formatted (B). Working in integer cents avoids the floating-point error you'd hit doing 20 * 1.2 directly, and Math.round keeps the tax a whole number of cents.

🧠 Quick Recall

55 — Number("5") is the number 5, but 5 + "5" triggers string concatenation (the number is coerced to text), producing "55". If you wanted 10, both operands must be numbers.

2. What is the result?

-3 — Math.floor always rounds toward negative infinity, so -2.1 becomes -3, not -2. Use Math.trunc(-2.1) if you want -2.

3. What does this log?

false — 0 / 0 is NaN, and NaN is the only value in JavaScript that is not equal to itself. That's exactly why you must use Number.isNaN(x) to detect it.

⚠️ Common Mistakes to Avoid

Lesson Complete — Numbers & Math!

Practice quiz

What does console.log(17 % 4) output?

  • 4
  • 1
  • 4.25
  • 0

Answer: 1. The % operator returns the remainder: 17 divided by 4 is 4 with 1 left over.

What does console.log(2 ** 10) output?

  • 20
  • 100
  • 1024
  • 12

Answer: 1024. ** is the exponent operator, so 2 ** 10 is 2 to the 10th power, which is 1024.

What does console.log(0.1 + 0.2 === 0.3) output?

  • true
  • false
  • NaN
  • 0.3

Answer: false. 0.1 + 0.2 equals 0.30000000000000004 due to floating-point rounding, so it is not strictly equal to 0.3.

What is the value of Math.floor(-4.7)?

  • -4
  • -5
  • 4
  • 5

Answer: -5. Math.floor always rounds toward negative infinity, so -4.7 becomes -5.

Which method just chops off the decimal part without rounding, giving -4 from -4.7?

  • Math.floor
  • Math.round
  • Math.ceil
  • Math.trunc

Answer: Math.trunc. Math.trunc(-4.7) deletes the fractional part and returns -4, unlike Math.floor which gives -5.

What does console.log(Number('12px')) output?

  • 12
  • NaN
  • 0
  • '12px'

Answer: NaN. Number requires the whole string to be numeric; '12px' has trailing letters, so it returns NaN.

What does console.log(parseInt('12px')) output?

  • NaN
  • 0
  • 12
  • '12'

Answer: 12. parseInt reads digits from the front and stops at the first non-digit, so it returns 12.

What does console.log(Number('')) output?

  • NaN
  • 0
  • undefined
  • ''

Answer: 0. An empty string converts to 0 in JavaScript, a classic trap that can hide validation bugs.

Why does x === NaN return false even when x is NaN?

  • NaN is never equal to itself
  • === does not work on numbers
  • NaN equals 0
  • It actually returns true

Answer: NaN is never equal to itself. NaN is the only value not equal to itself, so you must use Number.isNaN(x) to detect it reliably.

What does console.log(Number('5') + '5') output?

  • 10
  • '55'
  • NaN
  • 55 as a number

Answer: '55'. Number('5') is the number 5, but adding a string coerces it to text, producing the string '55'.

Continue this course

Frequently asked questions

Why does 0.1 + 0.2 equal 0.30000000000000004?

JavaScript numbers are 64-bit floating-point values, and like most languages it cannot represent 0.1 or 0.2 exactly in binary. The tiny rounding errors add up. For display, round with toFixed(2). For money, work in integer cents (multiply by 100) to avoid the problem entirely.

What is NaN and how do I check for it?

NaN means 'Not a Number' and appears when a math operation fails, like Number('hello') or 0/0. The trap is that NaN === NaN is false, so never compare to it directly. Use Number.isNaN(x) to test reliably.

What's the difference between parseInt, Number, and Math.round?

Number('3.9') converts the whole string to a number (3.9). parseInt('3.9px') reads digits from the front and stops, giving 3. Math.round(3.9) rounds the nearest integer (4). Use Number for clean conversions, parseInt when trailing junk is expected, and Math.round when you actually want rounding.

How do I generate a random integer in a range?

Math.random() gives a float from 0 (inclusive) to 1 (exclusive). To get an integer from min to max inclusive use Math.floor(Math.random() * (max - min + 1)) + min. The +1 and floor together make both ends reachable.

When should I use BigInt instead of Number?

Number can only safely represent integers up to 2^53 - 1 (Number.MAX_SAFE_INTEGER). Beyond that, precision breaks. BigInt (written like 9007199254740993n) handles arbitrarily large integers exactly — useful for IDs, cryptography, or huge counters. You cannot mix BigInt and Number in the same operation without converting.