Нам нужно реализовать итеративно. Если мы реализуем рекурсивно, это вызовет StackOverflow, если ввод станет очень большим (то есть 2 миллиарда). И нам нужно использовать число несвязанного размера, такое как BigInteger, чтобы избежать арифметического переполнения, когда факториальное число становится больше максимального числа данного типа (то есть 2 миллиарда для целого). Вы можете использовать int для максимум 14 факториалов и long для максимум 20
факториала до переполнения.
public BigInteger getFactorialIteratively(BigInteger input) {
if (input.compareTo(BigInteger.ZERO) <= 0) {
throw new IllegalArgumentException("zero or negatives are not allowed");
}
BigInteger result = BigInteger.ONE;
for (BigInteger i = BigInteger.ONE; i.compareTo(input) <= 0; i = i.add(BigInteger.ONE)) {
result = result.multiply(i);
}
return result;
}
Если вы не можете использовать BigInteger, добавьте проверку ошибок.
public long getFactorialIteratively(long input) {
if (input <= 0) {
throw new IllegalArgumentException("zero or negatives are not allowed");
} else if (input == 1) {
return 1;
}
long prev = 1;
long result = 0;
for (long i = 2; i <= input; i++) {
result = prev * i;
if (result / prev != i) { // check if result holds the definition of factorial
// arithmatic overflow, error out
throw new RuntimeException("value "+i+" is too big to calculate a factorial, prev:"+prev+", current:"+result);
}
prev = result;
}
return result;
}