Note that there are some explanatory texts on larger screens.

plurals
  1. POC++: doubles, precision, virtual machines and GCC
    primarykey
    data
    text
    <p>I have the following piece of code:</p> <pre><code>#include &lt;cstdio&gt; int main() { if ((1.0 + 0.1) != (1.0 + 0.1)) printf("not equal\n"); else printf("equal\n"); return 0; } </code></pre> <p>When compiled with O3 using gcc (4.4,4.5 and 4.6) and run natively (ubuntu 10.10), it prints the expected result of "equal". </p> <p>However the same code when compiled as described above and run on a virtual machine (ubuntu 10.10, virtualbox image), it outputs "not equal" - this is the case for when the O3 and O2 flags are set however not O1 and below. When compiled with clang (O3 and O2) and run upon the virtual machine I get the correct result.</p> <p>I understand 1.1 can't be correctly represented using double and I've read <em>"What Every Computer Scientist Should Know About Floating-Point Arithmetic"</em> so please don't point me there, this seems to be some kind of optimisation that GCC does that somehow doesn't seem to work in virtual machines.</p> <p>Any ideas?</p> <p>Note: The C++ standard says type promotion in this situations is implementation dependent, could it be that GCC is using a more precise internal representation that when the inequality test is applied holds true - due to the extra precision?</p> <p><strong>UPDATE1:</strong> The following modification of the above piece of code, now results in the correct result. It seems at some point, for whatever reason, GCC turns off floating point control word.</p> <pre><code>#include &lt;cstdio&gt; void set_dpfpu() { unsigned int mode = 0x27F; asm ("fldcw %0" : : "m" (*&amp;mode)); int main() { set_dpfpu(); if ((1.0 + 0.1) != (1.0 + 0.1)) printf("not equal\n"); else printf("equal\n"); return 0; } </code></pre> <p><strong>UPDATE2:</strong> For those asking about the const expression nature of the code, I've changed it as follows, and still fails when compiled with GCC. - but i assume the optimizer may be turning the following into a const expression too.</p> <pre><code>#include &lt;cstdio&gt; void set_dpfpu() { unsigned int mode = 0x27F; asm ("fldcw %0" : : "m" (*&amp;mode)); int main() { //set_dpfpu(); uncomment to make it work. double d1 = 1.0; double d2 = 1.0; if ((d1 + 0.1) != (d2 + 0.1)) printf("not equal\n"); else printf("equal\n"); return 0; } </code></pre> <p><strong>UPDATE3 Resolution:</strong> Upgrading virtualbox to version 4.1.8r75467 resolved the issue. However the their remains one issue, that is: why was the clang build working.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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