JavaScript provides you a built-in Math
object that comes with useful mathematical constants and functions.
You can use these mathematical constants and functions for getting square roots, rounding numbers, or even generating random values, and much more, by just calling them directly on the Math
object without creating an instance.
Key Points:
-
Math is not a constructor, you can't use
new Math()
, just useMath
directly. -
All Math properties and methods are static, that means you call them directly on the
Math
object rather than creating an instance. So you useMath.sqrt()
, not something likemyMath.sqrt()
. -
JavaScript automatically tries to turn your inputs (arguments) into numbers.
-
If any argument cannot be converted to a number, like if you pass a string that can't be turned into a number, the result is usually
NaN
(Not-a-Number). -
You can validate numbers before using them with methods like:
Number.isFinite(42); // true Number.isFinite(Infinity); // false Number.isNaN(NaN); // true Number.isNaN("hello"); // false (not NaN, just a string)
These are useful for checking whether an input is a real, finite number, especially helpful before doing any calculations.
Math Constants
JavaScript provides several important mathematical constants, like π (pi), euler's number and square roots, that are super useful for calculations.
No need to define them yourself. You can just use them directly.
// The value of π
console.log(Math.PI); // Output: 3.141592653589793
// Euler's number
console.log(Math.E); // Output: 2.718281828459045
// Natural log of 2 (ln(2))
console.log(Math.LN2); // Output: 0.6931471805599453
// Natural log of 10 (ln(10))
console.log(Math.LN10); // Output: 2.302585092994046
// log base 2 of e (log₂(e))
console.log(Math.LOG2E); // Output: 1.4426950408889634
// log base 10 of e (log₁₀(e))
console.log(Math.LOG10E); // Output: 0.4342944819032518
// Square root of 2 (√2)
console.log(Math.SQRT2); // Output: 1.4142135623730951
// Square root of 1/2 (√(1/2) or 1/√2)
console.log(Math.SQRT1_2); // Output: 0.7071067811865476
Using Constants in Calculations
// Calculate the area of a circle
function circleArea(radius) {
return Math.PI * radius * radius;
}
console.log(circleArea(5)); // Output: 78.53981633974483
// Calculate the circumference of a circle
function circleCircumference(radius) {
return 2 * Math.PI * radius;
}
console.log(circleCircumference(5)); // Output: 31.41592653589793
// Convert degrees to radians
function degreesToRadians(degrees) {
return degrees * (Math.PI / 180);
}
console.log(degreesToRadians(90)); // Output: 1.5707963267948966
// Convert radians to degrees
function radiansToDegrees(radians) {
return radians * (180 / Math.PI);
}
console.log(radiansToDegrees(Math.PI / 2)); // Output: 90
Basic Math Operations
JavaScript gives you built-in methods for getting the absolute value, finding the min or max from a set of numbers, or calculating distances.
Absolute Value
Math.abs(x)
is used to get the absolute value.
It returns the positive version of a number.
It turns negative numbers into positive, and leaves positive numbers as-is.
console.log(Math.abs(-5)); // Output: 5
console.log(Math.abs(5)); // Output: 5
console.log(Math.abs(-3.14)); // Output: 3.14
console.log(Math.abs(0)); // Output: 0
Min and Max
You can use Math.min()
and Math.max()
to find the smallest or largest number respectively.
Finding minimum and maximum values:
console.log(Math.min(1, 2, 3, 4, 5)); // Output: 1
console.log(Math.max(1, 2, 3, 4, 5)); // Output: 5
With arrays (using spread operator):
const numbers = [1, 2, 3, 4, 5];
console.log(Math.min(...numbers)); // Output: 1
console.log(Math.max(...numbers)); // Output: 5
Edge cases:
// Math.min() with no arguments returns Infinity
console.log(Math.min()); // Output: Infinity
// Math.max() with no arguments returns -Infinity
console.log(Math.max()); // Output: -Infinity
// If any argument is NaN, the result is NaN
console.log(Math.min(1, NaN, 3)); // Output: NaN
Rounding Functions
Math.round
- rounds to nearest integer
console.log(Math.round(4.7)); // Output: 5
console.log(Math.round(4.3)); // Output: 4
console.log(Math.round(4.5)); // Output: 5
console.log(Math.round(-4.5)); // Output: -4 (rounds towards positive infinity)
Math.ceil
- always rounds up
console.log(Math.ceil(4.1)); // Output: 5
console.log(Math.ceil(4.9)); // Output: 5
console.log(Math.ceil(-4.1)); // Output: -4
Math.floor
- always rounds down
console.log(Math.floor(4.1)); // Output: 4
console.log(Math.floor(4.9)); // Output: 4
console.log(Math.floor(-4.1)); // Output: -5
Math.trunc
- removes decimal part
console.log(Math.trunc(4.9)); // Output: 4
console.log(Math.trunc(-4.9)); // Output: -4
Power Functions
Math.pow
- raise numbers to any power
console.log(Math.pow(2, 3)); // Output: 8 (2³)
console.log(Math.pow(4, 0.5)); // Output: 2 (4^0.5 = √4)
console.log(Math.pow(8, 1 / 3)); // Output: 2 (8^(1/3) = ∛8)
Exponentiation operator
console.log(2 ** 3); // Output: 8
console.log(4 ** 0.5); // Output: 2
Math.exp
- e raised to power
console.log(Math.exp(1)); // Output: 2.718281828459045 (e¹)
console.log(Math.exp(2)); // Output: 7.38905609893065 (e²)
console.log(Math.exp(0)); // Output: 1 (e⁰)
Math.expm1
- e^x - 1
(more accurate for small x)
console.log(Math.expm1(1)); // Output: 1.718281828459045 (e¹ - 1)
console.log(Math.expm1(0)); // Output: 0
Root Functions
Math.sqrt
- square root of a number
console.log(Math.sqrt(16)); // Output: 4
console.log(Math.sqrt(2)); // Output: 1.4142135623730951
console.log(Math.sqrt(-1)); // Output: NaN
Math.cbrt
- cube root of a number
console.log(Math.cbrt(8)); // Output: 2
console.log(Math.cbrt(27)); // Output: 3
console.log(Math.cbrt(-8)); // Output: -2
Custom nth root function
function nthRoot(number, n) {
return Math.pow(number, 1 / n);
}
console.log(nthRoot(16, 4)); // Output: 2 (4th root of 16)
console.log(nthRoot(32, 5)); // Output: 2 (5th root of 32)
Logarithmic Functions
Math.log
- natural logarithm (base e)
console.log(Math.log(Math.E)); // Output: 1 (ln(e))
console.log(Math.log(1)); // Output: 0 (ln(1))
console.log(Math.log(10)); // Output: 2.302585092994046 (ln(10))
Math.log10
- base 10 logarithm
console.log(Math.log10(100)); // Output: 2 (log₁₀(100))
console.log(Math.log10(1000)); // Output: 3 (log₁₀(1000))
console.log(Math.log10(1)); // Output: 0 (log₁₀(1))
Math.log2
- base 2 logarithm
console.log(Math.log2(8)); // Output: 3 (log₂(8))
console.log(Math.log2(16)); // Output: 4 (log₂(16))
console.log(Math.log2(1)); // Output: 0 (log₂(1))
Math.log1p
- ln(1 + x)
(more accurate for small x)
console.log(Math.log1p(0)); // Output: 0 (ln(1 + 0) = ln(1))
console.log(Math.log1p(1)); // Output: 0.6931471805599453 (ln(2))
Custom logarithm function:
JavaScript doesn't have a built-in Math.logBase()
function, but you can calculate logarithms with any base using the change of base formula.
// Logarithm with custom base
function logBase(number, base) {
return Math.log(number) / Math.log(base);
}
console.log(logBase(8, 2)); // Output: 3 (same as Math.log2(8))
console.log(logBase(100, 10)); // Output: 2 (same as Math.log10(100))
console.log(logBase(27, 3)); // Output: 3.0000000000000004 (log₃(27))
-
Takes any number and a base.
-
Uses the change-of-base formula to compute the logarithm in that base.
-
Returns the result.
-
Explanation for the outputs:
console.log(logBase(8, 2)); // → 3 // Because 2^3 = 8 → log₂(8) = 3 console.log(logBase(100, 10)); // → 2 // Because 10^2 = 100 → log₁₀(100) = 2 console.log(logBase(27, 3)); // → 3.0000000000000004 // Because 3^3 = 27 → log₃(27) ≈ 3 // (The extra digits are just floating-point rounding issue. JavaScript, like most languages, can't represent some decimal numbers exactly.)
Trigonometric Functions
Note: All trigonometric functions work with radians, not degrees.
Basic Trigonometry
const angle = Math.PI / 4; // 45 degrees converted to radians
// sin(45°)
console.log(Math.sin(angle)); // Output: 0.7071067811865475
// cos(45°)
console.log(Math.cos(angle)); // Output: 0.7071067811865476
// tan(45°)
console.log(Math.tan(angle)); // Output: 0.9999999999999999 ~ 1
// sin(0°)
console.log(Math.sin(0)); // Output: 0
// sin(90°)
console.log(Math.sin(Math.PI / 2)); // Output: 1
// cos(0°)
console.log(Math.cos(0)); // Output: 1
// cos(180°)
console.log(Math.cos(Math.PI)); // Output: -1
// tan(0°)
console.log(Math.tan(0)); // Output: 0
Convert Between Degrees and Radians
// Convert degrees to radians
function degreesToRadians(degrees) {
return degrees * (Math.PI / 180);
}
console.log(degreesToRadians(90)); // Output: 1.5707963267948966 (π/2 radians)
// Convert radians to degrees
function radiansToDegrees(radians) {
return radians * (180 / Math.PI);
}
console.log(radiansToDegrees(Math.PI)); // Output: 180 degrees
Trigonometric Functions That Accept Degrees
If you want to use degrees directly, wrap the Math
functions with conversion:
function sinDegrees(degrees) {
return Math.sin(degreesToRadians(degrees));
}
function cosDegrees(degrees) {
return Math.cos(degreesToRadians(degrees));
}
function tanDegrees(degrees) {
return Math.tan(degreesToRadians(degrees));
}
console.log(sinDegrees(30)); // Output: 0.5 (sin(30°))
console.log(cosDegrees(60)); // Output: 0.5 (cos(60°))
console.log(tanDegrees(45)); // Output: 1 (tan(45°))
Inverse Trigonometric Functions
You can find the angle from a trigonometric ratio using inverse functions like asin
, acos
, and atan
. They return results in radians.
console.log(Math.asin(0.5)); // Output: 0.5235987755982989 radians (~30°)
console.log(Math.acos(0.5)); // Output: 1.0471975511965979 radians (~60°)
console.log(Math.atan(1)); // Output: 0.7853981633974483 radians (~45°)
You can use atan2(y, x)
to get the angle between the positive x-axis and the point (x, y). It's very useful in graphics and geometry.
console.log(Math.atan2(1, 1)); // Output: 0.7853981633974483 radians (~45°)
console.log(Math.atan2(1, 0)); // Output: 1.5707963267948966 radians (~90°)
console.log(Math.atan2(0, 1)); // Output: 0 radians (~0°)
To get angles in degrees, just convert the result:
function asinDegrees(value) {
return radiansToDegrees(Math.asin(value));
}
function acosDegrees(value) {
return radiansToDegrees(Math.acos(value));
}
function atanDegrees(value) {
return radiansToDegrees(Math.atan(value));
}
console.log(asinDegrees(0.5)); // Output: 30
console.log(acosDegrees(0.5)); // Output: 60
console.log(atanDegrees(1)); // Output: 45
Practical Trigonometry Examples
// Calculate angle between two points (in radians)
function angleBetweenPoints(x1, y1, x2, y2) {
return Math.atan2(y2 - y1, x2 - x1);
}
// Get coordinates of a point on a circle’s circumference
function pointOnCircle(centerX, centerY, radius, angle) {
return {
x: centerX + radius * Math.cos(angle),
y: centerY + radius * Math.sin(angle),
};
}
console.log(angleBetweenPoints(0, 0, 1, 1)); // Output: 0.7853981633974483 (45° in radians)
console.log(pointOnCircle(0, 0, 5, Math.PI / 4)); // Output: {x: 3.5355339059327378, y: 3.5355339059327373}
Common Applications
Trigonometry is essential for:
- Game Development: Character movement, physics simulations, collision detection
- Animation: Smooth transitions, circular motion, wave effects
- Data Visualization: Creating charts, graphs, and interactive visualizations
- Graphics Programming: 2D/3D transformations, rotations, scaling
- User Interface: Drag-and-drop interactions, gesture recognition
- Audio Processing: Sound wave generation, frequency analysis
Random Numbers
Basic Random Number Generation
Math.random()
returns a value between 0 and 1 (exclusive of 1):
console.log(Math.random()); // e.g., 0.39245424142783303
Random integer between 0 and max (exclusive):
function randomInt(max) {
return Math.floor(Math.random() * max);
}
console.log(randomInt(10)); // 0-9
Here,
Math.random()
gives a decimal between 0 (inclusive) and 1 (exclusive), like 0.7834.- Multiplying it by
max
gives a number between 0 and just undermax
, e.g., 0.7834 * 10 = 7.834. Math.floor(...)
rounds it down to the nearest whole number, so 7.834 becomes 7.- So if you pass 10, you get a random integer from 0 to 9, inclusive of 0, exclusive of 10.
Random integer between min and max (inclusive):
function randomIntRange(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(randomIntRange(5, 15)); // 5-15
Here,
Math.random()
generates a decimal between 0 (inclusive) and 1 (exclusive).- Multiplying it by
(max - min + 1)
gives a range from 0 up to (but not including)max - min + 1
. Math.floor(...)
converts that to an integer between 0 and(max - min)
.- Adding
min
shifts that range up, so the final result is frommin
tomax
(inclusive). - So
randomIntRange(5, 15)
returns a random integer between 5 and 15, inclusive on both ends.
Random float between min and max:
function randomFloat(min, max) {
return Math.random() * (max - min) + min;
}
console.log(randomFloat(1.5, 3.5)); // 1.5-3.5
Here,
Math.random()
gives a float between 0 (inclusive) and 1 (exclusive).- Multiplying it by
(max - min)
scales that to a range from 0 to just below(max - min)
. - Adding
min
shifts the result up, so the final range becomes frommin
to just belowmax
. - So
randomFloat(1.5, 3.5)
returns a floating-point number ≥ 1.5 and < 3.5.
Picking Random Elements
Random Item from Array:
function randomElement(array) {
return array[Math.floor(Math.random() * array.length)];
}
const colors = ["red", "blue", "green", "yellow"];
console.log(randomElement(colors)); // e.g., "green"
Here,
Math.random()
generates a float between 0 (inclusive) and 1 (exclusive).- Multiplying it by
array.length
gives a number between 0 and just below the array’s length. Math.floor(...)
converts that to a valid index between 0 andarray.length - 1
.- The function returns the element at that randomly chosen index.
- So each call returns a random element from the
colors
array.
Multiple Random Items (No Repeats):
function randomElements(array, count) {
const shuffled = [...array].sort(() => 0.5 - Math.random());
return shuffled.slice(0, count);
}
const colors = ["red", "blue", "green", "yellow"];
console.log(randomElements(colors, 2)); // e.g., ["blue", "red"]
Here,
[...]
creates a shallow copy of the original array..sort(() => 0.5 - Math.random())
randomly shuffles the array.- It uses a common but non-ideal trick to shuffle: each element gets a random sort value.
- This is not perfectly uniform, but works reasonably well for small arrays.
.slice(0, count)
picks the first count elements from the shuffled array.- This returns 2 random elements from the
colors
array, without duplicates.
Random Boolean:
function randomBoolean(probability = 0.5) {
return Math.random() < probability;
}
console.log(randomBoolean(0.3)); // true ~30% of the time
Here,
Math.random()
returns a random number between 0 (inclusive) and 1 (exclusive).- If that number is less than the
probability
, the result istrue
; otherwise, it'sfalse
. - The default
probability
is 0.5, so it returnstrue
roughly 50% of the time if no argument is passed. randomBoolean(0.3)
gives you atrue
with ~30% chance andfalse
with ~70% chance.
Random String Generator:
function randomString(
length,
chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
) {
let result = "";
for (let i = 0; i < length; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length));
}
return result;
}
console.log(randomString(8)); // e.g., "X7Ab3KqL"
Here,
chars
: Defaults to uppercase A–Z, lowercase a–z, and digits 0–9. You can override it to include symbols or limit to just letters or digits.Loop
: Runs length times.Math.random() * chars.length
: Picks a random index from thechars
string.chars.charAt(...)
: Gets the character at that random index.result += ...
: Builds the string character by character.- If length = 8, you might get something like "X7Ab3KqL".
- Each run will return a different random string of the given length.
Security Considerations
Important: Math.random()
is not cryptographically secure. For security-sensitive applications (passwords, tokens, cryptographic keys), use crypto.getRandomValues()
instead:
// NOT secure - don't use for passwords or tokens
const insecureRandom = Math.random();
Secure random generation:
function secureRandom() {
const array = new Uint32Array(1);
crypto.getRandomValues(array);
return array[0] / (0xffffffff + 1); // Convert to 0-1 range
}
Here,
Uint32Array(1)
creates a 32-bit unsigned integer array.crypto.getRandomValues(...)
fills it with a cryptographically secure random value.- Dividing by
0xFFFFFFFF + 1
normalizes it to a float between 0 and 1 (just likeMath.random()
but secure).
Generate secure random string:
function secureRandomString(length) {
const chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
const array = new Uint8Array(length);
crypto.getRandomValues(array);
return Array.from(array, (byte) => chars[byte % chars.length]).join("");
}
console.log(secureRandomString(12)); // e.g., "X7Ab3KqLmN9P"
Here,
chars
contains allowed characters (62 total: A–Z, a–z, 0–9).Uint8Array(length)
creates a byte array of the desired string length.crypto.getRandomValues(...)
fills it with secure random bytes.- Each byte is mapped to a character using
byte % chars.length
. Array.from(...).join('')
combines the characters into a random string.
Advanced Math Functions
Sign and Comparison Functions
Math.sign()
:
Returns the sign of a number:
-1
for negative numbers1
for positive numbers0
for zeroNaN
if input isn’t a number
console.log(Math.sign(-5)); // Output: -1
console.log(Math.sign(0)); // Output: 0
console.log(Math.sign(5)); // Output: 1
console.log(Math.sign(NaN)); // Output: NaN
Custom comparison functions:
isEven(n)
:
Returns true
if a number is even.
function isEven(n) {
return n % 2 === 0;
}
console.log(isEven(4)); // Output: true
isOdd(n)
:
Returns true
if a number is odd.
function isOdd(n) {
return n % 2 !== 0;
}
console.log(isOdd(3)); // Output: true
isPrime(n)
:
Checks whether a number is prime. It returns false for numbers < 2
. Otherwise, it tests divisibility up to the square root of n.
function isPrime(n) {
if (n < 2) return false;
for (let i = 2; i <= Math.sqrt(n); i++) {
if (n % i === 0) return false;
}
return true;
}
console.log(isPrime(17)); // Output: true
Hyperbolic Functions
Hyperbolic functions are like trigonometric functions but for hyperbolas instead of circles.
console.log(Math.sinh(1)); // Output: 1.1752011936438014
console.log(Math.cosh(1)); // Output: 1.5430806348152437
console.log(Math.tanh(1)); // Output: 0.7615941559557649
Inverse hyperbolic functions:
console.log(Math.asinh(1)); // Output: 0.881373587019543
console.log(Math.acosh(2)); // Output: 1.3169578969248166
console.log(Math.atanh(0.5)); // Output: 0.5493061443340548
Hyperbolic functions are useful for:
- Describing catenary curves (hanging cables)
- Calculating hyperbolic distances
- Some physics and engineering applications
Floating Point Functions
Math.fround()
:
Rounds a number to the nearest 32-bit float (useful for performance or precision comparisons).
console.log(Math.fround(1.5)); // Output: 1.5
console.log(Math.fround(1.337)); // Output: 1.3370000123977661
Math.imul()
:
Performs 32-bit integer multiplication, which is faster than regular multiplication for some low-level operations.
console.log(Math.imul(3, 4)); // Output: 12
console.log(Math.imul(0xffffffff, 5)); // Output: -5
Why -5?
0xffffffff
is 2³² - 1
(unsigned), but interpreted as -1 in signed 32-bit integer.
Math.clz32()
:
Returns the number of leading zero bits in a 32-bit integer.
console.log(Math.clz32(1)); // Output: 31 → binary: 000...0001
console.log(Math.clz32(1000)); // Output: 22 → binary: 00000000 00000000 00000011 11101000
This is useful in bitwise operations, graphics programming, or performance optimization.
Browser Compatibility
Most Math functions have excellent browser support and work in all modern browsers. However, some newer functions may need polyfills for older browsers:
Math.trunc()
,Math.sign()
,Math.cbrt()
- Need polyfills for IE- Hyperbolic functions (
Math.sinh()
,Math.cosh()
, etc.) - Need polyfills for IE Math.imul()
,Math.fround()
,Math.clz32()
- Need polyfills for IE
For production applications targeting older browsers, consider using a polyfill library like core-js or implement simple fallbacks:
// Simple polyfill for Math.trunc
if (!Math.trunc) {
Math.trunc = function (x) {
return x < 0 ? Math.ceil(x) : Math.floor(x);
};
}
Floating Point Precision
JavaScript uses 64-bit floating point numbers (IEEE 754 standard) for all its numeric calculations. This gives it a wide range of precision, but also introduces a classic issue: not all decimal numbers can be represented exactly.
console.log(0.1 + 0.2); // Output: 0.30000000000000004 (not 0.3!)
console.log(0.1 + 0.2 === 0.3); // Output: false
Why?
Because numbers like 0.1 and 0.2 can't be stored with perfect accuracy in binary. So when you add them, the result is almost 0.3, but not exactly.
How to Handle Precision Issues
1. Use Epsilon for Comparisons:
If two numbers are very close, you can check whether their difference is within a small allowed error (epsilon):
function isEqual(a, b, epsilon = Number.EPSILON) {
return Math.abs(a - b) < epsilon;
}
console.log(isEqual(0.1 + 0.2, 0.3)); // Output: true
Number.EPSILON
is the smallest difference JavaScript can reliably detect between two numbers. Perfect for floating-point comparisons.
2. Round to Fixed Decimal Places:
For visual accuracy or simplified values, round the result manually:
function roundToDecimal(num, decimals) {
return Math.round(num * 10 ** decimals) / 10 ** decimals;
}
console.log(roundToDecimal(0.1 + 0.2, 1)); // Output: 0.3
This multiplies the number, rounds it, and then divides it back. Handy for quick fixes when precision matters visually or in reports.
3. Format for Display Using toFixed()
:
If you just need to display the number nicely (not for further math), use toFixed()
and parse it back:
function formatNumber(num, decimals = 2) {
return parseFloat(num.toFixed(decimals));
}
console.log(formatNumber(0.1 + 0.2)); // Output: 0.3
toFixed()
returns a string, so you use parseFloat()
to turn it back into a number.
Be especially careful with:
- Financial calculations (where even a 0.01 difference matters) (consider using libraries like decimal.js).
- Iterative calculations where errors can accumulate.
- Strict equality comparisons (
===
) between results of arithmetic expressions.