我正在将一些C代码移植到Scala中,它广泛使用了浮点运算。我在斯卡拉写了下面的代码基础上的C版复制/粘贴:为什么添加括号会改变这个Scala表达式的结果?
val complimentaryTerms = 2640.96e-6 * sin (f5)
+ 63.52e-6 * sin (2.0 * f5)
+ 11.75e-6 * sin (2.0 * f3 - 2.0 * f4 + 3.0 * f5)
+ 11.21e-6 * sin (2.0 * f3 - 2.0 * f4 + f5)
- 4.55e-6 * sin (2.0 * f3 - 2.0 * f4 + 2.0 * f5)
+ 2.02e-6 * sin (2.0 * f3 + 3.0 * f5)
+ 1.98e-6 * sin (2.0 * f3 + f5)
- 1.72e-6 * sin (3.0 * f5)
- 0.87e-6 * t * sin (f5)
这个计算结果稍微偏离一下C版生产。但是,如果我将括号括起来,如下所示:
val complimentaryTerms = (2640.96e-6 * sin (f5)
+ 63.52e-6 * sin (2.0 * f5)
+ 11.75e-6 * sin (2.0 * f3 - 2.0 * f4 + 3.0 * f5)
+ 11.21e-6 * sin (2.0 * f3 - 2.0 * f4 + f5)
- 4.55e-6 * sin (2.0 * f3 - 2.0 * f4 + 2.0 * f5)
+ 2.02e-6 * sin (2.0 * f3 + 3.0 * f5)
+ 1.98e-6 * sin (2.0 * f3 + f5)
- 1.72e-6 * sin (3.0 * f5)
- 0.87e-6 * t * sin (f5))
结果值完全匹配C版本。当括号内有括号时,操作的顺序似乎不同,但我不明白为什么会有所不同。任何想法这里发生了什么?
奇怪。一个错误?你为什么不尝试逐渐简化表达式,直到得到最简单的表达式,从而导致差异?例如'2640.96e-6 * sin(f5)+ 63.52e-6 * sin(2.0 * f5)'会产生差异吗?如果删除第一学期的系数会怎样? –
(你也可以试着看看发出的字节码,它听起来不像看起来那么吓人,它不像看x86汇编器(虽然承认它并不遥远),尽管首先得到一个简单的表达式,所以字节码是相对的简而言之,我怀疑这与推断的complimentaryTerms类型有关。 –
(嗯,你也可以试试'println complimentaryTerms.getClass()',看看它是否相同。 –