Complete JavaScript Course Module 2: Beginner: Variables and Data Types

Numbers and Math in JavaScript

  • Beginner
  • Lesson 2.4
  • 5 min read
  • 7 of 76 in the course

In short

JavaScript numbers let you calculate prices, scores and sizes. Learn arithmetic operators, the Math object, random numbers, rounding, NaN and how to turn text into numbers. Arithmetic operators in JavaScript An operator is a symbol that does something with values.

JavaScript numbers let you calculate prices, scores and sizes. Learn arithmetic operators, the Math object, random numbers, rounding, NaN and how to turn text into numbers.

Arithmetic operators in JavaScript

An operator is a symbol that does something with values. You already know most math operators from school:

OperatorMeaningExampleResult
+Add7 + 310
-Subtract7 - 34
*Multiply7 * 321
/Divide7 / 23.5
%Remainder7 % 31
**Power (exponent)2 ** 38

The remainder operator % (also called modulo) gives what is left over after dividing. 7 % 3 is 1, because 3 fits into 7 twice (6) and 1 is left. It's very handy for checking if a number is even: number % 2 is 0 for even numbers.

The power operator ** multiplies a number by itself. 2 ** 3 means 2 × 2 × 2.

const pizzaSlices = 10;
const people = 4;

console.log(pizzaSlices / people);   // Output: 2.5
console.log(pizzaSlices % people);   // Output: 2   (slices left over if everyone gets 2)
console.log(14 % 2);                 // Output: 0   (14 is even)
console.log(5 ** 2);                 // Output: 25

Increment, decrement and shortcut operators

Changing a variable by a small amount is so common that JavaScript has shortcuts:

let likes = 10;

likes++;          // same as likes = likes + 1
console.log(likes);   // Output: 11

likes--;          // same as likes = likes - 1
console.log(likes);   // Output: 10

likes += 5;       // same as likes = likes + 5
console.log(likes);   // Output: 15

likes *= 2;       // same as likes = likes * 2
console.log(likes);   // Output: 30

++ adds 1 and -- subtracts 1. There are also +=, -=, *= and /=. These only work on variables made with let, because they reassign the value.

Operator precedence: which part is calculated first?

Operator precedence is the order in which JavaScript does calculations. It follows the same rules as math class: ** first, then *, / and %, then + and -. Use brackets ( ) to choose the order yourself.

console.log(2 + 3 * 4);      // Output: 14   (3 * 4 first, then + 2)
console.log((2 + 3) * 4);    // Output: 20   (brackets first)

const price = 20;
const shipping = 5;
const taxRate = 0.1;
console.log((price + shipping) * (1 + taxRate));   // Output: 27.500000000000004

That strange last result is explained below. When a calculation is not obvious, add brackets anyway: they make your intention clear to anyone reading the code.

The Math object: rounding, random, max and min

JavaScript has a built-in Math object full of ready-made math tools:

console.log(Math.round(4.5));    // Output: 5   (nearest whole number)
console.log(Math.round(4.4));    // Output: 4
console.log(Math.floor(4.9));    // Output: 4   (always rounds down)
console.log(Math.ceil(4.1));     // Output: 5   (always rounds up)
console.log(Math.max(3, 18, 7)); // Output: 18  (largest)
console.log(Math.min(3, 18, 7)); // Output: 3   (smallest)
console.log(Math.random());      // Output: a random decimal like 0.7134...

Math.random() gives a random decimal number from 0 up to (but not including) 1. To get a random whole number in a range, like a dice roll from 1 to 6, combine it with Math.floor:

const roll = Math.floor(Math.random() * 6) + 1;
console.log(`You rolled a ${roll}`);
// Output: You rolled a 4   (a different number from 1 to 6 each time)

// Reusable pattern: random whole number from min to max (both included)
const min = 10;
const max = 20;
const randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;
console.log(randomNumber);
// Output: a number from 10 to 20

Step by step for the dice: Math.random() * 6 gives a decimal from 0 up to almost 6. Math.floor cuts off the decimals, giving 0, 1, 2, 3, 4 or 5. Adding 1 shifts that to 1 to 6.

Why is 0.1 + 0.2 not 0.3? Decimals and toFixed

Try this in the console:

console.log(0.1 + 0.2);                // Output: 0.30000000000000004
console.log((0.1 + 0.2).toFixed(2));   // Output: 0.30

const total = 19.999;
console.log(total.toFixed(2));         // Output: 20.00
console.log(typeof total.toFixed(2));  // Output: string

This is not a JavaScript bug. Computers store numbers in binary (only 0s and 1s). Some simple decimals, like 0.1, can't be stored exactly in binary, just like 1/3 can't be written exactly in decimal (0.3333...). The tiny leftover error appears when you add them. Almost every programming language does this.

For showing numbers to people, use toFixed(digits). It rounds to the number of decimal places you choose. Notice that toFixed returns a string, which is perfect for displaying a price but not for more math.

Tip: For money, many developers calculate in cents (whole numbers) instead of dollars: 1999 cents instead of 19.99. Whole numbers don't have the rounding problem.

NaN and Infinity

Two special number values you will meet:

  • NaN means "Not a Number". You get it when a calculation makes no sense, like 'apple' * 2. Strangely, typeof NaN is 'number'.
  • Infinity is what you get when you divide by zero, like 10 / 0.
console.log('apple' * 2);           // Output: NaN
console.log(10 / 0);                // Output: Infinity
console.log(Number.isNaN('apple' * 2));  // Output: true

NaN is not equal to anything, not even itself, so use Number.isNaN(value) to check for it.

Turning text into numbers: Number(), parseInt and parseFloat

Values from forms and prompt() are strings. Before doing math, convert them:

console.log(Number('42'));          // Output: 42
console.log(Number('42px'));        // Output: NaN   (the whole text must be a number)
console.log(parseInt('42px'));      // Output: 42    (reads digits until it stops)
console.log(parseInt('3.99'));      // Output: 3     (whole numbers only)
console.log(parseFloat('3.99kg'));  // Output: 3.99  (keeps decimals)

console.log('5' + 3);               // Output: 53  (joined as text!)
console.log(Number('5') + 3);       // Output: 8

Use Number() when the text should be exactly a number. Use parseInt or parseFloat when the number is followed by other characters, like '42px' from CSS.

Common mistake: Adding a number to a string with +. '5' + 3 gives '53', because + joins text. Convert first with Number().

Practice exercise

Build a tip calculator. Create const bill = '48.00'; (a string, like from a form) and const tipPercent = 15;. Convert the bill to a number, calculate the tip and the total, and log Tip: $7.20, Total: $55.20 using toFixed(2). Bonus: log a random "lucky number" from 1 to 100.

Hint: the tip is billNumber * tipPercent / 100. For the lucky number, use the random pattern with min = 1 and max = 100.

Key takeaways

  • Use + - * / for basic math, % for the remainder and ** for powers.
  • ++, -- and += are shortcuts for changing a variable.
  • Brackets control the order of operations.
  • Math.floor(Math.random() * n) + 1 gives a random whole number from 1 to n.
  • Decimals can be slightly inexact, so use toFixed() for display; convert text to numbers with Number(), parseInt or parseFloat.