为什么要用高精度?

C++ 里 int 最大只能到 21 亿左右,long long 也就 19 位。想算 12345678901234567890 + 98765432109876543210 会溢出。

高精度加法的思路:用字符串存数字,模拟竖式加法


思路拆解

模拟我们小学学的竖式加法,分五步:

  1. 读入两个字符串(数字太大,必须当字符串读)
  2. 反转字符串(个位对齐下标 0,方便按位相加)
  3. 字符转数字'5'5
  4. 逐位相加 + 处理进位(满 10 进 1)
  5. 去前导零 + 反转输出

完整代码(带注释)

#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) + 1mm + 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 法

总结

高精度加法的本质就是用数组模拟竖式,核心流程就一句话:

反转 → 转数字 → 加 → 进位 → 去前导零 → 反转回来 → 输出

记住别漏了字符转数字那一步,那是最高频的翻车点~