科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件一元三次方程的求解问题

一元三次方程的求解问题

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

二分法的应用。

作者:明江 来源:CSDN 2008年3月21日

关键字: 求解 方程 C++ C Linux

  • 评论
  • 分享微博
  • 分享邮件

[问题描述]

    有形如:ax3+bx2+cx+d=0这样的一个一元三次方程。给出该方程中各项的系数(a

bcd  均为实数),并约定该方程存在三个不同实根(根的范围在-100100之间)

且根与根之差的绝对值≥1

    要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点

2位。

 

提示;记方程f(x)=0,若存在2个数x1x2,且x1 < x2f(x1)*f(x2) < 0

    则在(x1x2)之间一定有一个根。

[样例]

    输入:  1  -5  -4  20

    输出:-200  200  500

问题分析

根据题意,三次方程 ax^3+bx^2+cx+d=0在区间[-100,100]3个不等实根,不妨设这3个实根分别为x1,x2,x3,且x1<x2<x3,则方程可表示为a(x-x1)(x-x2)(x-x3)=0;于是,求解这3个实根,可转化为求函数f(x)= a(x-x1)(x-x2)(x-x3)图像与x轴交点的横坐标。如图:

二分法:

 

1.  确定根的区间

考虑在什么样的区间内会有根,由于题目给出了所有的根都在-100100之间,且根与根之间的差不小于1的限制条件,可知,在[-100,100][-99,-98],…[99,100],[100,100]201个区间内,每个区间内至多只能存在一个根,这样除去区间[100,100]外,其他区间[a,a+1],要么f(a)=0,要么f(a)×f(a+1)<0时这个方程在此区间内才有解。

2.  求方程的根

确定了方程f(x)=0在区间(a,b)内如果有且只有一个根,那么我们可以有逐步缩小根可能存在的范围的方法确定出某精度下根的数值。本题规定根的精度是0.01,下面采用二分法求区间(a,b)内方程的根,过程如下:

(1)       取当前可能存在解的区间(a,b;

(2)       a+0.001>b f((a+b)/2)=0,则可确定根为(a+b/2并退出过程;

(3)       f(a)×f((a+b)/2)<0,则根在区间(a, (a+b)/2)中,故对区间(a, (a+b)/2)重复该过程;

(4)       f(a)× f((a+b)/2)>0,则必然有 f((a+b)/2)×f(b)<0,也就是说根在((a+b)/2,b)中,应该对此区间重复该过程。

二分法求根的算法如下

#include<iostream>

#include<cmath>

using namespace std;

double x[3];

double a,b,c,d,u,v;

int i,t;

double f(double x)

 {

     double temp;

     temp=((a*x+b)*x+c)*x+d;

     return temp;

 }   

int main()

 { 

         while(cin>>a>>b>>c>>d)

      {

          t=-1;

          for(i=-100;i<=100;i++)

           {

               u=double(i);

               v=u+0.99999;

               if(fabs(f(u))<0.00001||f(u)*f(v)<=0)

                {

                    t++;

                    if(fabs(f(u))<0.00001)

                       x[t]=u;

                    else

                       {

                        while((u+0.001<v)&&fabs(f((u+v)/2))>=0.00001)  

                          

                           {

                               if(f(u)*f((u+v)/2)<0)

                                 v=(u+v)/2;

                               else

                                 u=(u+v)/2; 

                           }

                        x[t]=(u+v)/2;     

                       }      

                }   

           }   

      cout.setf(ios::fixed);

      cout.precision(2);

      cout<<x[0]<<" "<<x[1]<<" "<<x[2]<<endl;

      }

    

     return 0;

 }   

 

注意:由于实数运算的误差,判断x是否满足方程f(x)=0应用条件表达式 fabs(f(x))<0.00001来判断,否则将失根。

 

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章