高精度减法主要考虑这两件事:1.差为负数的情况。2.借位问题。
首先我们考虑一下第一个问题1.怎么解决差为负数
因为高精度就是列竖式模拟,而列竖式是小学学的,我记得那时候还没学负数吧,所以我们就默认用大数减小数,只要在前面输出一个符号就行。
那我们再想一想如何判断两个数大小。首先若位数不等,那位数大的一定就是大数。重点是两数位数相等的情况,就从最高位比较,若这一位 a 大,那么 a 就比 b 大,跳出循环;若这一位 b 大,那么 b 就比 a 大,跳出。也就是说,只有 a 和 b 该位相等的时候,才继续比较。
2.借位问题
其实这个非常简单,只要先判断该位是 a 大还是 b 大,若 b 大,a 的下一位就减1,该位加10,然后在正常减。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 using namespace std; 6 const int maxn = 1e3 + 5; 7 char a1[maxn], b1[maxn]; 8 int a[maxn], b[maxn]; //a 是被减数,b 是减数 9 bool flag = true; 10 int main() 11 { 12 gets(a1); gets(b1); //读入,所有高精都这么读 13 int la = strlen(a1), lb = strlen(b1); 14 if(la < lb) flag = false; //判断两数大小,默认大数减小数 15 if(la == lb) 16 { 17 for(int i = 0; i < la; ++i) 18 { 19 if(a1[i] > b1[i]) {flag = true; break;} 20 if(a1[i] < b1[i]) {flag = false; break;} 21 } 22 } 23 if(flag == false) {swap(a1, b1); swap(la, lb);} //若 a < b 就交换 a 和 b,别忘swap(la, lb) 24 for(int i = 0; i < la; ++i) a[i] = a1[la - i - 1] - '0'; 25 for(int i = 0; i < lb; ++i) b[i] = b1[lb - i - 1] - '0'; 26 for(int i = 0; i < la; ++i) 27 { 28 if(a[i] < b[i]) //借位 29 { 30 a[i + 1]--; a[i] += 10; 31 } 32 a[i] -= b[i]; 33 } 34 while(a[la] == 0 && la > 0) la--; //删除前导0 35 if(!flag) printf("-"); //负数先输出负号 36 for(int i = la; i >= 0; --i) printf("%d", a[i]); 37 printf(" "); 38 return 0; 39 }
高精减不用像高精加考虑最高位的问题,因为差的位数一定小于等于 a 的位数,而且最高位一定不会再进位了(默认是大数减小数嘛)。