用C++如何给一元三次方程求根

主要有哪些算法?详细的话追加分数... 主要有哪些算法? 详细的话追加分数 展开
 我来答
tobetterlife
2008-10-13 · TA获得超过741个赞
知道小有建树答主
回答量:188
采纳率:0%
帮助的人:251万
展开全部
一元三次方程的求根公式用通常的演绎思维是作不出来的,用类似解一元二次方程的求根公式的配方法只能将型如ax^3+bx^2+cx+d+0的标准型一元三次方程形式化为x^3+px+q=0的特殊型。
ax^3+bx^2+cx+d=0
为了方便,约去a得到
x^3+kx^2+mx+n=0
令x=y-k/3
代入方程(y-k/3)^3+k(y-k/3)^2+m(y-k/3)+n=0
(y-k/3)^3中的y^2项系数是-k
k(y-k/3)^2中的y^2项系数是k
所以相加后y^2抵消
得到y^3+py+q=0
其中p=(-k^2/3)+m
q=(2k^3/27)-(km/3)+n
一元三次方程的求解公式的解法只能用归纳思维得到,即根据一元一次方程、一元二次方程及特殊的高次方程的求根公式的形式归纳出一元三次方程的求根公式的形式。归纳出来的形如 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)只是一元三方程的一个实根解,按韦达定理一元三次方程应该有三个根,不过按韦达定理一元三次方程只要求出了其中一个根,另两个根就容易求出了。
ax3+bx2+cx+d=0 记:p=(27a2d-9abc+2b3)/(54a3) q=(3ac-b2)/(9a2) X1=-b/(3a)+(-p+(p2+q3)^(1/2))^(1/3)+ (-p-(p2+q3)^(1/2))^(1/3)
百度网友9118827
推荐于2016-02-02 · 超过28用户采纳过TA的回答
知道答主
回答量:90
采纳率:0%
帮助的人:0
展开全部
用弦截法求
我给出一个例子
求f(x)=x^3-5x^2+16x-80=0
#include<iostream>
using namepace std;
#include<cmath>
float f(float x)
{
float y;
y=((x-0.5)*x+16.0)*x-80.0;
return(y);
}

float xpoint (float x1,float x2)
{
float y;
y=(x1*f(x2)-x2*f(x1))/(f(x2)-f(x1));
return(y);
}

float root(float x1,float x2)
{
float x,y,y1;
y1=f(x1);
do
{
x=xpoin(x1,x2);
y=f(x);
if(y*y1>0)
{
y1=y;
x1=x;
}
else
x2=x;
}
return(x);
}

viod main()
{
float x1,x2,f1,f2;
do
{
cout<<"请输入x1,x2:"<<endl;
cin<<x1<<x2;
f1=f(x1);
f2=f(x2);
}
while(f1*f2>=0)
x=root(x1,x2);
cout<<x<<endl;
}

顺便说一下算法思想吧
(1)用函数调用xpoint(x1,x2)来求(x1,f(x2))的连线与x轴的交点x的坐标。
(2)用函数调用root(x1,x2)来求(x1,x2)区间的那个实根,显然,执行root函数过程中要用到函数xpoint,而执行xpoint函数过程中要用到f函数。

这种方法求一元三次方程比较简洁方便。
其实用二分法也可以的,不过要在C++上实现是相对比较难点。
如果你要知道更多弦截法,到百度收索一下就有很多,
呵呵~~希望能帮到你吧~~~
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
50573750
2008-10-12 · TA获得超过976个赞
知道大有可为答主
回答量:1800
采纳率:100%
帮助的人:0
展开全部
方程的跟主要使用二分法!

如果两个端点的函数值不同号!就取中点,下一次分段就从和中点函数值不同号的一端和中点为区段,然后以此类推当区段小于。。。时即求出了根。依据是闭区间函数连续定理!

#include <limit.h>
....

float f(float x)
{return x*x*x-x*x+x+1;}

float Get_Root(float a,float b)
{
if (a-b<1e-5) return (a+b)/2;
if (f(a)*f((a+b)/2)<0) return GetRoot(a,(a+b)/2);
else if(f(b)*f((a+b)/2)<0) GetRoot(b,(a+b)/2);
else return (a+b)/2;
}

double *GetRoot(float a,float b);
{
static double *root = new double[3];
static int pos=0;

while(pos==3)
{
if (fabs(a-b)<1e-4) return;
if (f(a)*f(b)<0) {root[pos++]=Get_Root(a,b);GetRoot(root[pos]-0.1,a);GetRoot(root[pos]+0.1,b);}

else if(f(a)*f(b)>0) {GetRoot((a+b)/2,a);GetRoot((a+b)/2,b);}
}

return root;
}

int main()
{
double *root = GetRoot(-INT_MAX,INT_MAX);

。。。
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户
2008-10-25
展开全部
用二分法将一元三次方程求根即可
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
恋_蝶
2008-10-16 · 超过12用户采纳过TA的回答
知道答主
回答量:35
采纳率:0%
帮助的人:0
展开全部
//弦截法为方法之一:例求方程(f(x)=x^3-5x^2+16x-80=0)的根
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
double root(double,double);
double f(double);
double xpoint(double,double);

int main()
{
double x1,x2,f1,f2,x;
do
{
cout<<"input x1,x2:";
cin>>x1>>x2;
f1=f(x1);
f2=f(x2);
}while(f1*f2>=0);
x=root(x1,x2);
cout<<setiosflags(ios::fixed)<<setprecision(7);
cout<<"A root of equation is "<<x<<endl;
return 0;
}

double f(double x)
{
double y;
y=x*x*x-5*x*x+16*x-80;
return y;
}

double xpoint(double x1,double x2)
{
double y;
y=(x1*f(x2)-x2*f(x1))/(f(x2)-f(x1));
return y;
}

double root(double x1,double x2)
{
double x,y,y1;
y1=f(x1);
do
{
x=xpoint(x1,x2);
y=f(x);
if (y*y1>0)
{
y1=y;
x1=x;
}
else
x2=x;
}while(fabs(y)>=0.000001);
return x;
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式