【算法】高精度(2)
五、高精度处理进位与借位
其实也很简单,我们再来模拟一下,1439+887的时候,首先我们最低位相加,得到16,那么答案最低位就是6,再进个1,然后两数的十位相加,3+8=11,然后再加上进位的1,就是11+1=12,所以答案十位就是2,再进1,4+8+1=13,答案百位是3,进1,1+0+1=2,答案千位是2。所以结果就是6232!哦,不对反了,是2326,这里要注意一下,输出的时候是倒着输出的,千万不要忘了。
总结一下,进位的步骤大致如下:
1、将当前位置的数相加,当前位的结果就是当前结果除以10的余数。
2、再讲当前结果除以10加到高位,表示进位。
注意:有同学可能会有疑问,为什么一定要倒着储存这个数呢?顺着存不是更好吗?这里我举一个非常简单的例子,比如10+90,谁都知道答案是100,那么我们来看看顺着储存和倒着储存有什么区别:
1.顺着存:a={1,0},b={9,0},当a的最高位(即数组第1位)加上b的最高位(即数组第2位)时我们是不是得进位?!?但是a的最高位是数组的第一位,那么我们要进位到a数组的第几个位置呢?第0个位置?太复杂了。还是存在第一个位置并把所有的数往数组右边移动一位?那更不行,时间复杂度又太高,所以不好办。
2.倒着存:a={0,1},b={0,9},当a的最高位(即数组第2位)加上b的最高位(即数组第2位)时我们同样要进位,这个时候就好办了,直接进位到数组的第三位就好了,所以答案的数组就是{0,0,1},倒过来输出答案100。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; //比较a和b的大小,如果a>b则返回真,否则返回假 int c[100]; void add(int a[],int b[]) { int i=1;x=0; //x是进位 c[i]=a[i]+b[i]+x; //第i位相加并加上上次的进位 x=c[i]/10; //向高位进位 c[i]%=10; //存储第i位 i++; //位置下标变量 }
int a[6666],b[6666],c[6666]; int lena,lenb,lenc; int main(){ lenc=max(lena,lenb); for(int i=1;i<=lenc;i++){ c[i]=c[i]+a[i]+b[i]; c[i+1]=c[i]/10; c[i]=c[i]%10; } while(c[lenc+1]>0) lenc++;//答案的长度有时还会增加 }
接下来讲讲当减法的时候如何借位
1、将当前位置的数向减。
2、如果结果大于或等于0就直接作为当前位的答案。
3、否则将结果加10作为当前位的答案,在将高位的数-1即可。
1 2 3 4 5 6 7 8 9 10 11 | int a[6666],b[6666],c[6666]; int lena,lenb,lenc;
int main(){ lenc=max(lena,lenb); for(int i=1;i<=lenc;i++){ c[i]=c[i]+a[i]-b[i]; if(c[i]<0) c[i]=c[i]+10,c[i+1]=-1; } while(c[lenc]==0&&lenc>1) lenc--;//细节,如果a-b结果为0,那么也要输出一个0 } |
(adsbygoogle = window.adsbygoogle || []).push({});