0

我正在尝试使用 BigDecimals 以高精度计算欧拉数,但过了一会儿,数字变得如此之小,以至于 JVM 抛出除以 0 错误。关于如何克服的任何想法?我发现 try-catch 块总是在 34 次除法迭代之后被调用,但我不知道为什么。欧拉数的公式是一个无限级数,因此 34 次迭代使其接近e的实际值,但不如我想要的准确。它实际上并不是除以 0,但对于 JVM 来说它可能太小而无法区分。

    BigDecimal ee = BigDecimal.ZERO;
    for (int k = 0; k < 50; k++) {
        int fact = factorial(k);
        try {
            BigDecimal trial = BigDecimal.ONE.divide(BigDecimal.valueOf(fact), 100, RoundingMode.CEILING);
        } catch (Exception e) {
            System.out.println("---- Div-by-0 error; Iterated " + k + " times ----");
            break;
        }
        ee = ee.add(BigDecimal.ONE.divide(BigDecimal.valueOf(fact), 100, RoundingMode.CEILING));
    }
    System.out.println("\n---- Final: \t\te = " + power(ee, x));
}
4

2 回答 2

2

你的阶乘计算溢出了。您的factorial方法必须返回int,因为您已将该方法的返回值分配给int.

开始13时会发生溢出。13!是 6,227,020,800,第一个因数值太大而无法在int. 溢出将此值表示为1932053504。当附加值变为负数时,问题变得更糟,例如 17!计算为-288522240

最终,2在乘积中积累了足够多的因子,所有1位都从末尾移开,离开0(从 34 开始!)。这就是导致您被零错误除法的原因。

但这只是更早发生的溢出的症状。用于BigDecimal阶乘计算以避免溢出并保持精度。那BigDecimal可以直接传递给divide而无需转换。

于 2019-10-16T19:50:13.380 回答
0

我认为您没有使用正确的数据类型来存储值。使用 BigInteger,因为它最多可以存储 100 个!其中的价值。

整数最大值:整数 4 字节 -2,147,483,648 到 2,147,483,647。

由于您分配的值高于限制,因此它将循环回负数,并可能在某些时候导致 0。

阶乘的值:

01!= 1 02!= 2 03!= 6 04!= 24 05!= 120 12!= 479001600

Int 的最大值 -- 2147483647

13!= 6227020800

于 2019-10-16T20:15:10.387 回答