高精度减法 超详细题解(C++ 版)
2026-04-04 11:49:01
发布于:广东
1阅读
0回复
0点赞
这道题要求计算两个极大整数(最多 10000 位)的减法,普通的 int/long long 存不下这么大的数字,必须用字符串存储 + 模拟手工减法来实现。
一、核心思路
- 大数存储:用字符串
string存储两个超大数,因为字符串可以存任意长度的数字。 - 大小判断:先判断两个数的大小,如果被减数 < 减数,结果为负数,交换两个数再计算,最后加负号。
- 倒序存储:把字符串数字倒着存入数组,方便从低位到高位逐位计算(手工减法也是从个位开始算)。
- 模拟减法:逐位相减,处理借位(不够减就向前一位借 1)。
- 去前导零:计算完后去掉结果前面多余的 0,最后倒序输出。
二、逐行代码解析
1. 头文件与全局变量
#include <bits/stdc++.h> // 万能头文件,包含所有C++标准库
using namespace std;
string a, b; // 存储两个输入的大整数
int s[100010]; // 存储计算结果,开足够大的空间(10000位够用)
2. 大小比较函数 cmp
作用:判断字符串表示的大数 a 是否 大于等于 b
bool cmp (string a, string b) {
// 第一步:位数不同,位数多的数更大
if (a.size() != b.size()) return a.size() > b.size();
// 第二步:位数相同,从左到右逐位比较
for (int i = 0; i < a.size(); i++) {
if (a[i] != b[i]) return a[i] > b[i];
}
return true; // 两个数完全相等
}
✅ 示例:
cmp("10086", "86")→ 位数 5>2 → 返回truecmp("86", "10086")→ 返回false
3. 主函数逻辑
(1)输入数据 + 判断正负
int main () {
string a, b;
cin >> a; // 输入第一个数
cin >> b; // 输入第二个数
int flag = 1; // 标记结果正负:1=正数,-1=负数
// 如果 a < b,结果为负,交换a和b(保证用大的数减小的数)
if (!cmp(a, b)) {
swap(a, b);
flag = -1;
}
✅ 关键逻辑:
- 比如计算
86 - 10086,直接算会出错,所以交换成10086 - 86,最后加负号。
(2)倒序存入数组
// 把a倒序存入数组 s
// 例如 a = "10086" → 倒序后是 6 8 0 0 1
for (int i = 0; i < a.size(); i++) {
s[i] = a[a.size() - i - 1] - '0';
}
// 逐位相减:用a的每一位 减去 b对应位
for (int i = 0; i < b.size(); i++) {
s[i] -= b[b.size() - i - 1] - '0';
}
- 字符转数字:
'8' - '0' = 8(ASCII 码运算) - 倒序原因:数组下标从 0 开始,对应个位、十位、百位,方便借位计算。
(3)处理借位(核心步骤)
int ssize = a.size(); // 结果的最大位数
// 遍历每一位,处理借位
for (int i = 0; i < ssize; i++) {
if (s[i] < 0) { // 当前位不够减,需要向前一位借1
s[i] += 10; // 本位加10
s[i+1]--; // 高位减1
}
}
✅ 示例:
- 某一位计算后是
-6→ 加 10 变成4,前一位减 1。
(4)去掉前导零
// 去掉结果最前面多余的0(例如 0010000 → 10000)
while (ssize > 1 && s[ssize - 1] == 0) {
ssize--;
}
- 保留至少 1 位:防止结果是
0时输出空。
(5)输出结果
if (flag == -1) cout << "-"; // 输出负号
// 倒序输出数组(从高位到低位)
for (int i = ssize - 1; i >= 0; i--) {
cout << s[i];
}
return 0;
}
三、样例执行过程(输入:10086 和 86)
- 判断大小:
10086 > 86→flag=1,不交换 - 倒序存储
a=10086→ 数组:[6,8,0,0,1]
- 逐位相减
- 第 0 位:6-6=0
- 第 1 位:8-8=0
- 其余位不变
- 处理借位:无负数,无需借位
- 去前导零:结果为
1 0 0 0 0 - 输出:
10000
四、关键知识点总结
- 高精度运算核心:用字符串存数,数组模拟计算,因为普通变量存不下超大数。
- 倒序存储:减法从低位开始,倒序后数组下标对应数位,方便计算。
- 借位处理:当前位 < 0 时,+10 并向前一位 -1。
- 前导零处理:必须去掉,否则输出错误(如
00123→123)。 - 正负判断:被减数 < 减数时,交换两数,最后加负号。
总结
- 高精度减法必须用字符串+数组模拟,无法直接用数字变量存储。
- 核心步骤:比较大小 → 倒序存数 → 逐位减法 → 处理借位 → 去前导零 → 输出。
- 借位和前导零是最容易出错的地方,一定要仔细处理。
这里空空如也

有帮助,赞一个