自己动手打造“超高精度浮点数类”

自己动手打造“超高精度浮点数类”
[email protected]

 tag:PI,超高精度浮点数,TLargeFloat,FFT乘法,二分乘法,牛顿迭代法,borwein四次迭代,AGM二次迭代

  很多人可能都想自己写一个能够执行任意精度计算的浮点数;:D我写的第一个程序就是用qbasic计算自然数e到100万位(后来计算PI);  这里有一个C++类的实现TLargeFloat,它能够执行高精度的浮点数运算;演示代码里面有一个计算PI的Borwein四次迭代式和一个AGM二次迭代式(我用它计算出了上亿位的PI小数位:)

  源代码的简要导读文章: http://blog.csdn.net/housisong/archive/2007/12/24/1965652.aspx

(2007.12.14 进行了一些速度优化,添加了FFT实现的大数乘法; 进行高精度(百万千万位)运算时的速度提高了很多!)

(2007.11.29  对代码进行了一次梳理,添加了二分法实现的大数乘法,改进了除法和开方运算;速度提高很多)  

(2007.11.20 对乘法进行了一点小的优化,速度提高了些; 修正了两处bug,在MoveLeft10Power和MulInt函数中的进位问题)

类的声明文件:TLargeFloat.h

/////
//  TLargeFloat.h: interface for the TLargeFloat class.
//
   超高精度浮点数类TLargeFloat
//   2004.03.28 by [email protected]

//
//  Update 2004.03.31 by HouSisong 
//
 ......
// Update 2007.11.29-12.20 by HouSisong  重构一遍,速度加快很多,我用它计算了上亿位的PI值:)



#ifndef _TLARGE_FLOAT_H__INCLUDED_
#define _TLARGE_FLOAT_H__INCLUDED_


#include 
<vector>
#include 
<sstream>
#include 
<string>
#include 
<Exception>
#include 
<limits>


class TLargeFloat;//超高精度浮点数类TLargeFloat
class TLargeFloatException;// 超高精度浮点数异常类

//
改进方向:
//
  1.强力优化ArrayMUL数组乘运算(当前实现了二分法和FFT算法): 
//
     a.将实数按齐偶作为复数进行傅立叶变换的算法实现,加快乘法速度
//
     b.实现混合基的傅立叶变换,加快乘法速度
//
     c.考虑用x87的10byte浮点数实现FFT以减小误差从而增大FFT能够计算的最大位数限制
//
     d.用SSE2等优化快速复利叶变换,加快乘法速度  
//
     e.或者将傅立叶变换替换为数论变换的实现(使用整数)
//
  2.内部使用8位(或9位)十进制来实现,节约内存;或者2进制的底数(这样的话,输出函数就会麻烦一些了)
//
  3.添加新的基本运算函数,如:指数运算power、对数运算log、三角函数sin,cos,tan等

//
注意:如果浮点数与TLargeFloat进行混合运算, 可能会产生误差(有效位数会受到浮点数影响);
//
  整数 或 为可表示整数的浮点数 参与运算不会产生误差;
//
  对于很大的整数或者有小数位的浮点数,建议用字符串的形式转换为超高精度浮点数(不会引入误差)

//void ArrayMUL(TInt32bit* result,long rminsize,const TInt32bit* x,long xsize,const TInt32bit* y,long ysize);//
数组乘, 需要优化的首要目标

//超高精度浮点数异常类  //TLargeFloat运算中出现错误的时候会抛出该类型的异常

class TLargeFloatException :public  std::runtime_error
{
public
:
    TLargeFloatException(
const char *
 Error_Msg) :runtime_error(Error_Msg){}
    
virtual ~TLargeFloatException() throw
() {}
};


//
TCatchIntError只是对整数类型TInt进行的一层包装
//
超高精度浮点数类的指数运算时使用
//
设计TCatchIntError是为了当整数运算超出值域的时候,抛出异常
//template<要包装的整数类型,超界时抛出的异常类型,TInt最小值,TInt最大值>

template <typename TInt,typename TException,TInt MinValue,TInt MaxValue>
class  TCatchIntError
{
private
:
    typedef TCatchIntError
<TInt,TException,MinValue,MaxValue>
 SelfType;
    TInt  m_Int;

    inline SelfType
& inc(const TInt&
 uValue)
    {
        
if ( (uValue<0)||(uValue>MaxValue)||(MaxValue-uValue<
m_Int) )
            
throw TException("ERROR:TCatchIntError::inc(); "
);
        m_Int
+=
uValue;
        
return (*this
);
    }
    inline SelfType
& dec(const TInt&
 uValue)
    {
        
if ( (uValue<0)||(uValue>MaxValue)||(MinValue+uValue>
m_Int) )
            
throw TException("ERROR:TCatchIntError::dec()"
);
        m_Int
-=
uValue;
        
return (*this
);
    }
    inline SelfType
& mul(const TInt&
 iValue)
    {
        
if (iValue==0
)
            m_Int
=0
;
        
else

        {
            TInt tmp
=m_Int* iValue;
            
if ( (iValue<MinValue)||(iValue>MaxValue)||(tmp<MinValue)||(tmp>MaxValue)||((tmp/iValue)!=
m_Int) )
                
throw TException("ERROR:TCatchIntError::mul(); "
);
            m_Int
=
tmp;
        }
        
return (*this
);
    }
public
:
    inline TCatchIntError() :m_Int(
0
){ }
    inline TCatchIntError(
const TInt& Value)       :m_Int(0) { (*this)+=
Value;}
    inline TCatchIntError(
const SelfType& Value)   :m_Int(0) { (*this)+=
(Value.m_Int); }
    inline 
const TInt& AsInt() const    { return
 m_Int; }
    inline SelfType
& operator +=(const TInt& Value) //throw(TLargeFloatException)

        { if (Value<0return dec(- Value);
            
else return
 inc(Value);   }
    inline SelfType
& operator -=(const TInt& Value) //throw(TLargeFloatException)

        { if (Value<0)  return inc(- Value);
            
else return
 dec(Value); }
    inline SelfType
& operator *=(const TInt& Value) //throw(TLargeFloatException)

       {  return  mul(Value); }

    inline SelfType
& operator +=(const SelfType& Value) { return (*this)+=(Value.m_Int); }//throw(TLargeFloatException)

    inline SelfType& operator -=(const SelfType& Value) { return (*this)-=(Value.m_Int); }//throw(TLargeFloatException)
    inline SelfType& operator *=(const SelfType& Value) { return (*this)*=(Value.m_Int); }//throw(TLargeFloatException)
};

    
//
指数部分使用的整数类型  填写编译器支持的较大的整数类型 
    
//typedef __int64 TMaxInt; //
type long long TMaxInt;   
    
//
const TMaxInt   TMaxInt_MAX_VALUE =   TMaxInt(9223372036854775807);
    
//const TMaxInt   TMaxInt_MIN_VALUE = - TMaxInt_MAX_VALUE;

    typedef long   TMaxInt; 
    
const TMaxInt  TMaxInt_MAX_VALUE =  2147483647
;
    
const TMaxInt  TMaxInt_MIN_VALUE = -
TMaxInt_MAX_VALUE;

    
//小数部分使用的整数类型  32bit位的整数类型 

    typedef long  TInt32bit;
    
const TInt32bit  TInt32bit_MAX_VALUE =  2147483647
;
    
const TInt32bit  TInt32bit_MIN_VALUE = -
TInt32bit_MAX_VALUE;


//超高精度浮点数类

class  TLargeFloat  
{
public
:
    
//一些常量和类型定义

    typedef std::vector<TInt32bit> TArray;//小数位使用的数组类型
    enum { em10Power =4,   //数组为10000进制,
           emBase =10000,  //数组的一个元素对应4个十进制位
           emLongDoubleDigits =std::numeric_limits<long double>::digits10,//long double的10进制有效精度
           emLongDoubleMaxExponent =std::numeric_limits<long double>::max_exponent10,//long double的最大10进制指数
           emLongDoubleMinExponent =std::numeric_limits<long double>::min_exponent10 };//long double的最小10进制指数
    typedef   TLargeFloatException   TException;
    typedef   TCatchIntError
<TMaxInt,TException,TMaxInt_MIN_VALUE,TMaxInt_MAX_VALUE>  TExpInt;//指数类型

    typedef  TLargeFloat  SelfType;
public
:
    
class TDigits//TDigits用来设置TLargeFloat的精度;//增加这个类是为了避免TLargeFloat的构造函数的可能误用

    {
    
private
:
        unsigned 
long
  m_DigitsArraySize;
    
public
:
        
explicit TDigits(const long
 uiDigitsLength) 
        {   
if (uiDigitsLength<=0throw TException("ERROR:TLargeFloat::TDigits()"
);
            m_DigitsArraySize
=(uiDigitsLength+em10Power-1)/
em10Power; }
        inline 
const unsigned long  GetDigitsArraySize() const   { return
 m_DigitsArraySize; }
    };
    TLargeFloat(
const SelfType&
 Value);
    
explicit TLargeFloat(const long double DefultValue);//默认浮点精度  //注意:转换可能存在小的误差

    explicit TLargeFloat(const long double DefultValue,const TDigits& DigitsLength);//TDigits 十进制有效位数 //注意:转换可能存在小的误差
    explicit TLargeFloat(const char* strValue);//使用字符串本身的精度
    explicit TLargeFloat(const char* strValue,const TDigits&  DigitsLength);
    
explicit TLargeFloat(const std::string&
 strValue);
    
explicit TLargeFloat(const std::string& strValue,const TDigits&
 DigitsLength);
    
long double AsFloat() const;//转化为浮点数

    std::string  AsString() const;//转换为字符串
    void SetDigitsLength(const TDigits& DigitsLength);  //重新设置10进制有效位数 
    inline void SetDigitsLength(const long  uiDigitsLength) { SetDigitsLength(TDigits(uiDigitsLength)); }
    unsigned 
long GetDigitsLength() const;//返回当前的10进制有效位数


    
void Swap(SelfType& Value);//交换值
    void Zero(); //设置为0

