/* In the following method, why the factorial goes wrong when n>12 ? */
static int factorial(int n){
int fac=1;
if ((n<0) || (n>12))
return -1;
for (int i=2; i<=n;i++)
fac *=i;
return fac;
}
/* In the following method, why the factorial goes wrong when n>12 ? */
static int factorial(int n){
int fac=1;
if ((n<0) || (n>12))
return -1;
for (int i=2; i<=n;i++)
fac *=i;
return fac;
}
Please write your code in the code-tags.
I don't see anything is wrong. What do you want to do with this method? You made a method that returns -1 if n > 12. So you can't compute the factorial when n > 12.
Thank you for your attention. My intention is to remind programmer about the Integer.MAX_VALUE, i.e. the limits in representing a value in Java. I belive the above code is correct as you agree. This means that the method is not valid if it returns -1 when n>12.
The factorial of 12 is 479001600
The factorial if 13 is 6227020800
if we use int to represent the result for 13, it would be 1932053504 which is wrong.
The maximum value a int can hold in java is 2,147,483,647 while
13! = 6,227,020,800.
So you see that an int cannot hold 13! or higher. Its only big enough to hold 12! or less.
If we use the long type to hold the factorial values, the output will be:
Factorial of 2 : 2
Factorial of 3 : 6
Factorial of 4 : 24
Factorial of 5 : 120
Factorial of 6 : 720
Factorial of 7 : 5040
Factorial of 8 : 40320
Factorial of 9 : 362880
Factorial of 10 : 3628800
Factorial of 11 : 39916800
Factorial of 12 : 479001600
Factorial of 13 : 6227020800
Factorial of 14 : 87178291200
Factorial of 15 : 1307674368000
Factorial of 16 : 20922789888000
Factorial of 17 : 355687428096000
Factorial of 18 : 6402373705728000
Factorial of 19 : 121645100408832000
Factorial of 20 : 2432902008176640000
Factorial of 21 : -4249290049419214848
The Long.MAX_VALUE is 9223372036854775807
which means, long type may hold the value of Factorial of 20 at most. It cannot hold the Factorial of 21.
For all scenarios dealing with arbitrary precision calculations use BigInteger/BigDecimal.
class FactorialCalculator {
public BigInteger compute(int num) {
if(num < 0) {
throw new IllegalArgumentException("negative number passed for factorial computation");
}
if(num < 2) {
return BigInteger.ONE;
}
BigInteger factorial = BigInteger.ONE;
while(num > 1) {
factorial = factorial.multiply(BigInteger.valueOf(num--));
}
return factorial;
}
}
BTW, for coding something which requires factorials, maintaining a hash of the number and its factorial is much more efficient as compared to computing it every time a factorial is request.
Thank you very much indeed for your comments.
I have created a driver program accordingly as follows.
import java.math.*;
class FactorialCalculator {
public static BigInteger compute(int num) {
if(num < 0) {
throw new IllegalArgumentException("negative number passed for factorial computation");
}
if(num < 2) {
return BigInteger.ONE;
}
BigInteger factorial = BigInteger.ONE;
while(num > 1) {
factorial = factorial.multiply(BigInteger.valueOf(num--));
}
return factorial;
}
public static void main(String args[]){
for (int i=2; i<25;i++)
System.out.println("The " + i + " ! is: "
+ compute(i));
}
}
And the following output is obtained:
The 2 ! is: 2
The 3 ! is: 6
The 4 ! is: 24
The 5 ! is: 120
The 6 ! is: 720
The 7 ! is: 5040
The 8 ! is: 40320
The 9 ! is: 362880
The 10 ! is: 3628800
The 11 ! is: 39916800
The 12 ! is: 479001600
The 13 ! is: 6227020800
The 14 ! is: 87178291200
The 15 ! is: 1307674368000
The 16 ! is: 20922789888000
The 17 ! is: 355687428096000
The 18 ! is: 6402373705728000
The 19 ! is: 121645100408832000
The 20 ! is: 2432902008176640000
The 21 ! is: 51090942171709440000
The 22 ! is: 1124000727777607680000
The 23 ! is: 25852016738884976640000
The 24 ! is: 620448401733239439360000