为什么要用高精度?
C++ 里 int 最大只能到 21 亿左右,long long 也就 19 位。想算 12345678901234567890 + 98765432109876543210 会溢出。
高精度加法的思路:用字符串存数字,模拟竖式加法。
思路拆解
模拟我们小学学的竖式加法,分五步:
- 读入两个字符串(数字太大,必须当字符串读)
- 反转字符串(个位对齐下标 0,方便按位相加)
- 字符转数字(
'5'→5) - 逐位相加 + 处理进位(满 10 进 1)
- 去前导零 + 反转输出
完整代码(带注释)
#include <bits/stdc++.h>
using namespace std;
string a, b;
int main() {
cin >> a >> b;
// 1. 反转 —— 让个位对齐数组下标 0
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
// 2. 创建数组,长度取最长加数 +1(预留进位空间)
int MaxLen = max(a.size(), b.size());
vector<int> a1(MaxLen + 1, 0); // 加数 A 的每一位
vector<int> a2(MaxLen + 1, 0); // 加数 B 的每一位
vector<int> a3(MaxLen + 1, 0); // 结果数组
// 3. 字符转数字(核心!千万别漏)
for (int i = 0; i < a.size(); i++) {
a1[i] = a[i] - '0';
}
for (int i = 0; i < b.size(); i++) {
a2[i] = b[i] - '0';
}
// 4. 逐位相加
for (int i = 0; i < MaxLen; i++) {
a3[i] = a1[i] + a2[i];
}
// 5. 处理进位
for (int i = 0; i < MaxLen; i++) {
if (a3[i] >= 10) {
a3[i + 1] += a3[i] / 10; // 进位加到下一位
a3[i] %= 10; // 当前位只保留个位
}
}
// 6. 去前导零
int Index = 0;
for (int i = MaxLen; i >= 0; i--) {
if (a3[i] != 0) {
Index = i;
break;
}
}
a3.resize(Index + 1);
// 7. 反转回来,输出
reverse(a3.begin(), a3.end());
for (int i = 0; i < a3.size(); i++) {
cout << a3[i];
}
return 0;
}
运行示例
输入:
12345678901234567890
98765432109876543210
输出:
111111111011111111100
常见踩坑指南
🔴 坑 1:忘记字符转数字
// ❌ 错误 —— a1[i] 存的还是字符的 ASCII 码
a1[i] = a[i];
// ✅ 正确 —— 减去 '0' 才是真正的数字
a1[i] = a[i] - '0';
字符 '5' 的 ASCII 码是 53,不减 '0' 的话你存的是 53 不是 5,结果全乱套。
🟡 坑 2:最高位进位被忽略
999 + 1 = 1000,结果是 4 位数,但原始加数最长只有 3 位。如果你只从 MaxLen - 1 开始输出,那个最高位的 1 就丢了。
用 Index 方法从 MaxLen 往 0 扫,找到第一个非零位,进位的那一位就不会漏掉。
🟡 坑 3:输入有前导零
如果输入 00123 + 456,程序可能输出 00579。因为字符串长度被前导零撑大了。
解决方法:在转数字时记录实际有效长度,或者输入后先手动去掉前导零。
加法、减法、乘法对照
| 加法 | 减法 | 乘法 | |
|---|---|---|---|
| 结果位数 | max(m, n) + 1 | m | m + n |
| 核心运算 | a3[i] = a1[i] + a2[i] | a3[i] = a1[i] - a2[i] | a3[i+j] += a1[i] * a2[j] |
| 循环层数 | 单层 | 单层 | 双层 |
| 进位/借位 | >= 10 进位 | < 0 借位 | >= 10 进位 |
| 负号 | 不需要 | ✅ 需要 | 不需要 |
| 去前导零 | Index 法 | Index 法 | Index 法 |
总结
高精度加法的本质就是用数组模拟竖式,核心流程就一句话:
反转 → 转数字 → 加 → 进位 → 去前导零 → 反转回来 → 输出
记住别漏了字符转数字那一步,那是最高频的翻车点~