Say I write an expression in c, for example
a = (((b+c) / d) / f) + ((3.14 * e) ) / f) ;
Here a,b,c,d,e,f are all double precision variables. When I compile my code using, for example, the gcc compiler with some optimization setting, does the compiler respect the particular form of the expression as I wrote it, or does it modify the expression to make the code run faster? For example, would/could gcc with -O2 optimization setting compile the above expression to
a = ((b+c + 3.14* d * e) / (d*f))
Or would it keep the expression as is? I am concerned about the compiler changing the forms of my equations, which may affect the numerical stability of my expressions.
The compiler is guaranteed to produce an expression that yields an equivalent result to evaluating your formula as it is written. This includes all type conversions, side effects, and exceptions the expressions may produce.
In particular, your way to optimize the expression would not pass the equivalency test, because ((b+c) / d)
in the original expression would be evaluated in terms of the types of b
, c
, and d
, which could be int
or float
; your second (optimized) formula, on the other hand, forces the double
type on the entire expression because of addition of 3.14
. It also multiplies e
by d
in the numerator to compensate for d*f
in the denominator, which may produce an overflow that did not exist in the original formula.