【问题标题】:Java: When dividing by factorials, how do I store the factorial? Its too large to be doubleJava:除以阶乘时,如何存储阶乘?它太大而不能加倍
【发布时间】:2013-10-25 08:38:58
【问题描述】:

我是 java 新手,我的程序可能远没有它应有的效率,但这里是:

public class Compute {
public static void main(String[] args) {
    for(double i = 10000; i <= 100000; i += 10000)
    {
        System.out.println("The value for the series when i = " + i + " is " + e(i));
    }
}
public static double e(double input) {
    double e = 0;
    for(double i = 0; i <= input; i++)
    {
        e += 1 / factorial(input);
    }
    return e;
}
public static double factorial(double input) {
    double factorial = 1;
    for(int i = 1; i <= input; i++)
    {
        factorial *= i;
    }
    return factorial;
}
}

我相信这会计算 i = 10000, 20000, ..., & 100000 的值 e。
其中 e = 1 + (1/1!) + (2/2!) + ... + (1/i!)
这样做大约需要 47 秒,但我相信它有效。

我的问题是,对于每个 i,结果总是 0.0
我相信这是因为每当调用阶乘方法时,返回值太大而无法存储,这会导致问题。

如何存储Factorial方法返回的值?

【问题讨论】:

  • 100000! has 456,574 digits。在不知道您实际上想要完成什么的情况下,任何人都很难以有意义的方式回答您的问题。
  • 它是用于家庭作业的,这本书几乎一字不差地讲述了我在代码下所说的关于给定系列 e 为 i 计算 e 的内容。我希望这是有道理的,我不确定如何使它更容易理解。 ://
  • 正如 Jim Garrison 所指出的,如果您想如此精确地计算 e,以至于在系列中使用 100000 项会有所不同,您需要将其存储在双精度之外的其他东西中。如果您确实需要 400000 位小数的答案,您应该考虑使用 BigInteger 作为阶乘,使用 BigDecimal 作为阶乘的倒数和部分总和。
  • 当你的数字与双精度数一样多时,你可以停止。

标签: java series


【解决方案1】:

虽然你可以用BigDecimal计算任意精度的结果,但是对于e的级数展开,不需要计算到100000!。考虑到系列中的第 20 项 (20/20!) 的量级约为 10-19,因此它对整体总数的贡献微不足道。

换句话说,20 位之后的任何项的贡献只会改变小数点后 19 位之后的数字。

【讨论】:

  • +1。我认为也许家庭作业的想法是学生自己会发现,如果要将结果存储在双精度中,则使用 e 的级数展开最多 100000 项是浪费时间。你的所作所为破坏了惊喜!
【解决方案2】:

您可能应该使用java.math.BigInteger 来存储阶乘。

【讨论】:

  • 不知道为什么投反对票。我相信您应该能够轻松计算 10000 甚至更大的数的阶乘。
  • 有时有助于理解 OP 的目标。在计算 e 的级数近似时,不需要计算那么大的阶乘。
【解决方案3】:

改变这个

e += 1 / factorial(input);

e += 1 / factorial(i);

要加快代码速度,还有很多工作要做。想想(i+1)! vs i!,不要每次都重新计算整个阶乘。

当答案的变化小于 Jim 所说的所需精度时,也停止计算。

【讨论】:

  • 他要求“其中 e = 1 + (1/1!) + (2/2!) + ... + (1/i!)”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-19
  • 2016-01-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多