模板:高精度

一个普普通通的压位大整数类,包含以下功能:(在使用时尽可能删减并调整合适的常数以达到效率最高)

  1. 通过整型、字符串赋值与初始化方式 (默认初值为0)

    Bign a(2147483648);
    
    a="234566464322469989856";
    
  2. 大整数类与大整数类大整数类与整型加、减、乘

    乘法未经过FFT优化 ( to-do++ )

    Bign a,b;ll x;
    
    a*b+x-a;//混合类型运算时运算顺序不变但请不要将整型置于算式首:((a*b)+x)-a
    
  3. 大整数类与整型除、取余

    Bign a;ll b;
    
    a/b+a%b;
    
  4. 大整数与大整数除、取余 (这里用的是倍增优化,FFT我太蒻了看不懂,可能会很慢慎用)

    Bign a,b;
    
    a/b;
    
  5. 大整数类的位移操作 (这玩意建议最多不要位移超过10位,但对于少量的位移,效率还是会更高一点)

    Bign a;
    
    a<<1;
    
  6. 大整数类与大整数类各运算对应的赋值运算

    Bign a,b;
    
    a*=b;
    
  7. 大整数类与大整数类大整数类与整型比较运算

    Bign a,b;ll c;
    
    if(a<=b || (a!=c && a>b))
    
  8. 大整数类 通过 cin、cout的输入输出

    Bign a;
    
    cin>>a;
    
    cout<<a+1<<endl;
    

注意在使用时需要用到以下常量:

  1. 
    const int MX_LEN=1010;
    

    决定大整数类内数组大小,影响空间复杂度的主要因素,数值越大运算(越容易)越慢

  2. 
    const int BASE=10000;
    

    决定大整数类压位大小(每一个数组元素表示的最大值+1),数值越大运算(总体上)越快。推荐使用10000 ( (10^4) ):既可使BASE尽可能大,同时保证两个大整数类进行乘法运算时不会溢出.当然如果想改成longlong推荐就是100000000 ( (10^8) )

    最大表示范围为(displaystyle 10^{ mbox{MX_LEN} * lg(mbox{BASE}) })​ ,默认是(10^{1010*4}=10^{4040})​​​​

以及需要以下函数

  1. 
    int _max(int a,int b){return (a>b?a:b);}
    
    

以及在数据10^10000以上时需要手动扩栈:


#pragma comment(linker, "/STACK:10240000,10240000")

模板代码如下:

无负数版

