混乱武林iii苍山负雪:求:一般形式1元3次方程解法!~

来源:百度文库 编辑:高考问答 时间:2024/04/26 15:04:57
呵呵!~

对于三次方程
ax^3+bx^2+cx+d=0
令x=y-b/(3a),方程化为
y^3+py+q=0
其根为
x1=u+v
x2=ue+ve^2
x3=ve+ue^2
其中
e=cos(2*PI/3)+isin(2*PI/3)
u=(-q/2+sqrt(q^2/4+p^3/27))^(1/3)
v=(-q/2-sqrt(q^2/4+p^3/27))^(1/3)
这就是Cartan公式。

因为我还是初学者,最近研究了一下关于一元三次方程的解法,参考有关资料,弦截法最为简便,假设我们来解

x3-3x2-6x+8=0这个方程在区间[-3,5]中求值。

以下是我设计的程序:

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

double Func(double);
int BowRoot(double,double,double,double,double *,int,int *);

void main()
{
int i,n,m;
double a,b,h,eps,*x;
n=3; //方程解的预估值
x=(double*)calloc(n,sizeof(double)); //开辟内存空间
if(x==NULL)
{
printf("内存分配失败\n");
exit(1);
}
a=-3; //区尖起始端点
b=5; //区尖终止断点
h=1; //步长
eps=1.e-8; //要求达到的精度
BowRoot(a,b,h,eps,x,n,&m); //调用二分法函数
printf("函数f(x)在范围%2.0f和%2.0f之间的根有个%d根",a,b,m);
printf("他们分别是:");
for(i=0;i<n;i++)
{
printf("x[%d]=%e\n",i,x[i]);
free(x); //释放内存空间
}
double Func(double x)
{
return (x*x*x-3*x*x-6*x+8);
}

int BowRoot(a,b,h,eps,x,n,m)
double a;
double b;
double h;
double eps;
double *x;
int n;
int *m;
{
double z,z1,z2,y,y1,y2;
*m=0;
z=a;
y=Func(z);
while(1) //无限循环,直到遇到return或break语句
{ //如果逐步扫描到求根区间的右端点或者得到的根的个数达到预估的个数
if((z>b+h/2)||(*m==n))
return(1);
if(fabs(y)<eps)
{
*m+=1;
x[*m-1]=z;
z+=h/2;
y=Func(z);
continue;
}

z1=z+h;
y1=Func(z1);
if(fabs(y1)<eps)
{
*m+=1;
x[*m-1]=z1;
z=z1+h/2;
y=Func(2);
continue;
}
if(y*y1>0)
{
y=y1;
z=z1;
continue;
}
while(1)
{
if(fabs(z1-z)<eps)
{
*m+=1;
x[*m-1]=(z1+z)/2;
y=Func(z);
break;
}
y1=Func(z1); //弦截法公式
y=Func(z);
z2=z1-(y1/(y1)-y)*(z1-z);
y2=Func(z);

if(fabs(y2)<eps)
{
*m=*m+1;
x[*m-1]=z2;
z=z2+h/2;
y=Func(z);
break;
}
if(y*y2<0)
{
z1=z2;
y1=y2;
}
else
{
z=z2;
y=y2;
}
}
}

}

对于高初中生,上面的方法是不实用的:
一般要选取较为简单的一个根,比方说:1,-1,2之类,当然,这一般是不难的,但也要有所熟练;
记这个简单根是a,然后将(x-a)从三次方程中提取出来,可以了,后面就是解二次方程的问题了……

二分法最好理解
例:计算x^3-x-1=0
float f(float xx)
{float s;
s=xx*xx*xx-xx-1;
return(s);
}
p()
{printf(" ********************************\n"); }
p1()
{printf(" 二分法\n");}
main()
{
float x,a,b,ep;
int i=0;
char j;
p();
p1();
p();
printf("请输入 a、b 的值和精度:\n");
scanf("%f%f%f",&a,&b,&ep);
do {
i++;
x=(a+b)/2.0;
if(f(a)*f(x)<0) {b=x; j='+';}
else {a=x;j='-';}
printf("第 %d 次计算\ta=%f\tb=%f\tx=%f\tf(x) %c\t\n",i,a,b,x,j);
}
while((b-a)>ep);

}

e=cos(2*PI/3)+isin(2*PI/3)

u=(-q/2+sqrt(q^2/4+p^3/27))^(1/3)

v=(-q/2-sqrt(q^2/4+p^3/27))^(1/3)
一般公式 要不去用MATLAB 编程太麻烦了 求近似解还可以凑合着用

e=cos(2*PI/3)+isin(2*PI/3)

u=(-q/2+sqrt(q^2/4+p^3/27))^(1/3)

v=(-q/2-sqrt(q^2/4+p^3/27))^(1/3)