1. 程式人生 > >弦截求根_試探逼近_斜率計算_函式巢狀_迭代運算

弦截求根_試探逼近_斜率計算_函式巢狀_迭代運算

一、弦截法(解一元三次方程)

通常,一元三次方程可以通過因式分解來得到根,如:x^3 + 3x^2 -3x - 5 = 0    等價於(x+1)(x^2 + 2x -5) = 0

然而多數一元高次方程很難進行因式分解。

試探法:  先估計大致的根,然後按照某種規則進行迭代、試探與修正,逐步逼近根,直到得出的根滿足一定的精度要求為止。根據逼近方式不同,有 弦截法,切線法(牛頓迭代法)等。

弦截法(解一元三次方程)步驟:

1、取兩個不同點的 x1, x2, 若 f(x1) 和 f(x2) 取值的符號相反,則開區間 ( x1, x2) 間必有一根,注意 x1,x2 取值不應相差太大,以期該區間內僅有一根。若  f(x1) 和 f(x2) 取值的符號相同,則重新選取 x1, x2 , 知道f(x1) 和 f(x2) 取值的符號不同為止。

2、連線 f(x1) 和 f(x2)兩點,連線交x軸於x  , 代入,得出 f(x)

3、若 f(x)  和 f(x1) 同號,則根在 (x, x2) 內, 用 x 作為新一次迭代的x2

4、重複2,3,直到  | f(x) | < 指定精度。 (此時,f(x) ≈ 0)

#include<stdio.h>
#include<math.h>

float f(float x);
float xc(float x1, float x2);
float root(float x1,float x2, float gizmo);

int main(){
	float x1,x2,fx1,fx2,x,gizmo;
	do{
		printf("set x1,x2,gizmo:\n");
		scanf("%f,%f,%f",&x1,&x2,&gizmo);	//輸入兩個預測的根的範圍和精度 
		fx1 = f(x1);
		fx2 = f(x2);
	}while(fx1*fx2>=0);
	
	x = root(x1,x2,gizmo);
	printf("a root is %f",x);
	return 0; 
}

float f(float x){		//函式值 
	float z;
	z = ((x-5.0)*x+16.0)*x-80.0;
	return z;
}

float xc(float x1,float x2){
	float z;
	z = (x1*f(x2)-x2*f(x1))/(f(x2)-f(x1));		// 根據斜率公式 計算x 
	return z;
}

float root(float x1,float x2,float gizmo){			//求根 
	float x,fx1,fx2,fx;
	fx1 = f(x2);
	do{
		x = xc(x1,x2);
		fx = f(x);
		if(fx*fx1>0){
			fx1 = fx;
			x1 = x;
		}else{
			x2 = x;
		}
	}while(fabs(fx)>=gizmo);			//精度判斷 
	return x;
}

二、輸入兩個數,根據韋達定理 計算一元二次方程的根(考慮根的情況)

三、用牛頓迭代法 求方程  2x^3 - 4x^2 + 3x -6 = 0 在1.5 附件的根(採用切線逼近的方法)