有四種高精度以下
(低精度意爲可用long long 或int存儲的數
高精度通常用於數沒法用int,long long表示出來的時候使用ios
其本質都是用數組存數的每一位,模擬加減乘除,最後從高位輸出到低位
(模擬豎式加減乘除)數組
通常從數組第一位存個位,第二位十位,第三位.....依次類推
(爲何數組第一位不爲最高位,由於若是第一位是最高位遇到進位很差處理,會數組越界)spa
這部份內容不難,結合代碼模擬下就懂了3d
#include<iostream> #include<cstring> using namespace std; int n;const int maxn=1000; int ans[maxn]; string s; int len=0,lens; int main(){ for(int i=1;i<=2;++i){ cin>>s;lens=s.length();len=lens>len?lens:len; for(int j=lens-1;j>=0;--j) ans[lens-j-1]+=s[j]-'0'; } for(int i=0;i<len;++i){ if(ans[i]>=10){ ans[i+1]+=ans[i]/10; ans[i]%=10; if(ans[len]>0) ++len; //最高位的下一位不爲0,則數的長度++ } }--len; while(len>=0) cout<<ans[len],--len; return 0; }
借鑑高精的作法,將低精轉爲數組,一樣可行code
高精度減法與加法不一樣的是,一個是進位,一個是借位(從後一個數借一個「1」)
注意會出現負數,判斷一下大小,而後仍然用大數減少數blog
#include<cstdio> #include<cstring> using namespace std; int n; const int maxn=10100; int ans[maxn]; int a[maxn],b[maxn]; char s1[maxn],s2[maxn]; int lena,lenb; void swap(int &a,int &b){ a=a^b;b=b^a;a=a^b; } int main(){ scanf("%s %s",s1,s2); lena=strlen(s1),lenb=strlen(s2); for(int i=0;i<lena;++i) a[i]=s1[lena-i-1]-'0'; for(int i=0;i<lenb;++i) b[i]=s2[lenb-i-1]-'0'; int len=lena>lenb?lena:lenb; bool flag=0; for(int i=len-1;i>=0;--i){//比較兩數大小,經過比較兩數最高的相等的位數, if(a[i]>b[i]) break; if(a[i]<b[i]){ flag=1;break; }if(i==0){ printf("0");return 0;//說明兩數想等 } } if(flag) printf("-");//b數較大因此a-b爲負 if(flag) for(int i=0;i<len;++i) swap(a[i],b[i]);//b數較大,因此交換兩值 for(int i=0;i<len;++i){ ans[i]=a[i]-b[i]; if(ans[i]<0) a[i+1]--,ans[i]+=10; } while(ans[len]==0) --len; while(len>=0) printf("%d",ans[len]),--len; }
高精乘高精必定要知道一件事
從數組第0位(做爲個位數)開始,a數的第i位和第j位相乘爲積的第i+j爲數
能夠本身用豎式模擬一下ci
#include<cstdio> #include<cstring> using namespace std; const int maxn=2e4+10; char s[maxn]; int a[maxn],b[maxn]; int ans[maxn]; int main(){ scanf("%s",s); int lena=strlen(s); for(int i=0;i<lena;++i) a[i]=s[lena-i-1]-'0'; scanf("%s",s);int lenb=strlen(s); for(int i=0;i<lenb;++i) b[i]=s[lenb-i-1]-'0'; for(int i=0;i<lena;++i) for(int j=0;j<lenb;++j){ ans[i+j]+=a[i]*b[j]; ans[i+j+1]+=ans[i+j]/10; ans[i+j]%=10; } int len=lena+lenb; while(ans[len]==0 && len>=0) --len; if(len==-1) printf("0"); else while(len>=0) printf("%d",ans[len]),--len; }
同理(霧get
(容我鴿一鴿)(逃string
高精除低精io
高精逐漸從高位轉化爲長整形,再除以低精
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int maxn=5e4+10; char a[maxn];//a爲高精度數 long long b,len;bool flag=0;//b爲低精度數,flag表示是否輸出過商 int main(){ cin>>a>>b;len=strlen(a);long long n=0,f;//n爲被除數,f爲餘數 for(int i=0;i<len;++i){ n=n*10+a[i]-48; f=n/b; n%=b; if(flag || f) flag=1,cout<<f; }return 0; }