二分法——求近似方程的解

本文通过实例详细介绍了如何使用二分法求解方程的近似解,包括在不同区间内的应用,如x^3+4x-10=0在[1,2],e^x+10x-2=0在[0,1],以及8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y在[0,100]。强调了二分法的适用条件和精度判断的重要性。" 111361662,9336631,Go语言教程:字典与字符串操作详解,"['Go', '编程语言', '数据结构', '字符串操作']

二分法求近似方程的解的原理我就不讲了,就是类似于零点存在定理之类的东西。

所以直接以实例来讲述:

例1:用二分法求方程x^3+4x-10=0在区间[1,2]内的根(精确到0.00001)

首先我们要判断一下能不能用二分法来求解,把首末两端代入式子中去计算可以得出,代入1得-6,代入2得6,满足二分求方程的解;

#include <stdio.h>
#include <math.h>
double f(double x)
{
	return pow(x,3)+4*x-10;
}
int main()
{
	double a=1,b=2,limit=0.00001;//a,b为区间,limit为精确程度
	if(f(a)*f(b)>0)
		printf("无法用二分法求解\n"); //假设f(a)=7,f(b)=13,f(x)=0?
	else
	{
		while((b-a)>limit)
		{
			if(f((a+b)/2)*f(b)<0) //一边为正,一边为负
				a=(a+b)/2;
			else //同号
				b=(a+b)/2;
		}
		printf("%.5f\n%.5f",a,b);
	}
	return 0;
}

如果mid*右边小于0,那么则说明零点肯定是在右半部分,所以mid移到右边去。

如果mid*左边小于0,那么则说明零点肯定是在左半部分,所以mid移到左边去。

至于上面那个函数调用是直接返回了方程,这样就会比较简便了。

 

例二:

C语言在区间[0,1]内用二分法求方程e^x+10x-2=0的近似根,误差不超过0.5*10^(-3)

#include <stdio.h> 
#include <math.h> 
#include <stdlib.h> 
#define e 2.7182828//定义自然对数底数的值 
float getvalue(float x) 
{ 
    return pow(e,x)+10*x-2; 
} 
int main() 
{ 
    float a=0,b=1,c; 
    c=(a+b)/2; 
    while(fabs(getvalue(c))>0.5*1e-3)//此处可以简单化 
    { 
        if(getvalue(c)*getvalue(b)<0) 
            a=c; 
        if(getvalue(a)*getvalue(c)<0) 
            b=c; 
        c=(a+b)/2; 
    } 
    printf("%0.3f\n",c); 
    return 0; 
} 

同上面相似,大致就是这么做的。

 

例三:贴一道我们学校OJ上的题

对于给定的Y,求8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y这个方程,在0<=x<=100中的实数解。

Input

第一行包含一个正整数T(1<=T<=100),代表有多少组测试样例。

接下来T行,每行一个实数Y(fabs(Y)<=1e10)。

Output

对于每一个测试样例,输出一个实数(小数点后保留4位),代表该方程的解。如果该方程在0~100没有解,则输出"No solution!"

Sample Input

2 100 -4

Sample Output

1.6152 No solution!

 

#include<stdio.h>
#include<math.h>
double func(double x,double y){
	double ans;
	ans=8.0*pow(x,4.0)+7.0*pow(x,3.0)+2.0*pow(x,2.0)+3.0*x+6.0-y;    //原来y也可以这样传过去的 
	return ans;
}
int judge(double y){					//这里是用来判断能不能进行二分法的,哈哈 
	double t1,t2;
	t1=func(0,y); t2=func(100,y);
	if(t1*t2<=0) return 1;
	else  return -1;
}
int main(){
	int t,i,j;
	double y,left,right,mid,dis,ans;
	scanf("%d",&t);
	for(i=1;i<=t;i++){
		scanf("%lf",&y);
		j=judge(y);
		if(j==-1) {
			printf("No solution!\n");continue;
		}
		left=0; right=100; dis=1e-8;
		while(right-left>dis)
		{
			mid=(left+right)/2.0;
			ans=func(mid,y);
			if(ans==0) break;
			if(ans>0) right=mid;	//主要是这里有些人写成right=mid-dis; 不是很明白,难道是为了精度? 
			else  left=mid;
		}
		printf("%.4lf\n",mid);
	}
	return 0;
}

*注意精度的判断就好了10的-8次。

 

最后注意二分法可以使用的条件,对于区间上连续不断的函数且f(a)*f(b)<0的函数f(x),通过不断地把函数f(x)的零点所在区间一分为二,使区间的两个端点逐渐逼近零点,近而得到零点近似值的方法为二分法。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值