• ベストアンサー

二分法のC++プログラム

#include<iostream> #include<cmath> using namespace std; int main(){ double x1, x2, c; cout <<"x1:"; cin >> x1; cout <<"x2:"; cin >> x2; while(fabs(x2-x1) > 0.00001){ c=(x1+x2)/2; if(cos(x1/2.0)*cos(c/2)>=0) x1 = c; else x2 = c; } cout << "x=" << x1 <<endl; return 0; } cos(x/2)=0の解となるxを挟んでいないx1,x2を与えると、結果は保証できないですが、それは別にいいんですか?それはダメだとするとどこを訂正すればいいんですか

noname#127615
noname#127615

みんなが選んだベストアンサー

  • ベストアンサー
  • f272
  • ベストアンサー率46% (8012/17124)
回答No.1

> 解となるxを挟んでいないx1,x2を与えると、結果は保証できないですが、それは別にいいんですか? よいわけないでしょ。 > それはダメだとするとどこを訂正すればいいんですか 入力されたx1とx2で解を挟んでいるかどうか確認して,挟んでなければもう一度入力させるのが一番簡単。それがいやなら,自動的に入力した区間を大きくするのでもよい

noname#127615
質問者

補足

どこを訂正すればいいんですか

その他の回答 (4)

  • ninoue
  • ベストアンサー率52% (1288/2437)
回答No.5

#4 です。 問題を読み間違えていたようですみません。 問題は、f(x/2)=cos(x/2)=0.0 となる xの値を求められているのですね。 f(x)=cos(x)=0.0 となる点を求めることを考えてコメントしていました。 (指定した変数に直接対応する関数の値を考えるのが普通だと考えていましたので) 申し訳ありませんでした。 cos(x/2)=0 を挟まない x1,x2が与えられた場合の処理についてですが、 while(...){...} の前に入力チェック、変数レンジ変更のロジックを追加します。 まず後の処理を分かりやすくするため、x1<x2となるように必要であれば入力を入れ替えます。 f(x1),f(x2)の符号が異なる場合は現在のwhile文へ進みます。 そうでない場合、dx=x2-x1; を先ず計算します。 その後、関数値の絶対値が小さい方へ、x1或いはx2を適当なステップ幅で 進めて行き、f(x1),f(x2)が異なった符号値になるまで繰返します。 (例えば 0<f(x1)<f(x2) の時、c=x1-dx; x1=c; として繰返す) その途中で一定回数繰返しても異なった値にならない場合、エラーとする必要があると思われます。 (関数値の変化割合:(f(c)-f(x2))/f(x2):が小さすぎる場合(例えば1/32以下等)は、ステップ幅dxを大きくする等の考慮も最適化迄考えると必要になりますが、初めはそこまでは不要でしょう) 以上等を考慮して検討を進めてください。

  • ninoue
  • ベストアンサー率52% (1288/2437)
回答No.4

http://okwave.jp/qa5396700.html 二分法のC++プログラム >簡単なプログラムが自分の思った通りには実行されない場合、 >まずデバッガでステップ実行し、関係する変数値、関数値、どのパスを通っているのかを確認する、 >或いはプリント文を追加し各変数値、関数値、通っているパス等を確認する >以上をやることはプログラマとしての常識のはずです。 >また関数としては何を考えているのですか、確認してください。 >これまでの他の人のヒントも考慮すれば解決出来るはずです。 >分かってしまえば簡単な事ですから、後は人に頼らず自分で解いてください。 >そうしないといつまでも力が付かないと思います。 以上の通り指摘していたはずですか、各変数値、関数値、実行パスの確認はされましたか? 次のようにprint文を2行追加すればすぐに分かるはずです。 関数値は0に近い値ですか、次第に0に近づいていますか? if(...){ print(...); ... } else { print(...); ... } 本当は机上デバッグをすればすぐに分かるはずです。 関数としては何を考えているのですかとのヒントで誤りに気が付かれることを期待していたのですが。 プログラムの中に不要な文字が6文字含まれています。

回答No.3

