二分法求零点,求根号2的近似值
const double eps = 1e-5; double func(double x) { return x*x; } double s_qrt(double low,double high,double obj) { double mid; while(high-low>eps) { mid=low+(high-low)/2;
//根据单调性,调整high和low if(func(mid)>obj) { high=mid; } else { low=mid; } } return low; }
这是在单调区间 [low,high] 中求根号下obj的值,low和high需要包含所求值
以求根号2的值为例,设根号2的值为x
即 x=根号2
x*x=2
x*x-2=0 方程构造出来了
根号2即为该方程的根,即为函数的零点,可以选择将区间[low,high] 之间的值(比如精度为2的话,就每0.01取一个数)都代入f(x)=x^2 -2试一下,比较其与0的接近程度,在误差范围内就可以认为得到了解
在单调情况下,更好的方法是利用二分法对区间进行搜索,不断缩小区间范围,根据单调增还是减来调整low和high
当区间足够小的时候,处于误差范围内即可
比如求根号2
调用 cout<<s_qrt(0,10,2);
二分法实际上就是零点定理
总结起来,求一个方程的根这类问题,其实核心就是试根法,f(x) = 0,将x的值取一个区间,将里面的数,一个一个往里面代,在误差以内的就可以认为是根
而一个一个代又要如何代?1到2之间有无穷多个数啊,怎么选?不可能全选。
那跨度为多少合适?看精度,精度为2就可以每0.01取一个数。那如果区间是1-100,那就是10000个数,1万次计算
如果函数在该范围内是单调的,就可以采用2分法对这一区间进行搜索,根据单调增还是减来调整low和high
这就是本方法的核心思想