java - 计算 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);
}
}
解决方案
这里需要四舍五入。使用类似的东西
HALF_EVEN
。更好的是,使用枚举值RoundingMode.HALF_EVEN
,因为舍入模式的整数常量已被弃用。在
calcDenominator
中,将您的for
循环条件更改为i <= n
,否则您将在其中添加1
一个太多次main
,您将获得一个1
过高的值。您可以使用
BigDecimal.ONE
来初始化numerator
. 这不会影响结果,但是为什么要创建一个不必要的对象呢?对 的初始化的评论相同e
,除了BigDecimal.ZERO
。您正在使用近似于无理数e
PRECISION
的无限级数(麦克劳林级数)的第一项。当你切断循环时会有一个错误项,这是数学上预期的。通过上述更改,并碰到,我得到以下内容,看起来足够精确。for
PRECISION
50
Computed value of e : 2.71828182845904523536028747135266249775496954201584
Expected value of e : 2.718281828459045
这是精确的,尽管使用了double
构造函数,BigDecimal
因为有效数字double
从第一个非零位开始,所以即使你正在计算 1/n!对于大n
,有效数字足以添加到e的现有近似值。
推荐阅读
- r - 如何为 R 中的每个唯一组合分别保存嵌套循环的结果
- c# - 部署 Db 时在哪里可以执行原始 SQL 代码?
- python - 为什么不确定性和熵采样函数会给我相同的结果?
- pandas - Pandas 中的子字符串列基于另一列
- r - 在单个函数/循环中从多个网页中提取多个元素
- html - 使用 R 和 rvest 抓取网页表
- c# - 如何使用 Azure Functions 将数据发送到服务总线主题?
- c# - c# Outlook addin 强制将光标移动到邮件正文的末尾
- java - JavaFX 在 fxml 文件中是否有循环,如 angular 的 *ngFor?
- asp.net - 如何运行预编译或已发布的 ASP.net MVC 项目并向其中添加文件并再次发布?