「解は保証できない」ではなく、「最初に入 れた x1, x2 の値のいずれかに収束」します。 ※冷静に考えれば、どちらに収束するかもわか  ります。 あと、プログラムの中に、意味の上では間違っ ているところが1カ所あります。 正しい解が求められるときには、たまたま、 x1 == x2 == c に収束するので、表示される 結果はあっていますが。 (その意味では、まあ、間違っているとも言 えず、「気持ち悪い」程度かもしれません) 最初に入力された x1, x2 が解を挟むかどうか は、一般的には、求める方程式 f(x) = 0 に対 して、f(x1) と f(x2) の符号が異なるという ことですが、このプログラムは、f(x) が単調 増加することを前提としているので、f(x1) > 0 かつ f(x2) < 0 が「解を挟む必要条件」です。 (ただし、x1 > x2) さらにいえば、これは、「ひとつ以上の解を 挟む」ための条件に過ぎないので、x1, x2 の 範囲が広くて、ふたつ以上の解を挟んでしま うと(その間に単調減少している部分が存在 するので)失敗することもあります。 これを考えると。 ・f(x1) > 0 かつ f(x2) < 0 (x1 > x2) ・f(x1) < 0 かつ f(x2) > 0 (x1 < x2) ・f(x1) = f(x2) = 0 (x1 = x2) ・x1 - x2 の絶対値が f(x) の 1/2 以下 が必要十分条件かなと思います。 最初の3つをまとめると ・f(x1)(x1 - x2) > 0 かつ f(x2)(x1 - x2) < 0 ・x1 - x2 の絶対値が f(x) の 1/2 以下 になるのかな?(未検証)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

「結果が保証できないけどそれでいいのかどうか」あるいは「それでダメなときにどう訂正すればよいか」はあなたがこのプログラムで解こうとしている問題に依存します. 「よくない」と断言してしまうのはちょっと勇み足っぽい気がします>#1.

