1. 程式人生 > >二分法——求近似方程的解

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

二分法求近似方程的解的原理我就不講了,就是類似於零點存在定理之類的東西。

所以直接以例項來講述:

例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)的零點所在區間一分為二,使區間的兩個端點逐漸逼近零點,近而得到零點近似值的方法為二分法。