高精度模板2(带符号压位加减乘除开方封包)
原来的那个模板:http://www.cnblogs.com/iwtwiioi/p/3991331.html 估计已经不用了。
现在我重新封包好了一个,一定很好用QAQ
加减乘除带开方带压位带重载运算符
注意一下符号即可,一定写的时候要手推四种情况!!
然后在重载<的时候,一定要注意同时判断!!!!要不然又错。。
struct big { typedef ll INT; static const INT S=100000000; static const int S_n=9; static const int SIZE=305; INT a[SIZE]; int len, tag; big() { len=1; CC(a, 0); } big(char *s) { len=1; CC(a, 0); *this=s; } big(INT x) { len=1; CC(a, 0); *this=x; } void cln() { memset(a, 0, sizeof(INT)*(len+1)); len=1; tag=0; } void fix() { while(len>1 && !a[len]) --len; } void M(big &a, big &b, big &c) { if(b.tag) { b.tag=0; P(a, b, c); b.tag=1; return; } if(a.tag) { a.tag=0; P(a, b, c); a.tag=1; c.tag=1; return; } c.cln(); int flag=0, i=1; big *x=&a, *y=&b; if(a<b) flag=1, swap(x, y); for(; i<=x->len; ++i) { c.a[i]+=x->a[i]-y->a[i]; if(c.a[i]<0) c.a[i]+=S, --c.a[i+1]; } c.len=i; c.fix(); c.tag=flag; } void P(big &a, big &b, big &c) { if(b.tag) { b.tag=0; M(a, b, c); b.tag=1; return; } if(a.tag) { a.tag=0; M(b, a, c); a.tag=1; return; } c.cln(); int i=1, l=max(a.len, b.len); INT k=0; for(; i<=l || k; ++i) { c.a[i]=a.a[i]+b.a[i]+k; k=c.a[i]/S; if(c.a[i]>=S) c.a[i]%=S; } c.len=i; c.fix(); } void T(big &a, big &b, big &c) { c.cln(); for1(i, 1, a.len) for1(j, 1, b.len) { int pos=i+j-1; c.a[pos]+=a.a[i]*b.a[j]; c.a[pos+1]+=c.a[pos]/S; c.a[pos]%=S; } c.len=a.len+b.len; c.fix(); c.tag=a.tag^b.tag; if(c.a[1]==0 && c.len==1) c.tag=0; } void D(big &a, INT b, big &c) { c.cln(); INT t=0; for(int i=len; i; --i) { c.a[i]=(a.a[i]+t)/b; t=((a.a[i]+t)%b)*S; } c.len=len; c.fix(); } void D(big &a, big &b, big &c) { c.cln(); big l, r=a, mid, TP, ONE=(INT)1; while(l<=r) { P(l, r, TP); D(TP, 2, mid); T(mid, b, TP); if(TP<=a) P(mid, ONE, l); else M(mid, ONE, r); } M(l, ONE, c); c.tag=a.tag^b.tag; if(c.a[1]==0 && c.len==1) c.tag=0; } big sqrt() { big l, r=*this, mid, TP, ONE=(INT)1; while(l<=r) { P(l, r, TP); D(TP, 2, mid); T(mid, mid, TP); if(TP<=*this) P(mid, ONE, l); else M(mid, ONE, r); } M(l, ONE, TP); return TP; } bool operator<(big &b) { if(b.tag && !tag) return 0; if(!b.tag && tag) return 1; if(b.tag && tag) { tag=b.tag=0; bool ret=b<*this; tag=b.tag=1; return ret; } if(len!=b.len) return len<b.len; for3(i, len, 1) if(a[i]<b.a[i]) return true; else if(a[i]>b.a[i]) return false; //这里一定要注意 return false; } big& operator= (INT b) { cln(); len=0; if(b==0) { len=1; return *this; } if(b<0) tag=1, b=-b; while(b) { a[++len]=b%S; b/=S; } return *this; } big& operator= (char *s) { cln(); if(s[0]=='-') tag=1, ++s; len=0; int l=strlen(s), t=0, k=1; for3(i, l-1, 0) { t=t+(s[i]-'0')*k; k*=10; if(k>=S) a[++len]=t%S, t=0, k=1; } if(k!=1) a[++len]=t%S; return *this; } big& operator= (const big &x) { cln(); memcpy(a, x.a, sizeof(INT)*(x.len+1)); len=x.len, tag=x.tag; return *this; } big operator+ (big x) { big c; P(*this, x, c); return c; } big operator- (big x) { big c; M(*this, x, c); return c; } big operator* (big x) { big c; T(*this, x, c); return c; } big operator/ (big x) { big c; D(*this, x, c); return c; } big operator/ (INT x) { big c; D(*this, x, c); return c; } big& operator+= (big x) { big c; P(*this, x, c); return *this=c; } big& operator-= (big x) { big c; M(*this, x, c); return *this=c; } big& operator*= (big x) { big c; T(*this, x, c); return *this=c; } big& operator/= (big x) { big c; D(*this, x, c); return *this=c; } big& operator/= (INT x) { big c; D(*this, x, c); return *this=c; } big& operator++ () { return *this+=1; } big operator++ (int) { big ret=*this; ++*this; return ret; } big& operator-- () { return *this-=1; } big operator-- (int) { big ret=*this; --*this; return ret; } bool operator> (big &x) { return x<*this; } bool operator== (big &x) { return x<=*this&&x>=*this; } bool operator<= (big &x) { return !(x<*this); } bool operator>= (big &x) { return !(x>*this); } void P() { if(tag) putchar('-'); printf("%d", (int)a[len]); char od[8]; od[0]='%'; od[1]='0'; sprintf(od+2, "%d", S_n-1); int l=strlen(od); od[l]='d'; od[l+1]='\0'; for3(i, len-1, 1) printf(od, (int)a[i]); } };
博客地址:www.cnblogs.com/iwtwiioi 本文为博主原创文章,未经博主允许不得转载。一经发现,必将追究法律责任。