    inline 
void StrToLargeFloat(const std::string&  strValue) { sToLargeFloat(strValue); }
    inline 
void StrToLargeFloat(const char* strValue) { sToLargeFloat(std::string
(strValue)); }
    SelfType
& operator =  (const SelfType&
 Value);
    SelfType
& operator =  (long double  fValue); //注意:转换可能存在小的误差  

    inline const SelfType  operator -  () const  {  SelfType temp(*this); temp.Chs(); return temp;  }//求负
    inline const SelfType& operator +  () const  { return (*this); }//求正

    SelfType
& operator += (const SelfType&  Value);
    SelfType
& operator -= (const SelfType&
 Value);
    inline SelfType
& operator += (long double  fValue)  { return (*this)+=
TLargeFloat(fValue); }
    inline SelfType
& operator -= (long double  fValue)  { return (*this)-=
TLargeFloat(fValue); }
    friend inline 
const TLargeFloat operator + (const TLargeFloat& x,const TLargeFloat& y)  { TLargeFloat temp(x);  return temp+=
y; }
    friend inline 
const TLargeFloat operator - (const TLargeFloat& x,const TLargeFloat& y)  { TLargeFloat temp(x);  return temp-=
y; }
    friend inline 
const TLargeFloat operator + (const TLargeFloat& x,long double y)  { TLargeFloat temp(x);  return temp+=
y; }
    friend inline 
const TLargeFloat operator - (const TLargeFloat& x,long double y)  { TLargeFloat temp(x);  return temp-=
y; }
    friend inline 
const TLargeFloat operator + (long double x,const TLargeFloat& y)  { return y+
x; }
    friend inline 
const TLargeFloat operator - (long double x,const TLargeFloat& y)  { return -(y-
x); }

    SelfType
& operator *= (long double
  fValue);
    SelfType
& operator *= (const SelfType&
 Value); 
    friend inline 
const TLargeFloat operator * (const TLargeFloat& x,const TLargeFloat& y)  { TLargeFloat temp(x); if (&x!=&y)  return temp*=y; else { temp.Sqr(); return
 temp;  } }
    friend inline 
const TLargeFloat operator * (const TLargeFloat& x,long double y)  {TLargeFloat temp(x); return temp*=
y;}
    friend inline 
const TLargeFloat operator * (long double x,const TLargeFloat& y)  { return y*
x; }
    SelfType
& operator /= (long double
  fValue);
    SelfType
& operator /= (const SelfType&
 Value);
    friend inline 
const TLargeFloat operator / (const TLargeFloat& x,const TLargeFloat& y)  { TLargeFloat temp(x); return temp/=
y; }
    friend inline 
const TLargeFloat operator / (const TLargeFloat& x,long double y)  { TLargeFloat temp(x); return temp/=
y; }
    friend inline 
const TLargeFloat operator / (long double x,const TLargeFloat& y)  { TLargeFloat temp(y); temp.Rev(); return temp*=
x; }

    friend inline 
bool operator ==(const TLargeFloat& x,const TLargeFloat& y) { return (x.Compare(y)==0
); }
    friend inline 
bool operator < (const TLargeFloat& x,const TLargeFloat& y) { return (x.Compare(y)<0
); }
    friend inline 
bool operator ==(const TLargeFloat& x,long double y) { return (x==
TLargeFloat(y)); }
    friend inline 
bool operator < (const TLargeFloat& x,long double y) { return (x<
TLargeFloat(y)); }
    friend inline 
bool operator ==(long double x,const TLargeFloat& y) { return (y==
x); }
    friend inline 
bool operator < (long double x,const TLargeFloat& y) { return (y>
x); }
    friend inline 
bool operator !=(const TLargeFloat& x,const TLargeFloat& y) { return !(x==
y); }
    friend inline 
bool operator > (const TLargeFloat& x,const TLargeFloat& y) { return (y<
x); }
    friend inline 
bool operator >=(const TLargeFloat& x,const TLargeFloat& y) { return !(x<
y); }
    friend inline 
bool operator <=(const TLargeFloat& x,const TLargeFloat& y) { return !(x>
y); }
    friend inline 
bool operator !=(const TLargeFloat& x,long double y) { return !(x==
y); }
    friend inline 
bool operator > (const TLargeFloat& x,long double y) { return (y<
x); }
    friend inline 
bool operator >=(const TLargeFloat& x,long double y) { return !(x<
y); }
    friend inline 
bool operator <=(const TLargeFloat& x,long double y) { return !(x>
y); }
    friend inline 
bool operator !=(long double x,const TLargeFloat& y) { return !(x==
y); }
    friend inline 
bool operator > (long double x,const TLargeFloat& y) { return (y<
x); }
    friend inline 
bool operator >=(long double x,const TLargeFloat& y) { return !(x<
y); }
    friend inline 
bool operator <=(long double x,const TLargeFloat& y) { return !(x>
y); }

    friend inline 
const TLargeFloat abs(const TLargeFloat& x)  { TLargeFloat result(x); result.Abs(); return result; }//绝对值,|x|

    friend inline const TLargeFloat sqrt(const TLargeFloat& x) { TLargeFloat result(x); result.Sqrt(); return result;} //开方,x^0.5 
    friend inline const TLargeFloat revsqrt(const TLargeFloat& x) { TLargeFloat result(x); result.RevSqrt(); return result; }//求1/x^0.5;
    friend inline const TLargeFloat sqr(const TLargeFloat& x) { TLargeFloat result(x); result.Sqr(); return result; };//平方,x^2
    friend inline void swap(TLargeFloat& a,TLargeFloat& b) { a.Swap(b); }//交换值
    friend inline std::ostream& operator << (std::ostream& cout, const TLargeFloat& Value) { return cout<< Value.AsString(); }

///

private :
    TInt32bit   m_Sign;     
//符号位  正:1,  负:-1, 零: 0

    TExpInt     m_Exponent; //保存10为底的指数
    TArray      m_Digits;   //小数部分 排列顺序是TArray[0]为第一个小数位(em10Power个10进制位),依此类推;取值范围[0--(emBase-1)]
private :
    
void Canonicity();//规格化 转化值到合法格式

    void fToLargeFloat(long double fValue);//内部使用 浮点数转化为 TLargeFloat,并采用默认精度
    void iToLargeFloat(TMaxInt iValue);//内部使用 整数转化为 TLargeFloat,并采用默认精度
    void sToLargeFloat(const std::string& strValue);//内部使用 字符串转化为 TLargeFloat
    long Compare(const SelfType& Value) const;//比较两个数;(*this)>Value 返回1,小于返回-1,相等返回0
    void Abs_Add(const SelfType& Value);//绝对值加  x:=|x|+|y|;
    void Abs_Sub_Abs(const SelfType& Value);//绝对值减的绝对值x:=| |x|-|y| |;
    
public
:
    
void Chs();//求负

    void Abs();//绝对值
    void MulInt(TMaxInt iValue);//乘以一个整数;
    void DivInt(TMaxInt iValue);//除以一个整数;
    void Rev();//求倒数
    void RevSqrt();//求1/x^0.5;
    inline void Sqrt()  { SelfType x(*this);  x.RevSqrt(); (*this)*=x; } //求x^0.5;
    inline void Sqr()   { (*this)*=(*this); };//平方,x^2
        

};


//单元测试

void  LargeFloat_UnitTest();


#endif // _TLARGE_FLOAT_H__INCLUDED_

// TLargeFloat.h
/// //


类的实现文件:TLargeFloat.cpp

/////
//  TLargeFloat.cpp: implementation of the TLargeFloat class.
//   超高精度浮点数类TLargeFloat

//

#include 
"TLargeFloat.h"
#include 
<algorithm>
//#include "assert.h"
#include <math.h>

// #define MyDebugAssert(b) { if (!(b)) __asm{ int 3 } }

//用以控制运算精度的工具

class  TDigitsLengthCtrl
{
private
:
    std::vector
<TLargeFloat*>
 m_list;
public
:
    inline 
void add_to_ctrl(TLargeFloat*
 var) { m_list.push_back(var); }
    
void SetDigitsLength(const long
 uiDigitsLength) 
    { 
        
long size=
m_list.size();
        
for (long i=0;i<size;++
i)
            m_list[i]
->
SetDigitsLength(uiDigitsLength);
    }
};

//自动精度控制

class TDigitsLengthAutoCtrl:public  TDigitsLengthCtrl
{
private
:
    std::vector
<long>
    m_DigitsLengthList;
    
long
   step;
public
:
    TDigitsLengthAutoCtrl(
long DigitsMul,long DigitsLength0,long MaxDigitsLength)//(收敛系数,初始精度,最终需要精度)

