2012-02-12 7 views
12

libcの "sin"関数に問題があります。g ++最適化オプションがsin関数の値に影響する

#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; 
} 

任意の最適化オプションなし「のG ++」を使用して、上記のコードをコンパイルすると、それは出力だろう「-0.00000000000000024492127076447545」。 "-O3"オプションを指定すると "-0.00000000000000024492935982947064"と出力されます。

なぜ "-0.00000000000000024492935982947064"に "-O3"が含まれていないのですか? ありがとうございます。

+0

g ++のバージョンと使用しているOSとハードウェアを知ることができますか? – Viet

+0

g ++ 4.4.3、ubuntu 10.04、およびIntel(R)Core(TM)i3-2310M CPU @ 2.10GHz。感謝します。 –

+0

'-ffast-math'オプションをチェックしてください。 –

答えて

6

"-O3"を指定すると、コンパイラはコンパイル時にsin(2*pi)を1つのアルゴリズムで事前計算するためです。 "-O3"を指定しないと、実行時に他のアルゴリズムで計算されます。

これは、コンパイラ自体が数学ライブラリとは異なる数学ライブラリで構築されている可能性があります。

更新

結果を与える唯一のエンティティは、 "-0.00000000000000024492127076447545" のlibstdC++の32ビットバージョンです。同じライブラリの64ビット版とgcc自体は、 "-0.00000000000000024492935982947064"を生成します。

新しいバージョンにアップグレードすることは役に立ちません。また、ここで提案されているさまざまなオプションを試しました。-float-storeも-fno-builtinも、long doubleとsinlだけでなく、何の違いもありません。

32ビットlibstdC++は387浮動小数点命令を使用しますが、gccはSSE命令を使用しています。ここに違いがあります。おそらく、一貫性を持たせる唯一の方法は、ソースからgccを再構築し、内部で387命令しか使用しないように指示することです。

+0

あなたの答えをありがとう。実行時に "-0.00000000000000024492935982947064"を取得できるかどうかは分かりますか?そしてどうやって? –

+1

@Sanders '-fno-builtin'は、組み込み関数が使用されていないことを確認するために、通常、コンパイル時に結果を計算しないようにします。しかし、それでも結果は正常ではなく、おそらくコンパイラやライブラリにバグがあります。新しいバージョンに更新しようとする必要があります。 – ouah

+0

@ouah OK、私はg ++のバージョンをアップデートしてみるつもりです。感謝します。 –

関連する問題