const int BASE = 10000;
const int MX_LEN = 1010;
struct Bign {
    int num[MX_LEN];
    int len;
    Bign() {
        memset(num, 0, sizeof(num));
        len = 1;
    }
    Bign(const ll x) { *this = x; }
    Bign(const string x) { *this = x; }
    Bign(const Bign& x) {
        memset(num, 0, sizeof(num));
        len = x.len;
        for (int i = 0; i < len; i++)
            num[i] = x.num[i];
    }
    void clean() {
        while (num[len - 1] == 0 && len != 1)
            len--;
    }
    Bign operator = (const ll x) {
        stringstream ss;
        ss << x;
        string temp;
        ss >> temp;
        return *this = temp;
    }
    Bign operator = (const string x) {
        len = 0;
        memset(num, 0, sizeof(num));
        ll temp = 0;
        ll base = 1;
        for (int i = x.length() - 1; i >= 0; i--) {
            temp += (x[i] - '0') * base;
            base *= 10;
            if (base == BASE) {
                num[len++] = temp;
                temp = 0;
                base = 1;
            }
        }
        num[len++] = temp;
        clean();
        return *this;
    }
    Bign operator + (const Bign& b) const {
        Bign c;
        c.len = _max(len, b.len) + 1;
        for (int i = 0; i < c.len; i++) {
            c.num[i] += num[i] + b.num[i];
            c.num[i + 1] += c.num[i] / BASE;
            c.num[i] %= BASE;
        }
        c.clean();
        return c;
    }
    Bign operator - (const Bign& b) const {//a-b保证a>b
        Bign c;
        c.len = _max(len, b.len);
        for (int i = 0; i < c.len; ++i) {
            c.num[i] += num[i] - b.num[i];
            if (c.num[i] < 0) {
                c.num[i] += BASE;
                c.num[i + 1] -= 1;
            }
        }
        c.clean();
        return c;
    }
    Bign operator << (const int& num) const {
        Bign c = *this;
        c.len += 10;
        for (R int i = 0; i < c.len; ++i) {
            c.num[i] <<= num;
            if (i && c.num[i - 1] >= BASE)
                ++c.num[i], c.num[i - 1] -= BASE;
        }
        c.clean();
        return c;
    }
    Bign operator >> (const int& num) const {
        Bign c = *this;
        for (R int i = len - 1; i >= 0; --i) {
            if ((c.num[i] & 1) && i)
                c.num[i - 1] += BASE;
            c.num[i] >>= num;
        }
        c.clean();
        return c;
    }
    Bign operator * (const Bign& b) const {
        Bign c;
        c.len = len + b.len + 5;
        for (int i = 0; i < c.len; ++i) {
            for (int j = 0; j < b.len; ++j) {
                c.num[i + j] += num[i] * b.num[j];
                c.num[i + j + 1] += c.num[i + j] / BASE;
                c.num[i + j] %= BASE;
            }
        }
        c.clean();
        return c;
    }
    Bign operator / (const ll& b) const { //大数除以long long
        Bign c;
        c.len = len;
        ll rest = 0;
        for (int i = len - 1; i >= 0; --i) {
            rest = rest * BASE + num[i];
            c.num[i] = rest / b;
            rest %= b;
        }
        c.clean();
        return c;
    }
    Bign operator / (const Bign& b) const {
        Bign c, rest, now, _base;
        now = *this;
        rest = b;
        _base = 1;
        while (now >= rest) {
            rest = rest << 1;
            _base = _base << 1;
        }
        while (_base.len > 1 || _base.num[0]) {
            if (now >= rest) {
                now -= rest;
                c += _base;
            }
            rest = rest >> 1;
            _base = _base >> 1;
        }
        c.clean();
        return c;
    }
    Bign operator % (const ll& b) const {
        return (*this) - ((*this) / b) * b;
    }
    Bign operator % (const Bign& b) const {
        return (*this) - ((*this) / b) * b;
    }
    Bign operator += (const Bign& b) {
        return (*this) = (*this) + b;
    }
    Bign operator -= (const Bign& b) {
        return (*this) = (*this) - b;
    }
    Bign operator *= (const Bign& b) {
        return (*this) = (*this) * b;
    }
    Bign operator /= (const ll& b) {
        return (*this) = (*this) / b;
    }
    Bign operator /= (const Bign& b) {
        return (*this) = (*this) / b;
    }
    Bign operator %= (const ll& b) {
        return (*this) = (*this) % b;
    }
    Bign operator %= (const Bign& b) {
        return (*this) = (*this) % b;
    }
    bool operator < (const Bign& b) const {
        if (len == b.len) {
            for (int i = len - 1; i >= 0; --i) {
                if (num[i] != b.num[i])
                    return num[i] < b.num[i];
            }
            return 0;
        }
        return len < b.len;
    }
    bool operator > (const Bign& b) const {
        if (len == b.len) {
            for (int i = len - 1; i >= 0; --i) {
                if (num[i] != b.num[i])
                    return num[i] > b.num[i];
            }
            return 0;
        }
        return len > b.len;
    }
    bool operator == (const Bign& b) const {
        if (len == b.len) {
            for (int i = len - 1; i >= 0; --i) {
                if (num[i] != b.num[i])
                    return 0;
            }
            return 1;
        }
        return 0;
    }
    bool operator != (const Bign& b) const {
        return !((*this) == b);
    }
    bool operator <= (const Bign& b) const {
        return !((*this) > b);
    }
    bool operator >= (const Bign& b) const {
        return !((*this) < b);
    }
    friend ostream& operator << (ostream& out, const Bign& x) {
        out << x.num[x.len - 1];
        for (int i = x.len - 2; i >= 0; i--) {
            int t = BASE / 10;
            while (x.num[i] < t && t>1) {
                out << 0;
                t /= 10;
            }
            out << x.num[i];
        }
        return out;
    }
    friend istream& operator >> (istream& in, Bign& x) {
        string temp;
        in >> temp;
        x = temp;
        return in;
    }
};

整合负数版

