求解三次方程
2007-09-17 18:22
411 查看
采用方法:先用二分法求一实根(三次方程必有一实根),然后化为二次方程,用解析法求得另外两根(包括实根和虚根)
#include <stdio.h>
#include <math.h>
#include <conio.h>
#define eps 1.0e-8
//三次函数
inline double pow3(double a3,double a2,double a1,double a0,double x)
{
return ((a3*x+a2)*x+a1)*x+a0;
}
int pow3root(double a3,double a2,double a1,double a0,double r[])
{
double left=0.0,right=0.0,half,temp,b,c;
//不是三次方程
if(a3<eps&&a3>-eps)
{
return -1;
}
//确定有实根的区间
do
{
left-=1.0;
right+=1.0;
temp=pow3(a3,a2,a1,a0,left);
if(temp<eps&&temp>-eps)
{
r[0]=left;
goto STEP2;
}
temp*=pow3(a3,a2,a1,a0,right);
if(temp<eps&&temp>-eps)
{
r[0]=right;
goto STEP2;
}
}
while(temp>0);
while(right-left>eps)
{
half=(right+left)/2.0;
temp=pow3(a3,a2,a1,a0,half);
if(temp<eps&&temp>-eps)
{
r[0]=half;
break;
}
else if(pow3(a3,a2,a1,a0,left)*temp<0)
{
right=half;
}
else
{
left=half;
}
}
r[0]=(right+left)/2.0;
STEP2:
b=a2/a3+r[0];
if(r[0]<eps&&r[0]>-eps)
{
c=a1/a3;
}
else
{
c=-a0/a3/r[0];
}
if(b<eps&&b>-eps)
{
if(c<=0)
{
r[1]=-sqrt(-c);
r[2]=r[1];
return 0;
}
else
{
r[1]=0.0;
r[2]=sqrt(c);
return 1;
}
}
temp=b*b-4*c;
if(temp<eps&&temp>-eps)
{
r[1]=r[2]=-b/2.0;
return 0;
}
else if(temp>0)
{
temp=sqrt(temp);
r[1]=(temp-b)/2.0;
r[2]=-(temp+b)/2.0;
return 0;
}
else
{
r[1]=-b/2.0;
r[2]=sqrt(-temp)/2.0;
return 1;
}
}
int main()
{
int flag=1,temp;
double a3,a2,a1,a0,r[3];
//pow3root(1.0,-3.0,3.0,-1.0,r);
while(flag)
{
printf("请依次输入三次方程的四个系数,以空格键隔开。/n");
printf("输入:");
scanf("%lf %lf %lf %lf",&a3,&a2,&a1,&a0);
switch(pow3root(a3,a2,a1,a0,r))
{
case -1:
printf("这不是一个三次方程!/n");
break;
case 0:
printf("结果:x1=%f x2=%f x3=%f/n/n",r[0],r[1],r[2]);
break;
case 1:
printf("结果:x1=%f x2=%f+%fi x3=%f-%fi/n/n",r[0],r[1],r[2],r[1],r[2]);
break;
}
printf("退出请按Q或q,继续按其他键。/n");
temp=getch();
if(temp==(int)('q')||temp==(int)('Q'))
{
flag=0;
}
printf("/n");
}
return 0;
}
#include <stdio.h>
#include <math.h>
#include <conio.h>
#define eps 1.0e-8
//三次函数
inline double pow3(double a3,double a2,double a1,double a0,double x)
{
return ((a3*x+a2)*x+a1)*x+a0;
}
int pow3root(double a3,double a2,double a1,double a0,double r[])
{
double left=0.0,right=0.0,half,temp,b,c;
//不是三次方程
if(a3<eps&&a3>-eps)
{
return -1;
}
//确定有实根的区间
do
{
left-=1.0;
right+=1.0;
temp=pow3(a3,a2,a1,a0,left);
if(temp<eps&&temp>-eps)
{
r[0]=left;
goto STEP2;
}
temp*=pow3(a3,a2,a1,a0,right);
if(temp<eps&&temp>-eps)
{
r[0]=right;
goto STEP2;
}
}
while(temp>0);
while(right-left>eps)
{
half=(right+left)/2.0;
temp=pow3(a3,a2,a1,a0,half);
if(temp<eps&&temp>-eps)
{
r[0]=half;
break;
}
else if(pow3(a3,a2,a1,a0,left)*temp<0)
{
right=half;
}
else
{
left=half;
}
}
r[0]=(right+left)/2.0;
STEP2:
b=a2/a3+r[0];
if(r[0]<eps&&r[0]>-eps)
{
c=a1/a3;
}
else
{
c=-a0/a3/r[0];
}
if(b<eps&&b>-eps)
{
if(c<=0)
{
r[1]=-sqrt(-c);
r[2]=r[1];
return 0;
}
else
{
r[1]=0.0;
r[2]=sqrt(c);
return 1;
}
}
temp=b*b-4*c;
if(temp<eps&&temp>-eps)
{
r[1]=r[2]=-b/2.0;
return 0;
}
else if(temp>0)
{
temp=sqrt(temp);
r[1]=(temp-b)/2.0;
r[2]=-(temp+b)/2.0;
return 0;
}
else
{
r[1]=-b/2.0;
r[2]=sqrt(-temp)/2.0;
return 1;
}
}
int main()
{
int flag=1,temp;
double a3,a2,a1,a0,r[3];
//pow3root(1.0,-3.0,3.0,-1.0,r);
while(flag)
{
printf("请依次输入三次方程的四个系数,以空格键隔开。/n");
printf("输入:");
scanf("%lf %lf %lf %lf",&a3,&a2,&a1,&a0);
switch(pow3root(a3,a2,a1,a0,r))
{
case -1:
printf("这不是一个三次方程!/n");
break;
case 0:
printf("结果:x1=%f x2=%f x3=%f/n/n",r[0],r[1],r[2]);
break;
case 1:
printf("结果:x1=%f x2=%f+%fi x3=%f-%fi/n/n",r[0],r[1],r[2],r[1],r[2]);
break;
}
printf("退出请按Q或q,继续按其他键。/n");
temp=getch();
if(temp==(int)('q')||temp==(int)('Q'))
{
flag=0;
}
printf("/n");
}
return 0;
}
相关文章推荐
- 牛顿迭代法在求解三次方程上的应用
- Eqs 源自罗马尼亚2002年信息学竞赛------------五元三次方程求解
- EXCEL 单变量求解 解一元三次方程
- nyoj 1178 && hdu 5105 Math Problem 求解一元二次三次方程
- 蓝桥杯 算法训练 一元三次方程求解
- 利用Matlab求解Laplace方程
- hdu_2348_三分求解最值方程_数学题_少用tan
- 【2031】求一元三次方程的解
- 第三周练习——二分法2 方程求解
- 用类方法求解一元二次实系数方程
- 弦截法求解方程
- 牛顿迭代法求解方程
- 【来自媳妇的需求】PHP实现随机数和方程求解
- 二分法求解方程(有错误,请高手指点)。
- 解方程 —— 简单三次方程
- 试位法求解非线性方程的根
- 二分法,matlab中利用二分法求解一个多项式方程的近似值。
- OpenCV2.2求解多项式方程的根
- 使用牛顿迭代法求解一阶导数方程 python
- 简单迭代法求解方程举例