The built-in Math object is JavaScript's calculator: rounding, powers, square roots, absolute values, and useful constants like pi. You have used a few of its methods already. This lesson covers the ones you will reach for most, and the rounding traps that catch people out.
Unlike Date or Map, you never write new Math(). Everything is used directly:
Math.PI // 3.141592653589793
Math.sqrt(16) // 4
new Math() // TypeError: Math is not a constructor
An object like this, used directly and never created with new, is called static. Every Math property is written Math.property, and every method Math.method(number).
| Method | Rule | 2.7 | -2.7 | 2.5 |
|---|---|---|---|---|
| Math.round | Nearest whole number | 3 | -3 | 3 |
| Math.floor | Always down | 2 | -3 | 2 |
| Math.ceil | Always up | 3 | -2 | 3 |
| Math.trunc | Chop off the decimals | 2 | -2 | 2 |
Math.floor(-2.7) is -3, not -2. If you just want to drop the decimal part regardless of sign, use Math.trunc.
One more surprise: halves always round up, toward positive infinity, even for negative numbers:
Math.round(2.5) // 3
Math.round(-2.5) // -2 (not -3)
Math.round only rounds to whole numbers. To round to 2 places, multiply, round, then divide:
Math.round(3.14159 * 100) / 100 // 3.14 (a number)
(3.14159).toFixed(2) // "3.14" (a string, for display)
Both can be tripped up by the decimal precision issue from the Numbers lesson:
Math.round(1.005 * 100) / 100 // 1 (expected 1.01)
(1.005).toFixed(2) // "1.00" (same problem)
1.005 is actually stored as 1.00499999... A tiny nudge fixes it:
function roundTo(n, places) {
const f = 10 ** places;
return Math.round((n + Number.EPSILON) * f) / f;
}
roundTo(1.005, 2) // 1.01
Math.pow(2, 10) // 1024 (same as 2 ** 10)
Math.sqrt(81) // 9
Math.cbrt(27) // 3 cube root
Math.sqrt(-1) // NaN (no real answer)
Math.abs(-7.5) // 7.5 distance from zero
Math.sign(-5) // -1 negative
Math.sign(0) // 0
Math.sign(42) // 1 positive
// How far apart are two temperatures, regardless of order?
Math.abs(58 - 71) // 13
Math.sign(x) tells you if x is "negative, null or positive." It means zero, not null: the three answers are -1, 0, and 1. (Two rare extras: Math.sign(-0) gives -0, and anything that is not a number, like Math.sign("abc"), gives NaN.)
Math.max(4, 19, 7) // 19
Math.min(...[4, 19, 7]) // 4 (spread an array)
Math.max() // -Infinity (nothing to compare)
Math.max and Math.min want separate numbers, not an array. Math.max([4, 19, 7]) gives NaN, with no error to warn you. Spread it: Math.max(...[4, 19, 7]).
A handy pattern built from both: keep a number inside a range, called clamping:
const clamp = (n, lo, hi) => Math.min(Math.max(n, lo), hi);
clamp(150, 0, 100) // 100
clamp(-20, 0, 100) // 0
clamp(42, 0, 100) // 42
Math.sin(x) and Math.cos(x) return a value between -1 and 1. The angle x must be in radians, not degrees, so convert first: radians = degrees × Math.PI / 180.
console.log(Math.sin(90 * Math.PI / 180)); // sine of 90 degrees
console.log(Math.cos(0 * Math.PI / 180)); // cosine of 0 degrees
console.log(Math.sin(90)); // 90 RADIANS: wrong!
JS Math Reference goes further with trig, including why answers are sometimes a hair off.
A logarithm answers "how many times must I multiply this base to get x?"
console.log(Math.log2(8)); // 2 x 2 x 2 = 8, so 3
console.log(Math.log10(1000)); // 10 x 10 x 10 = 1000, so 3
console.log(Math.log(10)); // base E: E multiplied about 2.3 times
console.log(Math.log(Math.E)); // 1
console.log(Math.log(1)); // any base to the power 0 is 1
Math.log uses base Math.E, so the two are twins: Math.log(Math.E) is exactly 1. The reference lesson shows a practical use (counting digits).
Math.random() returns a random decimal from 0 (included) up to 1 (never reached). JS Math Random is all about turning that into dice rolls and random picks.
JavaScript has 8 math constants, all written in capitals because they never change:
console.log(Math.E); // Euler's number
console.log(Math.PI); // pi
console.log(Math.SQRT2); // square root of 2
console.log(Math.SQRT1_2); // square root of 1/2
console.log(Math.LN2); // natural log of 2
console.log(Math.LN10); // natural log of 10
console.log(Math.LOG2E); // base-2 log of E
console.log(Math.LOG10E); // base-10 log of E
// Area and circumference of a circle
const r = 5;
console.log((Math.PI * r ** 2).toFixed(2));
console.log((2 * Math.PI * r).toFixed(2));
Which gives -4?
Math.floor(-4.2)Math.ceil(-4.7)Math.round(-3.5)Math.trunc(-3.9)ceil goes up, toward positive, so -4.7 becomes -4. floor(-4.2) goes down to -5, round(-3.5) rounds the half up to -3, and trunc(-3.9) chops to -3.What does this log?
const temps = [58, 71, 64];
console.log(Math.max(temps), Math.max(...temps));
NaN 71. Without the spread, Math.max gets one argument (an array), which is not a number.Why is Math.sin(90) not 1?
new Math().sin(90)Math.sin(90 * Math.PI / 180) is 1.round, floor, ceil, and trunc give for 4.5 and -4.5, then run ittoFixed(2), then with roundTo. Which one gives the answer you expect?clamp to keep a volume setting between 0 and 11max, min, and spread