上篇文章我们了解了高精度加法,今天我们来讲减法。
和加法一样,减法也是模拟小学减法竖式:
先用数组存下被减数和减数:
①如果a[i] < b[i]: 模拟a[i]向a[i+1]借位:a[i+1]--; a[i] += 10;
②模拟减法:c[i] = a[i]
这时有一个问题:如果a[i+1] == 0, 这样借位是否会出问题?
其实不会.因为最多借1位,即使a[i+1]被借位后等于-1,因为a>b, a[i+1]还可以向a[i+2]借位。借位后a[i+1]等于9,而b[i+1]最大为9。
我们来看一下高精度减法的思路:
①高精度数的读取存储:使用字符串方式读取,然后转成整型数组,为方便计算,进行逆向存储。
②模拟竖式进行减法:相同位置进行相减,不够减时进行借位
③去除前导0后,逆向输出。
那这时有问题了:
两个正整数a和b, 且a>b,a的长度为n,b的长度为m,那么c = a-b最长为多少?n
两个正整数a和b,如果判断a和b的大小?(as.size()<bs.size()||as.size()==bs.size()&&as<bs)
好,问题解决,最后给大家附上实现的子程序:
string Sub(string as,string bs){
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
string cs="";
if(as.size()<bs.size()||as.size()==bs.size()&&as<bs){
swap(as,bs);
cs+="-";
}
int al=as.size(),bl=bs.size();
int cl=max(al,bl);
for(int i=1;i<=al;i++)a[i]=as[al-i]-'0';
for(int i=1;i<=bl;i++)b[i]=bs[bl-i]-'0';
for(int i=1;i<=cl;i++){
if(a[i]<b[i]){
a[i]+=10;
a[i+1]--;
}
c[i]=a[i]-b[i];
}
while(c[cl]==0&&cl>1)cl--;
for(int i=cl;i>=1;i--)cs+=c[i]+'0';
return cs;
}