Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> But I do think that this is more a quirk on how operators are done specifically in C and not a general matte

That has nothing to do with C, but with the CPU and its registers. x86 has 80bit floating point registers (too), so if the compiler/CPU (doesn't matter which language) saves a value in a 80 bit floating point register and moves it from there to memory where it is stored in 64 bits, the number gets rounded (not truncated, it's actually converted).

See also the GCC page:

    For instance, in the following code segment, depending on the compilation 
    flags and numbers and calculations used to find tmp, the following code may 
    print out that the values are different:


     double tmp, X[2];
     tmp = ....
     tmp += ....
     ...
     X[0] = tmp;
     if (X[0] == tmp)
        printf("Values are the same, as expected!\n");
     else
        printf("Values are different!\n");

    This is because tmp will typically be moved to a register during register 
    assignment, which means tmp may hold a full 80 bits of accuracy, some of 
    which are lost in the store to X[0], and thus the numbers are no longer 
    equal. You may workaround this problem by always explicitly storing to 
    memory to force the round-down.
https://gcc.gnu.org/wiki/x87note

> Are the comparison and arithmetic operations considered to be contracted in these sort of situations?

No. Or well, maybe. 'Contracted' means using e.g. FMA (fused multiply and add), so addition and multiplication like `ab + c` is done in a single step instead of two. Which means that the result is only rounded once (`ab + c` is rounded), whereas without this fusing/contracting `ab` would be rounded and `ab + c` would be rounded again (actually depending on the optimization/compiler flags). So the results (may) differ.



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: