12

I have a problem with "sin" function of libc.

#include <cmath>
#include <stdio.h>

int main(int argc, char **argv)
{
    double tt = 6.28318530717958620000; // 2 * M_PI
    double yy = ::sin(tt);

    printf("%.32f\n", yy);

    return 0;
}

When compile the above code using "g++" without any optimization option, it would output "-0.00000000000000024492127076447545". But if with "-O3" option, it would output "-0.00000000000000024492935982947064".

Why doesn't it return "-0.00000000000000024492935982947064" without "-O3"? Thanks in advance.

1 Answers1

6

Because with "-O3" the compiler precomputes sin(2*pi) at compile time, with one algorithm. Without "-O3" this is computed at runtime, with other algorithm.

This may be because compiler itself was built with some math library, which differ from your math library.

Update

The only entity, giving the result "-0.00000000000000024492127076447545" is 32-bit version of libstdc++. 64-bit version of the same library as well as gcc itself produce "-0.00000000000000024492935982947064".

So upgrading to newer version will not help. Also I tried various options, proposed here: neither -ffloat-store, nor -fno-builtin do not make any difference, as well as long double and sinl.

32-bit libstdc++ uses 387 floating point instructions, while gcc apparently uses SSE instructions. Here is the difference. Probably, the only way to make them consistent is to rebuild gcc from sources, directing it to use only 387 instructions internally.

Evgeny Kluev
  • 24,287
  • 7
  • 55
  • 98
  • Thanks for your answer. DO you know whether it is possible to get "-0.00000000000000024492935982947064" at runtime? And how? – Shen Weizheng Feb 12 '12 at 15:05
  • 1
    @Sanders `-fno-builtin` to be sure no builtin function is used, it usually helps to avoid the result to be computed at compile time. But still, the result you get is not normal, there is a probably bug in the compiler or in the library. You should try to update to a new version. – ouah Feb 12 '12 at 15:10
  • @ouah OK, I will update my g++ version and have a try. THANKS. – Shen Weizheng Feb 12 '12 at 15:17
  • 1
    My gcc 4.6.1 gives -0.00000000000000024492935982947064 in all cases, so if you upgrade to this version or to the latest version (both the compiler and libraries), you'll get consistent result. Also you may try to upgrade them to the default versions of your ubuntu distribution. Or to recompile gcc from sources. – Evgeny Kluev Feb 12 '12 at 15:18
  • @EvgenyKluev Great. I will have a try. And by the way, what is your OS version? – Shen Weizheng Feb 12 '12 at 15:25
  • Maybe compiling with `-march=native` will change things. Without that AFAIK it compiles for the lowest common denominator of all x86 architectures. – celtschk Feb 12 '12 at 17:42
  • @celtschk, -march=native does not help either. I already tried to set several architecture options manually with no success. I didn't find any option changing precomputed constant. And, apparently, no option can alter the return value of the library function. – Evgeny Kluev Feb 12 '12 at 17:54