使用BigDecimal计算Euler数

时间:2016-04-20 17:41:01

标签: java bigdecimal eulers-number

我试图通过总结以下数字序列来制作一个程序来近似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);

        }
    }

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

e = 2

e = 2.5

线程“main”中的异常java.lang.ArithmeticException:非终止十进制扩展;没有确切的可表示的小数结果。在ch10.Chapter_10_E20_ApproximateE.main(Chapter_10_E20_ApproximateE.java:16)

的java.math.BigDecimal.divide(未知来源)

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

2 个答案:

答案 0 :(得分:3)

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

0.5 / 3 = 0.166666666666666666666666666666666666666666666666666666666666666666....

这就像你在BigDecimal内部进行的部门一样,除了正在计算二进制形式的int之外。

您需要一个different overload of divide,它需要使用刻度(小数点以外的小数位数)和舍入模式。这告诉BigDecimal要使用多少位数以及停止时如何舍入。

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

输出e的最终估算值:

e = 2.71828182828616856395

答案 1 :(得分:1)

出现此错误的原因是BigDecimal正在尝试精确计算该值,并且不能这样做,因为1/3会在基数10中永久重复。

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

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