一、弦截法(解一元三次方程)
通常,一元三次方程可以通过因式分解来得到根,如: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 附件的根(采用切线逼近的方法)