不能直接用int或long long做大数减法,因其位宽固定(int约21亿,long long约9×10¹⁸),无法表示百位级大数;必须用字符串模拟手算减法,关键在符号处理、对齐、借位和前导零。

c++中如何实现大数减法_c++字符串模拟高精度减法步骤【汇总】

为什么不能直接用 intlong long 做大数减法

因为 C++ 原生整型有固定位宽:int 通常最多存 231−1(约 21 亿),long long 也只到 263−1(约 9×1018)。一旦输入是 100 位的十进制数,比如 "123456789012345678901234567890",任何内置类型都会溢出或截断——必须用字符串存数字,逐位模拟手算减法。

字符串模拟减法的核心步骤与边界处理

关键不是“写个循环”,而是处理好符号、对齐、借位和前导零。真实编码中最容易错的是:没统一正负号逻辑、借位后忘记把当前位补 10、结果全零时返回空串。

C++ 实现示例:只处理非负整数相减(最常用子场景)

这是高频面试/ACM 场景:输入两个非负 string,输出其差(允许为负)。下面代码不依赖额外库,仅用标准 stringvector

#include <string>
#include <algorithm>
#include <vector>

std::string subtract(const std::string& a, const std::string& b) { // 先判断大小,确保 a >= b(绝对值),否则结果加负号 bool negative = false; std::string x = a, y = b; if (x.length() < y.length() || (x.length() == y.length() && x < y)) { std::swap(x, y); negative = true; }

std::vector&lt;int&gt; res;
int i = x.size() - 1, j = y.size() - 1, borrow = 0;
while (i &gt;= 0) {
    int d1 = x[i] - '0';
    int d2 = (j &gt;= 0) ? y[j] - '0' : 0;
    int digit = d1 - d2 - borrow;
    if (digit &lt; 0) {
        digit += 10;
        borrow = 1;
    } else {
        borrow = 0;
    }
    res.push_back(digit);
    i--; j--;
}

// 去前导零:从高位(即 res.back())开始找第一个非零
std::string ans;
bool leading = true;
for (int k = res.size() - 1; k &gt;= 0; k--) {
    if (leading &amp;&amp; res[k] == 0) continue;
    leading = false;
    ans += ('0' + res[k]);
}
if (ans.empty()) ans = "0";
if (negative) ans = "-" + ans;
return ans;

}

容易被忽略的细节:输入含符号、前导零、空串怎么办

实际输入往往不干净。比如 "-00123""000""" 都可能进来。生产级代码必须预处理:

高精度减法真正难的不是算法,是把所有边界条件塞进同一套逻辑里跑通。多数人卡在“以为自己处理了负数,其实漏了 "0 - 123" 这种情况”。

本文转载于:互联网 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。