• ベストアンサー

どこがおかしいのでしょうか??

下のプログラムはsinの級数展開を求めるプログラム…を書いたつもりなんですが計算機と違う値がでてしまい困っています。どこをどう直せばいいのか教えてもらえませんでしょうか??それともこのプログラムではうまくいかないのでしょうか?返答をお願いします。 #include <stdio.h> #include<math.h> #define NMAX 100 main() { float eps,x,t,s; int n; printf("Taylor series\n"); scanf("%g", &eps); printf("eps=%g\n", eps); for(;scanf("%g", &x)!=EOF;){ printf("\nx=%g\n n\tt\t\ts\n", x); t=s=x; for(n=1;n<NMAX;n++){ t*=-x*x/((2*n+1)*(2*n)); s+=t; printf("%2d %15.6e %15.6e\n", n, t, s); if(fabs(t)<eps) break; } if(n>=NMAX) printf("--- not converged ---\n"); printf("exp(%g)=%g\tn=%d\n", x, s, n); } return(0); }

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

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

x=0の近くだと問題ないと思いますので、sin関数の周期性を利用して x ← 0≦x≦π/2 に変換して計算するとよいでしょう。 そのとき正確なπの値が必要になりますが、 π/2 = 3216.99・・・/2048 = 3217/2048-d を使って計算する方法がどこかにあったと思います。 (1/2048は2進数で表すと誤差がないので精度がよくなる) 精度を求めるなら多倍長演算する方がよいのかもしれませんが、収束が早い近似式を使わないと時間がかかってしまいますね。 電卓の場合はtan(x)を連分数展開で求めてsin(x)に変換するとかやっているのではないでしょうか。(自信なし)

hyokkorri
質問者

お礼

ありがとうございました~!

その他の回答 (2)

  • hpsk
  • ベストアンサー率40% (48/119)
回答No.2

どんな値を入力すればおかしくなるかを具体的に示していただいたほうが良いと思うのですが、 私が気づいた問題点としては、 Taylor展開後の第n項の値を、(前の項)×(x^2)/((2n+1)*2n) で求めているという点があります。 もちろん数学上は間違っていないですが、計算機で計算すると、 (x^2)/((2n+1)*2n) の値が1より大きい場合、前の項で生じた誤差が増幅されていってしまうので、正しい結果が得られません。 実際、x=31.4159 とかを入力すると結果がおかしくなりますよね。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

特別問題ないように思いますけど、 なんだったら、 floatじゃなく doubleで計算してみたらどうでしょうか?