struct Bign {
    ll num[MX_LEN];
    int len;
    int neg;
    Bign() {
        memset(num, 0, sizeof(num));
        len = 1;
        neg = 0;
    }
    Bign(const ll x) { *this = x; }
    Bign(const string x) { *this = x; }
    Bign(const Bign& x) {
        memset(num, 0, sizeof(num));
        len = x.len;
        neg = x.neg;
        for (R int i = 0; i < len; ++i)
            num[i] = x.num[i];
    }
    void clean() {
        while (num[len - 1] == 0 && len != 1)
            --len;
        if (len == 1 && num[0] == 0)
            neg = 0;
    }
    Bign operator = (const ll& x) {
        stringstream ss;
        ss << x;
        string temp;
        ss >> temp;
        return *this = temp;
    }
    Bign operator = (const string& x) {
        len = 0;
        memset(num, 0, sizeof(num));
        if (x[0] == '-')
            neg = 1;
        else
            neg = 0;
        ll temp = 0;
        ll base = 1;
        for (R int i = x.length() - 1; i >= neg; --i) {
            temp += (x[i] - '0') * base;
            base *= 10;
            if (base == BASE) {
                num[len++] = temp;
                temp = 0;
                base = 1;
            }
        }
        num[len++] = temp;
        clean();
        return *this;
    }
    Bign operator + (const Bign& b) const {
        if (neg ^ b.neg) {
            if (neg)
                return b - (-*this);
            else
                return (*this) - (-b);
        }
        else {
            Bign c;
            if (neg)
                c.neg = 1;
            c.len = _max(len, b.len) + 1;
            for (R int i = 0; i < c.len; ++i) {
                c.num[i] += num[i] + b.num[i];
                c.num[i + 1] += c.num[i] / BASE;
                c.num[i] %= BASE;
            }
            c.clean();
            return c;
        }
    }
    Bign operator - (const Bign& b) const {
        if (neg ^ b.neg) {
            if (neg)
                return -((-*this) + b);
            else
                return (*this) + (-b);
        }
        else {
            Bign c;
            if (neg)
                c.neg = 1;
            if (abs(*this) < abs(b)) {
                c.neg ^= 1;
                c.len = _max(len, b.len);
                for (R int i = 0; i < c.len; ++i) {
                    c.num[i] += b.num[i] - num[i];
                    if (c.num[i] < 0) {
                        c.num[i] += BASE;
                        c.num[i + 1] -= 1;
                    }
                }
                c.clean();
                return c;
            }
            else {
                c.len = _max(len, b.len);
                for (R int i = 0; i < c.len; ++i) {
                    c.num[i] += num[i] - b.num[i];
                    if (c.num[i] < 0) {
                        c.num[i] += BASE;
                        c.num[i + 1] -= 1;
                    }
                }
                c.clean();
                return c;
            }

        }
    }
    Bign operator - () const {
        Bign c = *this;
        c.neg ^= 1;
        return c;
    }
    Bign operator * (const Bign& b) const {
        Bign c;
        c.len = len + b.len + 1;
        for (R int i = 0; i < len; ++i) {
            for (R int j = 0; j < b.len; ++j) {
                c.num[i + j] += num[i] * b.num[j];
            }
        }
        for (R int i = 0; i < c.len; ++i) {
            c.num[i + 1] += c.num[i] / BASE;
            c.num[i] %= BASE;
        }
        if (neg ^ b.neg)
            c.neg = 1;
        c.clean();
        return c;
    }
    Bign operator / (const ll& b) const {
        Bign c;
        c.len = len;
        ll rest = 0;
        for (R int i = len - 1; i >= 0; --i) {
            rest = rest * BASE + num[i];
            c.num[i] = rest / b;
            rest %= b;
        }
        if (neg ^ (b < 0))
            c.neg = 1;
        c.clean();
        return c;
    }
    Bign operator / (const Bign& b) const {
        Bign c, rest, now, _base;
        now = abs(*this);
        rest = abs(b);
        _base = 1;
        while (now >= rest) {
            rest <<= 1;
            _base <<= 1;
        }
        while (_base.len > 1 || _base.num[0]) {
            if (now >= rest) {
                now -= rest;
                c += _base;
            }
            rest >>= 1;
            _base >>= 1;
        }
        if (neg ^ b.neg)
            c.neg = 1;
        c.clean();
        return c;
    }
    Bign operator << (const int& num) const {
        Bign c = *this;
        c.len += 10;
        for (R int i = 0; i < c.len; ++i) {
            c.num[i] <<= num;
            if (i && c.num[i - 1] >= BASE)
                ++c.num[i], c.num[i - 1] -= BASE;
        }
        c.clean();
        return c;
    }
    Bign operator >> (const int& num) const {
        Bign c = *this;
        for (R int i = len - 1; i >= 0; --i) {
            if ((c.num[i] & 1) && i)
                c.num[i - 1] += BASE;
            c.num[i] >>= num;
        }
        c.clean();
        return c;
    }
    Bign operator % (const ll& b) const {
        return (*this) - ((*this) / b) * b;
    }
    Bign operator % (const Bign& b) const {
        return (*this) - ((*this) / b) * b;
    }
    Bign operator += (const Bign& b) {
        return (*this) = (*this) + b;
    }
    Bign operator -= (const Bign& b) {
        return (*this) = (*this) - b;
    }
    Bign operator *= (const Bign& b) {
        return (*this) = (*this) * b;
    }
    Bign operator /= (const ll& b) {
        return (*this) = (*this) / b;
    }
    Bign operator /= (const Bign& b) {
        return (*this) = (*this) / b;
    }
    Bign operator %= (const ll& b) {
        return (*this) = (*this) % b;
    }
    Bign operator %= (const Bign& b) {
        return (*this) = (*this) % b;
    }
    Bign operator <<= (const int& num) {
        return (*this) = (*this) << num;
    }
    Bign operator >>= (const int& num) {
        return (*this) = (*this) >> num;
    }
    bool operator < (const Bign& b) const {
        if (neg && !b.neg)
            return 1;
        if (!neg && b.neg)
            return 0;
        if (neg) {
            if (len == b.len) {
                for (R int i = len - 1; i >= 0; --i) {
                    if (num[i] != b.num[i])
                        return num[i] > b.num[i];
                }
                return 0;
            }
            return len > b.len;
        }
        else {
            if (len == b.len) {
                for (R int i = len - 1; i >= 0; --i) {
                    if (num[i] != b.num[i])
                        return num[i] < b.num[i];
                }
                return 0;
            }
            return len < b.len;
        }
    }
    bool operator > (const Bign& b) const {
        if (neg && !b.neg)
            return 0;
        if (!neg && b.neg)
            return 1;
        if (neg) {
            if (len == b.len) {
                for (R int i = len - 1; i >= 0; --i) {
                    if (num[i] != b.num[i])
                        return num[i] < b.num[i];
                }
                return 0;
            }
            return len < b.len;
        }
        else {
            if (len == b.len) {
                for (R int i = len - 1; i >= 0; --i) {
                    if (num[i] != b.num[i])
                        return num[i] > b.num[i];
                }
                return 0;
            }
            return len > b.len;
        }
    }
    bool operator == (const Bign& b) const {
        if (neg != b.neg)
            return 0;
        if (len == b.len) {
            for (R int i = len - 1; i >= 0; --i) {
                if (num[i] != b.num[i])
                    return 0;
            }
            return 1;
        }
        return 0;
    }
    bool operator != (const Bign& b) const {
        return !((*this) == b);
    }
    bool operator <= (const Bign& b) const {
        return !((*this) > b);
    }
    bool operator >= (const Bign& b) const {
        return !((*this) < b);
    }
    friend Bign abs(const Bign& x) {
        Bign c = x;
        c.neg = 0;
        return c;
    }
    friend ostream& operator << (ostream& out, const Bign& x) {
        if (x.neg)
            out << '-';
        out << x.num[x.len - 1];
        for (R int i = x.len - 2; i >= 0; --i) {
            int t = BASE / 10;
            while (x.num[i] < t && t>1) {
                out << 0;
                t /= 10;
            }
            out << x.num[i];
        }
        return out;
    }
    friend istream& operator >> (istream& in, Bign& x) {
        string temp;
        in >> temp;
        x = temp;
        return in;
    }
};
原文地址:https://www.cnblogs.com/lazy-people/p/15134439.html