我正在將一些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()',看看它是否相同。 –