ページ 1 / 1
[改訂版]2分法を使ってf(x)=0の解を求めるプログラムについて、間違っている箇所がわからないので訂正お願いします。
Posted: 2016年6月23日(木) 22:55
by yyy
f(x)=x^3-4x^2+x+12の近似解を求めるのですが、解が0.000010,0.000000 となりおかしいのですがどこを正すべきでしょうか。
コード:
#include <stdio.h>
int main(void)
{
double eps=0.00001;
printf("%lf %lf\n",eps);
double f(double x)
{
return x*x*x-4*x*x+x+12;
}
double g(double x1,double x2,double eps)
{
double x;
while(x2-x1>=eps)
{
x=(x1+x2)/2.0;
if(f(x1)*f(x)>0.0)
{
x1=x;
}
else
{
x2=x;
}
}
return (x1+x2)/2.0;
}
return 0;
}
Re: [改訂版]2分法を使ってf(x)=0の解を求めるプログラムについて、間違っている箇所がわからないので訂正お願いし
Posted: 2016年6月23日(木) 23:04
by みけCAT
まず、改善したコードを
元のトピックに書き込まず新しいトピックにしようという考えを正すべきです。
その上で、
- 現状ではepsをそのまま出力していており、全く解を求めていません。g()を宣言して何らかの形で呼び出すべきでしょう。
- フォーマットに対してprintfに渡す引数が足りないので、未定義動作です。データを増やすか、変換指定子を減らさなければいけません。
- 関数の中で関数を定義するのは標準ではできず、GCC拡張なので、必要が無ければやるべきではありません。
Re: [改訂版]2分法を使ってf(x)=0の解を求めるプログラムについて、間違っている箇所がわからないので訂正お願いし
Posted: 2016年6月23日(木) 23:30
by box
定義した関数g(mainの中にあるのが気持ち悪いけど)をどこで呼び出しているんですか?
なんか二分法の前に勉強することがたくさんありそうに思えてなりません。
Re: [改訂版]2分法を使ってf(x)=0の解を求めるプログラムについて、間違っている箇所がわからないので訂正お願いし
Posted: 2016年6月25日(土) 03:16
by かずま
yyy さんが書きました:f(x)=x^3-4x^2+x+12の近似解を求めるのですが、解が0.000010,0.000000 となりおかしいのですがどこを正すべきでしょうか。
main から g を適切に呼び出して、返ってきた結果を表示すればよいでしょう。
コード:
#include <stdio.h>
double f(double x) { return x*x*x - 4*x*x + x + 12; }
double g(double x1, double x2, double eps)
{
while (x2 - x1 >= eps) {
double x = (x1 + x2) / 2;
if (f(x1) * f(x) > 0)
x1 = x;
else
x2 = x;
}
return (x1 + x2) / 2;
}
int main(void)
{
printf("%f\n", g(-10, 10, 0.0000001));
return 0;
}
Re: [改訂版]2分法を使ってf(x)=0の解を求めるプログラムについて、間違っている箇所がわからないので訂正お願いし
Posted: 2016年6月25日(土) 09:45
by みけCAT
かずま さんが書きました:コード:
printf("%f\n", g(-10, 10, 0.0000001));
この呼び出し方は区間内で対象の関数が単調増加も単調減少もしないので、適切ではありません。
この関数f(x)をプロットするとこうなります。

- 関数のグラフ
- nibunhou-20160625.png (13.34 KiB) 閲覧数: 2968 回
これだけではわかりにくいですが、導関数をプロットすると符号が変わることがわかります。

- 導関数のグラフ
- nibunhou-bibun-20160625.png (17.65 KiB) 閲覧数: 2968 回
Re: [改訂版]2分法を使ってf(x)=0の解を求めるプログラムについて、間違っている箇所がわからないので訂正お願いし
Posted: 2016年6月25日(土) 11:41
by かずま
みけCAT さんが書きました:かずま さんが書きました:コード:
printf("%f\n", g(-10, 10, 0.0000001));
この呼び出し方は区間内で対象の関数が単調増加も単調減少もしないので、適切ではありません。
なるほど、(4-√13)/3 < x < (4+√13)/3、
すなわち 0.1314... < x < 2.535... では、f(x) は減少していますね。
[-10, 10] の範囲を指定したとき、最初の 1回で [-10, 0] になったから
たまたま解が求まっていたようです。
g(-10, 0, 0.00001) とか、g(-5, 0, 0.00001) とかで呼び出さないと、
適切な呼び出しとは言えませんね。
ご指摘ありがとうございました。