尝试在递归Java函数调用中放置catch



试图找出在放置递归调用时放置try-catch语句的最佳位置。阶乘计算是用长数据类型完成的。当阶乘变得太大而无法放入长变量时,期望抛出异常。

然而,只要factorial过大,代码就会显示它为0。没有引发异常。那么,试跳接球的位置有问题吗?还是大数字的投球也不例外?

class Fact
{
    static 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);
    }
}
}

整数溢出在Java中不会引发任何异常。整数除以零会抛出ArithmeticException,但不会溢出。

这个问题现在已经演变成了"为什么会返回零?"答案是这只是一个巧合。如果你这样修改功能:

static long fact(long n)
{
   if(n==1)
       return 1;
    long result =  n*fact(n-1);
    System.out.println(n + ", " + result);
    return result;
}

然后看看输出,你会得到(我删除了中间和结尾的一些行(:

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
...

一旦它达到零,它就永远是零。在反弹并溢出几次后,您的产品只是意外地碰到了一个最低有效64位中有0的数字。奇怪,但却是真的。

static long fact(long n) throws Exception
    {
       if (//when you want to throw exception){
           throw new Exception();
       }
       if(n==1)
           return 1;
    }

若你们想抛出这样一个异常,你们应该手动抛出它。顺便说一句,事实根本不是递归的,也不会像你们期望的那样。

编写的代码将始终返回1。我确信你的意思是有一个return n*fact(n-1)的其他块,但我看不出来。

你可能溢出了很长时间。我建议你不要用这种方法计算阶乘。更好地使用gamma函数进行编码并加倍:

http://mathworld.wolfram.com/GammaFunction.html

最新更新