I'm porting some C code to Scala, which makes extensive use of floating point arithmetic. I wrote the following code in Scala based on a copy/paste of the C version:
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)
The result of this computation is slightly off from what the C version produces. However, if I enclose the expression in parentheses, like this:
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))
the resulting value matches exactly the C version. It seems the order of operations must be different when there are enclosing parentheses vs when there are not, but I don't understand why that would make any difference. Any idea what's going on here?
It's because of semicolon inference. Sample (//;
- inferred semicolon):
val x = 1 //;
+ 1 //;
println(x) // 1
And with parentheses:
val x = (1
+ 1) //;
println(x) // 2
Or with tailing "+":
val x = 1 +
1 //;
println(x) // 2
The rules of semicolon inference
A line ending is treated as a semicolon unless one of the following conditions is true:
The line in question ends in a word that would not be legal as the end of a statement, such as a period or an infix operator.
The next line begins with a word that cannot start a statement.
The line ends while inside parentheses (...) or brackets [...], because these cannot contain multiple statements anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With