方程求根二分法

来源:互联网 发布:mac hosts无法修改 编辑:程序博客网 时间:2024/04/30 04:20

/**
***方程求根二分法***

  在实际计算允许的误差范围(ε)内
  对所求根区间(a,b)不断缩小直得到所期望精度的数据
  理论基础
  1:函数在区间[a,b]上连续
  2:f(a)*f(b)<0
  3:单调函数,一个根

  属性:数值逼近法
  误差(精度):| x-x'|≤( b'-a')/2             
                       = ( b -a )/pow(2,k+1)=ε.  x为精确值,x'为第k次二分后数据
                                   a',b'为第k次二分后求根区
  MSDN:中对pow()的解析:
 
  pow(const complex<T>& x, int y);
  pow(const complex<T>& x, const T& y);
  pow(const complex<T>& x, const complex<T>& y);
  pow(const T& x, const complex<T>& y);
 


  《数值分析简明教程》-2 Editon -高等教育出版社- page 6 算法流程图
  
  代码维护:2005.6.10  DragonLord
**/

#include<iostream.h>
#include<math.h>

float Formula(float x)//方程表达式
{
   float y;
 
  // y=x*x*x-x-1;  //范例方程 
 //  y=x*x*x-2*x*x-4*x-7;
   y=x*x+4*x+3;
   return y;
}

float Dimidiate(float x0,float x1)//二分表达式
{
 float k;
 k=(x0+x1)/2;
 return k;
}

int Binary(float a,float b,float e)//计算二分次数Exact_Binary
{
    int l=2;
 for(int k=0;k<100;k++)
 {
  if(pow(l,k)>=(b-a)/(2*e))break;  //|x-x'|≤(b'-a')/2=(b-a)/pow(2,k+1).
 }                                          
 return k;
}

void main()
{
 float a,b,e;                 //区间与精度
 float x,y,y0,y1;             //临时变量
 int k,n;
 
 cout<<"***方程求根二分法***"<<endl;
    cout<<"输入区间[a,b]与精度ε(绝对误差限)"<<endl;
   

 cin>>a>>b>>e;
   
 k=Binary(a,b,e);              //确定二分次数
   
 y0=Formula(a);
 y1=Formula(b);
   
 if(y0*y1<0)
 {
  for(n=0;n<=k;n++)
  {
   x=Dimidiate(a,b);
  
   cout<<"第"<<n+1<<"次二分结果:"<<x<<endl;
        
   y=Formula(x);
  
   if(y0*y>0)a=x;         //       选择领域 
   else b=x;              //确定进行下一步计算的边界
  }
     cout<<"二分次数:"<<k<<endl;
     cout<<"所求实根:"<<x<<endl;
 }
 else cout<<"限定区间内没有实根(不符合二分法的理论基础)"<<endl;
}