Try-catch placement in a recursive Java function call
Trying to figure out the best place to put a try catch statement when a recursive call is placed. The factorial computation is done with long datatype. Expecting an exception to be thrown when the factorial becomes too huge to fit into a long variable.
However the code is showing factorial = 0 whenever it's too large. No exception is being thrown. So is there a problem with the try-catch placement or does putting over-large numbers throw no exception?
class Fact
{
sta开发者_StackOverflow中文版tic long fact(long n)
{
if(n==1)
return 1;
return n*fact(n-1);
}
public static void main(String args[])
{
try{
long f = fact(555);
System.out.println("Factorial = "+f);
}
catch(Exception e){
System.out.println("Exception = "+e);
}
}
}
Integer overflow doesn't throw any exceptions in Java. Integer divide by zero throws ArithmeticException
, but not overflow.
The question has now morphed into "Why does this return zero?" And the answer is that it's just a coincidence. If you modify the function like this:
static long fact(long n)
{
if(n==1)
return 1;
long result = n*fact(n-1);
System.out.println(n + ", " + result);
return result;
}
and then look at the output, you get (I deleted some lines in the middle and at the end):
2, 2
3, 6
4, 24
5, 120
6, 720
7, 5040
8, 40320
...
19, 121645100408832000
20, 2432902008176640000
21, -4249290049419214848
...
60, -8718968878589280256
61, 3098476543630901248
62, 7638104968020361216
63, 1585267068834414592
64, -9223372036854775808
65, -9223372036854775808
66, 0
67, 0
...
and then once it's hit zero, it's zero ever after. After bouncing around and overflowing a few times, your product just accidentally hits a number with 0s in the least significant 64 bits. Strange, but true.
static long fact(long n) throws Exception
{
if (//when you want to throw exception){
throw new Exception();
}
if(n==1)
return 1;
}
If you want to throw such an exception you should manually throw it. And by the way, fact is not recursive at all and won't do what you are expecting.
The code, as written, will always return 1. I'm sure that you mean to have an else block with return n*fact(n-1)
, but I don't see it.
You probably overflowed long. I'd recommend that you not calculate factorials this way. Better to code using the gamma function and doubles:
http://mathworld.wolfram.com/GammaFunction.html
精彩评论