压位高精度模板

struct BigInteger {
    static const int BASE = 100000000;
    static const int WIDTH = 8;
    vector<int> s;
    bool sign;

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

    void normalize() {
        while (s.size() > 1 && s.back() == 0) s.pop_back();
        if (s.size() == 1 && s[0] == 0) sign = false;
    }

    bool operator < (const BigInteger& b) const {
        if (sign != b.sign) return sign;
        if (s.size() != b.s.size()) 
            return sign ? s.size() > b.s.size() : s.size() < b.s.size();
        for (int i = s.size() - 1; i >= 0; i--)
            if (s[i] != b.s[i]) 
                return sign ? s[i] > b.s[i] : s[i] < b.s[i];
        return false;
    }
    
    bool operator > (const BigInteger& b) const { return b < *this; }
    bool operator <= (const BigInteger& b) const { return !(b < *this); }
    bool operator >= (const BigInteger& b) const { return !(*this < b); }
    bool operator != (const BigInteger& b) const { return b < *this || *this < b; }
    bool operator == (const BigInteger& b) const { return !(b < *this) && !(*this < b); }

    BigInteger operator + (const BigInteger& b) const {
        if (sign == b.sign) {
            BigInteger c;
            c.sign = sign;
            c.s.clear();
            for (int i = 0, g = 0; ; i++) {
                if (g == 0 && i >= s.size() && i >= b.s.size()) break;
                int x = g;
                if (i < s.size()) x += s[i];
                if (i < b.s.size()) x += b.s[i];
                c.s.push_back(x % BASE);
                g = x / BASE;
            }
            return c;
        } else {
            if (sign) {
                BigInteger temp = *this;
                temp.sign = false;
                return b - temp;
            } else {
                BigInteger temp = b;
                temp.sign = false;
                return *this - temp;
            }
        }
    }
    
    BigInteger operator - (const BigInteger& b) const {
        if (sign != b.sign) {
            BigInteger temp = b;
            temp.sign = !b.sign;
            return *this + temp;
        }
        
        if (*this == b) return BigInteger(0);
        
        BigInteger c;
        if ((!sign && *this > b) || (sign && *this < b)) {
            c = *this;
            for (int i = 0, g = 0; i < c.s.size() || i < b.s.size(); i++) {
                int x = c.s[i] - g;
                if (i < b.s.size()) x -= b.s[i];
                if (x < 0) {
                    g = 1;
                    x += BASE;
                } else {
                    g = 0;
                }
                if (i < c.s.size()) c.s[i] = x;
                else c.s.push_back(x);
            }
            c.normalize();
            c.sign = sign;
        } else {
            c = b - *this;
            c.sign = !sign;
        }
        return c;
    }

    BigInteger operator * (const BigInteger& b) const {
        BigInteger c;
        c.sign = (sign != b.sign);
        c.s.resize(s.size() + b.s.size(), 0);
        
        for (int i = 0; i < s.size(); i++) {
            long long g = 0;
            for (int j = 0; j < b.s.size() || g > 0; j++) {
                long long x = c.s[i + j] + g;
                if (j < b.s.size()) x += (long long)s[i] * b.s[j];
                c.s[i + j] = x % BASE;
                g = x / BASE;
            }
        }
        c.normalize();
        return c;
    }

    BigInteger operator / (const BigInteger& b) const {
        if (b == BigInteger(0)) throw "Division by zero";
        
        BigInteger c, current;
        c.sign = (sign != b.sign);
        c.s.resize(s.size(), 0);
        
        for (int i = s.size() - 1; i >= 0; i--) {
            current = current * BASE + s[i];
            
            int l = 0, r = BASE - 1, ans = 0;
            while (l <= r) {
                int mid = (l + r) / 2;
                if (b.abs() * mid <= current.abs()) {
                    ans = mid;
                    l = mid + 1;
                } else {
                    r = mid - 1;
                }
            }
            c.s[i] = ans;
            current = current - b.abs() * ans;
        }
        c.normalize();
        return c;
    }
    
    BigInteger operator / (int b) const {
        if (b == 0) throw "Division by zero";
        
        BigInteger c;
        c.sign = (sign != (b < 0));
        c.s.resize(s.size(), 0);
        
        if(b < 0) b = -b;
        long long r = 0;
        for (int i = s.size() - 1; i >= 0; i--) {
            r = r * BASE + s[i];
            c.s[i] = r / b;
            r %= b;
        }
        c.normalize();
        return c;
    }
    
    BigInteger abs() const {
        BigInteger result = *this;
        result.sign = false;
        return result;
    }

    BigInteger operator += (const BigInteger& b) { *this = *this + b; return *this; }
    BigInteger operator ++ (int) { BigInteger temp = *this; *this = *this + 1; return temp; }
    BigInteger operator ++ () { *this = *this + 1; return *this; }
    BigInteger operator -= (const BigInteger& b) { *this = *this - b; return *this; }
    BigInteger operator -- (int) { BigInteger temp = *this; *this = *this - 1; return temp; }
    BigInteger operator -- () { *this = *this - 1; return *this; }
    BigInteger operator *= (const BigInteger& b) { *this = *this * b; return *this; }
    BigInteger operator /= (const BigInteger& b) { *this = *this / b; return *this; }
    
    friend ostream& operator << (ostream& out, const BigInteger& x) {
        if (x.sign && !(x.s.size() == 1 && x.s[0] == 0)) out << '-';
        out << x.s.back();
        for (int i = x.s.size() - 2; i >= 0; i--) {
            char buf[20];
            sprintf(buf, "%08d", x.s[i]);
            out << buf;
        }
        return out;
    }
    
    friend istream& operator >> (istream& in, BigInteger& x) {
        string s;
        if (!(in >> s)) return in;
        x = s;
        return in;
    }
};
posted @ 2024-05-06 17:10  Ke_scholar  阅读(92)  评论(3)    收藏  举报