以下のプログラムについて、二分法により解を求めていくのですが、k回目におけるx1とx2の値を表示していきたいのですが、うまくいきません。どこを改善すればよいでしょうか、教えてください。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define eps 1.0e-5
double f(double x){
return x*x*x-3*x*x+36*x-6;
}
void bisec(void);
int main(){
bisec();
return 0;
}
void bisec(void){
int k,a,b,i=0;
double x,x1,x2;
double datax1[a],datax2;
datax1[0]=x1;
datax2[0]=x2;
printf("初期値を入力してください\n");
scanf("%lf %lf",&x1,&x2);
printf("x1=%lf\n",x1);
printf("x2=%lf\n",x2);
if(f(x1)*f(x2)>0)
printf("初期値x1x2が不適当です\n");
else
{
printf("初期値x1=%lf,x2=%lfで求解\n",x1,x2);
while(!(fabs(x1-x2)<eps)){
i++;
x=(x1+x2)/2;
if(f(x)*f(xl)<0){
x2=x;
datax2=x2;
datax1=x1;
}else{
x1=x;
datax1=x1;
datax2=x2;
}
if(i==1000) break;
}
for(k=0;k<=i;k++){
printf("%d回目:x1=%lf x2=%lf",k,datax1[k],datax2[k]);
printf("\n");
}
printf("解は%fで、誤差はeps=%fです\n",x,eps);
}
}
関数の値の保存
Re: 関数の値の保存
> どこを改善すればよいでしょうか
まずはフォーラムルールを一読ください。「うまくいきません。」では伝わりません。
ちょっと見た感じでは
> double datax1[a],datax2;
コンパイルでエラーになりそう。配列の要素数が変数になっていて、その変数の値は初期化できていない。
> datax2[0]=x2;
datax2は配列ではない。
> datax1=x1;
datax1は配列。
いずれもコンパイラが吐き出すエラーをよく読めば改善できます。
まずはフォーラムルールを一読ください。「うまくいきません。」では伝わりません。
ちょっと見た感じでは
> double datax1[a],datax2;
コンパイルでエラーになりそう。配列の要素数が変数になっていて、その変数の値は初期化できていない。
> datax2[0]=x2;
datax2は配列ではない。
> datax1=x1;
datax1は配列。
いずれもコンパイラが吐き出すエラーをよく読めば改善できます。
Re: 関数の値の保存
上記のプログラムに不足がありましたので、貼り直します
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define eps 1.0e-5
double f(double x){
return x*x*x-3*x*x+36*x-6;
}
void bisec(void);
int main(){
bisec();
return 0;
}
void bisec(void){
int k,a,b,i=0;
double x,x1,x2;
double datax1[a],datax2;
datax1[0]=x1;
datax2[0]=x2;
printf("初期値を入力してください\n");
scanf("%lf %lf",&x1,&x2);
printf("x1=%lf\n",x1);
printf("x2=%lf\n",x2);
if(f(x1)*f(x2)>0)
printf("初期値x1x2が不適当です\n");
else
{
printf("初期値x1=%lf,x2=%lfで求解\n",x1,x2);
while(!(fabs(x1-x2)<eps)){
i++;
x=(x1+x2)/2;
if(f(x)*f(x1)<0){
x2=x;
datax2=x2;
datax1=x1;
}else{
x1=x;
datax1=x1;
datax2=x2;
}
if(i==1000) break;
}
for(k=0;k<=i;k++){
printf("%d回目:x1=%lf x2=%lf",k,datax1[k],datax2[k]);
printf("\n");
}
printf("解は%fで、誤差はeps=%fです\n",x,eps);
}
}
改善したい点としては、2分法により解を求めることはできているのですが、k回目のx1とx2の値がうまく表示されないところです。実行結果を以下に貼ります。
初期値を入力してください
x1=-10.000000
x2=15.000000
初期値x1=-10.000000,x2=15.000000で求解
0回目:x1=0.168916 x2=0.168916
1回目:x1=0.168916 x2=0.168916
2回目:x1=0.168916 x2=0.168916
3回目:x1=0.168916 x2=0.168916
4回目:x1=0.168916 x2=0.168916
5回目:x1=0.168916 x2=0.168916
6回目:x1=0.168916 x2=0.168916
7回目:x1=0.168916 x2=0.168916
8回目:x1=0.168916 x2=0.168916
9回目:x1=0.168916 x2=0.168916
10回目:x1=0.168916 x2=0.168916
11回目:x1=0.168916 x2=0.168916
12回目:x1=0.168916 x2=0.168916
13回目:x1=0.168916 x2=0.168916
14回目:x1=0.168916 x2=0.168916
15回目:x1=0.168916 x2=0.168916
16回目:x1=0.168916 x2=0.168916
17回目:x1=0.168916 x2=0.168916
18回目:x1=0.168916 x2=0.168916
19回目:x1=0.168916 x2=0.168916
20回目:x1=0.168916 x2=0.168916
21回目:x1=0.168916 x2=0.168916
22回目:x1=0.168916 x2=0.168916
解は0.168916で、誤差はeps=0.000010です
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define eps 1.0e-5
double f(double x){
return x*x*x-3*x*x+36*x-6;
}
void bisec(void);
int main(){
bisec();
return 0;
}
void bisec(void){
int k,a,b,i=0;
double x,x1,x2;
double datax1[a],datax2;
datax1[0]=x1;
datax2[0]=x2;
printf("初期値を入力してください\n");
scanf("%lf %lf",&x1,&x2);
printf("x1=%lf\n",x1);
printf("x2=%lf\n",x2);
if(f(x1)*f(x2)>0)
printf("初期値x1x2が不適当です\n");
else
{
printf("初期値x1=%lf,x2=%lfで求解\n",x1,x2);
while(!(fabs(x1-x2)<eps)){
i++;
x=(x1+x2)/2;
if(f(x)*f(x1)<0){
x2=x;
datax2=x2;
datax1=x1;
}else{
x1=x;
datax1=x1;
datax2=x2;
}
if(i==1000) break;
}
for(k=0;k<=i;k++){
printf("%d回目:x1=%lf x2=%lf",k,datax1[k],datax2[k]);
printf("\n");
}
printf("解は%fで、誤差はeps=%fです\n",x,eps);
}
}
改善したい点としては、2分法により解を求めることはできているのですが、k回目のx1とx2の値がうまく表示されないところです。実行結果を以下に貼ります。
初期値を入力してください
x1=-10.000000
x2=15.000000
初期値x1=-10.000000,x2=15.000000で求解
0回目:x1=0.168916 x2=0.168916
1回目:x1=0.168916 x2=0.168916
2回目:x1=0.168916 x2=0.168916
3回目:x1=0.168916 x2=0.168916
4回目:x1=0.168916 x2=0.168916
5回目:x1=0.168916 x2=0.168916
6回目:x1=0.168916 x2=0.168916
7回目:x1=0.168916 x2=0.168916
8回目:x1=0.168916 x2=0.168916
9回目:x1=0.168916 x2=0.168916
10回目:x1=0.168916 x2=0.168916
11回目:x1=0.168916 x2=0.168916
12回目:x1=0.168916 x2=0.168916
13回目:x1=0.168916 x2=0.168916
14回目:x1=0.168916 x2=0.168916
15回目:x1=0.168916 x2=0.168916
16回目:x1=0.168916 x2=0.168916
17回目:x1=0.168916 x2=0.168916
18回目:x1=0.168916 x2=0.168916
19回目:x1=0.168916 x2=0.168916
20回目:x1=0.168916 x2=0.168916
21回目:x1=0.168916 x2=0.168916
22回目:x1=0.168916 x2=0.168916
解は0.168916で、誤差はeps=0.000010です
Re: 関数の値の保存
ソースコードを提示する際は、BBCodeが有効な(無効にしない)状態で、
BBCodeのcodeタグの開始タグと終了タグの組(開始タグが先)で囲んでいただけると、
見やすくてありがたいです。
Wandboxで実行したところ、
という警告が出て、実行結果は
となりました。
・datax1およびdatax2の要素数を未初期化の自動変数ではなく、1001にする
(停止条件にマジックナンバー1000が使われているため。定数を定義して利用するとさらに良くなるでしょう)
・datax1[0]およびdatax2[0]への代入を、scanfの直後に移動する
と改善するでしょう。
BBCodeのcodeタグの開始タグと終了タグの組(開始タグが先)で囲んでいただけると、
見やすくてありがたいです。
Wandboxで実行したところ、
prog.c: In function 'bisec':
prog.c:18:1: warning: 'a' is used uninitialized in this function [-Wuninitialized]
18 | double datax1[a],datax2[b];
| ^~~~~~
prog.c:18:1: warning: 'b' is used uninitialized in this function [-Wuninitialized]
prog.c:19:10: warning: 'x1' is used uninitialized in this function [-Wuninitialized]
19 | datax1[0]=x1;
| ~~~~~~~~~^~~
初期値を入力してください
x1=-10.000000
x2=15.000000
初期値x1=-10.000000,x2=15.000000で求解
0回目:x1=0.000000 x2=0.000000
1回目:x1=-235.921875 x2=-235.921875
2回目:x1=-3.750000 x2=-3.750000
解は-3.750000で、誤差はeps=0.000010です
・datax1およびdatax2の要素数を未初期化の自動変数ではなく、1001にする
(停止条件にマジックナンバー1000が使われているため。定数を定義して利用するとさらに良くなるでしょう)
・datax1[0]およびdatax2[0]への代入を、scanfの直後に移動する
と改善するでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)