【模版】高精度算法
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const int power=4; 6 const int base=1e4; 7 const int maxn=2e3+5; 8 9 struct num{ 10 int a[maxn<<1]; 11 12 num(){memset(a,0,sizeof(a));} 13 int &operator [](int x){return a[x];}//重载中括号 14 num(char *s,int len){ 15 memset(a,0,sizeof(a)); 16 17 a[0]=(len+power-1)/power; 18 19 for(int t=0,w=1,i=len-1;i>=0;w=(w<<1)+(w<<3),--i){ 20 if((len-1-i)%power==0) w=1,++t; 21 a[t]+=(s[i]^48)*w;//注意+= 22 } 23 } 24 void add(int k) { if (k || a[0]) a[ ++a[0] ] = k; } //在末尾添加一个数,除法的时候要用到 25 void re() { reverse(a+1, a+a[0]+1); } 26 void print(){ 27 printf("%d",a[a[0]]); 28 for(int i=a[0]-1;i>0;--i) printf("%0*d",power,a[i]); 29 } 30 }ans,p,q; 31 32 char p1[maxn],q1[maxn]; 33 int lenp,lenq; 34 35 36 num operator +(num &p,num &q){//重载了中括号所以不用const 37 int cur=0,len=max(p[0],q[0]); 38 for(int i=1;i<=len;++i){ 39 cur+=i<=p[0]?p[i]:0; 40 cur+=i<=q[0]?q[i]:0; 41 p[i]=cur%base;cur/=base; 42 } 43 if(cur) p[++len]=cur; 44 p[0]=len;//注意更新长度 45 return p; 46 } 47 48 bool operator <(const num &p,const num &q){//比较大小 49 if(p.a[0]<q.a[0]) return true; 50 if(p.a[0]>q.a[0]) return false; 51 for(int i=p.a[0];i>=1;--i){//倒序 52 if(p.a[i]!=q.a[i]) return p.a[i]<q.a[i]; 53 } 54 return false; 55 } 56 57 num operator -(num &p,num &q){ 58 int len=max(p.a[0],q.a[0]); 59 for(int i=1;i<=len;++i){ 60 p.a[i]-=i<=q.a[0]?q.a[i]:0; 61 if(p.a[i]<0) p.a[i]+=base,p.a[i+1]-=1;//借位 62 } 63 while(p.a[0]>1&&p.a[p.a[0]]==0) --p.a[0]; 64 return p; 65 } 66 67 num operator / (num &p,num &q) //注意const不要冲突 68 { 69 num x, y; 70 for (int i = p.a[0];i >= 1;--i) //从最高位开始取数 71 { 72 y.add(p.a[i]); //把数添到末尾(最低位),这时候是高位在前,低位在后 73 y.re(); //把数反过来,变为统一的存储方式:低位在前,高位在后 74 while ( !(y < q) ) //大于等于除数的时候,如果小于的话,其实答案上的该位就是初始的“0” 75 y = y - q, ++x.a[i]; //看能减几个除数,减几次,答案上该位就加几次。 76 y.re(); //将数反过来,为下一次添数做准备 77 } 78 x.a[0] = p.a[0]; 79 while (x.a[0] > 0 && !x.a[x.a[0]]) --x.a[0]; 80 return x; 81 } 82 83 num operator *(const num &p,const num &q){ 84 num b; 85 for(int i=1;i<=p.a[0];++i){ 86 int cur=0; 87 for(int j=1;j<=q.a[0];++j) 88 cur+=b.a[i+j-1]+p.a[i]*q.a[j],b.a[i+j-1]=cur%base,cur/=base; 89 b.a[i+q.a[0]]=cur; 90 } 91 b.a[0]=q.a[0]+p.a[0];//得到大致位数 92 while(b.a[0]>1&&b.a[b.a[0]]==0) --b.a[0];//除去前导0 93 return b; 94 } 95 96 int main(){ 97 98 /* 99 scanf("%s%s",p1,q1); 100 lenp=strlen(p1);lenq=strlen(q1); 101 p=num(p1,lenp);q=num(q1,lenq); 102 ans=p*q; 103 ans.print(); 104 return 0; 105 */ 106 107 108 scanf("%s%s",p1,q1); 109 110 lenp=strlen(p1);lenq=strlen(q1); 111 112 p=num(p1,lenp);q=num(q1,lenq); 113 114 ans=p+q; 115 ans.print(); 116 return 0; 117 118 119 120 /* 121 122 scanf("%s%s",p1,q1); 123 lenp=strlen(p1);lenq=strlen(q1); 124 p=num(p1,lenp),q=num(q1,lenq); 125 if(q<p) ans=p-q; 126 else putchar('-'),ans=q-p; 127 ans.print(); 128 return 0; 129 130 */ 131 132 }
这个板子比我之前用的许多压位的都要快,就先用这个了。
不确定原作者
---- suffer now and live the rest of your life as a champion ----