【模版】高精度算法

强颜欢笑 提交于 2020-03-29 10:11:43
  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 }

这个板子比我之前用的许多压位的都要快,就先用这个了。

摘自:https://blog.csdn.net/weixin_44584560/article/details/89405691?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

不确定原作者

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!