【问题标题】:Parentheses and order of operations括号和运算顺序
【发布时间】:2014-07-15 13:03:32
【问题描述】:

我在 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_antnftints,其余的是doubles。

我已经在调试器中对这两个表达式进行了几次迭代评估,结果通常相差 0.3 左右。为什么会发生这种情况,为什么一个有效而另一个无效?

【问题讨论】:

  • 这不是很明显吗?您已经为操作顺序设置了自己的规则。
  • @Pascal Cuoq 在数学上,这两个写作是等价的。所以不要带着这样的cmets。这是我感到困惑的编程部分(如何评估结果),所以我问了。很简单。

标签: java operator-precedence


【解决方案1】:

如果nf_antnfints,您的问题是第二个版本如果执行整数除法 而不是浮点除法。您需要先投射其中一个。

让我们比较以下两个表达式:

miuf_ant * nf_ant / nf
miuf_ant * (nf_ant / nf)

按照Java的规则,第一个等价于以下:

(miuf_ant * nf_ant) / nf

这里发生的是首先评估产品,因为miuf_antdouble,所以结果也是double。之后,该部门也发生了同样的事情。

但在“坏”(第二种)情况下,因为两个除法运算符都是ints,所以结果也是int,通过有效截断结果而失去运算精度。然后将这种精度损失传递给产品。

【讨论】:

  • 请提及第二种情况下的精度损失,而不是说“一个在数学上不是你想要的操作数”,我会给你答案。否则很好解释。
【解决方案2】:

在第二种情况下,nf_ant / nf 将以整数算术计算,因为括号表示它是独立计算的。余数的损失是造成差异的原因。

在第一种情况下,它被 miuf_ant 预乘,这是一个浮点类型。由于*/ 具有相同的优先级,所有3 个参数在计算之前都被提升为浮点数。

【讨论】:

  • 好的,我明白了。所以在第二种情况下,因为 nf_ant 和 nf 都是 int 并且它们位于括号内,所以它们被评估为 int 并且我失去了一些精度。在第一种情况下,双精度乘以 int,结果变为双精度。然后将它除以另一个 int ant,结果再次变为双精度数。所以这样我就不会失去精度。谢谢。
  • 除了ints 在评估之前实际上被提升为浮点数之外,几乎就是这样。请注意,这在 C 和 C++ 中也是如此。我不会说其他语言。
  • 它们被提升了,但小数点后为 0,所以我丢失了所有应该存在的数字。
  • 是的,在第二种情况下,nf_ant / nf(整数类型)的结果将被提升为浮点数。但是到那时精度就会丢失。
  • 我希望你不要介意我给Darkhogg的答案,因为我认为他解释得更详细,让一个初学者都能理解。即使我的问题可能暗示其他情况,我实际上距离成为一个 Java 初学者还很远,而且我立即理解了你的意思,因为我一定已经读过很多次了,而且当场就得到了答案.希望您不要介意,谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-12-11
  • 2012-10-01
  • 2017-12-05
  • 2012-09-01
  • 2018-10-09
  • 1970-01-01
  • 2021-01-09
  • 2019-12-17
相关资源
最近更新 更多