解一元三次方程的C程序,来者有分
急求三次方程解的原代码.请各位高手指点 问题点数:20、回复次数:4Top
1 楼lalac(水月流影)回复于 2006-06-01 19:49:38 得分 3
线性代数里好像有这么个东东,不过不记得了,帮你顶Top
2 楼SamuelKevin(曼陀罗)回复于 2006-06-01 20:30:05 得分 5
汗颜 我不会 不过帮你找了点资料
一元三次方程的求根公式用通常的演绎思维是作不出来的,用类似解一元二次方程的求根公式的配方法只能将型如ax^3+bx^2+cx+d+0的标准型一元三次方程形式化为x^3+px+q=0的特殊型。
一元三次方程的求解公式的解法只能用归纳思维得到,即根据一元一次方程、一元二次方程及特殊的高次方程的求根公式的形式归纳出一元三次方程的求根公式的形式。归纳出来的形如 x^3+px+q=0的一元三次方程的求根公式的形式应该为x=A^(1/3)+B^(1/3)型,即为两个开立方之和。归纳出了一元三次方程求根公式的形式,下一步的工作就是求出开立方里面的内容,也就是用p和q表示A和B。方法如下:
(1)将x=A^(1/3)+B^(1/3)两边同时立方可以得到
(2)x^3=(A+B)+3(AB)^(1/3)(A^(1/3)+B^(1/3))
(3)由于x=A^(1/3)+B^(1/3),所以(2)可化为
x^3=(A+B)+3(AB)^(1/3)x,移项可得
(4)x^3-3(AB)^(1/3)x-(A+B)=0,和一元三次方程和特殊型x^3+px+q=0作比较,可知
(5)-3(AB)^(1/3)=p,-(A+B)=q,化简得
(6)A+B=-q,AB=-(p/3)^3
(7)这样其实就将一元三次方程的求根公式化为了一元二次方程的求根公式问题,因为A和B可以看作是一元二次方程的两个根,而(6)则是关于形如ay^2+by+c=0的一元二次方程两个根的韦达定理,即
(8)y1+y2=-(b/a),y1*y2=c/a
(9)对比(6)和(8),可令A=y1,B=y2,q=b/a,-(p/3)^3=c/a
(10)由于型为ay^2+by+c=0的一元二次方程求根公式为
y1=-(b+(b^2-4ac)^(1/2))/(2a)
y2=-(b-(b^2-4ac)^(1/2))/(2a)
可化为
(11)y1=-(b/2a)-((b/2a)^2-(c/a))^(1/2)
y2=-(b/2a)+((b/2a)^2-(c/a))^(1/2)
将(9)中的A=y1,B=y2,q=b/a,-(p/3)^3=c/a代入(11)可得
(12)A=-(q/2)-((q/2)^2+(p/3)^3)^(1/2)
B=-(q/2)+((q/2)^2+(p/3)^3)^(1/2)
(13)将A,B代入x=A^(1/3)+B^(1/3)得
(14)x=(-(q/2)-((q/2)^2+(p/3)^3)^(1/2))^(1/3)+(-(q/2)+((q/2)^2+(p/3)^3)^(1/2))^(1/3)
式 (14)只是一元三方程的一个实根解,按韦达定理一元三次方程应该有三个根,不过按韦达定理一元三次方程只要求出了其中一个根,另两个根就容易求出了Top
3 楼happytang(一只叫苏格拉底的猪)回复于 2006-06-01 21:50:00 得分 10
#include <iostream.h>
#include <stdio.h>
#include <math.h>
//////////////////函数--用卡丹公式解一元三次方程/////////////////
void fun(double a,double b,double c,double d,
double *real_y1,double *real_y2,double *real_y3,
double *imag_y1,double *imag_y2,double *imag_y3)
{
double p,q,r,u,v,g,h,fai;
p=(3.0*a*c-b*b)/(3*a*a);
q=(2.0*pow(b,3.0)-9*a*b*c+27.0*a*a*d)/(27.0*pow(a,3.0));
r=b/(3.0*a);
h=pow(q/2.0,2.0)+pow(p/3.0,3.0);
g=sqrt(h);
if(h>=0)
{
if(-q/2.0+g<0)
u=-pow(fabs(-q/2.0+g),1.0/3.0);
else
u=pow((-q/2.0+g),1.0/3.0);
if(-q/2.0-g<0)
v=-pow(fabs(-q/2.0-g),1.0/3.0);
else
v=-pow((-q/2.0-g),1.0/3.0);
if(h==0)
{
*real_y1=u+v-r; *imag_y1=0;
*real_y2=-(u+v)/2-r; *imag_y2=0;
*real_y3=-(u+v)/2-r; *imag_y3=0;
}
else
{
*real_y1=u+v-r; *imag_y1=0;
*real_y2=-(u+v)/2; *imag_y2=sqrt(3.0)*(u-v)/2;
*real_y3=-(u+v)/2; *imag_y3=-sqrt(3.0)*(u-v)/2;
}
}
else
{
fai=acos((-q/2)/(sqrt(pow(fabs(p),3)/27)));
*real_y1=2*sqrt(fabs(p)/3.0)*cos(fai/3.0)-r;
*real_y2=-2*sqrt(fabs(p)/3.0)*cos((fai+3.1415926)/3.0)-r;
*real_y3=-2*sqrt(fabs(p)/3.0)*cos((fai-3.1415926)/3.0)-r;
*imag_y1=0; *imag_y2=0; *imag_y3=0;
}
}
//////////////////////////////////主函数////////////////////////////////
void main()
{
double a,b,c,d;
double real_x1,real_x2,real_x3;
double *preal_x1=&real_x1;
double *preal_x2=&real_x2;
double *preal_x3=&real_x3;
double imag_x1,imag_x2,imag_x3;
double *pimag_x1=&imag_x1;
double *pimag_x2=&imag_x2;
double *pimag_x3=&imag_x3;
cout<<"请输入方程的系数a,b,c,d:"<<"\n"<<endl;
cout<<"系数a=";
cin>>a;
cout<<endl;
cout<<"系数b=";
cin>>b;
cout<<endl;
cout<<"系数c=";
cin>>c;
cout<<endl;
cout<<"系数d=";
cin>>d;
cout<<endl;
fun(a,b,c,d,preal_x1,preal_x2,preal_x3,pimag_x1,pimag_x2,pimag_x3);
cout<<" "<<" "<<"根的实部"<<" "<<"根的虚部"<<"\n"<<endl;
printf("x1 %.5f %.5f\n\n",real_x1,imag_x1);
printf("x2 %.5f %.5f\n\n",real_x2,imag_x2);
printf("x3 %.5f %.5f\n\n",real_x3,imag_x3);
}
///////////////////////////结束/////////////////////////////
Top
4 楼breakind(冰舞,把练街舞的精神拿来编程,必有所成.)回复于 2006-06-01 22:30:35 得分 2
学习了Top




