gcc precision bug?
gcc, precision
Solution
This is something that has bitten me, too.
Yes, floating point numbers should never be compared for equality because of rounding error, and you probably knew that.
But in this case, you're computing `t1+t2`, then computing it again. Surely that has to produce an identical result?
Here's what's probably going on. I'll bet you're running this on an x86 CPU, correct? The x86 FPU uses 80 bits for its internal registers, but values in memory are stored as 64-bit doubles.
So `t1+t2` is first computed with 80 bits of precision, then -- I presume -- stored out to memory in `sum_2` with 64 bits of precision -- and some rounding occurs. For the assert, it's loaded back into a floating point register, and `t1+t2` is computed again, again with 80 bits of precision. So now you're comparing `sum_2`, which was previously rounded to a 64-bit floating point value, with `t1+t2`, which was computed with higher precision (80 bits) -- and that's why the values aren't exactly identical.
Edit So why does the first test pass? In this case, the compiler probably evaluates `4.0+6.3` at compile time and stores it as a 64-bit quantity -- both for the assignment and for the assert. So identical values are being compared, and the assert passes.
Second Edit Here's the assembly code generated for the second part of the code (gcc, x86), with comments -- pretty much follows the scenario outlined above:
// t1 = 4.0
fldl LC3
fstpl -16(%ebp)
// t2 = 6.3
fldl LC4
fstpl -24(%ebp)
// sum_2 = t1+t2
fldl -16(%ebp)
faddl -24(%ebp)
fstpl -32(%ebp)
// Compute t1+t2 again
fldl -16(%ebp)
faddl -24(%ebp)
// Load sum_2 from memory and compare
fldl -32(%ebp)
fxch %st(1)
fucompp
Interesting side note: This was compiled without optimization. When it's compiled with `-O3`, the compiler optimizes all of the code away.
Problem
I can only assume this is a bug. The first assert passes while the second fails: ``` double sum_1 = 4.0 + 6.3; assert(sum_1 == 4.0 + 6.3); double t1 = 4.0, t2 = 6.3; double sum_2 = t1 + t2; assert(sum_2 == t1 + t2); ``` If not a bug, why?