首页 > 解决方案 > 计算 BigDecimal 会导致答案不准确

问题描述

所以我只是想看看我是否能做到,这样我就可以计算 E,而是拥有它,这样我就可以获得动态的精度。虽然我确实在技术上完成了它,但无论我为变量 PRECISION 输入什么 int,最后几个数字总是与 E 的实际值不同。我不完全确定为什么,但我们将不胜感激。

import java.math.BigDecimal; //To use for calculating E

public class ComputeE {
    public static double calcDenominator(int n)
    {
        double denominator = 1.0;   //Start the BigInt with 1
        for(int i = 1; i < n; i++) // Run n-1 amount of times
        {
            denominator = denominator * i;   // Multiply BigInteger by the BigInteger obtained with the int value i
        }
        return denominator;

    }


    public static void main(String[] args) {


        BigDecimal e = new BigDecimal(0.0);
        int PRECISION = 15;
        int iterations = 0;
        for(int i = 0; i < PRECISION; i++)
        {
            iterations++;
            BigDecimal numerator = new BigDecimal(1.0); // to divide, we need two BigDecimals, the numerator is 1
            BigDecimal factorial = new BigDecimal(calcDenominator(i));  // the denominator is i! which we get from calling the factorial method
            factorial = numerator.divide(factorial, PRECISION, BigDecimal.ROUND_UNNECESSARY);  // compute 1/i!, note divide is overloaded, this version is used to
                                                                  //     ensure a limit to the iterations when division is limitless like 1/3
            e = e.add(factorial);                   // add the latest 1/i! to e

        }



        System.out.println("Computed value of e : " + e);
        System.out.println("Expected value of e : " + Math.E);

    }
}

标签: javamath

解决方案


  1. 这里需要四舍五入。使用类似的东西HALF_EVEN。更好的是,使用枚举值RoundingMode.HALF_EVEN,因为舍入模式的整数常量已被弃用。

  2. calcDenominator中,将您的for循环条件更改为i <= n,否则您将在其中添加1一个太多次main,您将获得一个1过高的值。

  3. 您可以使用BigDecimal.ONE来初始化numerator. 这不会影响结果,但是为什么要创建一个不必要的对象呢?对 的初始化的评论相同e,除了BigDecimal.ZERO

  4. 您正在使用近似于无理数ePRECISION的无限级数(麦克劳林级数)的第一项。当你切断循环时会有一个错误项,这是数学上预期的。通过上述更改,并碰到,我得到以下内容,看起来足够精确。forPRECISION50

Computed value of e : 2.71828182845904523536028747135266249775496954201584
Expected value of e : 2.718281828459045

这是精确的,尽管使用了double构造函数,BigDecimal因为有效数字double从第一个非零位开始,所以即使你正在计算 1/n!对于大n,有效数字足以添加到e的现有近似值。


推荐阅读