设计要求:二分法解非线性方程:给定非线性方程(x*x*x-2.0*x-2=0),输入区间起点实数A和终点实数B ,输出满足最大误差(EPS=0.4E-14)时,最后的区间起点,区间终点,非线性方程根的近似值(使用双精度double类型精确到小数点后15位有效数)。
输入格式
m(整数,实验数据总数)
A1 B1(实数,区间起点与终点)
A2 B2(实数,区间起点与终点)
Am Bm(实数,区间起点与终点)
输出格式
A B X(输出满足最大误差(EPS=0.4E-14)时,最后的区间起点,区间终点,非线性方程根的近似值)
A B X(输出满足最大误差(EPS=0.4E-14)时,最后的区间起点,区间终点,非线性方程根的近似值)
A B X(输出满足最大误差(EPS=0.4E-14)时,最后的区间起点,区间终点,非线性方程根的近似值)
设计思路:该实验主要是两个函数,一个是funx用于计算出函数值,一个main函数用于二分法计算零点区间以及输入输出,对于funx函数的设计就是简单的传递参数x然后返回值是函数值,既x*x*x+2*x-2。对于主函数则是主要关于二分法的设计也就是在while循环里面,
while(1){ay = funx(am[i]);by = funx(bm[i]);axb[i] = (am[i]+bm[i])/2;axby = funx(axb[i]);if(ay*axby<0) bm[i] = axb[i];//f(a)·f(x)<0,此时我们有x*∈[a,x];if(ay*axby>0) am[i] = axb[i];//f(a)·f(x)>0,此时我们有x*∈[x,b];if(ay*axby==0) bm[i] = axb[i];//f(a)·f(x)=0,此时我们有x*∈[a,x];if((fabs(am[i]-bm[i]))/2<=0.4E-14) break;}
通过不断调用funx函数计算y值来判断零点与x中值位置关系,f(a)·f(x)<0,此时我们有x*∈[a,x];f(a)·f(x)>0,此时我们有x*∈[x,b];f(a)·f(x)=0,此时我们有x*∈[a,x];然后更新零点区间,再然后判断误差是否满足题目要求,如果无满足要求则继续进行二分法计算新的x区间。函数内采用三个double类型数组am[m],bm[m],axb[m]来存储x值,其中am存的是起点值。bm是终点值,而axb则是中值;其对应的y值则是double ay = 0.00,by = 0.0,axby = 0.0。至此程序大致设计完成。
完整代码:
#include <stdio.h>#include <stdlib.h>#include <math.h>double funx(double x){double y = x*x*x-2.0*x-2;return y;}//计算函数y值int main(){double ay = 0.00,by = 0.0,axby = 0.0;int m;scanf("%d",&m);double am[m],bm[m],axb[m];for(int i=0; i<m; i++){scanf("%lf %lf",&am[i],&bm[i]);}for(int i=0; i<m; i++){while(1){ay = funx(am[i]);by = funx(bm[i]);axb[i] = (am[i]+bm[i])/2;axby = funx(axb[i]);if(ay*axby<0) bm[i] = axb[i]; //f(a)·f(x)<0,此时我们有x*∈[a,x];if(ay*axby>0) am[i] = axb[i]; //f(a)·f(x)>0,此时我们有x*∈[x,b];if(ay*axby==0) bm[i] = axb[i]; //f(a)·f(x)=0,此时我们有x*∈[a,x];if((fabs(am[i]-bm[i]))/2<=0.4E-14) break;//判断是否满足精度}}for(int i=0; i<m; i++){printf("%0.15lf %0.15lf %0.15lf\n",am[i],bm[i],(am[i]+bm[i])/2);}return 0;}
运行截图: