题目描述
编写程序,用非线性方程二分法求解函数BiRoot(),求任意方程f(x)=0在区间[a,b]之间的一个解,精确到10-6。
函数原型为:double BiRoot(double (*fun)(double), double, double)。
二分法求解的基本思路如下图所示,对于区间[a,b]上连续且f(a)•f(b)<0的函数y=f(x),通过计算a,b中点的函数值,不断把区间一分为二,并舍弃无解的半段区间,并更新a,b,使两个端点逐步逼近零点,迭代的终止条件是计算的函数值小于10-6,最终得到符合精度要求的近似解。
例:如a=-5, b=0,且f(x)= x3-10x2+3x+20.0则函数返回-1.209
如a=0, b=3, 且f(x)= x3-6x-1则函数返回2.529
提示
若f(a)•f(b)>0,则意味着方程在[a,b]之间可能无解,输出信息“error! a,b have the same sign.\n”后,可直接结束程序。
该题目可参考教材P317,tabulate.c代码。
#include<stdio.h>
#include<math.h>double bi_search(double (*fun)(double),double a,double b)
{double min=(a+b)/2.0;if(fabs(fun(min))<1e-6)return min;if(fun(a)*fun(min)<0)return bi_search(fun,a,min);else if(fun(b)*fun(min)<0)return bi_search(fun,min,b);
}double BiRoot(double (*fun)(double),double a,double b)
{double min=0;if(fun(a)*fun(b)>0){printf("error!a,b have the same sign.\n");}else if(fun(a)*fun(b)<0){return bi_search(fun,a,b);}else{if(fun(a)==0)return a;elsereturn b;}
}double fac(double x)
{//return x*x*x-6*x-1;return x*x*x-10*x*x+3*x+20.0;
}
int main()
{double a,b;scanf("%lf %lf",&a,&b);double (*f)(double)=fac;double k=BiRoot(f,a,b);printf("%.3f\n",k);return 0;
}