Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is something that has bitten me, too.</p> <p>Yes, floating point numbers should never be compared for equality because of rounding error, and you probably knew that.</p> <p>But in this case, you're computing <code>t1+t2</code>, then computing it again. <em>Surely</em> that has to produce an identical result?</p> <p>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.</p> <p>So <code>t1+t2</code> is first computed with 80 bits of precision, then -- I presume -- stored out to memory in <code>sum_2</code> with 64 bits of precision -- and some rounding occurs. For the assert, it's loaded back into a floating point register, and <code>t1+t2</code> is computed again, again with 80 bits of precision. So now you're comparing <code>sum_2</code>, which was previously rounded to a 64-bit floating point value, with <code>t1+t2</code>, which was computed with higher precision (80 bits) -- and that's why the values aren't exactly identical.</p> <p><em>Edit</em> So why does the first test pass? In this case, the compiler probably evaluates <code>4.0+6.3</code> 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.</p> <p><em>Second Edit</em> Here's the assembly code generated for the second part of the code (gcc, x86), with comments -- pretty much follows the scenario outlined above:</p> <pre><code>// 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 </code></pre> <p>Interesting side note: This was compiled without optimization. When it's compiled with <code>-O3</code>, the compiler optimizes <em>all</em> of the code away.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload