高精度类(面向对象)

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cassert>

class BigInt {
private:
    std::vector<int> digits;  // 小端序存储,digits[0] 是个位
    bool negative;            // true 表示负数,false 表示非负数

    // 去除前导零(同时处理结果为 0 时的符号)
    void trim() {
        while (digits.size() > 1 && digits.back() == 0)
            digits.pop_back();
        if (digits.size() == 1 && digits[0] == 0)
            negative = false;
    }

    // 比较绝对值大小(小端序),返回 1: |a|>|b|, 0: 相等, -1: |a|<|b|
    static int absCompare(const BigInt& a, const BigInt& b) {
        if (a.digits.size() != b.digits.size())
            return a.digits.size() > b.digits.size() ? 1 : -1;
        for (int i = a.digits.size() - 1; i >= 0; --i) {
            if (a.digits[i] != b.digits[i])
                return a.digits[i] > b.digits[i] ? 1 : -1;
        }
        return 0;
    }

    // 加法核心(绝对值相加),结果为正
    static BigInt absAdd(const BigInt& a, const BigInt& b) {
        BigInt res;
        res.digits.clear();
        int carry = 0;
        size_t i = 0;
        while (i < a.digits.size() || i < b.digits.size() || carry) {
            int sum = carry;
            if (i < a.digits.size()) sum += a.digits[i];
            if (i < b.digits.size()) sum += b.digits[i];
            res.digits.push_back(sum % 10);
            carry = sum / 10;
            ++i;
        }
        res.negative = false;
        return res;
    }

    // 减法核心(绝对值相减),要求 |a| >= |b|,结果为正
    static BigInt absSub(const BigInt& a, const BigInt& b) {
        BigInt res;
        res.digits.clear();
        int borrow = 0;
        for (size_t i = 0; i < a.digits.size(); ++i) {
            int diff = a.digits[i] - borrow;
            if (i < b.digits.size()) diff -= b.digits[i];
            if (diff < 0) {
                diff += 10;
                borrow = 1;
            } else {
                borrow = 0;
            }
            res.digits.push_back(diff);
        }
        res.negative = false;
        res.trim();
        return res;
    }

public:
    // 构造函数
    BigInt() : digits{0}, negative(false) {}
    BigInt(long long num) : negative(false) {
        if (num < 0) {
            negative = true;
            num = -num;
        }
        do {
            digits.push_back(num % 10);
            num /= 10;
        } while (num > 0);
    }
    BigInt(const std::string& s) {
        if (s.empty()) {
            digits.push_back(0);
            negative = false;
            return;
        }
        size_t start = 0;
        negative = (s[0] == '-');
        if (negative || s[0] == '+') start = 1;
        for (int i = s.size() - 1; i >= (int)start; --i) {
            digits.push_back(s[i] - '0');
        }
        trim();
    }

    // 转换为字符串
    std::string toString() const {
        if (digits.empty()) return "0";
        std::string res;
        if (negative) res += '-';
        for (int i = digits.size() - 1; i >= 0; --i)
            res += (digits[i] + '0');
        return res;
    }

    // 比较运算符
    bool operator==(const BigInt& other) const {
        return negative == other.negative && digits == other.digits;
    }
    bool operator!=(const BigInt& other) const { return !(*this == other); }
    bool operator<(const BigInt& other) const {
        if (negative != other.negative) return negative;
        if (negative) {
            // 两个负数,绝对值大的反而小
            int cmp = absCompare(*this, other);
            return cmp == 1;
        } else {
            int cmp = absCompare(*this, other);
            return cmp == -1;
        }
    }
    bool operator>(const BigInt& other) const { return other < *this; }
    bool operator<=(const BigInt& other) const { return !(*this > other); }
    bool operator>=(const BigInt& other) const { return !(*this < other); }

    // 加减法
    BigInt operator+(const BigInt& other) const {
        if (negative == other.negative) {
            // 同号相加:绝对值相加,符号不变
            BigInt res = absAdd(*this, other);
            res.negative = negative;
            return res;
        } else {
            // 异号相加:相当于绝对值相减,符号由绝对值大的决定
            int cmp = absCompare(*this, other);
            if (cmp == 0) return BigInt(0);
            BigInt res;
            if (cmp == 1) { // |this| > |other|
                res = absSub(*this, other);
                res.negative = negative; // 符号与绝对值大的相同
            } else {
                res = absSub(other, *this);
                res.negative = other.negative;
            }
            return res;
        }
    }

