码迷,mamicode.com
首页 > 其他好文 > 详细

Big int

时间:2016-04-09 15:20:05      阅读:248      评论:0      收藏:0      [点我收藏+]

标签:

/* 
    Author:  No Name
    Date  :  2016/4/9
*/
#include <iostream>
#include <iomanip>
#include <string>
#define ull unsigned long long
#define INT_e18 1000000000000000000
#define INT_2e18 2000000000000000000
#define inlbinto inline bigint operator
//BIG_SIZE must one of {4,8,12,16,20,24......}
#define BIG_SIZE 64
#define BIG_1 63
#define OUT_SIZE 78
#define OUT_1 77
using namespace std;

class bigint{
    friend ostream& operator<<(ostream& out, const bigint x);
    friend istream& operator>>(istream& in,bigint& x);
    public:
        bigint (){;};
        bigint (const bigint& b){
            for(int i=BIG_SIZE;i;){
                num[--i]=b.num[i];
            }
        }
        bigint (const ull& u){
            for(int i=BIG_1;i;) num[--i]=0;
            num[BIG_1]=u;
        }
inline  ull &operator [](unsigned pos){
            return num[pos];
        }
inline  bigint &operator =(const bigint& b_int){
            for(unsigned i=BIG_SIZE;--i;) num[i]=b_int.num[i];num[0]=b_int.num[0];
            return *this;
        }
inline  bigint &operator =(const ull &_ull_int){
            ull* i=num+BIG_1;*i=_ull_int;
            while(i!=num) (*(--i))=0;
            return *this;
        }
inline  bigint &operator =(const string str){
    *this=0;
    unsigned end=str.size();
    for(unsigned i=0;i!=end;++i){
        (*this).mult_ul(10);
        (*this)+=((unsigned long long)(str[i]-48));
    }
    return *this;
}

inline  bigint &operator <<=(unsigned step){
            unsigned _st_=64-step;ull a=0,b=0;
            for(int i=BIG_SIZE;i;){
                a=(num[--i]>>_st_);
                num[i]<<=step;
                num[i]|=b;
                b=(num[--i]>>_st_);
                num[i]<<=step;
                num[i]|=a;
            }
            return *this;
        }
inline  bigint &l_move64(unsigned step){
            unsigned _st_=BIG_SIZE-step,i=0;
            for(;i!=_st_;++i){
                num[i]=num[i+step];
            }
            while(i!=BIG_SIZE){
                num[i]=0;++i;
            }
        }
inline  bigint &operator >>=(unsigned step){
            unsigned _st_=64-step;ull a=0,b=0;
            for(int i=-1;i!=BIG_1;){
                a=(num[++i]<<_st_);
                num[i]>>=step;
                num[i]|=b;
                b=(num[++i]<<_st_);
                num[i]>>=step;
                num[i]|=a;
            }
            return *this;
        }
inline  bigint &r_move64(unsigned step){
            unsigned _st_=BIG_SIZE-step,i=BIG_SIZE;
            for(;i!=step;i){
                num[--i]=num[i-step];
            }
            while(i){
                num[--i]=0;
            }
        }
        inlbinto <<(unsigned step){
    bigint b=*this;b<<=step;return b;
}
        inlbinto >>(unsigned step){
    bigint b=*this;b>>=step;return b;
}
inline  bigint &operator &=(const bigint &b){
    for(unsigned i=BIG_SIZE;i;) num[--i]&=b.num[i];
    return *this;
}
inline  bigint &operator |=(const bigint &b){
    for(unsigned i=BIG_SIZE;i;) num[--i]|=b.num[i];
    return *this;
}
inline  bigint &operator ^=(const bigint &b){
    for(unsigned i=BIG_SIZE;i;) num[--i]^=b.num[i];
    return *this;
}
        inlbinto &(const bigint &b){
    bigint a=*this;a&=b;return a;
}
        inlbinto |(const bigint &b){
    bigint a=*this;a|=b;return a;
}
        inlbinto ^(const bigint &b){
    bigint a=*this;a^=b;return a;
}

inline  bigint &operator +=(const bigint& b_int){
            unsigned j;
            for(unsigned i=BIG_SIZE;i;){
                num[--i]+=b_int.num[i];
                if(num[i]<b_int.num[i]) for(j=i;!++num[--j];);
            }
            return *this;
        }
inline  bigint &operator +=(const ull &_ullint){
            if((num[BIG_1]+=_ullint)<_ullint){
                for(unsigned i=BIG_1;!++num[--i];);
            }
            return *this;
        }
        inlbinto +(const bigint &b_int){
            bigint r=*this;
            r+=b_int;
            return r;
        }
        inlbinto +(const ull &_ullint){
            bigint r=*this;
            r+=_ullint;
            return r;
        }
inline  bigint &operator ++() {for(unsigned i=BIG_SIZE;!++num[--i];);return *this;}
inline  bigint operator ++(int){
            bigint old=*this;
            for(unsigned i=BIG_SIZE;!++num[--i];);
            return old;
        }
        
inline  bigint &operator -=(const bigint &b_int){
            unsigned j;
            for(unsigned i=BIG_SIZE;i;){
                if(num[--i]<(num[i]-=b_int.num[i])) for(j=i;~--num[--j];);
            }
            return *this;
        }
inline  bigint &operator -=(const ull _ullint){
            if(num[BIG_1]<num[BIG_1]-_ullint) for(unsigned i=BIG_1;~--num[--i];);
            return *this;
        }
        inlbinto -(const bigint &b_int){
            bigint r=*this;
            r-=b_int;
            return r;
        }
        inlbinto -(const ull _ullint){
            bigint r=*this;
            r-=_ullint;
            return r;
        }
inline  bigint &operator --() {for(unsigned i=BIG_SIZE;~--num[--i];);return *this;}
inline  bigint operator --(int){
            bigint old=*this;
            for(unsigned i=BIG_SIZE;~--num[--i];);
            return old;
        }
        
inline  bigint &operator *=(const ull& that){
            bigint c;c=*this;
            (*this).mult_ul(that>>32);*this<<=32;
            c.mult_ul(that&0xffffffff);
            *this+=c;
            return *this;
        }
inline  bigint &mult_ul(const unsigned long that){
            bigint c;c=*this;c<<=32;
            for(int i=BIG_SIZE;i;){
                (num[--i]&=0xffffffff)*=that;
                (c.num[i]&=0xffffffff)*=that;
            }
            c>>=32;*this+=c;
            return *this;
        }
        inlbinto * (ull that){
    bigint b=*this;return b*=that;
}    
inline  bigint divi_ul(const ull ula){
            ull b,c=0,d=0;/*
            从高位到低位,与上次未除残留c一同取余b, 除,  加已除残留d
            对b进行"%""/ "
            */
            for(unsigned i=0;i!=BIG_SIZE;++i){
                b=(num[i]%ula+c%ula);
                num[i]=(num[i]/ula+c/ula);
                if(b>=ula){
                    ++num[i];b-=ula;
                }
                if((num[i]+=d)<d) ++(num[i-1]);
                b<<=32;
                c=(b%ula);c<<=32;
                d=(b/ula);d<<=32;
            }
            return *this;
        }

//  BELOW METHODS ARE DEVELOPING!!!  DEVELOPING!!!  DEVELOPING!!!
        inlbinto / (bigint b);
inline  bigint &operator /= (bigint b){
    unsigned i=0;bigint c;c=*this;*this=0;
    while(i!=BIG_SIZE){
        if(b[i]) break;
        ++i;
    }
    b.l_move64(i);
    i<<=6;
    if(!b[0]&0xffffffff00000000) i+=32;
    if(!b[0]&0xffff000000000000) i+=16;
    if(!b[0]&0xff00000000000000) i+=8;
    if(!b[0]&0xf000000000000000) i+=4;
    if(!b[0]&0x3000000000000000) i+=2;
    if(!b[0]&0x8000000000000000) ++i;
    b<<=(i&63);++i;
    while(--i){
        *this<<=1;
        if(b<c) {
            c-=b;num[BIG_1]|=1;
        }
        b>>=1;
    }
    if(b<c) num[BIG_1]|=1;
    return *this;
}
        inlbinto / (ull b);
inline  bigint &operator /= (ull b){
    *this-=(*this%b);
    unsigned i;
    if(!(b&0xffffffff)) b>>=32;i+=32;
    if(!(b&0xffff)) b>>=16;i+=16;
    if(!(b%0xff)) b>>=8;i+=8;
    if(!(b&15)) b>>=4;i+=4;
    if(!(b&3)) b>>=2;i+=2;
    if(!(b&1)) b>>=1;++i;
    *this>>=i;
}
        inlbinto % (bigint b);
inline  bigint &operator %= (bigint b){
    unsigned i=0;
    while(i!=BIG_SIZE){
        if(b[i]) break;
        ++i;
    }
    b.l_move64(i);
    i<<=6;
    if(!b[0]&0xffffffff00000000) i+=32;
    if(!b[0]&0xffff000000000000) i+=16;
    if(!b[0]&0xff00000000000000) i+=8;
    if(!b[0]&0xf000000000000000) i+=4;
    if(!b[0]&0x3000000000000000) i+=2;
    if(!b[0]&0x8000000000000000) ++i;
    b<<=(i&63);++i;cout<<b;
    while(--i){
        if(b<*this) {*this-=b;cout<<"as";}
        
        b>>=1;
    }
    if(b<*this) *this-=b;
    
    return *this;
}
inline  bigint &operator %= (const ull& that){
    for(unsigned i=31;--i;){
        num[0]%=that;*this<<=32;
    }
    num[0]%=that;return *this;
}
        inlbinto % (ull that){
    bigint a=*this;
    a%=that;
    return a;
}
        inlbinto *=(const bigint &b);
        inlbinto *(const bigint &b);     
//OK???
        
inline  bool operator <(bigint b){
            for(unsigned i=0;i!=BIG_SIZE;++i){
                if(num[i]<b.num[i]) return true;
                else if(num[i]==b.num[i]) continue;
                else return false;
            }
            return false;
        }
inline  bool operator >(bigint b) {return b<*this;}
inline  bool operator ==(bigint b){
            for(unsigned i=BIG_SIZE;i;){
                if(num[--i]!=b.num[i]) return false;
            }
            return true;
        }
inline  bool operator !=(bigint b){
              for(unsigned i=BIG_SIZE;i;) {if(num[--i]!=b.num[i]) return true;}
              return false;
        }

