加法 只限两个非负整数相加
string add(string a,string b) { string ans; memset(ta,0,sizeof(ta)); memset(tb,0,sizeof(tb)); int lena=a.size(),lenb=b.size(); for(int i=0;i<lena;i++) ta[lena-i-1]=a[i]-'0'; for(int i=0;i<lenb;i++) tb[lenb-i-1]=b[i]-'0'; int len=max(lena,lenb); for(int i=0;i<len;i++) { ta[i]+=tb[i]; ta[i+1]+=ta[i]/10,ta[i]%=10; } if(ta[len]) len++; for(int i=len-1;i>=0;i--) ans+=ta[i]+'0'; return ans; }
减法 只限大的非负整数减小的非负整数
string sub(string a,string b) { string ans; memset(ta,0,sizeof(ta)); memset(tb,0,sizeof(tb)); int la=a.size(),lb=b.size(); for(int i=0;i<la;i++) ta[la-1-i]=a[i]-'0'; for(int i=0;i<lb;i++) tb[lb-1-i]=b[i]-'0'; int len=max(lena,lenb); for(int i=0;i<len;i++) { ta[i]-=tb[i]; if(ta[i]<0) ta[i]+=10,ta[i+1]--; } while(!ta[--len]&&len>0); len++; for(int i=len-1;i>=0;i--) ans+=ta[i]+'0'; return ans; }
乘法
高精度乘高精度
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <map> #include <queue> #include <set> #include <vector> using namespace std; #define L(x) (1 << (x)) const double PI=acos(-1.0); const int Maxn=133015; double ax[Maxn],ay[Maxn], bx[Maxn], by[Maxn]; char sa[Maxn/2],sb[Maxn/2]; int sum[Maxn]; int x1[Maxn],x2[Maxn]; int revv(int x,int bits) { int ret=0; for(int i=0;i<bits;i++) { ret<<=1; ret|=x&1; x>>=1; } return ret; } void fft(double * a,double * b,int n,bool rev) { int bits=0; while(1<<bits<n) ++bits; for(int i=0;i<n;i++) { int j=revv(i,bits); if(i<j) swap(a[i],a[j]),swap(b[i],b[j]); } for (int len=2;len<=n;len<<=1) { int half=len>>1; double wmx=cos(2*PI/len),wmy=sin(2*PI/len); if(rev) wmy=-wmy; for (int i=0;i<n;i+=len) { double wx=1,wy=0; for(int j=0;j<half;j++) { double cx=a[i+j],cy=b[i+j]; double dx=a[i+j+half],dy=b[i+j+half]; double ex=dx*wx-dy*wy,ey=dx*wy+dy*wx; a[i+j]=cx+ex,b[i+j]=cy+ey; a[i+j+half]=cx-ex,b[i+j+half]=cy-ey; double wnx=wx*wmx-wy*wmy,wny=wx*wmy+wy*wmx; wx=wnx,wy=wny; } } } if (rev) for(int i=0;i<n;i++) a[i]/=n,b[i]/=n; } int solve(int a[],int na,int b[],int nb,int ans[]) { int len=max(na,nb),ln; for(ln=0;L(ln)<len;++ln); len=L(++ln); for(int i=0;i<len;i++) { if(i>=na) ax[i]=0,ay[i]=0; else ax[i]=a[i],ay[i]=0; } fft(ax, ay, len, 0); for(int i=0;i<len;i++) { if(i>=nb) bx[i]=0,by[i]=0; else bx[i]=b[i],by[i]=0; } fft(bx,by,len,0); for(int i=0;i<len;i++) { double cx=ax[i]*bx[i]-ay[i]*by[i]; double cy=ax[i]*by[i]+ay[i]*bx[i]; ax[i]=cx,ay[i]=cy; } fft(ax,ay,len,1); for(int i=0;i<len;i++) ans[i]=(int)(ax[i]+0.5); return len; } string mul(string sa,string sb) { int l1,l2,l,i; string ans; memset(sum,0,sizeof(sum)); l1=sa.size(),l2=sb.size(); for(i=0;i<l1;i++) x1[i]=sa[l1-i-1]-'0'; for(i=0;i<l2;i++) x2[i]=sb[l2-i-1]-'0'; l=solve(x1,l1,x2,l2,sum); for(i=0;i<l||sum[i]>=10;i++) { sum[i+1]+=sum[i]/10; sum[i]%=10; } l=i; while(sum[l]<=0&&l>0) l--; for(i=l;i>=0;i--) ans+=sum[i]+'0'; return ans; } int main() { string a,b; while(cin>>a>>b) cout<<mul(a,b)<<endl; return 0; }
高精度乘单精度
string mul(string a,int b) { memset(ta,0,sizeof(ta)); string ans; int lena=a.size(); fill(ta,ta+maxn,0); for(int i=lena-1;i>=0;i--) ta[lena-i-1]=a[i]-'0'; int w=0; for(int i=0;i<lena;i++) ta[i]=ta[i]*b+w,w=ta[i]/10,ta[i]=ta[i]%10; while(w) ta[lena++]=w%10,w/=10; lena--; while(lena>=0) ans+=ta[lena--]+'0'; return ans; }
除法
高精度除高精度
int sub(int *a,int *b,int La,int Lb) { if(La<Lb) return -1; if(La==Lb) { for(int i=La-1;i>=0;i--) if(a[i]>b[i]) break; else if(a[i]<b[i]) return -1; } for(int i=0;i<La;i++) { a[i]-=b[i]; if(a[i]<0) a[i]+=10,a[i+1]--; } for(int i=La-1;i>=0;i--) if(a[i]) return i+1; return 0; } string div(string n1,string n2,int nn) { //n1,n2是字符串表示的被除数,除数,nn是选择返回商还是余数 const int L=1e5; string s,v;//s存商,v存余数 int a[L],b[L],r[L],La=n1.size(),Lb=n2.size(),i,tp=La; //a,b是整形数组表示被除数,除数,tp保存被除数的长度 fill(a,a+L,0);fill(b,b+L,0);fill(r,r+L,0);//数组元素都置为0 for(i=La-1;i>=0;i--) a[La-1-i]=n1[i]-'0'; for(i=Lb-1;i>=0;i--) b[Lb-1-i]=n2[i]-'0'; if(La<Lb || (La==Lb && n1<n2)) { //cout<<0<<endl; return n1;}//如果a<b,则商为0,余数为被除数 int t=La-Lb;//除被数和除数的位数之差 for(int i=La-1;i>=0;i--)//将除数扩大10^t倍 if(i>=t) b[i]=b[i-t]; else b[i]=0; Lb=La; for(int j=0;j<=t;j++) { int temp; while((temp=sub(a,b+j,La,Lb-j))>=0) { La=temp; r[t-j]++; } } for(i=0;i<L-10;i++) r[i+1]+=r[i]/10,r[i]%=10;//统一处理进位 while(!r[i]) i--;//将整形数组表示的商转化成字符串表示的 while(i>=0) s+=r[i--]+'0'; i=tp; while(!a[i]) i--;//将整形数组表示的余数转化成字符串表示的</span> while(i>=0) v+=a[i--]+'0'; if(v.empty()) v="0"; if(nn==1) return s;//返回商 if(nn==2) return v;//返回余数 }
高精度除单精度
string div(string a,int b) { string r,ans; int d=0; if(a=="0") return a;//特判 for(int i=0;i<a.size();i++) { r+=(d*10+a[i]-'0')/b+'0';//求出商 d=(d*10+(a[i]-'0'))%b;//求出余数 } int p=0; for(int i=0;i<r.size();i++) if(r[i]!='0') {p=i;break;} return r.substr(p); }
高精度阶乘
string fac(int n) { const int L=100005; int a[L]; string ans; if(n==0) return "1"; fill(a,a+L,0); int s=0,m=n; while(m) a[++s]=m%10,m/=10; for(int i=n-1;i>=2;i--){ int w=0; for(int j=1;j<=s;j++) a[j]=a[j]*i+w,w=a[j]/10,a[j]=a[j]%10; while(w) a[++s]=w%10,w/=10; } while(!a[s]) s--; while(s>=1) ans+=a[s--]+'0'; return ans; }