数值计算—方程求根(C语言+二分法、牛顿法)

求解方程:x3-0.2x2-0.2x-1.2=0的根
编写二分法、牛顿法程序,分析运行结果。

思想:

二分法

给定区间,并设f(a)与f(b)符号相反,取Ɛ1为根的允许误差,Ɛ2为|f(x)|的允许误差。
1)c=(a+b)/ 2;
2)如果(c-a)< Ɛ1或|f( c )|< Ɛ2,则输出 c,结束;否则执行3);
3)如果 f( a )·f( b ) > 0,则令 a=c,否则令 b=c,重复以上步骤。

牛顿迭代法

给定初值x0,取Ɛ1为根的允许误差,Ɛ2为|f(x)|的允许误差,N为迭代次数的允许值。
1)如果 f’(x0)=0 或迭代次数大于N,则算法失败,结束,否则执行2);
2)计算 x1 = x0 - (f(x0) / f’(x0));
3)若|x1 - x0|< Ɛ1或|f(x1)|< Ɛ2,则输出x1,程序结束,否则执行4);
4)令 x0 = x1,转向1)。

代码:

//二分法
#include <stdio.h>
#include <math.h>

float Bisection(float a, float b, float (*f)(float)) {
	float c,fa=(*f)(a),fb=(*f)(b),fc=(*f)(c);
	int n=1;
	printf("二分次数 \t c \t f(c)\n");
	while(1){
		if(fa * fb > 0){
			printf("不能用二分法求解!");
			break;
		}
		c = ( a + b ) / 2;
		printf("%d \t %f \t %f\n",n++,c,fc);
		if(fabs(fc) < 1e-6)
			break;
		else if(fa * fc < 0){
			b = c;
			fb = fc;
		} 
		else{
			a=c;
			fa=fc;
		}
		if (b-a < 5e-6)
			break;
	}
	return c;
}

float f(float x){
	return pow(x,3)-0.2*pow(x,2)-0.2*x-1.2; //方程
}

int main(int argc, char* argv[]){
	float a=1,b=2; //注意有根区间的判断
	float x;
	x = Bisection(a,b,f);
	printf("\n方程的根为:%f",x);
	return 0;
}
//牛顿迭代法
#include <stdio.h>
#include <math.h>

float Newton(float(*f)(float), float(*f1)(float), float x0){
	float x1,d;
	int k=0;
	do{
		x1 = x0 - (*f)(x0) / (*f1)(x0);
		if(k++>100 || fabs((*f1)(x1)) < 1e-6){
			printf("\nNewton迭代法发散!");
			break;
		}
		d = fabs(x1) <1 ? x1-x0 : (x1-x0)/x1;
		x0 = x1;
		printf("x(%d) = %f\t",k,x0);
	} 
	while(fabs(d)>1e-6 && fabs((*f)(x1)) > 1e-8);
	return x1;
}

float f(float x){
	return pow(x,3)-0.2*pow(x,2)-0.2*x-1.2;  //方程
} 

float f1(float x){
	return 3.0*pow(x,2)-0.4*x-0.2;  //方程求导
}

int main(){
	float x0,y0;
	printf("请输入迭代初值x0\n:");
	scanf("%f",&x0);
	printf("x(0) = %f\n",x0);
	y0 = Newton(f,f1,x0);
	printf("方程的根为:%f\n",y0);
}

运行结果:

在这里插入图片描述在这里插入图片描述

分析:

1、无论选哪种方法,首先都要进行有根区间的判断。
2、牛顿迭代法取不同初值得到同样的结果,但迭代次数不同。初值越接近所求的根,迭代次数越少。所以在取初值时,可以先采用二分法取得一个好的初值,再进行迭代。

  • 1
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值