Reputation: 379
I suppose this is a rather rudimentary question, but I don't know why these 2 pieces of code give different results. Does the Pentium handle the variable Divider differently than the intermediate value ( 256.0 / (double)k )?
int j=64, k=20;
double x, y, Divider;
Divider = 256.0 / (double)k;
x = (double)j / Divider - 5.0;
y = (double)j / ( 256.0 / (double)k ) - 5.0;
Results: x = -2.77555756156289E-16 y = 0.0
For reference, I am using Embarcadero's XE3 C++ Builder, which gives the same results as Builder 6. I am using the default compiler settings on both.
Upvotes: 2
Views: 167
Reputation: 241881
The issue is that when you don't use SSE instructions, the compiler may well chose to do intermediate computations with the native 387
floating point unit, which does all computations with 80-bit values.
In the computation of x
, you force the intermediate value to be truncated to 64 bits by storing it in Divisor
. Then the next division uses an already rounded divisor; since the division is done with enough precision, the result is slightly different from 5.0.
In the computation of y
, the division is done with 80-bit precision, so that the result is closer to 5.0 (sufficiently close that truncating to 64 bits makes it 0).
You would also get two 0
values if you use SSE (which only has 64-bit registers), or otherwise forced the compiler to do all computations with 64-bit precision.
Upvotes: 2
Reputation: 638
Perhaps it is the optimizer. In the second one
y = (double)j / ( 256.0 / (double)k )
is the same mathematically as
y = (double)j * (double)k / 256.0
This only does one division (which coincidentally divides cleanly) and is subject to less rounding error.
For x
it is forced to do two divisions.
Upvotes: 0