Reputation: 650
Why does this java code throw a StackOverflowError
exception?
public class factorial2 {
public BigInteger fact( BigInteger n)
{
BigInteger one = new BigInteger("1");
if(n.equals("0"))
return one;
else
return n.multiply(fact(n.subtract(one)));
}
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
factorial2 f = new factorial2();
for(int i=0;i<n;i++)
{
BigInteger b = sc.nextBigInteger();
System.out.println(f.fact(b));
}
sc.close();
}
}
I have attempted to generate a factorial using BigInteger
. But, why does my code give the reference exception on input?
Upvotes: 4
Views: 1276
Reputation: 201497
The issue is with your base case; n
(which is a BigInteger
) will not equal "0"
(which is a String
). So you continue to the else
block, which re-curses. Also, BigInteger
includes constants for ONE
and ZERO
so you could write something like
public static BigInteger fact(BigInteger n) {
if (n.equals(BigInteger.ZERO) || n.equals(BigInteger.ONE))
return BigInteger.ONE;
else
return n.multiply(fact(n.subtract(BigInteger.ONE)));
}
or using a ternary operation (conditional operator ? :
) like
public static BigInteger fact(BigInteger n) {
return (n.equals(BigInteger.ZERO) || n.equals(BigInteger.ONE)) ? BigInteger.ONE
: n.multiply(fact(n.subtract(BigInteger.ONE)));
}
Upvotes: 5
Reputation: 11619
BigInteger#equals method
public boolean equals(Object x) {
// This test is just an optimization, which may or may not help
if (x == this)
return true;
if (!(x instanceof BigInteger))
return false;
This condition is always false
if (n.equals("0"))
Instead, use
if (BigInteger.ZERO.equals(n))
Upvotes: 2