您的位置:首页 > 其它

求解三次方程

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: