【问题描述】
编写程序求方程在区间[0.1,0.2]的根。函数=的图像如图5-1-6所示。方程的根在函数图像中就是曲线与x轴交点的x坐标。
输出结果:
0.13201588341034948
图5-1-6 函数图像
【题前思考】
根据问题描述,填写表5-1-4。
表5-1-4 问题分析
【解题思路】
将x的值代入方程,使等式成立,则x就是方程的根。求方程的根的方法就是将可能的数逐个代入,等式成立就是它的根。但是,实数是无穷的,逐个试是没有办法找出根的。
但是,从函数图像可以看出,在区间[0.1,0.2]上的函数是减函数,即它的值随着x的增加不断变小,重要的是区间两个端点的函数值是异号的(即一正一负,分别处于x轴的上方和下方)。为了便于表述,用l表示区间的左边界,意为left(左边),用r表示区间的右边界,意为right(右边),用m表示区间的中点,意为middle(中间)。我们可以求出区间的中点m,将区间分成两个小区间(见图5-1-7),两个小区间中,必定有一个小区间的两个端点上的函数值也是异号的,根就在这个小区间上。本例中左侧小区间两个端点的函数值就是异号的,分别处于x轴的上方和下方。
将这个小区间再分成两个小区间。本例中,就是求出左侧小区间的中点,将其分成两个更小的区间,如图5-1-8所示。
图5-1-7 第1次划分中点
图5-1-8 第2次划分中点
从以上两幅图可以看出,区间的宽度变小了一半,而且会越来越小。重复以上的操作,直到小区间的宽度非常小,则我们就可以用这个小区间的中点近似表示方程的根,这就是二分法。
【程序代码】
【代码分析】
①:定义函数binsearch( )用于求方程的根,参数f是表示方程的函数,l是根所在区间的左边界,r是根所在区间的右边界。为了让这个函数能求所有方程的根,将方程本身定义为一个参数,这样这个函数就更具重用性。这是一个典型的以函数为参数的例子。
②:求左边界l和右边界r的中点m。
③:r-l>1e-10表示两个根的距离超过10-10就继续求解。因为根就在两个边界之间,所以两个边界的距离越小,根的精度就越高,本例中的精度为10-10,即真实根与程序求出的根的误差不超过10-10,小数前10位都是准确的。
④:用来选择下一个小区间。如果f(l)*f(m)>0成立,则f(l)和f(m)同号,说明左边小区间没有根,那么根必然在右边的小区间,所以,以m为左边界(l=m)构造下一个小区间。如果f(l)*f(m)>0不成立,则f(l)和f(m)异号,说明根就在左侧小区间,于是,将m作为右边界(r=m)构造下一个小区间。
⑤:重新计算区间的中点。因为区间的左、右边界发生变化了,所以需要重新计算区间的中点。
⑥:binsearch(f,0.1,0.2)表示调用函数求方程的根。方程就是函数f,根的区间为[0.1,0.2],左边界为0.1,右边界为0.2。