2

我正在尝试通过对以下数字系列求和来制作一个近似 e 的程序:

e = 1 + (1 / 1!) + (1 / 2!) + (1 / 3!) .... + (1 / i!)

目前,我的代码如下所示:

public static void main(String[] args) {

        BigDecimal one = new BigDecimal(1);
        BigDecimal e = new BigDecimal(1.0);
        BigDecimal divisor = new BigDecimal(1.0);

        for (int i =  1; i <= 12; i++) {

            divisor = divisor.multiply(new BigDecimal(i));
            e = e.add(one.divide(divisor));

            System.out.println("e = " + e);

        }
    }

该程序成功执行计算(1 / n!)为 n <= 2,但只要 n >= 3 我收到一条错误消息。似乎程序无法处理大于 2 的除数。程序的输出是:

e = 2

e = 2.5

线程“主”java.lang.ArithmeticException 中的异常:非终止十进制扩展;没有精确可表示的十进制结果。在 java.math.BigDecimal.divide(Unknown Source) at ch10.Chapter_10_E20_ApproximateE.main(Chapter_10_E20_ApproximateE.java:16)

我应该如何使用 BigDecimal 类对 e = 1 + (1 / 1!) + (1 / 2!) + (1 / 3!) .... + (1 / i!) 进行求和?

4

2 回答 2

3

众所周知,除以3产生一个永远持续的十进制表示的数字。

0.5 / 3 = 0.166666666666666666666666666666666666666666666666666666666666666666....

这就像您在 内部的除法一样BigDecimal,除了int正在计算二进制形式的 s 。

您将需要一个不同的重载divide,需要使用比例(小数点后的小数位数)和舍入模式。这告诉了BigDecimal要使用多少位数以及停止时如何舍入。

e = e.add(one.divide(divisor, 20, RoundingMode.HALF_EVEN));

输出的最终估计e

e = 2.71828182828616856395
于 2016-04-20T17:48:10.903 回答
1

出现此错误的原因是 BigDecimal 试图准确计算该值,但它无法做到这一点,因为 1/3 在基数 10 中永远重复。

要解决此问题,您需要定义精度和舍入模式。例如:

  e = e.add( one.divide(divisor, 20, RoundingMode.HALF_UP) );
于 2016-04-20T17:48:43.377 回答