- ベストアンサー
C言語 正弦関数の級数展開のプログラム
sinxの級数展開を7項まで取った場合と組み込み関数で求めたsinxの値の差を,0度から360度まで,プログラムを作成して求めよ、という問題がわかりません。 どなたか、わかる方がいまいたら、教えてください。
- みんなの回答 (9)
- 専門家の回答
質問者が選んだベストアンサー
pow(x,3/p1) ではなくて pow(x,3)/p1 ですね
その他の回答 (8)
- koko_u_
- ベストアンサー率18% (459/2509)
階乗の計算に int 型を使っているので オーバーフローしています。 float の有効桁数は 7桁です。double でも 15桁。 他は見ていませんが、単純に級数展開の式を使うとどんどん精度が落ちていきます。 誤差が拡大しないように計算式を工夫しましょう。
- asuncion
- ベストアンサー率33% (2127/6289)
> 7項で終わる場合は終了条件を k <= 7 にすればよいでしょう k > 7 ではありませんか?
- php504
- ベストアンサー率42% (926/2160)
ちょっと実行してみましたがこれは p6=kaijyo(13); でオーバーフローしてますね。 昔作ったプログラムがあったので参考にどうぞ double mysin(double x) { double EPS = 1e-08; /* 項の値がこれより小さくなったらループ終了 */ double s = 0.0; /* 求める sin 値 */ int k; /* 項数 */ int n; /* 級数(1, 3, 5, 7, ...) */ int sign = 1; /* 加算か減算かのための変数。1項ごとに符号が反転 */ double diff; /* 項の値 (x^n/n!)*sign */ int i; /* ループ用の変数 */ k = 1; for (; ;) { n = 2 * k - 1; diff = 1.0; /* x^n / n! */ for (i = 1; i <= n; i++) { diff *= x / i; } if(diff < EPS) { break; } /* + or - */ diff *= sign; s += diff; k++; sign *= -1; } return s; } 7項で終わる場合は終了条件を k <= 7 にすればよいでしょう
- asuncion
- ベストアンサー率33% (2127/6289)
> p1=kaijyo(3); > p2=kaijyo(5); > p3=kaijyo(7); > p4=kaijyo(9); > p5=kaijyo(11); > p6=kaijyo(13); ループの中で毎回これらを計算するのは効率が悪いです。 それから、13の階乗はint型で扱える範囲を超えてしまうため、 p6の値は正しくありません。 ロジックを見直す方がよいと思います。
補足
回答ありがとうございます。 double kaijyo(double k) { double seki,i; seki=1; for(i=1;i<=k;i++){ seki*=i; } return(seki); } と直しました。 int sum(int a,int b) { int ans; ans=a+b; return ans; } main() { z=sum(a,b); } のように項数と角度を渡すと値を返すような関数を作成したいのですが、項数と角度の渡し方(上記でいうz=sum(a,b))をどのように変えればいいかわかりません。ヒントでもいいので教えてください。
- php504
- ベストアンサー率42% (926/2160)
級数展開部分のプログラムを見せてもらえませんか おそらく角度がラジアンになっていないのではないでしょうか 組み込み関数は #include <math.h> で使えるようになる double sin(double x) のことです。 この関数の値と自作関数(例えばmysin( ))の値の差を求めよということなので mysin(x) - sin(x)の値をプリントすればよいでしょう
補足
#include<stdio.h> #include<conio.h> #include<stdlib.h> #include<math.h> main() { int kaijyo(int k); int i,p1,p2,p3,p4,p5,p6; float deg,z,a,x; float pi=3.1415926535897932384626433832795; for(i=0;i<=360;i+=5){ p1=kaijyo(3); p2=kaijyo(5); p3=kaijyo(7); p4=kaijyo(9); p5=kaijyo(11); p6=kaijyo(13); x=pi*i/180; z=x-pow(x,3/p1)+pow(x,5/p2)-pow(x,7/p3)+pow(x,9/p4)-pow(x,11/p5)+pow(x,13/p6); printf("%d,%f\n",i,z); } getch(); exit(0); } int kaijyo(int k) { int seki,i; seki=1; for(i=1;i<=k;i++){ seki*=i; } return(seki); } 実行結果の前にpow: DOMAIN errorとなっているので、powの使い方が間違っているのでしょうか?
- php504
- ベストアンサー率42% (926/2160)
1. sin xの級数展開がわからない 2. 7項まで取った場合がわからない 3. 組み込み関数がわからない 4. 値の差を求めるのがわからない 5. 0度から360度までがわからない 6. プログラムの作成がわからない なにがわからないのでしょうか。 ここでは問題の丸投げはだめです。 自分である程度プログラムを書いてそれを書き込むと回答率が上がります。
補足
回答ありがとうございます。 とりあえずsinxの級数展開部分のプログラムを作ってみたのですが、電卓でsinxを計算した場合と0から90°はほぼ等しいのですが、90から180の値は減少せずに増加し、180から360°はマイナスの値が出てこず、電卓の値と全く違ってわかりません。 3と4もわかりません。 よろしくお願いします。
- asuncion
- ベストアンサー率33% (2127/6289)
プログラムを書く前の話として、 「sinxの級数展開を7項まで取った場合」は おわかりですね?
補足
回答ありがとうございます。 「sinxの級数展開を7項まで取った場合」は x-x^3/3!+x^5/5!-x^7/7!+x^9/9!-x^11/11!+x^13/13!です。 よろしくお願いします。
- koko_u_
- ベストアンサー率18% (459/2509)
>どなたか、わかる方がいまいたら、教えてください。 常套句ですが、わかる人を探すより前に girugiru さんが何がわからないかを補足しなければいけません。
お礼
ありがとうございました。 エラーなく動作しました。