        ull num[BIG_SIZE];
};

ostream& operator<<(ostream& out,bigint x){
    ull outint[OUT_SIZE]={};bool c;unsigned i,j,n;bigint cx;cx=x;
    for(i=0;i!=BIG_SIZE;++i){
        for(j=65;--j;){
            c=false;
            for(n=OUT_SIZE;--n;){
                if(outint[n]==INT_e18) {outint[n]=0;++outint[n-1];c=false;}
                outint[n]<<=1;
                if(c) ++outint[n];
                if(c=(INT_e18<=outint[n])) outint[n]-=INT_e18;
            }
            outint[0]<<=1;if(c) ++outint[0];
            if(cx.num[i]&0x8000000000000000) ++outint[OUT_1];
            cx.num[i]<<=1;
        }
    }
    j=OUT_1;
    for(i=0;i!=OUT_SIZE;++i){
        if(outint[i]) {j=i;break;}
    }
    out<<outint[j];
    while(++j!=OUT_SIZE) out<<setfill(0)<<setw(18)<<outint[j];
    out<<setw(0)<<setfill( );
    return out;
}
istream& operator>>(istream& in,bigint &x){
    char str[OUT_SIZE]={};
    in>>str;
    unsigned end;
    for(end=0;str[end]!=0;++end);
    x=0;
    for(unsigned i=0;i!=end;++i){
        x*=10;
        x+=(str[i]-48);
    }
    return in;
}

bigint mult(const bigint &a,const unsigned long &b){
    bigint r;r=a;r.mult_ul(b);return r;
}
unsigned long mod(const bigint &a,const ull &b){
    ull r=0;
    for(unsigned i=0;i!=BIG_1;++i){
        r+=(a.num[i]%b);r%=b;
        r<<=32;
        r%=b;
        r<<=32;
        r%=b;
    }
    r+=(a.num[BIG_1]%b);r%=b;
    return (unsigned long) r;
}
bigint divi(const bigint &a,const unsigned long &b){
    bigint r;r=a;
    return r.divi_ul(b);
}

 

 

Big int

标签:

原文地址:http://www.cnblogs.com/TheName/p/5244912.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!