1. 程式人生 > 其它 >高精度加減乘除

高精度加減乘除

(大數運算)long long型別一般佔8個位元組是C/C++中的精度最高的整數型別,其取值範圍是: -9223372036854775808~+9223372036854775807。在很多場景中,整數範圍超出了long long的最值,例如在非對稱加密中金鑰長度一般為1024bit,轉換為十進位制數將超過300位,因此不能直接用內建的整數型別來運算。請編寫大數運算型別MyBigInteger,使其支援大資料的加法,減法,乘法的運算。(除法為選做功能,除法運算符合C/C++中的整數除法運算的規則,有20%的測試用例包含除法運算,)
【輸入】
大整數n,n的位數<=200
大整數m,m的位數<=200
運算子(+,-,*, /)
【輸出】n和m的運算結果
例如:
【輸入】
56891237265
32156789215
-
【輸出】
24734448050

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn = 500 + 5 ;
string n,m;
char str;
int flag1=1,flag2=1,c=1;
int len_x=0,len_y=0;
int ans[maxn * 2],x[maxn],y[maxn];
void Addition(){//x+y
    reverse(x,x+len_x);
    reverse(y,y
+len_y); int digit = max(len_x,len_y); for(int i=0;i<digit;i++) { ans[i]+=x[i]+y[i]; if(ans[i]>=10) ans[i+1]++,ans[i]%=10; } if(ans[digit]) digit++; if(c==-1) cout<<'-'; for(int i=digit-1;i>=0;i--) cout<<ans[i]; } int judge(int p[],int
q[],int len) { for(int i=len-1;i>=0;i--) { if(p[i]>q[i]) return 1;//p>q if(p[i]<q[i]) return -1;//p<q } return 0;//p=q } void Subtraction(){//x-y int vis = 1; reverse(x,x+len_x); reverse(y,y+len_y); if(len_x<len_y||(len_x==len_y && judge(x,y,len_x)==-1)) { swap(x,y); swap(len_x,len_y); vis=-1; } int digit = max(len_x,len_y); for(int i=0;i<digit;i++) { ans[i]+=x[i]-y[i]; if(ans[i]<0) ans[i+1]--,ans[i]+=10; } if(!ans[digit-1]) digit--; if(vis==-1) cout<<'-'; vis=0; int p=0; for(int i=digit-1;i>=0;i--) { if(ans[i]!=0) vis=1; if(vis) { p=1; cout<<ans[i]; } } if(!p) cout<<0; } void Multiplication(){//x*y if((len_x==1 && x[0]==0 ) ||(len_y==1 && y[0]==0) ) { cout<<0; return ; } reverse(x,x+len_x); reverse(y,y+len_y); int digit = len_x + len_y - 1; for(int i=0;i<len_x;i++) for(int j=0;j<len_y;j++) ans[i+j]+=x[i]*y[j]; for(int i=0;i<digit;i++) if(ans[i]>=10) { ans[i+1]+=ans[i]/10; ans[i]%=10; } if(ans[digit]) digit++; if(flag1*flag2==-1) cout<<"-"; for(int i=digit-1;i>=0;i--) cout<<ans[i]; } /* void chu(){//x/y gaojing/danjing if(len_x==1 && x[0]==0 ) { cout<<0; return ; } if(len_y==1 && y[0]==0 ) return ; long long b=0,rema; for(int i=0;i<len_y;i++) { b*=10; b+=y[i]; } for(int i=0;i<len_x;i++) { rema=x[i]%b; ans[i]=x[i]/b; x[i+1]+=rema*10; }1 int j=0; while(!ans[j]) j++; if(j>=len_x) { cout<<0; return; } if(flag1*flag2==-1) cout<<"-"; for(int i=j;i<len_x;i++) cout<<ans[i]; if(j>=len_x) cout<<0; }*/ int z[maxn],len_z; int num_substr(int pos){ for(int i=0;i<len_y;i++) z[i+pos]=y[i]; len_z=len_y+pos; } void sub(){//x,z if(len_x==len_z && judge(x,z,len_x)==0) { len_x=0; return ; } if(len_x>len_z || (len_x==len_z && judge(x,z,len_x)==1)){ for(int i=0;i<len_x;i++){ if(x[i]<z[i]){ x[i+1]--; x[i]+=10; } x[i]-=z[i]; } while(len_x>0 && !x[len_x-1]) len_x--; return; } } void Division(){//x/y gaojing/gaojing if(len_x==1 && x[0]==0 || len_x<len_y) { cout<<0; return ; } if(len_y==1 && y[0]==0 ) return ; reverse(x,x+len_x); reverse(y,y+len_y); int digit = len_x - len_y + 1;//shang for(int i=digit-1;i>=0;i--){ memset(z,0,sizeof(z)); num_substr(i);//y,z while(len_x>len_z || (len_x==len_z && judge(x,z,len_x)>=0)){ ans[i]++; sub();//x,z } } while(digit && !ans[digit-1]) digit--; if(!digit) { cout<<0; return ; } if(flag1*flag2==-1) cout<<"-"; for(int i=digit-1;i>=0;i--) cout<<ans[i]; } void Init() { len_x=n.length();len_y=m.length(); if(n[0]=='-') { n=n.substr(1,--len_x); flag1*=-1; } if(m[0]=='-') { m=m.substr(1,--len_y); flag2*=-1; } for(int i=0;i<len_x;i++) x[i]=n[i]-'0'; for(int i=0;i<len_y;i++) y[i]=m[i]-'0'; } int main() { cin>>n>>m>>str; Init(); if(str=='+' || str=='-'){ if(str=='-') flag2*=-1; if(flag1==1 && flag2==1) Addition(); if(flag1==1 && flag2==-1) Subtraction(); if(flag1==-1 && flag2==1){ swap(x,y); swap(len_x,len_y); Subtraction(); } if(flag1==-1 && flag2==-1){ c=-1;Addition(); } } if(str=='*') Multiplication(); if(str=='/') Division(); return 0; }