(1)二分法求解非线性方程:
#include<stdio.h>
#include<math.h>
#define f(x)((x*x-1)*x-1)
void main()
{float a,b,x,eps;
int k=0;
printf("intput eps\n");/*容许误差*/
scanf("%f",&eps);
printf("a,b=\n");
for(;;)
{scanf("%f,%f",&a,&b);
if(f(a)*f(b)>=0)/*判断是否符合二分法使用的条件*/
printf("二分法不可使用,请重新输入:\n");
else break;
}
do
{x=(a+b)/2;
k++;
if(f(a)*f(x)<0)/*如果f(a)*f(x)<0,则根在区间的左半部分*/
b=x;
else if(f(a)*f(x)>0)/*否则根在区间的右半部分*/
a=x;
else break;
}while(fabs(b-a)>eps);/*判断是否达到精度要求,若没有达到,继续循环*/
x=(a+b)/2;/*取最后的小区间中点作为根的近似值*/
printf("\n The root is x=%f,k=%d\n",x,k);
}
运行结果:
intput eps
0.00001
a,b=
2,-5
The root is x=1.324721,k=20
Press any key to continue
总结:本题关键在于两个端点的取值和误差的判断,此程序较容易。
二分法收敛速度较快,但缺点是只能求解单根。
(2)牛顿法求解非线性方程:
#include<stdio.h>
#include<math.h>
float f(float x)/*定义函数f(x)*/
{return((-3*x+4)*x-5)*x+6;}
float f1(float x)/*定义函数f(x)的导数*/
{return(-9*x+8)*x-5;}
void main()
{float eps,x0,x1=1.0;
printf("input eps:\n");
scanf("%f",&eps);/*输入容许误差*/
do
{x0=x1;/*准备下一次迭代的初值*/
x1=x0-f(x0)/f1(x0);/*牛顿迭代*/
}while(fabs(x1-x0)>eps);/*当满足精度,输出近似根*/
printf("x=%f\n",x1);
}
程序运行结果:
x=1.265328
总结:关键是牛顿迭代的应用,程序中最大缺点是函数及其导数已唯一给出确定不可求的随意函数的根,牛顿法比二分法收敛快,可以求重根。