例8.6 用弦截法求方程x3-5x2+16x-80=0的根。
方法如下:
(1) 取两个不同点x1\,x2,如果f(x1)和f(x2)符号相反,则(x1,x2)区间内必有一个根。如果f(x1)与f(x2)同符号,则应改变x1\,x2,直到f(x1)、f(x2)异号为止。注意x1、x2的值不应差太大,以保证(x1,x2)区间内只有一个根。
(2) 连接f(x1)和f(x2)两点,此线(即弦)交x轴于x,见图8.6。
x点坐标可用下式求出:
x=x1·f(x2)-x2·f(x1)f(x2)-f(x1)
再从x求出f(x)\.
(3) 若f(x)与f(x1)同符号,则根必在(x,x2)区间内,此时将x作为新的x1。如果f(x)与f(x2)同符号,则表示根在(x1,x)区间内,将x作为新的x2。
(4) 重复步骤 (2) 和 (3),直到 |f(x)|<ε 为止,ε为一个很小的数,例如 10-6\,此时认为 f(x)≈0\.根据上述思路画出NS流程图,见图8.7。
分别用几个函数来实现各部分功能:
(1) 用函数f(x)来求x的函数:x3-5x2+16x-80\.
(2) 用函数xpoint (x1,x2)来求f(x1)和f(x2)的连线与x轴的交点x的坐标。
(3) 用函数root (x1,x2)来求(x1,x2)区间的那个实根。显然,执行root函数过程中要用到函数xpoint,而执行xpoint函数过程中要用到f函数。
请读者先分析下面的程序。
#include <math.h>
float f(float x) /* 定义f函数,以实现f(x)=x3-5x2+16x-80 */

 float y;
 y=((x-5.0)*x+16.0)*x-80.0;
 return(y);

float xpoint(float x1,float x2) /*定义xpoint函数,求出弦与x轴交点 */

 float y;
 y=(x1*f(x2)-x2*f(x1))/(f(x2)-f(x1));
 return(y);

float root(float x1,float x2) /定义root函数,求近似根 */

 int i;
 float x,y,y1;
 y1=f(x1);
 do
 {
 x=xpoint(x1,x2);
y=f(x);
  if(y*y1>0) /f(x)与f(x1)同符号 */
  {y1=y;
  x1=x;}
 else
x2=x;
}while(fabs(y)>=0.0001);
return(x);

main() /主函数/

 float x1,x2,f1,f2,x;
 do
 {
printf("input x1,x2:\n");
scanf("%f,%f",&x1,&x2);
f1=f(x1);
f2=f(x2);
}while(f1*f2>=0);
 x=root(x1,x2);
printf("A root of equation is%8.4f",x);

运行情况如下:
input x1,x2:
2,6
A root of equation is 5.0000