高精度减法

715 字
4 分钟
高精度减法

高精度减法#

高精度减法也是模拟竖式。和加法相比,它多了两个问题:

  • 要判断两个大整数谁更大。
  • 做减法时要处理借位。

通常我们先保证 A >= B,然后计算 A - B。如果原本 A < B,就计算 B - A,输出时前面加负号。

1、为什么要先比较大小#

例如:

123 - 456

结果是负数。

为了让减法函数只处理一种情况,我们可以先判断:

如果 A >= B,输出 A - B
如果 A < B,输出 -(B - A)

这样 sub 函数内部只需要处理“大数减小数”。

2、倒序存储#

和高精度加法一样,先把字符串倒序存入数组:

12345 -> [5, 4, 3, 2, 1]

这样从个位开始减,借位也好处理。

3、借位怎么写#

设 t 表示上一位是否借位。

当前位先减掉借位:

t = A[i] - t;

再减去 B[i]:

if (i < B.size()) t -= B[i];

当前位结果:

(t + 10) % 10

如果 t < 0,说明需要向高位借 1。

4、C++ 模板#

#include <bits/stdc++.h>
using namespace std;
bool cmp(vector<int>& A, vector<int>& B) {
if (A.size() != B.size()) return A.size() > B.size();
for (int i = A.size() - 1; i >= 0; i--) {
if (A[i] != B[i]) return A[i] > B[i];
}
return true;
}
vector<int> sub(vector<int>& A, vector<int>& B) {
vector<int> C;
int t = 0;
for (int i = 0; i < (int)A.size(); i++) {
t = A[i] - t;
if (i < (int)B.size()) t -= B[i];
C.push_back((t + 10) % 10);
if (t < 0) t = 1;
else t = 0;
}
while (C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
int main() {
string a, b;
cin >> a >> b;
vector<int> A, B;
for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');
vector<int> C;
if (cmp(A, B)) {
C = sub(A, B);
} else {
C = sub(B, A);
printf("-");
}
for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
return 0;
}

5、为什么要去掉前导零#

比如:

1000 - 999 = 1

数组里可能得到:

[1, 0, 0, 0]

倒序输出会变成 0001,所以要去掉高位多余的 0:

while (C.size() > 1 && C.back() == 0) C.pop_back();

保留 C.size() > 1 是为了避免结果为 0 时把最后一个 0 也删掉。

6、容易写错的地方#

(1)比较大小要从最高位开始#

因为数组是倒序存储,高位在 back() 附近,所以比较时从后往前。

(2)借位变量要在每一位更新#

if (t < 0) t = 1;
else t = 0;

t 不再是当前位结果,而是下一位需要减掉的借位。

(3)负号只输出一次#

不要在 sub 函数里处理负号,让主函数根据大小判断输出即可。

总结#

高精度减法可以拆成:

先比较大小 -> 大数减小数 -> 逐位借位 -> 去掉前导零

这和手算竖式完全一致,只是数组为了方便从低位开始存。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

高精度减法
https://blog.tjcheng.cn/posts/migrated/old-85/
作者
TengJinCheng
发布于
2025-10-08
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
TengJinCheng
Hello, I'm Teng.
公告
欢迎来到TengJinCheng工作铺!
音乐
封面

音乐

暂未播放

0:000:00
暂无歌词
分类
标签
站点统计
文章
157
分类
7
标签
114
总字数
109,939
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Local
博客版本
Firefly v6.13.4
文章许可
CC BY-NC-SA 4.0

文章目录