高精度
导入:
在OI比赛中我们常常面临数据类型选择的难题,浮点型大家都会选择double,一般不会爆范围所
以大家也没有什么顾虑,但整型就不一样了,大家习惯了int本人就因为没有开long long无缘省队,在
OI界总是流传这么一句话“一场比赛不开long long,十年OI两行泪”可见数据类型选择的重要性,我们
都知道int可以处理[-231+1~231-1]内的数据,long long [-263+1~263-1],如果数据再大可以用
unsiged long long [0~264-1],如果再大那么该怎么办好呢,这就要用到高精度。
算法:
大家对列竖式应该都会吧,不会的请出门右转问度娘蛤,高精度算法就是模拟这个过程。在高精
度算法中要使用3个数组,分别用来存储两个运算数和一个答案,具体过程就不再赘述了,想必大家
都会。直接上代码。
加法:
void add() { string s1,s2; cin>>s1>>s2; la=s1.size(); lb=s2.size(); for(int i=0;i<la;i++) a[la-i]=s1[i]-'0'; for(int i=0;i<lb;i++) b[lb-i]=s2[i]-'0'; //逆序位数分离 int x=max(la,lb)+1; int k=0; for(int i=1;i<=x;i++) { c[i]=a[i]+b[i]+k; k=c[i]/10; c[i]%=10; } //模拟竖式 if(c[x]==0)x--; //如果最后一位没有进位,为0,在正常的书写中没有前导零,不要输出 for(int i=x;i;i--)cout<<c[i]; }
减法:
void jian() { string s1,s2; cin>>s1>>s2; la=s1.size(); lb=s2.size(); for(int i=0;i<la;i++) a[la-i]=s1[i]-'0'; //我们保证被减数大于减数 for(int i=0;i<lb;i++) b[lb-i]=s2[i]-'0'; //逆序位数分离 int x=max(la,lb)+1; int k=0; for(int i=1;i<=x;i++) { c[i]=a[i]-b[i]-k; if(c[i]<0)c[i]+=10,k=1; else k=0; } //模拟竖式 while(c[x]==0&&x)x--; //除去前导零 for(int i=x;i;i--)cout<<c[i]; }
乘法:
void mul() { string s1,s2; cin>>s1>>s2; la=s1.size(); lb=s2.size(); for(int i=0;i<la;i++) a[la-i]=s1[i]-'0'; for(int i=0;i<lb;i++) b[lb-i]=s2[i]-'0'; //逆序位数分离 int x=la+lb+1; int k=0; for(int i=1;i<=la;i++) for(int j=1;j<=lb;j++) c[i+j-1]=a[i]*b[j]; //模拟竖式 for(int i=1;i<=x;i++) { c[i]+=k; k=c[i]/10; c[i]%=10; } //模拟进位 while(c[x]==0)x--; //删去前导零 for(int i=x;i;i--)cout<<c[i]; }
除法:
在高精度算法中我们一般用减法来模拟除法,这里就不t代码了,因为本人太懒了代码和减法类似。
最后:
在高精度算法中有一种比较简单的优化方式——压位,将几位数字压成一位,可以大幅度减少空间
复杂度,代码也比较简单,只需要在分离位数,模拟竖式和删去前导零的时候进行调整,但实用性不
大,对于一般OI比赛说性价比不大。