BigInteger 类(高精度亿进制)模板 - 也许是全网最好的 BigInteger 高精度模板

这篇博客提供了一个全面的 BigInteger 高精度模板,支持负数、整型和字符串赋值、加减乘除取模等算术操作,并具备与 cin 和 cout 的直接交互功能。这个模板旨在简化高精度计算的复杂性,使得使用起来如同普通整型变量一样方便。对于想要提升编程技巧和熟悉高精度算法的开发者来说,这是一个理想的资源。
摘要由CSDN通过智能技术生成

高精度亿进制模板,支持负数,支持通过整型和字符串赋值,支持加减乘除取模等算术运算符,支持比较运算符,支持+=-=*=/=%-,支持用 cin 和 cout 直接输入输出。抄了之后直接当成 int 来用也问题不大。

也许是全网最好的 BigInteger 高精度模板。

#include <algorithm>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

class BigInteger {
public:
    BigInteger(long long num = 0);
    BigInteger(const string &str);
    ~BigInteger();

    BigInteger operator=(const long long num);
    BigInteger operator=(const string &str);

    BigInteger operator+() const;
    BigInteger operator-() const;

    friend BigInteger operator+(const BigInteger &a, const BigInteger &b);
    friend BigInteger operator-(const BigInteger &a, const BigInteger &b);
    friend BigInteger operator*(const BigInteger &a, const BigInteger &b);
    friend BigInteger operator/(const BigInteger &a, const BigInteger &b);
    friend BigInteger operator%(const BigInteger &a, const BigInteger &b);

    BigInteger operator+=(const BigInteger &b);
    BigInteger operator-=(const BigInteger &b);
    BigInteger operator*=(const BigInteger &b);
    BigInteger operator/=(const BigInteger &b);
    BigInteger operator%=(const BigInteger &b);

    friend bool operator<(const BigInteger &a, const BigInteger &b);
    friend bool operator>(const BigInteger &a, const BigInteger &b);
    friend bool operator==(const BigInteger &a, const BigInteger &b);
    friend bool operator<=(const BigInteger &a, const BigInteger &b);
    friend bool operator>=(const BigInteger &a, const BigInteger &b);

    friend ostream &operator<<(ostream &out, const BigInteger &x);
    friend istream &operator>>(istream &in, BigInteger &x);

private:
    vector<int> s;
    int sign = 1;

    static const int BASE = 100000000;
    static const int WIDTH = 8;

    void __defragment();
    friend BigInteger __BigInteger_shift(const BigInteger &b, const int &x);
};

BigInteger __BigInteger_shift(const BigInteger &b, const int &x) {
    BigInteger c;
    c.s.resize(b.s.size() + x);
    for (int i = 0; i < b.s.size(); i++) c.s[i + x] = b.s[i];
    return c;
}

BigInteger::BigInteger(long long num) { *this = num; }
BigInteger::BigInteger(const string &str) { *this = str; }
BigInteger::~BigInteger() {}

BigInteger BigInteger::operator=(long long num) {
    s.clear();
    if (num >= 0)
        sign = 1;
    else
        sign = -1, num *= -1;
    do {
        s.push_back(num % BASE);
        num /= BASE;
    } while (num > 0);
    return *this;
}
BigInteger BigInteger::operator=(const string &str) {
    s.clear();
    sign = str[0] == '-' ? -1 : 1;
    int first = str[0] == '-';
    while (str[first] == '0' && first < str.length()) first++;
    int x = 0, start = str.length() - WIDTH;
    for (; start > first; start -= WIDTH) {
        sscanf(str.substr(start, WIDTH).c_str(), "%d", &x);
        s.push_back(x);
    }
    sscanf(str.substr(first, start + WIDTH - first).c_str(), "%d", &x);
    s.push_back(x);
    return *this;
}

BigInteger BigInteger::operator+() const { return *this; }
BigInteger BigInteger::operator-() const {
    BigInteger c(*this);
    c.sign *= -1;
    return c;
}

