【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言

C言語初心者です。

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

(2)のやり方を教えてください。
(1)も上手くいったとは言い難いので、気づいた点があればご指摘願います。

A 回答 (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変換」が交代級数の値を求めるときの参考になるでしょう
    • good
    • 0
この回答へのお礼

(1)に引き続きのお礼欄です。

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

回答ホントにありがとうございました。

お礼日時:2012/10/20 01:37

> (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)の平均値をとる
ことで精度を上げることができます。
    • good
    • 0
この回答へのお礼

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

お礼日時:2012/10/20 01:22

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報