Definition
- Factorial (N!) – the product of every integer from 1 up to N.
- Zero factorial – 0! = 1 because the product of no numbers is the multiplicative identity.
- Running product – initialize at 1, multiply by each counter value from 1 to N.
- Overflow – a Java
longoverflows past 20!; useBigIntegerfor arbitrary-precision results. - Negative guard – factorial is undefined for negative numbers; reject with
IllegalArgumentException.
National Bank of India calculates how many different orders N pending cheques can be processed in. The first cheque can go in any of N slots, the next in N-1 slots, and so on down to one. Multiplying those choices is exactly N!. Rajesh asks how many ways his five cheques can be arranged, and the answer is 120.
Understanding the Concepts
What is the iterative factorial algorithm?
The algorithm needs one accumulator (result) and one counter (i). The accumulator starts at 1, the multiplicative identity. The counter walks from 1 to N, and each step multiplies: result = result * i. When the loop finishes, result holds N!.
package com.bank.service;
import java.math.BigInteger;
public class FactorialCalculator {
public static BigInteger factorial(int n) {
if (n < 0) {
throw new IllegalArgumentException("Factorial undefined for negative: " + n);
}
BigInteger result = BigInteger.ONE;
for (int i = 2; i <= n; i++) {
result = result.multiply(BigInteger.valueOf(i));
}
return result;
}
public static void main(String[] args) {
System.out.println("5! = " + factorial(5));
System.out.println("0! = " + factorial(0));
System.out.println("20! = " + factorial(20));
}
}
5! = 120
0! = 1
20! = 2432902008176640000
Why does the zero case work without special code?
When N is zero, the loop condition i <= 0 is false immediately (since i starts at 2), so the body never runs and result stays at its initial value of 1. That is exactly the mathematical definition of 0!.
Why use BigInteger for banking?
Factorials grow explosively. 13! exceeds Integer.MAX_VALUE, and 21! exceeds Long.MAX_VALUE. Using a primitive type silently wraps around to a wrong or negative number. In a financial system, a silently wrong count is dangerous.
// Wrong: long overflows silently
long result = 1;
for (int i = 1; i <= 25; i++) result *= i;
System.out.println(result); // 7034535277573963776 (WRONG)
// Correct: BigInteger is exact
System.out.println(factorial(25));
// 15511210043330985984000000
What is the flowchart?
Start → Read N → result=1, i=1
│
▼
i <= N? ──No──→ Print result → End
│ Yes
▼
result = result * i
i = i + 1
└──→ back to i <= N?
What are common mistakes?
// Wrong: starting result at 0
BigInteger result = BigInteger.ZERO;
// Every multiplication gives zero!
// Correct: start at 1 (multiplicative identity)
BigInteger result = BigInteger.ONE;
How is iterative different from recursive?
The iterative version uses constant stack space and cannot overflow the stack. The recursive version matches the mathematical definition but adds one stack frame per call, risking StackOverflowError for large N. Both produce the same result.
What should a senior engineer know?
For repeated queries, cache previously computed factorials in a lookup table. For very large N, specialized libraries use divide-and-conquer multiplication (split-recursive) which is faster than the naive linear multiply chain because large BigInteger multiplications are super-linear in the number of digits.
What are common interview follow-up questions?
- How many trailing zeros does N! have? (Count factors of 5.)
- Can you compute N! modulo a prime efficiently? (Yes, just mod at each step.)
- What is the time complexity considering BigInteger multiplication cost?
Visual Overview
┌─────────┐
│ Start │
└────┬────┘
▼
┌──────────┐
│ Read N │
└────┬─────┘
▼
┌────────────────┐
│ result=1, i=1 │
└────┬───────────┘
▼
┌──────────┐ No ┌──────────────┐
│ i <= N? │──────→│ Print result │→ End
└────┬─────┘ └──────────────┘
│ Yes
▼
┌──────────────────┐
│ result=result*i │
│ i = i + 1 │
└────┬─────────────┘
└──→ back to i <= N?
Key Takeaway
Factorial of a non-negative integer N is the product of every integer from one up to N, and by definition zero factorial is one because the product of no numbers is the multiplicative identity. The iterative algorithm starts a running product at one, multiplies by each integer from one to N, and the zero case needs no special code because the loop condition fails immediately and the product stays at one.
The real-world subtlety for banking is overflow. Factorials grow astonishingly fast, and a Java long overflows past twenty factorial, silently producing a wrong or negative number. In a financial system that is unacceptable, so the computation uses BigInteger, which has arbitrary precision and never overflows. A guard clause rejects negative input because factorial is undefined there.
In a banking project at National Bank of India, an audit-sampling tool needed to know how many distinct orders a small batch of cheques could be processed in, which is exactly N!. The FactorialCalculator used BigInteger and validated the input. For five cheques it reported 120, and because BigInteger was used it stayed exact for much larger batches too.
Remember one sentence: seed the product at one because one is the multiplicative identity, and use BigInteger so the growing result never overflows.
---