質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

4回答

1756閲覧

課題の考え方がわかりません

tocchi

総合スコア8

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2018/07/01 01:12

前に質問してからしばらく考えてみた結果今だによくわからないままなので再質問します。
関数y=sin(x)のテイラー展開は次式で求められる。n番目の値が1*10^-8よりも小さくなるまでの級数を求め、任意のxに対するsin(x)を近似して求めよ。
y=sinx=Σ((-1)^n /(2n+1)!)*x^2n+1
というものをc言語を使って求めるという課題が出ました。コードを書いてみたのですが答えが0.000000000となってしまい正しい答えが出ません。直した方がいいところを教えていただきたいです。できるだけわかりやすく教えていただきたいです。

#include <stdio.h> #include <math.h> int main(void){ float n,x,sum,coeff_mole,coeff_deno,vari,series; printf("任意のxを入力>>"); scanf("%d",&x); n = 0.0; sum = 0.0; while(1){ //mole_計算 coeff_mole = pow(-1.0,n); //deno_計算 coeff_deno = 1; for(int i = 2*n+1;i>0;i--){ coeff_deno = coeff_deno+i; } //vari_計算 vari = pow(x,2*n+1); //series_計算 series = coeff_mole/coeff_deno*vari; if(series >= pow(10,-8)){ sum = sum + series; }else{ break; } n++; } printf("近似値は>>%.10f",sum); return 0; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

考え方は問題ありませんが、コーディングで3点ほどミスがあるようです。

1. scanf の変換指定が正しくありません。
floatを入力させるための変換指定子は%fです。

2. 階乗の計算が加算になっています。
「//deno_計算」の部分を再確認してみてください。

3. 終了条件の判定に誤りがあります。
nが奇数のときの項は負の数になるので、その時点で必ず終了してしまいます。

3に関しては、例えば下記のような修正はいかがでしょうか。

C

1//series_計算 2series = coeff_mole / coeff_deno * vari; 3 4if (fabs(series) >= pow(10, -8)) { 5 sum = sum + series; 6}

以上の3点を修正すれば、とりあえず目的通りに動くはずです。

こういうデバッグでは、自分が思った通りの処理ができているかをしっかり確認すると良いですよ。
(途中結果を出力してみる、IDEのデバッグモードを使うなど。)

投稿2018/07/01 06:38

編集2018/07/01 11:59
shiron46

総合スコア111

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/07/01 10:10

> 3. 終了条件の判定に誤りがあります。について x > 0の時、第2項目が負になり、初項しか足されない x < 0の時、第(2k + 1)項目が負になるので結果が0になる これを解決する方法の一つはマクローリン展開のそれぞれの係数の「絶対値」をとればいいと思います。 実際にコードにすると while(fabs(series) >= pow(10,-8)){}
shiron46

2018/07/01 11:59 編集

ご指摘ありがとうございます。 恥ずかしながら、x < 0 の場合がごっそり頭から抜けておりました。 コードは修正しておきました。
退会済みユーザー

退会済みユーザー

2018/07/01 14:21

@shiron46さんへ ソースコードを修正してくださり、ありがとうございます。
guest

0

今までの回答以外に

  • if(series >= pow(10,-8)){

  • if(fabs(series) >= pow(10,-8)){

にすれば動くでしょう。seriesはcoeff_moleにより正と負をとりえますから絶対値にして比較しなければなりません。

投稿2018/07/01 06:28

ikapy

総合スコア1167

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

とりあえず2点
scanfの使い方が違います。
テイラー展開の近似は任意の点では有効ではありません。基準点(この場合原点)近傍以外では無効です。

投稿2018/07/01 04:51

HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/07/01 10:03

>テイラー展開の近似は任意の点では有効ではありません。 今回のsin(x)のマクローリン展開は |x| < ∞ で成り立つので任意の点で有効なはずですが....
HogeAnimalLover

2018/07/01 11:52

マクローリン展開は原点を離れるほど誤差範囲が広がります。定義だけならできますけど。 マクローリン展開による近似式はあくまでも有限多項式ですから、原点を離れるほど、最高次の項が優位となります。つまり、両端では単調増加または単調減少関数になるので、三角関数とは似つかない形になります。
退会済みユーザー

退会済みユーザー

2018/07/01 14:29 編集

マクローリン展開について何か勘違いをしていませんか? たとえば、log(1 + x)だったら、収束半径は |x| < 1より xが1より大きい場合は誤差範囲は広がります。 収束半径が∞でない場合はあなたのおっしゃる通りです。 しかし、今回の関数はsin(x)です。sin(x)は収束半径が |x| < ∞ より、xがどの値であっても必ず 右辺は収束し、左辺と等しくなります。(xがどんな値をとっても右辺はライプニッツの交代級数です。) 詳しくは https://mathtrain.jp/sincostenkai をご覧ください。 また、sin(x)のマクローリン展開は符号が交互に入れ替わるので単調増加関数でも単調減少関数でもありません。少しずつ値が増えたり、減ったりして、増える値、減る値の絶対値が小さくなり収束していきます。
HogeAnimalLover

2018/07/01 17:45

どうやら、互いに話が噛み合っていませんね。私はコンピュータ近似の都合上の有限性を原因とした誤差について述べています。 仰るとおり、無限に次数を高めれば収束範囲内で展開結果の誤差はゼロに近づきます。ただし、コンピュータ処理において無限はありえません。 有限近似である限り、展開結果は有限多項式でしかなく、原点から充分離れた範囲では単調関数になります。
退会済みユーザー

退会済みユーザー

2018/07/02 05:02 編集

なるほど、コンピューター近似の都合上の話ですか、誤解してすみません。 ただ、回答の「テイラー展開の近似は任意の点では有効ではありません。」だと、今回のように 語弊がある場合があるので「マクローリン展開を用いて、コンピューターでsin(x)の近似を求める際、あまり大きな値を入力だと誤差が出る」などのように書き直した方がいいでしょう。 一般にマクローリン展開において収束半径が無限大の場合、任意の点で有効ですから. (n番目の値の絶対値が10^-8未満になるまで求めるのである程度までは誤差範囲は小さくて済みます。) ちなみに解決方法としては入力した値をn回転して、-pi <= x <= pi にすればいいでしょう。
guest

0

これだけでは正しく動かないのでさらに修正が必要なようですが、floatを入力させるためのscanfの書式は%fです。

投稿2018/07/01 02:14

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問