有四种高精度以下
(低精度意为可用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; }