原理
设函数f(x)在[a,b]上连续,且f(a)*f(b)<0,则表明f(x)在[a,b]上至少有一个零点。微积分中的介值定理。然后通过二分区间,缩小区间范围,当小到一定的精确度的时候,这个x就是我们所求的近似根了。
问题描述:
用二分法求方程在区间(a,b)之间的根,并求出尝试的次数;
问题分析:
1. 区间端点a, b由用户输入(确保输入区间内有根)。
2. 计算至误差小于10-6为止。
3. 程序中,浮点型数据应定义为双精度double类型。
思路
1.bool类型的isZero函数:判断是否double类型的值(两数之差)绝对值小于等于EPS
2.double类型的f函数:求出函数值
3.主函数:二分查找求根
(1)取左右端点以及中间值,记尝试次数为1
(2)算出x0对应的函数值
(3)判断函数值是否为0,若不为0则进入循环;如果函数值大于0,则改变右端点,反之,则改变左端点;在循环内改变中间值,求函数值,计数++,再回到循环进行判断
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define EPS 1e-6
bool isZero(double x)
{
return fabs(x)<=EPS;
}
double f(double x)
{
return x*x*x-5*x*x+10*x-80; //函数->函数表达式
}
int main()
{
double root,x1=0,x2=100,y;
root=x1+(x2-x1)/2; //取中间值为x0
int triedTimes=1; //记尝试次数为1
y=f(root); //算出x0所对应的函数值
while(!isZero(y)) //判断函数值是否为0,若不为0则进入循环
{
if(y>0) //如果函数值大于0,则记x2为x0
x2=root;
else //如果函数值小于0,则记x1为x0
x1=root;
root=x1+(x2-x1)/2; //算出x0所对应的函数值
y=f(root); //算出x0所对应的函数值
triedTimes++; //记录一共尝试多少次
}
printf("%.8f\n",root);
printf("%d",triedTimes);
return 0;
}