我在java中有一个返回整数的函数。我知道应该返回什么,所以我知道它何时正常运行。无论如何,在for循环的某个点上有这行代码:
如果我这样写的话
miuf = miuf_ant * nf_ant / nf - ((double) ((t - 1) * hist[t - 1]) / (double) nf);`
结果很好。
如果我这样写的话
miuf = (miuf_ant * (nf_ant / nf) - ((double) ((t - 1) * hist[t - 1]) / (double) nf));
结果很远。
nf_ant
,nf
和t
为int
s,其余为double
s。
我已经在调试器中对这两个表达式进行了几次迭代的评估,结果总的来说差异大约为0.3。为什么会发生这种情况,为什么一个有效,另一个无效?
答案 0 :(得分:1)
在第二种情况下,nf_ant / nf
将以整数运算计算,因为括号表示它自己进行求值。剩余的损失是导致差异的原因。
在第一种情况下,它被miuf_ant
预乘,这是一种浮点类型。由于*
和/
具有相同的优先级,因此在计算之前将所有3个参数提升为浮点。
答案 1 :(得分:1)
如果nf_ant
和nf
是int
s,那么问题是第二个版本如果执行整数除法而不是浮点除法< / em>的。你需要先投出其中一个。
让我们比较以下两个表达式:
miuf_ant * nf_ant / nf
miuf_ant * (nf_ant / nf)
第一个与Java规则相当:
(miuf_ant * nf_ant) / nf
这里发生的事情是首先评估产品,因为miuf_ant
是double
,结果也是double
。之后,分裂也是如此。
在&#34;坏&#34; (第二种)情况,因为两个除法运算符都是int
s,结果也是int
,通过有效地截断结果而失去对操作的准确性。然后将这种精确度的损失传递给产品。