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

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

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

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

Q&A

解決済

1回答

2568閲覧

二分法と積分を組み合わせて方程式を解くことについて

lack_un

総合スコア58

C

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

0グッド

1クリップ

投稿2016/06/20 23:13

###前提・実現したいこと
∫[0,a]dx/1+sin(x/2)-2=0が成立するaを計算せよ。
ただし、0<a<10とする。
###発生している問題・エラーメッセージ

aの答えは1.24994です。 おそらく本当の答えは円周率πと同じ3.1415...になると思われるが(手計算)、そうならなかった。

###該当のソースコード

C

1#include <stdio.h> 2#include <math.h> 3double Nibun(double a,double b); 4double Kansu(double x); 5double Sekibun(double b); 6double f(double x); 7 8int main(){ 9 10 double a,b,x; 11 12 a=0; 13 b=10.0; 14 15 x = Nibun(a,b); 16 17 printf("aの答えは%fです。",x); 18 19 return 0; 20} 21 22double Nibun(double a,double b){ 23 24 double c; 25 double e = 0.0001; //誤差 26 int flag = 1; 27 28 while(flag){ 29 30 c = (a+b)/2.0; 31 32 if(Kansu(a)*Kansu(b)<0){ b=c; } 33 else{ a=c; } 34 35 if( b-a < e){ flag = 0; } 36 37 } 38 39 return a; 40} 41 42double Kansu(double x){ 43 44 double y; 45 46 y = Sekibun(x) - 2.0; 47 48 return y; 49} 50 51double Sekibun(double b){ 52 53 double x,h,a,sum; 54 int i,num; 55 56 57 h = 0.0001; 58 a = 0.0; //積分区間。bがもう片方の積分区間になり、aは固定されている。 59 num = (b-a)/h; 60 sum = 0; 61 62 for(i=0; i<num; i=i+2){ 63 x=a + h*i; 64 sum = sum + (f(x)+4*(x+h)+f(x+2*h))/3*h; 65 } 66 67 return sum; 68} 69 70double f(double x){ 71 72 double y; 73 74 y = 1.0 / 1.0 + sin(x/2.0); 75 76 return y; 77}

###試したこと
プログラムの流れとしては、Nibunに引数を渡し、ここで二分法を行い方程式を解きます。
その時に、検査したい方程式をKansuに渡します。Kansuの中で積分が入った式があるので、これを別に計算してもらうSekibunに渡します。
どこがうまくいっていないのか、一日考えたのですがわかりません。
ご教授お願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

1.0 / 1.0 + sin(x/2.0);

1.0 /( 1.0 + sin(x/2.0) );
の間違いでは?


(∫ dx (1.0 + sin(x/2.0)) from x = 0 to a ) = 2
だとしても
a≒1.487らしいので
他にも間違っているんでしょうが。


二分法も間違えてます。
比較すべきはKansu(a)*Kansu(b)ではなくKansu(c)*Kansu(b)です。
参考


積分も間違えてます。
これは
f(x) = 1 としてSekibun(1)を計算してみれば
明らかにおかしいことに気づけます。


ただ眺めてもバグを見つけるのは難しいです。
プログラムの構成要素を一つ一つに分解して
正しい動作をしているか実際に動かして確かめましょう。

今回であれば、

  • 適当な簡単な関数に対して、定積分が正しく行えるか。
  • 適当な簡単な方程式に対して、二分法で解が正しく求められるか。

・・・
みたいにです。

投稿2016/06/20 23:21

編集2016/06/21 00:04
ozwk

総合スコア13512

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

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

lack_un

2016/06/21 07:36

ありがとうございます。 理解できました。指定箇所を直せば3.14に近い値が出ました。 二分法、積分ともに理解が不十分でした。参考文献とともにもう一度勉強しようと思います。
ozwk

2016/06/21 08:00

思うに、あなたが一日中悩んだのは、 二分法や数値積分の理解が足らなかったのが原因ではなく、 デバッグのやり方を知らなかっただけではないかと。 対象を充分理解していてもバグなく一発で実装できる事のほうが稀ですし、 理解が充分であるとむしろ正しく書いたと思い込んじゃうので 読んでも自分ではわかりません
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問