    BigInt operator-(const BigInt& other) const {
        BigInt negOther = other;
        negOther.negative = !negOther.negative;
        return *this + negOther;
    }

    BigInt operator-() const {
        BigInt res = *this;
        if (res.digits.size() != 1 || res.digits[0] != 0)
            res.negative = !res.negative;
        return res;
    }

    // 乘法(普通 O(n^2) 算法,可替换为 Karatsuba)
    BigInt operator*(const BigInt& other) const {
        BigInt res;
        res.digits.assign(digits.size() + other.digits.size(), 0);
        for (size_t i = 0; i < digits.size(); ++i) {
            int carry = 0;
            for (size_t j = 0; j < other.digits.size(); ++j) {
                long long prod = (long long)digits[i] * other.digits[j] + res.digits[i + j] + carry;
                res.digits[i + j] = prod % 10;
                carry = prod / 10;
            }
            if (carry) {
                res.digits[i + other.digits.size()] += carry;
            }
        }
        res.negative = negative ^ other.negative;
        res.trim();
        return res;
    }

    // 除法(高精除以高精,返回商和余数)
    friend std::pair<BigInt, BigInt> divmod(const BigInt& a, const BigInt& b);
    BigInt operator/(const BigInt& other) const {
        return divmod(*this, other).first;
    }
    BigInt operator%(const BigInt& other) const {
        return divmod(*this, other).second;
    }

    // 复合赋值运算符
    BigInt& operator+=(const BigInt& other) { *this = *this + other; return *this; }
    BigInt& operator-=(const BigInt& other) { *this = *this - other; return *this; }
    BigInt& operator*=(const BigInt& other) { *this = *this * other; return *this; }
    BigInt& operator/=(const BigInt& other) { *this = *this / other; return *this; }
    BigInt& operator%=(const BigInt& other) { *this = *this % other; return *this; }

    // 输入输出
    friend std::ostream& operator<<(std::ostream& os, const BigInt& bi) {
        os << bi.toString();
        return os;
    }
    friend std::istream& operator>>(std::istream& is, BigInt& bi) {
        std::string s;
        is >> s;
        bi = BigInt(s);
        return is;
    }
};

// 除法辅助函数(高精除以高精,使用竖式试商)
std::pair<BigInt, BigInt> divmod(const BigInt& a, const BigInt& b) {
    if (b == BigInt(0)) throw std::runtime_error("Division by zero");
    if (a == BigInt(0)) return {BigInt(0), BigInt(0)};
    // 确定商的符号
    bool resNegative = a.negative ^ b.negative;
    // 取绝对值进行计算
    BigInt absA = a;
    absA.negative = false;
    BigInt absB = b;
    absB.negative = false;

    if (absA < absB) return {BigInt(0), a}; // 商为0,余数为a

    BigInt quotient;
    BigInt remainder;
    remainder.digits.clear();

    // 从被除数的高位开始逐位试商
    for (int i = absA.digits.size() - 1; i >= 0; --i) {
        // 将当前余数左移一位(乘以10),加上被除数的下一位
        remainder.digits.insert(remainder.digits.begin(), absA.digits[i]);
        remainder.trim();
        // 试商:在 0-9 之间找到最大的 q 使得 q * absB <= remainder
        int q = 0;
        int left = 0, right = 9;
        while (left <= right) {
            int mid = (left + right) / 2;
            BigInt prod = absB * BigInt(mid);
            if (prod <= remainder) {
                q = mid;
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        quotient.digits.push_back(q);
        BigInt prod = absB * BigInt(q);
        remainder = remainder - prod;
        remainder.trim();
    }
    // 此时 quotient.digits 是从高位到低位存储的,需要反转成小端序
    std::reverse(quotient.digits.begin(), quotient.digits.end());
    quotient.trim();
    quotient.negative = resNegative;
    remainder.negative = a.negative; // 余数符号与被除数一致
    return {quotient, remainder};
}

// 示例用法
int main() {
    BigInt a("12345678901234567890");
    BigInt b("98765432109876543210");
    std::cout << "a = " << a << "\nb = " << b << std::endl;
    std::cout << "a + b = " << a + b << std::endl;
    std::cout << "a - b = " << a - b << std::endl;
    std::cout << "a * b = " << a * b << std::endl;
    std::cout << "a / b = " << a / b << std::endl;
    std::cout << "a % b = " << a % b << std::endl;
    return 0;
}