标签:
/* 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); }
标签:
原文地址:http://www.cnblogs.com/TheName/p/5244912.html