Java';s Math.Pow()函数返回令人困惑的结果

Java';s Math.Pow()函数返回令人困惑的结果,java,pow,Java,Pow,我正在使用Math.pow()函数,代码如下: double monthlyRate = (0.7d / 12); int loanLength = 3; double powerTest = Math.pow(1.00583, 36); double powerResult = Math.pow((1 + monthlyRate),(loanLength * 12)); 当通过调试器运行时,值将变为 powerTest => 1.2327785029794363 powerResul

我正在使用Math.pow()函数,代码如下:

double monthlyRate = (0.7d / 12);
int loanLength = 3;

double powerTest = Math.pow(1.00583, 36);
double powerResult = Math.pow((1 + monthlyRate),(loanLength * 12));
当通过调试器运行时,值将变为

powerTest => 1.2327785029794363
powerResult => 7.698552870922063
第一个是正确的。我在两条作业线上都加入了Math.pow函数。对于powerTest, Math.pow的参数为 双a=>1.00583 双b=>36.0

对于powerResult,它们是 双a=>1.0058333 双b=>36.0

我知道这是机器执行浮点数学的一个问题,我只是不知道如何纠正它。在计算之前,我尝试了以下操作,但结果很差:

monthlyRate = Math.round(monthlyRate * 1000) / 1000;

您使用的是整数除法。

1+monthlyRate
1.0583…
,而不是
1.00583
我认为部分问题在于
0.7/12~0.058333
,以及
1.0583>1.00583
。我敢打赌,这是您的差异的真正来源,浮点调整与此无关。

您的表达式0.7d/12=0.0583,在您使用的powerTest表达式0.00583中。

在Java上,您可以使用它来执行货币操作,从而生成精确的数字:它是存储货币数字的关键

// I'm using Strings for most accuracy

BigDecimal monthlyRate = new BigDecimal("0.7").divide(new BigDecimal(12));
int loanLength = 3;

BigDecimal powerTest = new BigDecimal("1.00583").pow(36);
BigDecimal powerResult = BigDecimal.ONE.add(monthlyRate).pow(loanLength * 12);

很明显,结果(1.23…和7.70)中如此大的差异与浮点数的编码方式无关,但比你在某个地方犯的错误还要多
1+0.7/12=1.0583不同于1.00583;-)

你对(1+(0.7/12))^(3)有什么期望⋅12)? 我在一个普通的计算器中得到7.698552870922058862786。在Java上,你应该使用BigDecimal来执行货币操作。看看我的答案。忽略这一点,实际问题是额外的零,正如axtavt所指出的。我留下答案,以防OP真的想要执行舍入。谢谢Nikita,我会注意到,如果将来我必须编写类似的函数,请解释你的反对票。OP正在执行货币操作,他应该使用BigDecimal。
// I'm using Strings for most accuracy

BigDecimal monthlyRate = new BigDecimal("0.7").divide(new BigDecimal(12));
int loanLength = 3;

BigDecimal powerTest = new BigDecimal("1.00583").pow(36);
BigDecimal powerResult = BigDecimal.ONE.add(monthlyRate).pow(loanLength * 12);
monthlyRate = ((double)Math.round(monthlyRate * 1000)) / 1000;