    {
        
//
MyDebugAssert(DigitsLength0>0);
        
//得到最佳的精度梯度

        long curDigitsLength= MaxDigitsLength;
        
while (curDigitsLength>
DigitsLength0)
        {
            m_DigitsLengthList.push_back(curDigitsLength);

            
if ((DigitsLength0<=1)&&(curDigitsLength==1)) break
;
            curDigitsLength
=(curDigitsLength+DigitsMul-1)/
DigitsMul;
        }
        step
=get_runcount()-1
;
    }
    inline 
long get_runcount() { return
 m_DigitsLengthList.size(); }
    inline 
void
 SetNextDigits()
    {
        
//MyDebugAssert(step>=0);

        long DigitsLength= m_DigitsLengthList[step];
        
if (step>0
)
            DigitsLength
+=4
;
        SetDigitsLength(DigitsLength);
        
--
step;
        
if (step<0) step=0
;
    }
};

/

void TLargeFloat_CtrlExponent(TLargeFloat::TArray&  v,TMaxInt iMoveRightCount)
{
    
//iMoveCountBig 有可能存不下 但现在的体系下因右移超过值域比较难

    long iMoveCountBig=(long)(iMoveRightCount/ TLargeFloat::em10Power);
    
long iMoveCountSmall=(long)(iMoveRightCount%
TLargeFloat::em10Power);

    
//大的右移

    if (iMoveCountBig>0 )
    {
        
for (long i=v.size()-1;i>=iMoveCountBig;--
i)
            v[i]
=v[i-
iMoveCountBig];
        
for (long j=0;j<iMoveCountBig;++
j)
            v[j]
=0
;
    }
    
//小的右移

    if (iMoveCountSmall>0 )
    {
        TInt32bit iDiv
=1
;
        
for (long j=0;j<iMoveCountSmall;++j) iDiv*=10
;

        
long v_size=
v.size();
        
for (long i=iMoveCountBig;i<v_size-1;++
i)
        {
            v[i
+1]+=(v[i]%iDiv)*
TLargeFloat::emBase;
            v[i]
/=
iDiv;
        }
        
if (v_size>=1
)
            v[v_size
-1]/=
iDiv;
    }
    
}

    
void TLargeFloat_ArrayAddTestLast(TInt32bit* x,long
 xsize)
    {
        
for (long i=xsize-1;i>0;--
i)
        {
            
if (x[i]>=TLargeFloat::emBase)//进位

            {
                
++x[i-1
];
                x[i]
-=
TLargeFloat::emBase;
            }
            
else

                
break ;
        }   
    }

void TLargeFloat_ArrayAdd(TInt32bit* result,long rsize,const TInt32bit* y,long
 ysize)
{
    
//
MyDebugAssert(rsize>=ysize);
    
//MyDebugAssert(ysize>0);

    TInt32bit* ri=&result[rsize- ysize];
    
long
 i;
    
for (i=ysize-1;i>0;--
i)
    {
        TInt32bit r
=ri[i]+
y[i];
        
if (r>=TLargeFloat::emBase)//进位

        {
            
++ri[i-1
];
            r
-=
TLargeFloat::emBase;
        }
        ri[i]
=
r;
    }    
    ri[
0]+=y[0
];
  
    TLargeFloat_ArrayAddTestLast(result,rsize
-ysize+1
);
}

void TLargeFloat_ArraySub(TInt32bit* result,long rsize,const TInt32bit* y,long
 ysize)
{
    
//
MyDebugAssert(rsize>=ysize);
    
//MyDebugAssert(ysize>0);

    TInt32bit* ri=&result[rsize- ysize];
    
long
 i;
    
for (i=ysize-1;i>0;--
i)
    {
        TInt32bit r
=ri[i]-
y[i];
        
if (r<0)//借位

        {
            
--ri[i-1
];
            r
+=
TLargeFloat::emBase;
        }
        ri[i]
=
r;
    }    
    ri[
0]-=y[0
];
  
    
for (i=rsize-ysize;i>0;--
i)
    {
        
if (result[i]<0)//借位

        {
            
--result[i-1
];
            result[i]
+=
TLargeFloat::emBase;
        }
        
else

            
break ;
    }   
}


        TInt32bit _inti_csMaxMuliValue()
        {
            
double rb=1double mb=1
;
            
for (long i=0;i<100/TLargeFloat::em10Power;++
i)
            {
                mb
*=(1.0/
TLargeFloat::emBase);
                rb
+=
mb;
            }
            
return (TInt32bit)( TInt32bit_MAX_VALUE*(1.0/(TLargeFloat::emBase-1))/rb ) -1
;
        }
    
//不超界所允许的乘数值M满足: (emBase-1)*M + (emBase-1)*M/B + (emBase-1)*M/B^2 + (emBase-1)*M/B^3 ... <=TInt32bit_MAX_VALUE