BigInteger operator+(const BigInteger &a, const BigInteger &b) {
    BigInteger c;
    c.s.clear();
    int i = 0, g = 0, length_min = min(a.s.size(), b.s.size());
    for (; i < length_min; i++) {
        int x = g + a.sign * a.s[i] + b.sign * b.s[i];
        c.s.push_back(x % BigInteger::BASE);
        g = x / BigInteger::BASE;
    }
    for (; i < a.s.size(); i++) {
        int x = g + a.sign * a.s[i];
        c.s.push_back(x % BigInteger::BASE);
        g = x / BigInteger::BASE;
    }
    for (; i < b.s.size(); i++) {
        int x = g + b.sign * b.s[i];
        c.s.push_back(x % BigInteger::BASE);
        g = x / BigInteger::BASE;
    }
    for (; g; i++) {
        c.s.push_back(g & BigInteger::BASE);
        g /= BigInteger::BASE;
    }
    c.__defragment();
    return c;
}
BigInteger operator-(const BigInteger &a, const BigInteger &b) { return a + (-b); }
BigInteger operator*(const BigInteger &a, const BigInteger &b) {
    BigInteger c;
    c.s.resize(a.s.size() + b.s.size());
    c.sign = a.sign * b.sign;
    for (int i = 0; i < a.s.size(); i++) {
        int g = 0, j = 0;
        for (; j < b.s.size(); j++) {
            long long x = c.s[i + j] + g;
            x += (long long)a.s[i] * b.s[j];
            c.s[i + j] = x % BigInteger::BASE;
            g = x / BigInteger::BASE;
        }
        while (g) {
            long long x = c.s[i + j] + g;
            c.s[i + j] = x % BigInteger::BASE;
            g = x / BigInteger::BASE;
        }
    }
    while (c.s.size() > 1 && !*(c.s.end() - 1)) c.s.pop_back();
    return c;
}
BigInteger operator/(const BigInteger &init_a, const BigInteger &init_b) {
    if (init_b.s.size() == 0 || init_b.s.size() == 1 && init_b.s[0] == 0) throw("Divided by zero.");
    BigInteger a(init_a), b(init_b);
    BigInteger c;
    c.s.resize(a.s.size());
    c.sign = a.sign * b.sign;
    a.sign = b.sign = 1;
    for (int i = a.s.size() - b.s.size(); i >= 0; i--) {
        int l = 0, r = BigInteger::BASE - 1;
        int mid = (l + r + 1) >> 1;
        BigInteger d;
        for (; l < r; mid = (l + r + 1) >> 1) {
            d = __BigInteger_shift(b * mid, i);
            if (a > d)
                l = mid;
            else
                r = mid - 1;
        }
        a = a - __BigInteger_shift(b * l, i);
        c.s[i] = l;
    }
    while (c.s.size() > 1 && !*(c.s.end() - 1)) c.s.pop_back();
    return c;
}
BigInteger operator%(const BigInteger &init_a, const BigInteger &init_b) {
    if (init_b.s.size() == 0 || init_b.s.size() == 1 && init_b.s[0] == 0) throw("Divided by zero.");
    BigInteger a(init_a), b(init_b);
    int _a_sign = a.sign;
    a.sign = b.sign = 1;
    for (int i = a.s.size() - b.s.size(); i >= 0; i--) {
        int l = 0, r = BigInteger::BASE - 1;
        int mid = (l + r + 1) >> 1;
        BigInteger d;
        for (; l < r; mid = (l + r + 1) >> 1) {
            d = __BigInteger_shift(b * mid, i);
            if (a > d)
                l = mid;
            else
                r = mid - 1;
        }
        a = a - __BigInteger_shift(b * l, i);
    }
    while (a.s.size() > 1 && !*(a.s.end() - 1)) a.s.pop_back();
    a.sign = _a_sign;
    return a;
}

BigInteger BigInteger::operator+=(const BigInteger &b) { return *this = *this + b; }
BigInteger BigInteger::operator-=(const BigInteger &b) { return *this = *this - b; }
BigInteger BigInteger::operator*=(const BigInteger &b) { return *this = *this * b; }
BigInteger BigInteger::operator/=(const BigInteger &b) { return *this = *this / b; }
BigInteger BigInteger::operator%=(const BigInteger &b) { return *this = *this % b; }

bool operator<(const BigInteger &a, const BigInteger &b) {
    if (a.sign < b.sign) return true;
    if (a.s.size() != b.s.size())
        return a.sign * a.s.size() < b.sign * b.s.size();
    else
        for (int i = a.s.size() - 1; i >= 0; i--)
            if (a.s[i] != b.s[i]) return a.sign * a.s[i] < b.sign * b.s[i];
    return false;
}
bool operator>(const BigInteger &a, const BigInteger &b) { return b < a; }
bool operator==(const BigInteger &a, const BigInteger &b) { return !(a < b) && !(b < a); }
bool operator<=(const BigInteger &a, const BigInteger &b) { return !(b < a); }
bool operator>=(const BigInteger &a, const BigInteger &b) { return !(a < b); }

ostream &operator<<(ostream &out, const BigInteger &x) {
    if (x.sign == -1) out << '-';
    out << x.s.back();
    for (int i = x.s.size() - 2; i >= 0; i--) {
        char buf[20];
        sprintf(buf, "%08d", x.s[i]);
        for (int j = 0; j < strlen(buf); j++) out << buf[j];
    }
    return out;
}
istream &operator>>(istream &in, BigInteger &x) {
    string s;
    if (!(in >> s)) return in;
    x = s;
    return in;
}

void BigInteger::__defragment() {
    while (s.size() > 1 && !s[s.size() - 1]) s.pop_back();
    int len = s.size();
    sign = s[len - 1] >= 0 ? 1 : -1;
    s[len - 1] *= sign;
    for (int i = 0; i < len - 1; i++) {
        s[i] *= sign;
        if (s[i] >= 0) continue;
        s[i + 1] -= sign; // 借位
        s[i] += BASE;
    }
    while (s.size() > 1 && !s[s.size() - 1]) s.pop_back();
}

int main() {
    BigInteger y;
    BigInteger x = y;
    BigInteger z = -12356789012345678ll;
    cout << z << "\n";

    BigInteger a, b;
    cin >> a >> b;
    cout << a + b << "\n";
    cout << a - b << "\n";
    cout << a * b << "\n";
    cout << a / b << "\n";
    cout << a % b << "\n";

    return 0;
}

高精度算法原理简单但代码实现繁琐,编程时还得充分考虑各种特殊情况。敲一遍高精度能充分锻炼代码能力,实乃居家旅行赛前必备

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值