• ベストアンサー

テイラー展開とその精度について

C言語初心者です。 自分で作ったプログラムのソースはhttp://www1.axfc.net/uploader/He/so/375902.txtにあります。 (1)は一応解けたと思うのですが、(2)に関してはお手上げでした。 <問題> π = 4*(π/4) = 4*arctan(1) arctan(x) のテイラー展開を用いてπの値を正しく求めよ。(最低7桁まで) (1)単精度・倍精度で誤差を比較せよ。 (2)単精度のみを用いて正しく求めよ。 (2)のやり方を教えてください。 (1)も上手くいったとは言い難いので、気づいた点があればご指摘願います。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

#1の続きです 級数の値を求めるとき、値の小さい項を先に足しこむほうが正確に求められます プログラムを作って確かめてみました #include <iostream> #include <iomanip> int main(void) { int n=10000; float p4a=0.0f; for (int i=n-3; i>0; i-=4) p4a+=2.0f/i/(i+2); float pa=4.0f*p4a; std::cout << std::setprecision(20)<<pa<<"\n"; float p4b=0.0f; for ( int i=n-1; i>0; i-=4 ) p4b+=2.0f/i/(i+2); float pb=4.0f*(1.0f-p4b); std::cout << std::setprecision(20)<<pb<<"\n"; float pc=(pa+pb)/2; std::cout << std::setprecision(20)<<pc<<"\n"; } 結果 3.141392707824707 3.1417925357818604 3.1415925025939941 7桁目まで求められました 「Euler変換」が交代級数の値を求めるときの参考になるでしょう

trokky
質問者

お礼

(1)に引き続きのお礼欄です。 std::cout << std::setprecision(20)<<pa<<"\n";のみよくわかりませんでしたが、printfみたいなものですよね。 他はわかった気がしますが、見慣れない書き方もあって未熟さを実感しつつも勉強になりました。 足す順によって結果が変わること、ご回答のように今回の場合は平均をとることで精度が上がることも勉強になりました。精進いたします。 回答ホントにありがとうございました。

その他の回答 (1)

回答No.1

> (1)も上手くいったとは言い難いので、気づいた点があればご指摘願います。 xの値は1.0なので、 double f_double(void){ double z; int n; z = 0; for(n=1;n<pow(10,7);n+=2){ if(n%4 == 1){ z = z + 1.0/n; } else{ z = z - 1.0/n; } } return z; } にする。 > (2)のやり方を教えてください。 交代級数(項ごとに符号が変わる級数)をそのまま計算すると誤差が大きくなるので、たとえば、 a(n)=1.0/n-1.0/(n+2)=2.0/(n*(n+2)) を、(1):n=1から4おきに加えるか、 (2):n=3から4おきに加えたものを1.0から引くか、 あるいは、(3):(1)と(2)の平均値をとる ことで精度を上げることができます。

trokky
質問者

お礼

(1)の1の~乗は確かに無駄でした。 (2)のやり方もわかりやすかったです。