Java 为什么在1676年之后这个阶乘方法失败了?

Java 为什么在1676年之后这个阶乘方法失败了?,java,performance,int,biginteger,Java,Performance,Int,Biginteger,我使用biginger(由于long的限制)创建了一个阶乘方法,它是“无限的”,但由于某些原因,当n>1676(返回值为n!)时,返回值将不会打印。这是我的密码: private static BigInteger factorial (int n) { //init ans at 1 BigInteger ans = BigInteger.ONE; //multiply ans by decreasing n while (n > 1) {

我使用biginger(由于long的限制)创建了一个阶乘方法,它是“无限的”,但由于某些原因,当n>1676(返回值为n!)时,返回值将不会打印。这是我的密码:

private static BigInteger factorial (int n) {

    //init ans at 1
    BigInteger ans = BigInteger.ONE;

    //multiply ans by decreasing n
    while (n > 1) {
        ans = ans.multiply(BigInteger.valueOf(n--));
    }

    //return ans after loop
    return ans;

}

我使用了迭代方法而不是递归方法,因为我不想引起
堆栈溢出异常
。 以下是我所知道的:
factorial(1676).toString().length()是4679
,远低于int甚至short溢出限制。 然而,
System.out.println(factorial(1676))
工作正常,而
System.out.println(factorial(1677)
根本不打印任何内容。
这就是我所知道的,如果可以请帮助我。

Whell,你的算法是正确的,在我的机器下工作正常。如果你对一些增强感兴趣,你可以使用pararell处理。因为你可以将其分为子工厂, 比如:

您可以将此列表拆分为多个子列表:

n! = k*l*h
在哪里

其要点是计算子模块,然后对它们进行分解

在这里,这个话题不久前得到了回答:

无法复制。我的建议是使用调试器或添加一些打印语句,以查看它的确切位置。“我使用迭代方法而不是递归方法,因为我不想导致堆栈溢出”–1700个堆栈帧?如果您的Java VM实现无法处理这样一个微不足道的函数的1700个堆栈帧,那将是令人伤心的。@NPE的确如此。OP的代码为我工作了至少300000个。也许OP是在一些小的东西上运行的。您的问题可能很简单,一行太长,IDE无法打印。请尝试打印
“完成”
而不是数字,或者
f.toString().substring(01000))
或者,为了得到完整的数字,使用
System.out.println(str.substring(i,i+1000))
循环。这是Java 8中的一行:
返回IntStream.range(2,n+1).parallel().mapToObj(biginger::valueOf).reduce(biginger::multiply).orElse(biginger.one)。然而,计算数字不是OP的问题。我只是希望我能在工作中使用JDK8:)Guava不一样:)Guava确实支持这个操作,在BigIntegerMath.factorial中进行了大量优化。@LouisWasserman我想Bari的意思是,带Guava的8之前的Java在语法上与不带Guava的Java 8不匹配:)当然,番石榴和Java8完全不同。
n! = k*l*h
k=1*2*....*k
l=(k+1)*(k+2)*...*h
h=(h+1)*...*n