    static const TInt32bit csMaxMuliValue= _inti_csMaxMuliValue();
    
static const TInt32bit csMaxMulAddValue = csMaxMuliValue - (TLargeFloat::emBase-1
);

void TLargeFloat_ArrayMUL_ExE(TInt32bit* result,long rminsize,const TInt32bit* x,long xsize,const TInt32bit* y,long
 ysize)
{
    
//N*N复杂度的简单乘法实现

    for (long k=0;k<rminsize;++k) result[k]=0 ;
    
while ((ysize>0)&&(y[0]==0)) { --ysize; ++y; ++result; --
rminsize;}
    
//while ((xsize>0)&&(x[0]==0)) { --xsize; ++x; ++result; --rminsize;}

    while ((ysize>0)&&(y[ysize-1]==0)) { -- ysize; }
    
//while ((xsize>0)&&(x[xsize-1]==0)) { --xsize; }


    
long add_sum=0 ;
    
for (long i=0;i<xsize;++
i)
    {
        
long xi=
x[i];
        
if (xi>0
)
        {
            TInt32bit
* resulti=&result[i+1
];
            
long y_limit=std::min(rminsize-1-
i,ysize);
            
for (long j=0;j<y_limit;++
j)
            {
                resulti[j]
+=(xi*
y[j]);
            }
            add_sum
+=
xi;
            
if (add_sum>
csMaxMulAddValue)
            {
                
for (long k=i+y_limit;k>0;--
k)
                {
                    TInt32bit v
=
result[k];
                    
if (v>=
TLargeFloat::emBase)
                    {
                        result[k
-1]+=v/
TLargeFloat::emBase;
                        result[k]
= v%
TLargeFloat::emBase;
                    }
                }
                add_sum
=0
;
            }
        }
    }
    
if (add_sum>0
)
    {
        
for (long k=rminsize-1;k>0;--
k)
        {
            TInt32bit v
=
result[k];
            
if (v>=
TLargeFloat::emBase)
            {
                result[k
-1]+=v/
TLargeFloat::emBase;
                result[k]
= v%
TLargeFloat::emBase;
            }
        }
    }
}

//数组乘法  核心

void ArrayMUL(TInt32bit* result,long rminsize,const TInt32bit* x,long xsize,const TInt32bit* y,long  ysize);


void ArrayMUL_Dichotomy(TInt32bit* result,long rminsize,const TInt32bit* x,const TInt32bit* y,long
 MulSize)
{

    
//
二分法的乘法实现
    
//
   x*y=(a*E+b)*(c*E+d)=(E*E-E)*ac + E*(a+b)*(c+d) -(E-1)*bd

    
//
   temp_a_add_b=a+b;
    
//
   temp_c_add_d=c+d;
    
//
   result=E*temp_a_add_b*temp_c_add_d;

    
//
   temp_ac=a*c;
    
//
   result+=E*E*temp_ac;
    
//
   result-=E*temp_ac;

    
//
   temp_bd=b*d;
    
//
   result+=temp_bd;
    
//
   result-=E*temp_bd;
    
// 

    long  i;

    
const long E=((MulSize+1)>>1
);
    
//if (tmpData+2*(E+1)>end_tmpData)  __asm int 3

    const long acSize=MulSize- E;
    
const long acErrorSize=E-
acSize; 

    
const TInt32bit* a=
x;
    
const TInt32bit* b=&
x[acSize];
    
const TInt32bit* c=
y;
    
const TInt32bit* d=&
y[acSize];

    TLargeFloat::TArray _tmpData((E
+1)*2
);
    TInt32bit
* tmpData=&_tmpData[0
];

    TInt32bit
* temp_a_add_b=&tmpData[0
];
    TInt32bit
* temp_c_add_d=&tmpData[(E+1
)];

    temp_a_add_b[
0]=0
;     
    
for (i=0;i<E;++i) temp_a_add_b[i+1]=
b[i];
    TLargeFloat_ArrayAdd(temp_a_add_b,
1+E,a,E-
acErrorSize);
    temp_c_add_d[
0]=0
;
    
for (i=0;i<E;++i) temp_c_add_d[i+1]=
d[i];
    TLargeFloat_ArrayAdd(temp_c_add_d,
1+E,c,E-
acErrorSize);

    
const long abcdPos=(2*MulSize-E-2*(E+1
));
    
for (i=0;i<abcdPos;++i) result[i]=0
;
    ArrayMUL(
&result[abcdPos],std::min(rminsize-abcdPos,2*(E+1)),temp_a_add_b,E+1,temp_c_add_d,E+1
);
    
for (i=abcdPos+2*(E+1);i<rminsize;++i) result[i]=0
;

    TInt32bit
* temp_ac=&tmpData[0
];
    
const long acminsize=std::min(rminsize,acSize*2
);
    ArrayMUL(temp_ac,acminsize,a,acSize,c,acSize);
    TLargeFloat_ArrayAdd(result,acminsize,temp_ac,acminsize);
    
long sub_ac_size=acSize*2
;
    
if (E+sub_ac_size>rminsize) sub_ac_size=rminsize-
E;
    TLargeFloat_ArraySub(result,E
+
sub_ac_size,temp_ac,sub_ac_size);

    
const long add_bdPos=2*MulSize-2*
E;
    
long sub_bd_size=2*
E;
    
const long sub_bdPos=add_bdPos-
E;
    
if (sub_bdPos+sub_bd_size>rminsize) sub_bd_size=rminsize-
sub_bdPos;
    
if (sub_bd_size>0
)
    {
        TInt32bit
* temp_bd=&tmpData[0
];
        ArrayMUL(temp_bd,sub_bd_size,b,E,d,E);
        
long add_bd_size=2*
E;
        
if (add_bdPos+add_bd_size>rminsize) add_bd_size=rminsize-
add_bdPos;
        
if (add_bd_size>0
)
          TLargeFloat_ArrayAdd(result,add_bdPos
+
add_bd_size,temp_bd,add_bd_size);
        TLargeFloat_ArraySub(result,sub_bdPos
+
sub_bd_size,temp_bd,sub_bd_size); 
    }
}


void ArrayMUL_DichotomyPart(TInt32bit* result,long rminsize,const TInt32bit* x,long xsize,const TInt32bit* y,long
 ysize)
{
    
//二分法的辅助函数

    ///
    //x*y=(a*E+b)*y=a*y*E+b*y;

    
if (xsize== ysize)
    {
        ArrayMUL_Dichotomy(result,rminsize,x,y,ysize);
        
return
 ;
    }

    
if (xsize<
ysize)
    {
        std::swap(xsize,ysize);
        std::swap(x,y);
    }

    
const long E=
ysize;
    
const long asize=xsize-
E;
    
const TInt32bit* a=&x[0
];
    
const TInt32bit* b=&
x[asize];

 
    ArrayMUL(result,rminsize,a,asize,y,ysize);
    
for (long i=asize+ysize;i<rminsize;++i) result[i]=0
;
    
const long byPos=
asize;
    
if (byPos<
rminsize)
    {
        
const long byminsize=rminsize-
byPos;
        TLargeFloat::TArray tmpData(byminsize);
        TInt32bit
* tmp_by=&tmpData[0
];
        ArrayMUL_Dichotomy(tmp_by,byminsize,b,y,E);
        TLargeFloat_ArrayAdd(result,rminsize,tmp_by,byminsize);
    }
}


/

const long csTMaxInt_Digits=(long)(log10((long double)TMaxInt_MAX_VALUE)+1 );

TLargeFloat::TLargeFloat(
const SelfType&
 Value)
:m_Digits(Value.m_Digits)
{
    m_Exponent
=
Value.m_Exponent;
    m_Sign
=
Value.m_Sign;
}
    
TLargeFloat::TLargeFloat(
const long double
 DefultValue)
:m_Digits(TDigits(emLongDoubleDigits
+1).GetDigitsArraySize(),0
)
{
    fToLargeFloat(DefultValue);
}

TLargeFloat::TLargeFloat(
const long double DefultValue,const TDigits&
 DigitsLength)
:m_Digits(DigitsLength.GetDigitsArraySize(),
0
)
{
    fToLargeFloat(DefultValue);
}

TLargeFloat::TLargeFloat(
const char*
 strValue)
:m_Digits(TDigits(csTMaxInt_Digits).GetDigitsArraySize(),
0
)
{
    sToLargeFloat(std::
string
(strValue));
}
TLargeFloat::TLargeFloat(
const char* strValue,const TDigits&
 DigitsLength)
:m_Digits(DigitsLength.GetDigitsArraySize(),
0
)
{
    sToLargeFloat(std::
string
(strValue));
}
TLargeFloat::TLargeFloat(
const std::string&
 strValue)
:m_Digits(TDigits(csTMaxInt_Digits).GetDigitsArraySize(),
0
)
{
    sToLargeFloat(strValue);
}
TLargeFloat::TLargeFloat(
const std::string& strValue,const TDigits&
 DigitsLength)
:m_Digits(DigitsLength.GetDigitsArraySize(),
0
)
{
    sToLargeFloat(strValue);
}


void
 TLargeFloat::Zero()
{
    
if (m_Sign==0return
;
    m_Sign
=0
;
    m_Exponent
=0
;
    
long old_size=
m_Digits.size();
    
for (long i=0;i<old_size;++
i)
        m_Digits[i]
=0
;
}

void
 TLargeFloat::Canonicity()
{
    
//
规格化 小数部分
    
//
规格化前允许:m_Digits[0]>=emBase 也就是小数部分的值大于等于1.0;
    
//
规格化前允许:m_Digits[]前面有多个0值 也就是小数部分的值小于0.1;
    
//规格化后的数满足的条件:小数部分的值 小于1.0,大于等于0.1;


    
if (m_Sign==0 )
    {
        
return
;
    }
    
long old_size=
m_Digits.size();
    
if (old_size<=0return//不可能发生:)


    
if ( (m_Digits[0]<emBase)&&(m_Digits[0]>=(emBase/10)) ) return ;

    
//处理右移

    while (m_Digits[0]>=emBase)//是否需要右移1
    {
        m_Exponent
+=
em10Power;
        
for (long i=old_size-1;i>=2;--
i)
            m_Digits[i]
=m_Digits[i-1
];
        
if (old_size>=2) m_Digits[1]=m_Digits[0%
 emBase;
        m_Digits[
0]/=
emBase;
    }

    

    //
考虑左移

    
//大的左移

    long iMoveCountBig= old_size;
    
for (long i=0;i<old_size;++
i)
    {
        
if (m_Digits[i]!=0
)
        {
            iMoveCountBig
=
i;
            
break
;
        }
    }
    
if (iMoveCountBig==
old_size)
    {
        
//as Zero();

        m_Sign=0 ;
        m_Exponent
=0
;
        
return
;
    }

    
if (iMoveCountBig>0
)
    {
        m_Exponent
-=(iMoveCountBig*
em10Power);
        
for (long j=0;j<old_size-iMoveCountBig;++
j)
            m_Digits[j]
=m_Digits[j+
iMoveCountBig];
        
for (long k=old_size-iMoveCountBig;k<old_size;++
k)
            m_Digits[k]
=0
;
    }

    
//小的左移

    TInt32bit iMoveMul=1 ;
    
long iMoveCountSmall=0
;
    
while (iMoveMul*m_Digits[0]<(emBase/10
))
    {
        iMoveMul
*=10
;
        
++
iMoveCountSmall;
    }
    
if (iMoveCountSmall>0

    {
        m_Exponent
-=
iMoveCountSmall;
        
for (long i=old_size-1;i>=0;--
i)
            m_Digits[i]
*=
iMoveMul;
        
for (long j=old_size-1;j>0;--
j)
        {
            TInt32bit value
=
m_Digits[j];
            m_Digits[j]
=value%
emBase;
            m_Digits[j
-1]+=value/
emBase;
        }
    }
}

void
 TLargeFloat::iToLargeFloat(TMaxInt iValue)
{
    Zero();
    
long new_size=
TDigits(csTMaxInt_Digits).GetDigitsArraySize();
    
if ((long)m_Digits.size()<
new_size)
        m_Digits.resize(new_size,
0
);
    
if (iValue==0
)
        
return
;
    
else if (iValue>0
)
        m_Sign
=1
;
    
else

    {
        m_Sign
=-1 ;
        iValue
=-
iValue;
    }

    
//无误差转换

    TMaxInt tmp_iValue= iValue;
    
long n=0
;
    
for (;tmp_iValue!=0;++
n)
        tmp_iValue
/=
emBase;
    m_Exponent
=n*
em10Power;
    
for (long i=0;i<n;++
i)
    {
        m_Digits[n
-1-i]=(TInt32bit)(iValue%
emBase);
        iValue
/=
emBase;
    }
    Canonicity();
}

void TLargeFloat::fToLargeFloat(long double
 fValue)
{
    TMaxInt iValue
=
(TMaxInt)fValue;
    
if (iValue==
fValue)
    {
        iToLargeFloat(iValue);
        
return
;
    }

    Zero();
    
long new_size=TDigits(emLongDoubleDigits+1
).GetDigitsArraySize();
    
if ((long)m_Digits.size()<
new_size)
        m_Digits.resize(new_size,
0
);
    
if (fValue==0
)
        
return
;
    
else if (fValue>0
)
        m_Sign
=1
;
    
else

    {
        m_Sign
=-1 ;
        fValue
=-
fValue;
    }

    m_Exponent
=(long
)floor(log10(fValue));
    fValue
/=pow(10.0,(long
)m_Exponent.AsInt());
    
long size=
m_Digits.size();
    
for (long i=0;i<size;++i)//得到小数位

    {
        
if (fValue<=0break
;
        fValue
*=
emBase;
        TInt32bit iValue
=
(TInt32bit)floor(fValue);
        fValue
-=
iValue;
        m_Digits[i]
=
iValue;
    }      
    
    Canonicity();
}

void TLargeFloat::Swap(SelfType&
 Value)
{
    
if (this==&Value) return
;
    m_Digits.swap(Value.m_Digits);
    std::swap(m_Sign,Value.m_Sign);
    std::swap(m_Exponent,Value.m_Exponent);
}

void
 TLargeFloat::Chs()
{
    m_Sign
*=(-1
);
}

void
 TLargeFloat::Abs()
{
    
if (m_Sign!=0) m_Sign=1
;
}

unsigned 
long TLargeFloat::GetDigitsLength() const

{
    
return m_Digits.size()* em10Power;
}

void TLargeFloat::SetDigitsLength(const TDigits&
 DigitsLength)
{
    m_Digits.resize(DigitsLength.GetDigitsArraySize(),
0
);
}

TLargeFloat::SelfType
& TLargeFloat::operator =  (const SelfType&
 Value)
{
    
if (this==&Value) return *this
;
    m_Digits
=
Value.m_Digits;
    m_Sign
=
Value.m_Sign;
    m_Exponent
=
Value.m_Exponent;
    
return *this
;
}

TLargeFloat::SelfType
& TLargeFloat::operator =  (long double
  fValue)
{
    fToLargeFloat(fValue);
    
return *this
;
}

long double TLargeFloat::AsFloat() const

{
    
if ( ((m_Exponent.AsInt())>= emLongDoubleMaxExponent)
        
||((m_Exponent.AsInt())<=
emLongDoubleMinExponent) )
    {
        
throw TException("ERROR:TLargeFloat::AsFloat()"
);
    }

    
if (m_Sign==0return 0
;
    
long double result=m_Sign*pow((long double)10.0,(long double
)m_Exponent.AsInt());

    
long double r=1
;
    
long double Sum=0
;
    
long old_size=
m_Digits.size();
    
for (long i=0;i<old_size;++i)//得到小数位

    {
        r
/=emBase;//r*=(1.0/emBase);

        if (r==0break
        Sum
+=(m_Digits[i]*
r);
    }       
    
return result*
Sum;
}
std::
string  TLargeFloat::AsString() const

{
    
if (m_Sign==0 )
        
return "0"
;

    
//计算需要的字符串空间大小

    long str_length=2+m_Digits.size()* em10Power;
    
if  (m_Sign<0++str_length; //负号


    TMaxInt EpValue
= m_Exponent.AsInt();
    
long UEP_StrLength=0
;
    
if (EpValue!=0

    {
        
++
str_length;
        
if (EpValue<0
)
        {
            EpValue
=-
EpValue;
            
++
str_length;
        }
        UEP_StrLength
=0
;
        
while (EpValue>0
)
        {
            EpValue
/=10
;
            
++
UEP_StrLength;
        }
        str_length
+=
UEP_StrLength;
    }

    std::
string result(str_length,' '
);
    std::
string::value_type* pStr=&result[0
];

    
//输出字符串

    if  (m_Sign<0) { *pStr='-'++ pStr; }
    
*pStr='0'++pStr;   *pStr='.'++
pStr;

    
long dgsize=
m_Digits.size();
    
for (long i=0;i<dgsize;++
i)
    {
        TInt32bit Value
=
m_Digits[i];
        
for (long d=0;d<em10Power;++
d)
        {
            pStr[em10Power
-1-d]=(char)('0'+(Value%10
));
            Value
/=10
;
        }
        pStr
+=
em10Power;
    }

    EpValue
=
m_Exponent.AsInt();
    
if (EpValue!=0

    {
        
*pStr='e'++
pStr;
        
if (EpValue<0
)
        {
            EpValue
=-
EpValue;
            
*pStr='-'++
pStr;
        }
        
for (long i=0;i<UEP_StrLength;++
i)
        {
            pStr[UEP_StrLength
-1-i]=(char)('0'+(EpValue%10
));
            EpValue
/=10
;
        }
        pStr
+=
UEP_StrLength;
    }

    
return
 result;
}

    template
<class PChar>

    PChar sToLargeFloat_GetCharIntEnd(PChar int_begin,PChar str_end)
    {
        
long int_count=0 ;
        
for (PChar i=int_begin;i<str_end;++
i)
        {
            
if ( ('0'<=(*i)) && ((*i)<='9'
) )
                
++
int_count;
            
else

                
break ;
        }
        
return &
int_begin[int_count];
    }

    inline 
void sToLargeFloat_setAChar(TLargeFloat::TArray& Digits,long set_index,char
 aChar)
    {
        unsigned 
long Value=aChar-'0'
;
        
long e10Power_count=TLargeFloat::em10Power-1-(set_index%
TLargeFloat::em10Power);
        
for (long i=0;i<e10Power_count;++
i)
          Value
*=10
;
        Digits[set_index
/TLargeFloat::em10Power]+=
Value;
    }

void TLargeFloat::sToLargeFloat(const std::string&
 strValue)
{
    
if (strValue.size()<=0
)
    {
        
this->
Zero();
        
return
;
    }
    typedef 
const std::string::value_type*
 PChar;
    PChar pstr_begin
=
strValue.c_str();
    PChar pstr_end
=&
pstr_begin[strValue.size()];

    
//str as:  [+|-][0..9][.][0..9][E|e][+|-][0..9] 

    bool is_have_sign=false ;
    
long  sign=1
;
    
bool is_have_int=false
;
    PChar int_begin
=0; PChar int_end=0

    
bool is_have_dot=false
;
    
bool is_have_digits=false
;
    PChar digits_begin
=0; PChar digits_end=0

    
bool is_have_ep=false
;
    
bool is_have_ep_sign=false
;
    
long  ep_sign=1
;
    
bool is_have_ep_int=false
;
    PChar ep_int_begin
=0; PChar ep_int_end=0


    
//处理正负号

    if ((*pstr_begin)=='-'
    {
        sign 
= -1
;
        is_have_sign
=true
;
        
++
pstr_begin; 
    }
    
else if ((*pstr_begin)=='+'

    {
        is_have_sign
=true
;
        
++
pstr_begin; 
    }

    
//处理前面的整数部分

    int_begin= pstr_begin;
    int_end
=
sToLargeFloat_GetCharIntEnd(int_begin,pstr_end);
    is_have_int
=(int_begin!=
int_end);
    
if ((int_end-int_begin>=2)&&((*int_begin)=='0')) throw TException("ERROR:TLargeFloat::sToLargeFloat(); 0"); //'0?'数字表示错误

    pstr_begin= int_end;
    
if (((*pstr_begin)!='.')&&(!is_have_int)) throw TException("ERROR:TLargeFloat::sToLargeFloat(); 1"); //
没有任何数字
    
    
//处理小数部分

    if ((*pstr_begin)=='.' )
    {
        is_have_dot
=true
;
        
++
pstr_begin;

        digits_begin
=
pstr_begin;
        digits_end
=
sToLargeFloat_GetCharIntEnd(digits_begin,pstr_end);
        is_have_digits
=(digits_begin!=
digits_end);
        
if ((!is_have_digits)&&(!is_have_int)) throw TException("ERROR:TLargeFloat::sToLargeFloat(); 2"); //没有任何数字

        pstr_begin= digits_end;
    }

    
//处理指数部分

    if ( ((*pstr_begin)=='e')||((*pstr_begin)=='E' ) )
    {
        is_have_ep
=true
;
        
++
pstr_begin;
        
//处理指数的正负号

        if ((*pstr_begin)=='-'
        {
            ep_sign 
= -1
;
            is_have_ep_sign
=true
;
            
++
pstr_begin; 
        }
        
else if((*pstr_begin)=='+'

        {
            is_have_ep_sign
=true
;
            
++
pstr_begin; 
        }
        
//处理指数中的整数

        ep_int_begin= pstr_begin;
        ep_int_end
=
sToLargeFloat_GetCharIntEnd(ep_int_begin,pstr_end);
        is_have_ep_int
=(ep_int_begin!=
ep_int_end);
        
if ((ep_int_end-ep_int_begin>=2)&&((*ep_int_begin)=='0')) throw TException("ERROR:TLargeFloat::sToLargeFloat(); 3"); //'0?'数字表示错误

        pstr_begin= ep_int_end;
        
if (!is_have_ep_int) throw TException("ERROR:TLargeFloat::sToLargeFloat(); 4"); //指数没有数字

    }
    
if (pstr_begin!=pstr_end) throw TException("ERROR:TLargeFloat::sToLargeFloat(); 5"); //未预料的字符



    
//
    //实际的类型转换


    
this-> Zero();
    
this->m_Sign=
sign;
    
this->m_Exponent=(int_end-
int_begin);
    
long need_digits_count=(int_end-int_begin)+(digits_end-
digits_begin);
    
if ((long)this->GetDigitsLength()<
need_digits_count)
      
this->
SetDigitsLength(need_digits_count);
    
long set_index=0
;
    PChar set_begin
=
int_begin;
    
for (;set_begin<int_end;++set_begin,++
set_index)
        sToLargeFloat_setAChar(
this->m_Digits,set_index,*
set_begin);
    set_begin
=
digits_begin;
    
for (;set_begin<digits_end;++set_begin,++
set_index)
        sToLargeFloat_setAChar(
this->m_Digits,set_index,*
set_begin);

    
if
 (is_have_ep)
    {
        TExpInt ep
=0
;
        
for (PChar set_begin=ep_int_begin;set_begin<ep_int_end;++
set_begin)
        {
            ep
*=10
;
            ep
+=((*set_begin)-'0'
);
        }
        ep
*=
ep_sign;
        
this->m_Exponent+=
ep;
    }
    Canonicity();
}


long  TLargeFloat::Compare(const SelfType& Value) const

{
    
if (this==&Value) return 0 ;
    
//
(*this)>Value 返回1,小于返回-1,相等返回0

    
//比较符号

    if (m_Sign> Value.m_Sign)
        
return 1
;
    
else if(m_Sign<
Value.m_Sign)
        
return -1
;
    
else //m_Sign==Value.m_Sign

    {
        
if(m_Sign==0
)
            
return 0
;
    }
    
//
m_Sign==Value.m_Sign

    
//比较指数

    if (m_Exponent.AsInt()> Value.m_Exponent.AsInt())
        
return
 m_Sign;
    
else if (m_Exponent.AsInt()<
Value.m_Exponent.AsInt())
        
return -
m_Sign;
    
else//(m_Exponent==Value.m_Exponent)

    {
        
long sizeS=
m_Digits.size();
        
long sizeV=
Value.m_Digits.size();
        
long min_size=
std::min(sizeS,sizeV);
        
for (long i=0;i<min_size;++
i)
        {
            
if (m_Digits[i]!=
Value.m_Digits[i])
            {
                
if (m_Digits[i]>
Value.m_Digits[i])
                    
return
 m_Sign;
                
else //if (m_Digits[i]

                    return - m_Sign;
            }
        }

        
//继续比较 处理尾部

        if (sizeS> sizeV)
        {
            
for (long i=sizeV;i<sizeS;++
i) 
            {
                
if (m_Digits[i]>0
)
                    
return
 m_Sign;;
            }
        }
        
else if (sizeS<
sizeV)
        {
            
for (long i=sizeS;i<sizeV;++
i) 
            {
                
if (Value.m_Digits[i]>0
)
                    
return -
m_Sign;
            }
        }
        
//sizeS==sizeV

        
        
return 0
;
    }
}

//
//+ -


TLargeFloat::SelfType
& TLargeFloat::operator += (const SelfType&  Value)
{
    
if (Value.m_Sign==0
)
        
return (*this
);
    
else if (m_Sign==0
)
        
return (*this)=
Value;
    
else if (m_Sign==
Value.m_Sign)
    {
        TInt32bit oldSign
=
m_Sign;
        Abs_Add(Value);
        m_Sign
=
oldSign;
        
return *this
;
    }
    
else

        
return *this-=(- Value);
}

TLargeFloat::SelfType
& TLargeFloat::operator -= (const SelfType&
 Value)
{
    
if (Value.m_Sign==0
)
        
return (*this
);
    
else if (m_Sign==0
)
    {
        (
*this)=-
Value;
        
return (*this
);
    }
    
else if (m_Sign==
Value.m_Sign)
    {
        
long comResult=this->
Compare(Value);    
        
if (comResult==0
)
        {
            
this->
Zero();
        }
        
else

        {
            Abs_Sub_Abs(Value);
            m_Sign
= comResult;
        } 
        
return *this
;
    }
    
else

        
return *this+=(- Value);
}

void TLargeFloat::Abs_Add(const SelfType& Value)//绝对值加法

{
    
this->
Abs();
    SelfType Right(Value);
    Right.Abs();

    
//精度一致

    if (m_Digits.size()< Right.m_Digits.size())
        m_Digits.resize(Right.m_Digits.size(),
0
);
    
else if (m_Digits.size()>
Right.m_Digits.size())
        Right.m_Digits.resize(m_Digits.size(),
0
);
    
//被加数指数较大就可以了

    if (m_Exponent.AsInt()< Right.m_Exponent.AsInt())
        
this->
Swap(Right);
    
long size=
m_Digits.size();

    TMaxInt iMoveRightCount
=m_Exponent.AsInt()-
Right.m_Exponent.AsInt();
    
if (iMoveRightCount>=size*(TMaxInt)TLargeFloat::em10Power) return
;
    TLargeFloat_CtrlExponent(Right.m_Digits,iMoveRightCount);
//对齐小数点


    TLargeFloat_ArrayAdd(
&m_Digits[0],size,&Right.m_Digits[0 ],size);
    
if (m_Digits[0]>=
emBase)
        Canonicity();
}

void TLargeFloat::Abs_Sub_Abs(const SelfType& Value)//绝对值减法

{
    
this->
Abs();
    SelfType Right(Value);
    Right.Abs();

    
long comResult=this->
Compare(Right);
    
if (comResult==0
)
    {
        
this->
Zero();
        
return
;
    }
    
else if (comResult<0
)
        
this->
Swap(Right);

    
//精度一致

    if (m_Digits.size()< Right.m_Digits.size())
        m_Digits.resize(Right.m_Digits.size(),
0
);
    
else if (m_Digits.size()>
Right.m_Digits.size())
        Right.m_Digits.resize(m_Digits.size(),
0
);

    
long size=
m_Digits.size();

    TMaxInt iMoveRightCount
=m_Exponent.AsInt()-
Right.m_Exponent.AsInt();
    
if (iMoveRightCount>=size*(TMaxInt)TLargeFloat::em10Power) return
;
    TLargeFloat_CtrlExponent(Right.m_Digits,iMoveRightCount); 
//对齐小数点


    TLargeFloat_ArraySub(
&m_Digits[0],size,&Right.m_Digits[0 ],size);
    
if (m_Digits[0]*10<
emBase)
        Canonicity();
}



/
//
 /

    
//最大的32bit整数除数M满足: (emBase-1)+(M-1)*emBase<=TInt32bit_MAX_VALUE

    const TInt32bit csMaxDiviValue=TInt32bit_MAX_VALUE/TLargeFloat::emBase -1 ;
    
//最大的整数除数M满足: (emBase-1)+(M-1)*emBase<=TMaxInt_MAX_VALUE

    const TMaxInt csMaxDiviValueBig=TMaxInt_MAX_VALUE/TLargeFloat::emBase -1 ;

void TLargeFloat::DivInt(TMaxInt iValue)//除以一个整数

{
    
if (iValue==0

        
throw TException("ERROR:TLargeFloat::DivInt()"
);
    
else if (iValue<0
)
    {
        iValue
=-
iValue;
        
this->
Chs();
        
//continue

    }
    
if (iValue==1)  return
;
    
if (this->m_Sign==0return
;

    
if (iValue>
csMaxDiviValueBig) 
    {
        TLargeFloat y(
0.0
);
        y.iToLargeFloat(iValue);
        (
*this)/=
y;
        
return
;
    }
    
    
if (iValue<=
csMaxDiviValue)
    {
        TInt32bit iDiv
=
(TInt32bit)iValue;
        
long size=
m_Digits.size();
        
for (long i=0;i<size-1;++
i)
        {
            m_Digits[i
+1]+=(m_Digits[i]%iDiv)*
emBase;
            m_Digits[i]
/=
iDiv;
        }
        
if (size>=1
)
            m_Digits[size
-1]/=
iDiv;
    }
    
else
 
    {
        TMaxInt iDiv
=
iValue;
        
long size=
m_Digits.size();
        TMaxInt cur_value
=m_Digits[0
];
        
for (long i=0;i<size-1;++
i)
        {
            m_Digits[i]
=(TInt32bit)(cur_value/
iDiv);
            cur_value
=m_Digits[i+1]+(cur_value%iDiv)*
emBase;
        }
        
if (size>=1
)
            m_Digits[size
-1]=(TInt32bit)(cur_value/
iDiv);
    }

    Canonicity();
}

TLargeFloat::SelfType
& TLargeFloat::operator /= (long double
  fValue)
{
    TMaxInt iValue
=
(TMaxInt)fValue;
    
if (iValue==
fValue)
    {
        DivInt(iValue);
        
return *this
;
    }
    
else

        
return (*this)/= TLargeFloat(fValue);
}

TLargeFloat::SelfType
& TLargeFloat::operator /= (const SelfType&
 Value)
{
    SelfType x(Value);
    x.Rev();
//x=1/x;

    return (*this)*= x;
}

void TLargeFloat::Rev()//求倒数

{
    
//
求1/a,
    
//
 则有a=1/x;  y=a-1/x;
    
//
 求导得y'=1/x^2;
    
//
 代入牛顿方程 x(n+1)=x(n)-y(x(n))/y'(x(n));
    
// 有迭代式 x_next=(2-a*x)*x; //
可证明:该公式为2阶收敛公式
    
//
 证明:令x=1/a+dx;
    
//
 则有x_next-1/a=(2-a*(1/a+dx))*(1/a+dx)-1/a
    
//
               =(-a)*dx^2
    
// 证毕.


    
if (this->m_Sign==0throw TException("ERROR:TLargeFloat::Rev()" );
    TExpInt oldExponent
=
m_Exponent;

    SelfType a(
*this
);
    a.m_Exponent
=0
;
    SelfType x(
0.0
,TLargeFloat::TDigits(a.GetDigitsLength()));
    x
=1.0/a.AsFloat();//初始迭代值


    TDigitsLengthAutoCtrl dlCtrl(
2,emLongDoubleDigits-1,(a.m_Digits.size()* TLargeFloat::em10Power));
    SelfType ta(
0.0
,TLargeFloat::TDigits(a.GetDigitsLength()));
    SelfType temp(
0.0
,TLargeFloat::TDigits(a.GetDigitsLength()));
    dlCtrl.add_to_ctrl(
&
ta);
    dlCtrl.add_to_ctrl(
&
x);
    dlCtrl.add_to_ctrl(
&
temp);
    
for (long i=0;i<dlCtrl.get_runcount();++
i)
    {
        ta
=
a;
        dlCtrl.SetNextDigits();
        
//x=x*2-x*x*ta;

        temp= x;
        temp
*=
temp;
        temp
*=
ta;
        x
*=2
;
        x
-=
temp;
    }

    x.m_Exponent
-=
oldExponent;
    
this->
Swap(x);
}


/////

//

void TLargeFloat::RevSqrt() //
{
    
//
求1/a^0.5,
    
//
 则有a=1/x^2;  y=a-1/x^2;
    
//
 求导得y'=2/x^3;
    
//
 代入牛顿方程 x(n+1)=x(n)-y(x(n))/y'(x(n));
    
// 有迭代式 x_next=(3-a*x*x)*x/2; //
可证明:该公式为2阶收敛公式
    
//
 证明:令x=1/a^0.5+dx;
    
//
 则有x_next-1/a^0.5=(3-a*(1/a^0.5+dx)*(1/a^0.5+dx))*(1/a^0.5+dx)/2 - 1/a^0.5
    
//
                   =-(1.5/a^0.5)*dx^2-0.5*a*dx^3;
    
// 证毕.

    if (this->m_Sign<0throw TException("ERROR:TLargeFloat::RevSqrt()" );
    
if (this->m_Sign==0return
;

    SelfType a(
*this
);
    TMaxInt sqrExponent
=a.m_Exponent.AsInt()/2
;
    a.m_Exponent
-=(sqrExponent*2
);


    SelfType x(
0.0
,TDigits(a.GetDigitsLength()));
    x
=1.0/sqrt(a.AsFloat());//初始迭代值


    TDigitsLengthAutoCtrl dlCtrl(
2,emLongDoubleDigits-1,(a.m_Digits.size()* TLargeFloat::em10Power));
    SelfType ta(
0.0
,TLargeFloat::TDigits(a.GetDigitsLength()));
    SelfType temp(
0.0
,TLargeFloat::TDigits(a.GetDigitsLength()));
    dlCtrl.add_to_ctrl(
&
ta);
    dlCtrl.add_to_ctrl(
&
x);
    dlCtrl.add_to_ctrl(
&
temp);
    
for (long i=0;i<dlCtrl.get_runcount();++
i)
    {
        ta
=
a;
        dlCtrl.SetNextDigits();
        
//x=(3-x*x*ta)*x/2;

        temp= x;
        temp
*=
temp;
        temp
*=
ta;
        temp.Chs();
        temp
+=3
;
        x
*=
temp;
        x
/=2
;
    }

    x.m_Exponent
-=
sqrExponent;
    
this->
Swap(x);
}

////

//*

void  TLargeFloat::MulInt(TMaxInt iValue)
{
    
if (this->m_Sign==0return
;
    
if (iValue==0

    {
        
this->
Zero();
        
return
;
    }
    
else if (iValue<0
)
    {
        iValue
=-
iValue;
        
this->
Chs();
        
//continue

    }

    
if (iValue>
csMaxMuliValue)
    {
        TLargeFloat y(
0.0
);
        y.iToLargeFloat(iValue);
        (
*this)*=
y;
        
return
;
    }

    
//乘以一个整数

    TInt32bit Value= (TInt32bit)iValue;
    
long size=
m_Digits.size();
    
for (long i=size-1;i>=0;--
i)
    {
        m_Digits[i]
*=
Value;
    }
    
for (long j=size-1;j>=1;--
j)
    {
        
if (m_Digits[j]>=
emBase)
        {
            m_Digits[j
-1]+=m_Digits[j]/
emBase;
            m_Digits[j]
%=
emBase;
        }
    }
    Canonicity();
}
TLargeFloat::SelfType
& TLargeFloat::operator *= (long double
  fValue)
{
    TMaxInt iValue
=
(TMaxInt)fValue;
    
if (iValue==
fValue)
    {
        MulInt(iValue);
        
return *this
;
    }
    
else

    {
        TLargeFloat temp(fValue);
        
return (*this)*= temp;
    }
}

inline 
void getBestMulSize(const TInt32bit*& x,long& xsize,const TInt32bit*& y,long&
 ysize)
{
    
long bxsize=
xsize;
    
long bysize=
ysize;

    
long
 i;
    
for (i=xsize-1;i>=0;--
i)
    {
        
if (x[i]==0

            
--
bxsize;
        
else

            
break ;
    }
    
for (i=ysize-1;i>=0;--
i)
    {
        
if (y[i]==0

            
--
bysize;
        
else

            
break ;
    }

    
if (bxsize<
bysize)
    {
        std::swap(bxsize,bysize);
        std::swap(xsize,ysize);
        std::swap(x,y);
    }
    xsize
=
bxsize;

    
const long csABigMulSize=1000
;
    
if ( (bysize<csABigMulSize)||(bxsize*2>=bysize*3)||(bxsize>
ysize) )
        ysize
=
bysize;
    
else
 
        ysize
=
bxsize;
}

TLargeFloat::SelfType
& TLargeFloat::operator *= (const SelfType&
 Value)
{
    
long xsize=
m_Digits.size();
    
long ysize=
Value.m_Digits.size();
    
if ((m_Sign==0)||(Value.m_Sign==0
)) 
    {
        
if (m_Sign!=0
)
            
this->
Zero();
        
if (xsize<
ysize)
            m_Digits.resize(ysize,
0
);
        
return *this
;
    }
    
if (xsize<
ysize)
        m_Digits.resize(ysize,
0
);
    
    
long rminsize=std::max(xsize,ysize)+2;//乘法结果需要的位数


    
const TInt32bit* x=&m_Digits[0 ];
    
const TInt32bit* y=&Value.m_Digits[0
];
    getBestMulSize(x,xsize,y,ysize);
    
if (rminsize>xsize+
ysize)
        rminsize
=xsize+
ysize;

    TArray tempArray(rminsize);
    ArrayMUL(
&tempArray[0
],rminsize,x,xsize,y,ysize);

    xsize
=
m_Digits.size();
    
long resultsize=
std::min(xsize,rminsize);
    
long
 i;
    
for (i=0;i<resultsize;++i)  this->m_Digits[i]=
tempArray[i];
    
for (i=resultsize;i<xsize;++i) this->m_Digits[i]=0
;
    m_Exponent
+=
Value.m_Exponent;
    m_Sign
*=
Value.m_Sign;
    Canonicity();
    
return *this
;
}



//
快速傅立叶变换实现大整数乘法 
//  FFT Mul


struct TComplex //复数类型    
{
    
double
  i;
    
double
  r;
};

//初始化


void FFTInitial(TComplex* w,long* lst,const long  n)
{
    
//计算W^i , i in [0--n)

    const double PI=3.1415926535897932385 ;
    
const double seta=2.0*PI/
n;
    
long
 i,j;

    
long n2=n>>2
;
    
for (i=0;i<=n2;++
i)
    {
        w[i].i
=sin(seta*
i);
        w[i].r
=cos(seta*
i);
    }
    
for (j=(n2+1),i=(n2-1); i>=0 ;--i,++
j)
    {
        w[j].i
=
 w[i].i;
        w[j].r
=-
w[i].r;
    }

    
//计算排序用数组

    lst[0]=0
    i
=1
;
    
long
 m;
    
for (n2=n>>1,m=2; n2>0 ;n2=n2>>1,m =m<<1

    {
        
for (long j=0;i<m;++i,++
j)
        {
            lst[i]
=lst[j]+
n2;
        }
    }
}

//快速傅立叶变换

void FFT(TComplex* a,const TComplex* w,const long  n)
{
    
long n2=1
;  
    
long n1=>> 1
;
    
for (long per=1;per<
n;)
    {
        
long m=n2;  long j=0;  long k=
n2;
        per
<<=1
;
        
while (k<
n) 
        {
            
for (long i2=0; j<m ;++j,++k,i2+=
n1)
            {
                TComplex tmpb
=
a[j];
                
double   tmp1=a[k].r*w[i2].r-a[k].i*
w[i2].i;
                
double   tmp2=a[k].r*w[i2].i+a[k].i*
w[i2].r;
                a[j].r
=tmpb.r+
tmp1;
                a[j].i
=tmpb.i+
tmp2;
                a[k].r
=tmpb.r-
tmp1;
                a[k].i
=tmpb.i-
tmp2;
            }
            m
+=
per;  
            j
+=
n2;  
            k
+=
n2;
        }
        n2
=
per;
        n1
>>=1
;
    }
}


//反向快速傅立叶变换

void InvFFT(TComplex* a,const TComplex* w,const long  n)
{
    
for (long i=0;i<n;++
i)
        a[i].i
=-
a[i].i;
    FFT(a,w,n);
}

void FFT_Convolution(const TComplex* a,TComplex* b,const long
 n)
{
    
for (long i=0;i<n;++
i)
    {
        
double br=a[i].r*b[i].r - a[i].i*
b[i].i;
        b[i].i
=a[i].r*b[i].i + a[i].i*
b[i].r;
        b[i].r
=
br;
    }
}

    
void FFT_IntArrayCopyToComplexArray(const TInt32bit* ACoef,const long ASize,TComplex* result,const long n,const long*
 lst)
    {
        
for (long i=0;i<n;++
i)
        {
            
long ai=
lst[i];
            
if (ai<
ASize)
                result[i].r
=
ACoef[ai];  
            
else

                result[i].r
=0.0 ;  
            result[i].i
=0.0
;
        }
    }

    
void FFT_ComplexArrayToIntArray(const TComplex* cmx,const long n,TInt32bit* result,const long
 rMinSize)
    {
        
const double tmpRevN=1.0/
n;
        
double
 FFT_int_base;
        TLargeFloat::TArray tempResult;
        TInt32bit
* dst=0
;
        
long dstsize=0
;
        {   
            FFT_int_base
=(long
)TLargeFloat::emBase;
            dstsize
=
rMinSize;
            dst
=
result;
        }
        
const double tmpRevFFT_int_base=1.0/
FFT_int_base;

        
double MaxWorstEr=0
;
        
double tmp=0.0
;
        
for (long i=std::min(n,dstsize)-1;i>=1;--
i)
        {
            
double num =cmx[i-1].r*tmpRevN+
tmp;
            tmp
=floor((num+0.499)*
tmpRevFFT_int_base);
            dst[i]
=(TInt32bit)(num+0.499-tmp*
FFT_int_base);

            
double newWorstEr=abs(num-tmp*FFT_int_base-dst[i]);//记录最大误差

           if (newWorstEr> MaxWorstEr)
                MaxWorstEr
=
newWorstEr;  
        }
        
if (dstsize>0
)
            dst[
0]=(TInt32bit)(tmp+0.1
);
        
if (MaxWorstEr>=0.499

            
throw TLargeFloat::TException("ERROR:FFT's FFT_ComplexArrayToIntArray(); "); //误差过大

    }


//FFT平方

void SquareFFT(const TInt32bit* ACoef,const long ASize,TInt32bit* CCoef,const long  CMinSize)
{
    
long ansize=ASize+
ASize;
    
long n=1
;
    
while (n<ansize) n<<=1
;

    std::vector
<TComplex>   _w((n>>1)+1
);   
    std::vector
<long>
       _lst(n);        
    TComplex
* w=&_w[0
];
    
long*     lst=&_lst[0
];
    FFTInitial(w,lst,n);

    std::vector
<TComplex>
   _a(n);  
    TComplex
* a=&_a[0
];
    FFT_IntArrayCopyToComplexArray(ACoef,ASize,a,n,lst);

    FFT(a,w, n);
    FFT_Convolution(a,a,n);

    std::vector
<TComplex>
   _tmpa(n);
    _tmpa.swap(_a);
    TComplex
* tmpa=&_tmpa[0]; a=&_a[0
];
    
for (long i=0;i<n;++i)  a[i]=
tmpa[lst[i]];  
    _tmpa.clear();
    _lst.clear();
    InvFFT(a,w,n);
    _w.clear();
    FFT_ComplexArrayToIntArray(a,n,CCoef,CMinSize);
 }


//FFT乘法

void MulFFT(const TInt32bit* ACoef,const long ASize,const TInt32bit* BCoef,const long BSize,TInt32bit* CCoef,const long  CMinSize)
{
    
long absize=(ASize+
BSize);
    
long n=1
;
    
while (n<absize) n<<=1
;

    std::vector
<TComplex>   _w((n>>1)+1
);
    std::vector
<long>
       _lst(n);
    TComplex
* w=&_w[0
];
    
long*     lst=&_lst[0
];
    FFTInitial(w,lst,n);

    std::vector
<TComplex>
   _a(n);
    TComplex
* a=&_a[0
];
    FFT_IntArrayCopyToComplexArray(ACoef,ASize,a,n,lst);
    std::vector
<TComplex>
   _b(n);
    TComplex
* b=&_b[0
];
    FFT_IntArrayCopyToComplexArray(BCoef,BSize,b,n,lst);

    FFT(b,w, n);
    FFT(a,w, n);
    FFT_Convolution(a,b,n);
    
for (long i=0;i<n;++i)  a[i]=
b[lst[i]];  
    _b.clear();
    _lst.clear();
    InvFFT(a,w,n);
    _w.clear();
    FFT_ComplexArrayToIntArray(a,n,CCoef,CMinSize);
}


/

const long csBestMUL_ExE_size           =1024       / TLargeFloat::em10Power;
const long csBestMUL_Dichotomy_size     =4096       /
TLargeFloat::em10Power;
const long csBestMul_FFT4Max_size       =16777216   /
TLargeFloat::em10Power;
void ArrayMUL(TInt32bit* result,long rminsize,const TInt32bit* x,long xsize,const TInt32bit* y,long
 ysize)
{
    
if (xsize<
ysize)
    {
        std::swap(xsize,ysize);
        std::swap(x,y);
    }
    
if (rminsize<
ysize)
    {
        xsize
=
rminsize;
        ysize
=
rminsize;
    }
    
if (ysize<=csBestMUL_ExE_size)  
//
        TLargeFloat_ArrayMUL_ExE(result,rminsize,x,xsize,y,ysize);
    
else  if (ysize<=
csBestMUL_Dichotomy_size)
        ArrayMUL_DichotomyPart(result,rminsize,x,xsize,y,ysize);
    
else if ((xsize+ysize)<=(csBestMul_FFT4Max_size*2
))
    {
        
if (x==
y)
            SquareFFT(x,xsize,result,rminsize);
        
else

            MulFFT(x,xsize,y,ysize,result,rminsize);
    }
    
else
        ArrayMUL_DichotomyPart(result,rminsize,x,xsize,y,ysize);
}





void  LargeFloat_UnitTest()
{
    
//
单元测试

    
//
测试先行... 但作者太懒...
    
//todo:


    TLargeFloat x(
200,TLargeFloat::TDigits(100 ));
    TLargeFloat y(
12345.678987654321,TLargeFloat::TDigits(100
));
    
//TLargeFloat z("-12345.678987654321e-100",TLargeFloat::TDigits(100));


    TLargeFloat z(
"99999999999999999999999999999999999999999999",TLargeFloat::TDigits(200 ));
//
}

main函数,Demo程序

///
//  LargeFloat.cpp
//

#include 
<iostream>
#include 
"TLargeFloat.h"

//#define _MY_TIME_CLOCK

#ifdef _MY_TIME_CLOCK
    #include 
<windows.h>
    
#define clock_t __int64
    clock_t CLOCKS_PER_SEC
=0 ;
    inline clock_t clock() 
    {
        __int64 result;
        
if (CLOCKS_PER_SEC==0
)
        {
            QueryPerformanceFrequency((LARGE_INTEGER 
*)&
result);
            CLOCKS_PER_SEC
=
(clock_t)result;
        }
        QueryPerformanceCounter((LARGE_INTEGER 
*)&
result);
        
return
 (clock_t)result;
    }
#else

    #include 
<time.h>
#endif


//计算圆周率PI
TLargeFloat GetBorweinPI(unsigned long  uiDigitsLength);
TLargeFloat GetAGMPI(unsigned 
long
 uiDigitsLength);
TLargeFloat GetChudnovskyPI(unsigned 
long
 uiDigitsLength);

void Debug_toCout(const std::string& strx,const TLargeFloat& x)//调试输出

            { std::cout<<strx<<std::endl<<x<< std::endl; }

int
 main()
{
    
try

    {
        LargeFloat_UnitTest();

        TLargeFloat x(
0.0,TLargeFloat::TDigits(100 ));
        x
=1
;
        Debug_toCout(
"1/7:=",x/7
);

        x.StrToLargeFloat(
"12345678987654321"
);
        Debug_toCout(
"12345678987654321*12345678987654321 := ",x*
x);

        x
=2
;
        Debug_toCout(
"2^0.5 := "
,sqrt(x));

        
//test PI

        std::cout<<std::endl<<"请输入需要PI的有效位数:" ;
        
long pi_length=0; std::cin>>pi_length;    std::cout<<
std::endl;
        clock_t t0
=
clock();
        x
=GetAGMPI(pi_length); //

        //x=GetBorweinPI(pi_length) 
        t0=clock()- t0;

        Debug_toCout(
"PI := "
,x);
        std::cout
<<"PI计算时间:"<<(t0*1.0/CLOCKS_PER_SEC)<<" 秒"
;

    }
    
catch (const TLargeFloatException&
 lfe)
    {
        std::cout
<<">> LargeFloat运算时发生异常: "<<lfe.what()<<
std::endl;
    }
    
catch (const std::exception&
 e)
    {
        std::cout
<<">> 异常: "<<e.what()<<
std::endl;
    }
    
catch
 (...)
    {
        std::cout
<<">> 未知的异常! "<<
std::endl;
    }

    std::cout
<<
std::endl;
    std::cout
<<"...end..."<<
std::endl;
    
char c; std::cin>>
c;
    
    
return 0


}


//计算圆周率PI

TLargeFloat GetBorweinPI(unsigned long  uiDigitsLength)
{
    
//
Borwein四次迭代式:
    
//
    初值: a0=6-4*2^0.5; y0=2^0.5-1;    
    
//
    重复计算: y(n+1)=[1-(1-y^4)^0.25]/[1+(1-y^4)^0.25];
    
//
               y=y(n+1);
    
//
               a(n+1)=a*(1+y)^4-2^(2*n+3)*y*(1+y+y*y);
    
//
    最后计算: PI=1/a;

    
//
迭代次数和10进制有效精度  每迭代一次有效精度增长4倍
    
//
0 1  2  3   4    5    6   ...
    
//0 8 40 170 693 2789 11171 ...

    long  loop_count; 
    
if (uiDigitsLength<=8
)
        loop_count
=1
;
    
else if (uiDigitsLength<=40
)
        loop_count
=2
;
    
else if (uiDigitsLength<=170
)
        loop_count
=3
;
    
else if (uiDigitsLength<=693
)
        loop_count
=4
;
    
else if (uiDigitsLength<=2789
)
        loop_count
=5
;
    
else
 
    {
        loop_count
=6
;
        
long DigitsLength=11171
;
        
while (DigitsLength<(long
)uiDigitsLength)
        {
            DigitsLength
*=4;//四阶收敛

            ++ loop_count;
        }
    }
    std::cout
<<"        ... 开始计算PI,Borwein四次迭代式, 总循环次数:"<<loop_count<<"  ...   "<<
std::endl;

    TLargeFloat::TDigits sCount(uiDigitsLength);
//计算采用的十进制精度


    TLargeFloat a(
0.0,sCount),y(0.0 ,sCount);
    TLargeFloat temp(
0.0
,sCount);
    TLargeFloat pow(
2*2*2,sCount); //
2^(2*n+3); (n=0);

    
//a0=6-4*2^0.5; 

    temp=2 ;
    temp.Sqrt();
    a
=6-4*
temp;
    
//y0=2^0.5-1;    

    y=temp-1 ;


    TLargeFloat tmpa(
0.0
,sCount);
    
for (long i=0;i<loop_count;++
i)
    {
        std::cout
<<"        ... 计算PI "<<uiDigitsLength<<" 位的当前循环次数:"<<i+1<<"/"<<loop_count<<"  ...   "<<
std::endl;
       
        temp
=1-
sqr(sqr(y));
        temp
=revsqrt(revsqrt(temp));//等价于 temp=sqrt(sqrt(temp));

        y=(1-temp)/(1+ temp);
        temp
=sqr(1+
y);
        a
=a*sqr(temp)-pow*y*(temp-
y);

        pow
*=4
;
    }
    std::cout
<<"        ... 计算PI的循环结束,准备输出  ...   "<<
std::endl; 
    
return 1/a;//PI=1/a;

}


TLargeFloat GetAGMPI(unsigned 
long
 uiDigitsLength)
{
    
//
AGM二次迭代式:
    
//
初值:a=x=1 b=1/sqrt(2) c=1/4
    
//
重复计算:y=a a=(a+b)/2 b=sqrt(by) c=c-x(a-y)^2 x=2x
    
//
最后:pi=(a+b)^2/(4c)

    
//
迭代次数和10进制有效精度  每迭代一次有效精度增长2倍
    
//
0  1  2  3   4    5    6    7     8  ...
    
//1 39 82 169 344  693 1391 2788  5582 ...

    long  loop_count; 
    
if (uiDigitsLength<=39
)
        loop_count
=1
;
    
else if (uiDigitsLength<=82
)
        loop_count
=2
;
    
else if (uiDigitsLength<=169
)
        loop_count
=3
;
    
else if (uiDigitsLength<=344
)
        loop_count
=4
;
    
else if (uiDigitsLength<=693
)
        loop_count
=5
;
    
else if (uiDigitsLength<=1391
)
        loop_count
=6
;
    
else if (uiDigitsLength<=2788
)
        loop_count
=7
;
    
else
 
    {
        loop_count
=8
;
        
long DigitsLength=5582
;
        
while (DigitsLength<(long
)uiDigitsLength)
        {
            DigitsLength
*=2;//2阶收敛

            ++ loop_count;
        }
    }
    std::cout
<<"        ... 开始计算PI,AGM二次迭代式, 总循环次数:"<<loop_count<<"  ...   "<<
std::endl;

    TLargeFloat::TDigits sCount(uiDigitsLength);
//计算采用的十进制精度


    TLargeFloat c(
8,sCount);  c.RevSqrt(); c.Chs();  //c=-sqrt(1/8);
    TLargeFloat a(c); a*=(-3); a+=1;                 //a=1-3*c;
    TLargeFloat b(a); b.Sqrt();                      //b=sqrt(a);
    TLargeFloat e("-0.625"); e += b;                 //e=b-0.625
    b *= 2 ;
    c 
+=
 e;
    a 
+=
 e;
    
long npow=4
;
    
for (long i=0;i<loop_count;++
i)
    {
        std::cout
<<"        ... 计算PI "<<uiDigitsLength<<" 位的当前循环次数:"<<i+1<<"/"<<loop_count<<"  ...   "<<
std::endl;
        e  
=
 a;
        e 
+=
 b;
        e 
/= 2
;
        b 
*=
a;
        b.Sqrt();
        e 
-=
 b;
        b 
*= 2
;
        c 
-=
 e;
        a  
=
 e; 
        a 
+=
 b;
        npow 
*= 2
;
    }
    std::cout
<<"        ... 计算PI的循环结束,准备输出  ...   "<<
std::endl; 
    e 
*=
 e;
    e 
/= 4
;
    a 
+=
 b;

    c 
*=
a;
    c 
-=
e;
    c 
*=
npow;
    
    a 
*=
a;
    a
-=
e;
    e
/=2
;
    a
-=
e;

    a
/=
c;

    
return
  a;
}
//
///

你可能感兴趣的:(未分类)