Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the addition of enclosing parentheses change the result of this Scala expression?

Tags:

scala

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?

like image 496
anelson Avatar asked Oct 14 '12 01:10

anelson


1 Answers

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:

  1. 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.

  2. The next line begins with a word that cannot start a statement.

  3. The line ends while inside parentheses (...) or brackets [...], because these cannot contain multiple statements anyway.

like image 65
Sergey Passichenko Avatar answered Oct 22 '22 15:10

Sergey Passichenko