对于大输入,递归阶乘返回0

时间:2016-02-01 15:26:50

标签: recursion factorial

以下Java代码返回的答案是variables = who; toexclude = {'variable1', 'variable2'}; variables = variables(~ismember(variables, toexclude)); save(output_file, variables{:}); 。任何人都可以帮我找到错误吗?

0

3 个答案:

答案 0 :(得分:1)

最大值int可以包含2 ^ 32和1000!对于int而言,它太大了。您可以使用java.math.BigInteger来实现此目的。 BigInteger类分配尽可能多的内存来保存它所要保存的所有数据位。但是,有一些实际限制,由可用内存决定。

使用BigInteger,您的代码有点像:

import java.math.BigInteger;

public class ComplexityOrder {  

    public static void main(String[] args) {    
        ComplexityOrder co = new ComplexityOrder();
        co.Order(1000);   
    }

    public BigInteger Order(int n) {
        BigInteger[] a = new BigInteger[10];
        a[0] = fact(n);
        System.out.println("Factorial " + a[0]);
        return a[0];    
    }

    public static BigInteger fact(int n) {
        if (n == 0 || n ==1) {
            return BigInteger.ONE;
        } else {
            return fact(n-1).multiply(BigInteger.valueOf(n));
        }
    }    
}

另外,我没有看到使用数组的任何意义。

答案 1 :(得分:0)

这是因为int变量的溢出最多包含number = 2 ^ 32,而Fact(1000)大于Max int,如果你没有获得数字leas而不是100,你可以使用BigInteger类而不是int ,如果你获得大数字,你必须实现你的字符串添加功能,以避免溢出。

答案 2 :(得分:0)

更具体......

您正在使用标准整数, n 位符号二进制数。然后你计算1000!与任何标准整数表示相比,这是非常大数。主要因子分解包括2 ^ 994。这意味着结果数字以二进制形式结尾,以994个字符串结束。

当整数溢出不作为异常处理时,条件是一种非正式的方式来减少你的结果mod 2 ^ n,其中n是内部表示的长度,通常是32或64位,然后映射较高的一半范围为负数。以至少n个零结尾的数字将减少为0(mod 2 ^ n)。这就是你的情况,因为你的计算机没有1024位整数。 : - )

正如其他人已经建议的那样,您可以通过切换到BigInteger并调整类来处理扩展范围来处理此容量。请注意,它会慢得多,因为您超出了硬件的本机整数范围,并且处理类似于在2 ^ n基础上手动执行所有操作。 “记下00110111001010010110110001010110,携带1,然后进入下一栏。” : - )