Arithmetic operators do math on numbers. Most work exactly like they did in math class. A few are specific to programming, and a couple of them (% and ++) turn out to be some of the most useful tools you will have.
| Operator | Name | Example | Result |
|---|---|---|---|
| + | Addition | 5 + 2 | 7 |
| - | Subtraction | 5 - 2 | 3 |
| * | Multiplication | 5 * 2 | 10 |
| / | Division | 5 / 2 | 2.5 |
| % | Remainder (modulus) | 5 % 2 | 1 |
| ** | Exponentiation (ES2016) | 5 ** 2 | 25 |
| ++ | Increment | x++ | adds 1 to x |
| -- | Decrement | x-- | subtracts 1 from x |
The numbers an operator works on are its operands. In 100 + 50, the operands are 100 and 50 and the operator is +. An operand can be a literal number, a variable, or a whole expression:
let a = 2;
let b = 3;
let x1 = 100 + 50; // literals
let x2 = a + b; // variables
let x3 = (100 + 50) * a; // an expression as an operand
console.log(x1, x2, x3);
let a = 10;
let b = 3;
console.log(a + b); // addition
console.log(a - b); // subtraction
console.log(a * b); // multiplication
console.log(a / b); // division
Two things about division are different from what you might expect:
5 / 2 is 2.5, not 2. There is no separate "whole number division" operator; the % section below shows how to get the whole part and the remainder.10 / 0 gives Infinity and -10 / 0 gives -Infinity. 0 / 0 gives NaN ("Not a Number"). Your program keeps running with a strange value, so watch for these.The % operator (called modulus or remainder) divides and gives back only what is left over. Think back to long division: 10 ÷ 3 is 3 remainder 1.
console.log(10 % 3); // 10 ÷ 3 = 3 remainder 1
console.log(12 % 4); // 12 ÷ 4 = 3 remainder 0 (divides evenly)
console.log(7 % 2); // 7 ÷ 2 = 3 remainder 1
It looks minor, but % answers questions that come up constantly:
// Is a number even? Even numbers have no remainder when divided by 2
let n = 14;
console.log(n % 2 === 0);
// Does 99 divide evenly by 9?
console.log(99 % 9 === 0);
// Convert 135 seconds to minutes and seconds
let total = 135;
let minutes = Math.floor(total / 60); // whole minutes
let seconds = total % 60; // what is left over
console.log(minutes + "m " + seconds + "s");
Math.floor() rounds a number down to a whole number, so Math.floor(135 / 60) turns 2.25 into 2. Paired with %, it gives you "how many whole times" and "how much is left". You will see Math properly in the JS Math lesson.
The ** operator raises the first operand to the power of the second. 5 ** 2 means 5², which is 5 × 5:
console.log(5 ** 2); // 5 × 5
console.log(2 ** 10); // 2 × 2 × 2 ... ten times
console.log(Math.pow(5, 2)); // the older way to write 5 ** 2
** was added in 2016. Before that, everyone used Math.pow(x, y), which gives exactly the same result. You will see both.
++ adds 1 to a variable and -- subtracts 1. They are shorthand for the very common x = x + 1 and x = x - 1:
let count = 5;
count++; // 6
count++; // 7
count--; // 6
console.log(count);
Each can go after the variable (postfix, x++) or before it (prefix, ++x). On a line by itself, as above, there is no difference. The difference only shows up when you use the result in the same line:
let x = 5;
console.log(x++); // postfix: hands over the OLD value, then adds 1
console.log(x);
let y = 5;
console.log(++y); // prefix: adds 1 first, then hands over the NEW value
console.log(y);
++ and -- on their own line. You will use i++ constantly in loops, where it always sits on its own.
Precedence is the order in which operations happen when an expression has more than one. Is 100 + 50 * 3 the same as 150 * 3, or 100 + 150? Just like in math class, multiplication goes first:
console.log(100 + 50 * 3); // 100 + 150
console.log((100 + 50) * 3); // parentheses first: 150 * 3
| Order | Operators |
|---|---|
| 1st | ( ) parentheses |
| 2nd | ** exponent |
| 3rd | * / % multiply, divide, remainder |
| 4th | + - add, subtract |
When operators have the same precedence, like + and -, or * and /, they are worked out left to right:
console.log(100 + 50 - 3); // (100 + 50) - 3
console.log(100 / 50 * 3); // (100 / 50) * 3, NOT 100 / 150
console.log(2 + 3 ** 2); // 3 ** 2 first, then + 2
let avg = a + b / 2; divides only b by 2, then adds a. For an average you need (a + b) / 2. When an expression mixes groups, add parentheses even if you think you know the rules. JavaScript has a full precedence table covering every operator, but parentheses mean you never need to memorize it.
Arithmetic operators expect numbers. Give them a string and JavaScript tries to convert it:
console.log("10" - 5); // "10" becomes 10
console.log("10" * "2"); // both become numbers
console.log("abc" * 2); // "abc" cannot become a number
console.log("10" + 5); // + joins strings instead!
NaN means "Not a Number": the result of math that could not be done. Once a NaN appears, any further math with it also gives NaN, so one bad value can spread through a whole calculation.
// Tip calculator
const bill = 85.50;
const tipPct = 0.18;
const tip = bill * tipPct;
const total = bill + tip;
console.log(tip);
console.log("Tip: $" + tip.toFixed(2));
console.log("Total: $" + total.toFixed(2));
Look at the first line of output: the raw tip is 15.389999999999999, not 15.39. Computers store decimals in binary, so tiny rounding errors like this are normal. .toFixed(2) rounds a number to 2 decimal places for display, which is exactly what you want for money. The JS Numbers lesson explains why the error happens.
What is 17 % 5?
3.4320% gives only the remainder. 3.4 is what 17 / 5 gives.What does this log?
console.log(20 - 4 * 2 + 1);
13. Multiplication first: 4 * 2 is 8. Then left to right: 20 - 8 is 12, and 12 + 1 is 13.What does this log?
let lives = 3;
console.log(lives--);
console.log(lives);
3 then 2. Postfix -- hands over the old value (3) to console.log, and only then subtracts 1.Math.floor, /, and %** to compute 2 to the power of 10, then check it with Math.pow80 + 90 / 2, then fix it with parentheses. Why were the answers different?let n = 5; console.log(n++); console.log(n);, predicting the output before you click Run. Then try it with ++n