← 返回目录

当整数超出 long long 范围时,只能用字符串模拟竖式运算。下面是一套完整可用的加减乘除与取模模板。

#include <bits/stdc++.h>
using namespace std;

// ------------------------------
// 1. 高精度加法 (a + b)
// ------------------------------
string add(string a, string b) {
    reverse(a.begin(), a.end());
    reverse(b.begin(), b.end());
    string res;
    int carry = 0, i = 0;
    while (i < a.size() || i < b.size() || carry) {
        int sum = carry;
        if (i < a.size()) sum += a[i] - '0';
        if (i < b.size()) sum += b[i] - '0';
        carry = sum / 10;
        res.push_back(sum % 10 + '0');
        i++;
    }
    reverse(res.begin(), res.end());
    return res;
}

// ------------------------------
// 2. 高精度减法 (a - b,保证 a >= b)
// ------------------------------
string sub(string a, string b) {
    reverse(a.begin(), a.end());
    reverse(b.begin(), b.end());
    string res;
    int borrow = 0, i = 0;
    while (i < a.size()) {
        int digitA = a[i] - '0' - borrow;
        int digitB = (i < b.size()) ? b[i] - '0' : 0;
        borrow = 0;
        if (digitA < digitB) {
            digitA += 10;
            borrow = 1;
        }
        res.push_back(digitA - digitB + '0');
        i++;
    }
    reverse(res.begin(), res.end());
    int pos = res.find_first_not_of('0');
    if (pos == string::npos) return "0";
    return res.substr(pos);
}

// ------------------------------
// 3. 高精度乘法 (a * b)
// ------------------------------
string mul(string a, string b) {
    reverse(a.begin(), a.end());
    reverse(b.begin(), b.end());
    vector<int> res(a.size() + b.size(), 0);

    for (int i = 0; i < a.size(); i++)
        for (int j = 0; j < b.size(); j++)
            res[i + j] += (a[i] - '0') * (b[j] - '0');

    int carry = 0;
    for (int k = 0; k < res.size(); k++) {
        int total = res[k] + carry;
        res[k] = total % 10;
        carry = total / 10;
    }

    string ans;
    for (int x : res) ans.push_back(x + '0');
    reverse(ans.begin(), ans.end());
    int pos = ans.find_first_not_of('0');
    return pos == string::npos ? "0" : ans.substr(pos);
}

// ------------------------------
// 辅助:比较 a >= b
// ------------------------------
bool ge(string a, string b) {
    if (a.size() != b.size()) return a.size() > b.size();
    return a >= b;
}

// ------------------------------
// 4. 高精度除法 (a / b,整数除法,向下取整)
// ------------------------------
string div(string a, string b) {
    string res, cur;
    for (char c : a) {
        cur += c;
        if (cur.size() == 1 && cur[0] == '0') cur = "";
        int cnt = 0;
        while (ge(cur, b)) {
            cur = sub(cur, b);
            cnt++;
        }
        if (!res.empty() || cnt) res.push_back(cnt + '0');
    }
    return res.empty() ? "0" : res;
}

// ------------------------------
// 5. 高精度取模 (a % b)
// ------------------------------
string mod(string a, string b) {
    string cur;
    for (char c : a) {
        cur += c;
        if (cur.size() == 1 && cur[0] == '0') cur = "";
        while (ge(cur, b)) cur = sub(cur, b);
    }
    return cur.empty() ? "0" : cur;
}

// ------------------------------
// 测试主函数
// ------------------------------
int main() {
    string a, b;
    cin >> a >> b;

    cout << "a + b = " << add(a, b) << endl;
    if (ge(a, b)) cout << "a - b = " << sub(a, b) << endl;
    cout << "a * b = " << mul(a, b) << endl;
    cout << "a / b = " << div(a, b) << endl;
    cout << "a % b = " << mod(a, b) << endl;

    return 0;
}

实现要点

运算核心操作复杂度
加法逆序后按位相加,处理进位$O(n)$
减法逆序后按位相减,处理借位$O(n)$
乘法双层循环累加到 res[i+j],最后统一进位$O(nm)$
除法逐位试减,商累加$O(n^2)$
取模逐位试减,保留余数$O(n^2)$

除法与取模用的是试减法,正确性是确定的,但常数较大。如果数据规模很大,可以换成二分商的做法,把单次试减降到 $O(\log 10) \approx O(1)$。