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?
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
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+t2is first computed with 80 bits of precision, then — I presume — stored out to memory insum_2with 64 bits of precision — and some rounding occurs. For the assert, it’s loaded back into a floating point register, andt1+t2is computed again, again with 80 bits of precision. So now you’re comparingsum_2, which was previously rounded to a 64-bit floating point value, witht1+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.3at 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:
Interesting side note: This was compiled without optimization. When it’s compiled with
-O3, the compiler optimizes all of the code away.