- C++相談室 part114
732 :デフォルトの名無しさん[]:2014/12/02(火) 10:32:45.66 ID:P59XjAfc - gccのfmod関数の誤差が大きいようです.VC++2008ではfmodもyもきっちり0
です.バグだと思うのですが,どこに言ったらいいんでしょうか? int i; double x,y,fmd,dx=0.01; for(i=0; i<=100000000; ++i) { x=i*dx; fmd=fmod(x, 2.0); y=sin(pi*fmd); } [gcc4.8.1の実行結果] x=1e+006 fmod=2.08047e-011 y=6.53599e-011
|
- C++相談室 part114
733 :デフォルトの名無しさん[]:2014/12/02(火) 10:37:46.55 ID:P59XjAfc - >>732
あ・・・,実行結果はforループで回した直後に出力したものです.
|
- C++相談室 part114
737 :デフォルトの名無しさん[]:2014/12/02(火) 11:15:57.77 ID:P59XjAfc - ideoneが使ったことがなくてC++4.8.1のところに貼り付けて実行
してみましたが,時間オーバーになってしまいました. >>734 そうですか.正常に実行されましたか. 環境はWindows7,TDM gcc(MinGWのBinary,gcc.4.8.1)です. ideoneで実行してみましたが,そちらから見れるかどうか わかりませんので,下に問題のプログラム全体を貼り付けます.
|
- C++相談室 part114
738 :デフォルトの名無しさん[]:2014/12/02(火) 11:17:33.11 ID:P59XjAfc - #include <cmath>
#include <iostream> using namespace std; int main() { const double pi=3.141592653589793; double x, y, fmd, dx=0.01; int i; for(i=0; i<=100000000; ++i) { x=i*dx; fmd=fmod(x, 2.0); y=sin(pi*fmd); } cout<<"x="<< x <<" fmod="<< fmd << " y=" <<y<<endl; return 0; }
|
- C++相談室 part114
742 :デフォルトの名無しさん[]:2014/12/02(火) 12:32:19.89 ID:P59XjAfc - >>738です.
forループを取っ払って, fmd=fmod(100000000,2.0);とやると,0 になりました. forループの直後のiを調べてみると,i=100000001になっています. それでx=i*dxの値が増えたのでしょうが,わからないのはループの直後 でprintf("%21.14e \n", x);としても1.00000000000000e+006が出力され ることです. まあ,fmodみたいな単純な関数にバグがあるとは考えにくいので,言い過ぎ たのですが,何でxの値が1.00000001000000e+006と表示されないのか わかりません.
|
- C++相談室 part114
743 :デフォルトの名無しさん[]:2014/12/02(火) 12:37:06.74 ID:P59XjAfc - i<=iが100000000の判定からi=100000001になってもokだし,
xが100000000*0.01のままであることもok. ならなぜfmod(x,2.0)が0にならない?わかりません.
|
- C++相談室 part114
744 :デフォルトの名無しさん[]:2014/12/02(火) 12:42:17.87 ID:P59XjAfc - i<=iが100000000の判定から→i<=100000000の判定から
|
- C++相談室 part114
747 :デフォルトの名無しさん[]:2014/12/02(火) 12:59:59.60 ID:P59XjAfc - >>739
for(i=100000000 - 1; i<=100000000; ++i)なら,自分の環境でもidoneでも fmod=0となる. >>745 ありがとうございます.VC++上でのクラングでうまくいくんですね.VC++2008 では問題なく動きます. >>746 倍精度の有効桁数が14〜15桁,0か1e-14以下となるべきなのが,fmod=2.08047e-011 というのは誤差が大きすぎる. まあ,いいや.これ以上書き込むのは止めておきます.
|
- C++相談室 part114
754 :デフォルトの名無しさん[]:2014/12/02(火) 15:33:18.05 ID:P59XjAfc - >>748 gccだったら最適化オプションの違いでどうなるか知りたい。
これが原因でした.話には聞いてましたが,経験するのは今回が初めてです. それも最適化なしで0にならないなんて 最適化オプション: 指定なし,-o, -o2, -o3 (速度重視) x=1e+006 fmod(x, 2.0)=2.08047e-011 y=sin(pi*fmod(x, 2.0))=6.53599e-011 -os (サイズ重視) x=1e+006 fmod(x, 2.0)=0 y=sin(pi*fmod(x, 2.0))=0 もう一度環境を書くと,テストコード >>738 Intel Corei7, Windows 7 Professional 64bit,TDM gcc4.8.1 + Code::Blocks13.12 -std=C++11,Releaseモード
|