zoukankan      html  css  js  c++  java
  • 模板:高精度

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

    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;
        }
    };
    
  • 相关阅读:
    WPF Image Binding Uri Source 失败解决办法
    redis哈希表数据类型键的设置
    redis字符串类型键的二进制操作
    redis字符串类型的基本命令
    redis字符串数据类型基本概念和应用场景
    redis键的迁移操作
    redis键的排序操作
    Redis键的序列化和反序列化
    Redis过期命令
    Redis键的基本操作
  • 原文地址:https://www.cnblogs.com/lazy-people/p/15134439.html
Copyright © 2011-2022 走看看