関連するQ&A

  • C++で二分法のプログラム

    C++で二分法のプログラムを作るんですが x1-x2が十分小さくなれば(10^-5)終了する 例 cos(x/2)の解を出す これどうやればいいんですか?whileを使うらしいですが。 文法というのは、 if系、while、switch、continue、for、break文くらいしかやってないんですが #include <iostream> #include <cmath> using namespace std; int main() { までは行きますが… 出力はcout 入力はcinでお願いできないでしょうか

  • 二分法のC++プログラム

    #include<iostream> #include<cmath> using namespace std; int main(){ double x1, x2, c, a; double x1, x2, c; cout <<"x1:"; cin >> x1; cout <<"x2:"; cin >> x2; while(x2-x1 > 0.00001){ c=(x1+x2)/2; c=(x1+x2)/2; if(cos(x1/2)*cos(c/2)>=0) x1 = c; else x2 = c; } cout << "x=" << x1 <<endl; return 0; } x1 cos(x/2)って入れると x2 -9.25596e+061 って出て cos(pi/2)って入れても同じ風に出てしまうんですがこれも同じように出るんですが故障ですか? x1に3と入れると x2が出てきて、x2は4と入れると xが3.14159と出て、3回xが出ますが、上の2つ(cos(pi/2)とcos(x/2))はx1とx2しか出ません .

  • C++で二次方程式のプログラム

    大分前に二次方程式のプログラムを作るって問題が出ていました。 しかし、セットで作ったプログラムのフローチャートを書くんですがフローチャートが分かりません。 条件は 虚数解 a=0 実数解 の場合分けをして、解を出すってプログラムなんですが、多分、それ自体は合っていると思います。 しかし、そのフローチャートを書きなさいって問題があったんですが、それが未だに分からないんですが、これをフローチャートに書くとすると、どう書けばいいですか? #include <iostream> #include <cmath> using namespace std; int main() { double a,b,c,d,x0,x1; cout << "aを入力してください\n"; cin >> a; cout << "bを入力してください\n"; cin >> b; cout << "cを入力してください\n"; cin >> c; d=b*b-4*a*c; x0 = (-b + sqrt(d)) / (2 * a); x1 = (-b - sqrt(d)) / (2 * a); if(a==0) { cout << "解は1つで" << -c/b << "です\n"; } else if(d>0) { cout << "解は二つの実数解で,解は" << x0 << "," << x1 << "です\n"; } else { cout << "解は二つの虚数解で,解は" << (-b) / (2 * a) << "+i" << sqrt(-d) / (2 * a) << " , " << (-b) / (2 * a) << "-i" << sqrt(-d) / (2 * a) << "です\n"; } return 0; }

  • C++の二次方程式のプログラム

    二次方程式の解を求めるプログラムで虚数解の場合、a=0の場合、実数解の場合で求めるようにしているんですが、 #include <iostream> #include <cmath> using namespace std; int main() { double a,b,c; cin >> a >> b >> c; if(a==0) { cout << (-c/b) << '\n'; } else if((b*b-4*a*c)<0) { cout << (-b/2/a) << 'i' << sqrt(4*a*c-b*b)/2/a << '\n'; } else { 次にcout が来るのは分かってるんですが、数学でこういう書き方しなし、ここから先の書き方が分からないんですが、どうやって書けばいいですか? 多分return 0; } のぞいてあと2行か1行だと思うんですが

  • javaプログラミング

    以下のプログラムがコンバイルできません なぜでしょうか? #include<iostream> #include<cmath> using namespace std; int main() { double a, b; cout << "実数 a の値を入力してください " << endl; cin >> a; cout << "実数 b の値を入力してください " << endl; cin >> b; cout << a << " の " << b << " 乗は " << pow(a, b) << "です" << endl; return 0; }

    • ベストアンサー
    • Java
  • 二次方程式のプログラム

    C++で二次方程式の解を求めるんですが、虚数解の場合、a=0の場合、実数解の場合で求めるようにしているんですが、 #include <iostream> #include <cmath> using namespace std; int main() { double a,b,c; cin >> a >> b >> c; if(a==0) { cout << (-c/b) << '\n'; } else if((b*b-4*a*c)<0) { cout << (-b/2/a) << 'i' << sqrt(4*a*c-b*b)/2/a << '\n'; } else { この先の最後の一文教えてください。抜けてて書いてないんです。

  • プログラミング言語Cとプログラミング言語C++

    プログラミング言語Cとプログラミング言語C++の違いって何ですか? あと、プログラミング言語C++についていくつか質問があります。 #include <iostream> using namespace std; void main(){ cout << "Hello world!" << endl; } このプログラムについて質問なんですが、iostreamってプログラミング言語Cで言うstdio.hのことですか? using namespace stdって何ですか? あと、 cout <<"Hello world!"って何ですか?

  • C++で2点間の内積と距離を求めるプログラム

    C++で2点間の内積と距離を求めるプログラムを作ったのですが、コンパイルの時点でエラーが6つも出てしまいます>< 何がいけないのでしょうか? #include <iostream> #include <cmath> using namespace std; int main(void){ int x, y, z, w, l, n; cin >> x >> y >> z >> w; n=x*w+y*z;   l=sqrt((x-z)(x-z)+(y-w)(y-w)); cout << "距離は" << l << "で、内積は" << n; return 0; }

  • c++ 整数値の各桁を足し合わせるプログラム

    上記の通りの質問です #include <iostream> using namespace std; int main () { int x; int sum = 0; cout << "正の整数値の各桁を足す。\n " ; do{ cout << "正の整数値:"; cin >> x; }while (x <= 0); cout << "足すと"; while (x > 0){ cout << sum += x % 10; x /= 10; return sum; } cout << "です。\n " ; } とまでは書けましたがうまくいきません。 初心者なので簡単かもしれませんがお願いします。

  • C++

    C++で書いた下記のプログラムが、文字の入力が1023個までなら実行されますが、1024個を超えると実行されません。なぜだか分かる方、教えてください。 #include <iostream> #include <string> using namespace std; int main(void) { string Str; cin >> Str; cout << "here"; }

専門家に質問してみよう