こんばんは。去年までフォートランをやっていたため現在C言語に苦戦中です。以下のプログラムを書いたのですが計算誤差が出てしまいます。修正をお願いいたします。
#include <iostream.h>
#include <math.h>
int main (void)
{
double t,x,pi=4.0*atan(1.0);
for(t=0.0; t<=20.0; t+=0.1){
x=double(sin(pi/3*t));
cout<<t<<" "<<x<<endl;
}
return 0;
}
この文はtの値を0.1ずつを変化させて正弦波を描こうと思って書いたプログラムです。t=3.0のときsin(180°)となりx=0.0になるのはずなんですが、そうはならず10の-15乗くらいの誤差が出てしまいます。どうしたら誤差をなくせれるでしょうか?
また、フォートランではt=0.1d0というような表現をして計算誤差をなくしていたのですがC(++)にはこういった方法はないのでしょうか?
ご教授よろしくお願いいたします。
No.5ベストアンサー
- 回答日時:
piが15桁めまでの精度までしかないのが原因で、
sin(pi) や sin(pi/6) (=1/2) が
仮に15桁よりちょっと下の桁で誤差eがあった場合、
sin(pi)= 0 + e
sin(pi/6)=0.5 + e
になります。これが精度がdoubleの変数に入り、その精度の位置で四捨五入された場合、sin(pi)は誤差eがそのまま残りますが、sin(pi/6)は四捨五入されると0.5ぴったりになる、ということじゃないでしょうか。ちなみに、0.5は二進数でもキリのいい数字ですよ。
実際に、eがどの程度の値になるかは、
e = sin(x+δ)-sin(x)
で見積もれます。
e/δ=( sin(x+δ)-sin(x) )/ δ
は大体sinの微分になるので、
e/δ = cos(x) 程度、つまり、
e = δ cos(x)程度でしょう。
x=piの時、cos(x)=-1なので、e=-δ程度、
x=pi/6の時、cos(x)= √3 / 2 = 1.732/2 = 0.866 なので、e= 0.87 δ程度、
よって 0.5+e = 0.5 + 0.87 δ = 0.5 * (1+1.74δ)となり、この計算結果からだけでは(1+1.74δ)がdoubleの精度で四捨五入されて1になるかどうかは微妙であることしかしめせませんでしたが、結果がそうなのだから、そうなのでしょう。
No.4
- 回答日時:
計算誤差ではなく、まるめ誤差ですよ。
sin(pi)の値を表示してみましたか?
doubleの精度で、10の-15乗程度まで0ならば、それは0ということです。たぶん。
piの値がdoubleの精度しかなければ、sin piの値もdoubleの精度までしかでません。
引数の単位がラジアンではないサイン関数を作ってください。
おまけ。
t=20のときにループの内容は実行されていますか?私の実行系では、0.1ずつ足すと、t=20.00000000000000001のような値になるので、t=約19.9の回までしか実行されません。
for(i=1;i<200;i++){
t=i/10.0;
/*処理*/
}
のようにしましょう。
遅くなってすみません。ご回答ありがとうございます。
御礼のところで申し訳ないのですが、なぜsin(pi/3.0*t)=0.0となるはずのところだけ誤差が出るのでしょうか?piがdoubleの制度ならば他のところも誤差が出ているはずだと思うのですが。例えばt=0.5のときはちゃんとx=0.5が表示されています。よろしければご教授ください。
No.3
- 回答日時:
10の-15とはしびあですね
pi/3*tで既に誤差がでていませんか?
一度定数で求めて確認してはいかがでしょうか?
また、pi/3を定数(詳しい値)にしてtを掛けたらいかがでしょうか?
もうひとつ、pi/3*tを整数で計算し、少数に直した方が誤差は減ると思います(割り算で誤差がでますので)
例
pi/3*t/100
(pai、tは100倍)
(精度上げるならば、倍率をあげる)
うまく動けばいいですね
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・ハマっている「お菓子」を教えて!
- ・最近、いつ泣きましたか?
- ・夏が終わったと感じる瞬間って、どんな時?
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
c languageで 簡単な質問があ...
-
O(n log n)について2
-
VBAのINT関数について
-
大きすぎる数値になるとE+にな...
-
VisualBasic と Fortran の計算...
-
距離から緯度経度を求める方法
-
各種デジタルカメラ用のRAWデー...
-
VBA "double"から0.1を引くと・...
-
16進数 加算 減算 C言語
-
EXCELの関数"STDEV(標準偏差)"...
-
ExcelでPC(パソコン)によって...
-
2進数の足し算(C言語)
-
ExcelのINT関数の計算結果がお...
-
C言語でπを2万桁まで計算するには
-
VB.net Double と...
-
printf( "%d", i % 10 );で?
-
VBAでミリ秒まで出力する方法
-
浮動小数演算は実行環境の変化...
-
除算を使わずに10で割りたい。
-
計算誤差について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
O(n log n)について2
-
c languageで 簡単な質問があ...
-
ExcelでPC(パソコン)によって...
-
16進数 加算 減算 C言語
-
ExcelのINT関数の計算結果がお...
-
EXCELの関数"STDEV(標準偏差)"...
-
三菱シーケンサ(Aシリーズ)で...
-
VB.net Double と...
-
除算を使わずに10で割りたい。
-
有効数字について 以前質問をし...
-
BCD・HEX・BINについて
-
C言語でセルオートマトンを作成...
-
VB6.0での小数点の扱いについて
-
VBAでミリ秒まで出力する方法
-
2進数の足し算(C言語)
-
floatの有効桁数
-
”/”を使わずに割り算したいんで...
-
計算の丸め誤差の解消について
-
VB6のFIX関数での誤差について
-
三角比の俯角の計算
おすすめ情報