- Expand
5·4·3·2·1
Find Factorial in JavaScript
What you’ll learn
- The definition of
n!forn ≥ 0, including0! = 1. - A recursive solution matching the classic interview style, plus an iterative equivalent.
- Overflow limits for JavaScript
Number(Number.MAX_SAFE_INTEGER), input validation, and a small live preview.
Overview
Factorial grows faster than any exponential. A correct small-n program is easy; a robust one also checks n ≥ 0, watches overflow, and picks recursion or a loop based on constraints.
Two programs
Recursive (5! = 120) and iterative with the same result.
Live preview
Exact integers for 0 ≤ n ≤ 20 in this widget (fits exact Number).
Rigor
Guards for negative inputs and 21+ where n! exceeds Number.MAX_SAFE_INTEGER.
Prerequisites
Functions, if, multiplication, and optional for loops.
console.log,Number.isSafeInteger, and template literals or string concatenation for output.- Awareness that floating-point
Numberloses integer precision above253-1.
What is factorial?
For an integer n ≥ 0, n! is the product of every integer from 1 through n. When n = 0, that is the empty product, defined as 1, so 0! = 1.
Factorials count permutations: n! is the number of ways to order n distinct objects. They appear in Taylor series, binomial coefficients, and probability.
Formal definition
Define 0! = 1 and, for n ≥ 1, n! = n · (n-1)!. Equivalently n! = ∏k=1n k.
5!5 × 4 × 3 × 2 × 1 = 120.
Intuition
- Step
6 · 5!
Takeaway: each increment of n multiplies the previous factorial by n, which is why values explode in size.
Live preview
Exact factorial for 0 ≤ n ≤ 20 (matches exact Number range before 21! exceeds Number.MAX_SAFE_INTEGER).
Algorithm
Goal: compute n! for nonnegative n within a chosen numeric type.
Base case
If n ≤ 1, return 1 (covers 0! and 1!).
Recurrence or loop
Otherwise multiply n by (n-1)!, or initialize result = 1 and absorb factors 2..n in a loop.
📜 Pseudocode
function factorial(n): // assume n >= 0
if n <= 1:
return 1
return n * factorial(n - 1)Recursive factorial
Classic recursion with number = 5 and a safe upper bound FACT_MAX so every intermediate product stays an exact JavaScript integer.
const FACT_MAX = 20;
function calculateFactorial(num) {
if (num === 0 || num === 1) {
return 1;
}
return num * calculateFactorial(num - 1);
}
const number = 5;
if (number < 0) {
console.log("Factorial is not defined for negative integers here.");
} else if (number > FACT_MAX) {
console.log(
"n too large for exact Number in this demo (max " + FACT_MAX + ")."
);
} else if (!Number.isSafeInteger(number)) {
console.log("Use a JavaScript safe integer for n.");
} else {
const result = calculateFactorial(number);
console.log("Factorial of " + number + " is: " + result);
}Explanation
Each call shrinks num until the base case; the products bubble back up. Keeping n ≤ 20 ensures no intermediate loses precision as a Number.
Iterative factorial
Same numeric result for n = 5, with O(1) auxiliary space and no call-stack depth proportional to n.
const FACT_MAX = 20;
function factorialIter(n) {
let r = 1;
for (let i = 2; i <= n; i++) {
r *= i;
}
return r;
}
const number = 5;
if (number < 0) {
console.log("Factorial is not defined for negative integers here.");
} else if (number > FACT_MAX) {
console.log(
"n too large for exact Number in this demo (max " + FACT_MAX + ")."
);
} else if (!Number.isSafeInteger(number)) {
console.log("Use a JavaScript safe integer for n.");
} else {
console.log("Factorial of " + number + " is: " + factorialIter(number));
}Explanation
The loop multiplies 1 by every integer from 2 through n. For n in {0,1}, the loop body never runs and r stays 1.
Optimization and scaling
Bigger values. Use BigInt (1n and * BigInt(i)), arbitrary-precision libraries, logarithms of gamma for floating approximations, or prime-factor exponent tables for exact huge factorials—not widening Number alone.
Prime swing / split recursion. Advanced algorithms reduce the number of large multiplications; overkill for basic interviews.
Interview: state overflow, validate n ≥ 0, and compare recursion depth vs loop.
❓ FAQ
🔄 Input / output examples
Change number in either example (within 0..20 for exact Number here).
| n | n! |
|---|---|
0 | 1 |
1 | 1 |
5 | 120 |
20 | 2432902008176640000 |
Edge cases and pitfalls
Floating-point overflow becomes Infinity; precision loss appears as rounded digits. Bound n or use BigInt before that happens.
n < 0
Not the standard factorial; reject or map to an error instead of recursing.
21! and beyond
Exceeds Number.MAX_SAFE_INTEGER; use BigInt or reduce the problem (e.g. trailing zeros modulo).
Deep recursion
Even when n fits in a type, very large n can overflow the call stack before the integer limit does.
Number result
13! already exceeds 231-1; wide integers or BigInt matter for exact factorials beyond toy ranges.
⏱️ Time and space complexity
| Version | Time | Extra space |
|---|---|---|
| Recursive | O(n) multiplications | O(n) call frames |
| Iterative | O(n) multiplications | O(1) |
Both approaches use Θ(n) arithmetic operations for exact n!; only the hidden stack differs.
Summary
- Definition:
0! = 1andn! = n·(n-1)!forn ≥ 1. - Code: recursion matches the classic template; iteration saves stack depth.
- Watch-outs: negatives undefined, exact
Numbercaps near20!, useBigIntbeyond.
Stirling's approximation describes how fast n! grows: asymptotically n! ∼ √(2πn) · (n/e)n. It is standard in analysis even when the exact integer no longer fits in fixed-precision types.
8 people found this page helpful
