By default, the compiler attempts to perform as much arithmetic as possible at compile time. A floating-point operation with constant operands is folded, which means that the arithmetical expression is replaced with the compile-time result. If you enable optimization, increased folding might occur. However, the result of a compile-time computation might differ slightly from the result that would have been calculated at run time, because more rounding operations occur at compile time. For example, where a multiply-add-fused (MAF) operation might be used at run time with less rounding, separate multiply and add operations might be used at compile time, producing a slightly different result.
To prevent the possibility of unexpected results due to compile-time rounding, you have two options:
For example, if you were to compile the following code sample with -yz, which specifies a rounding mode of round-to-zero, the two results of u.x would be slightly different:
int main () { union uu { float x; int i; } u; volatile float one, three; u.x=1.0/3.0; printf("1/3=%8X \n", u.i); one=1.0; three=3.0; u.x=one/three; printf ("1/3=%8X \n", u.i); return 0; }
This is because the calculation of 1.0/3.0 would be folded at compile-time using round-to-zero rounding, while one/three would be calculated at run-time using the default rounding mode of round-to-nearest. (Declaring the variables one and three as volatile suppresses folding by the compiler, even under optimization.) The output of the program would be:
1/3=3EAAAAAA 1/3=3EAAAAAB
To ensure consistency between compile-time and run-time results in this
example, you would compile with the option -yn (which is the
default).