RocksonLee's Blog
avatar
RocksonLee
2021-10-08 22:09:20
  • 本文总阅读量

代码

#include <bits/stdc++.h>
using namespace std;

#define il inline
#define INF 0x3f3f3f3f
#define cl(a, b) memset(a, b, sizeof(a))
typedef long long ll;
typedef unsigned long long ull;

static const int LEN = 10010;

struct BIGNUM
{
    typedef long long ll;
    static const int LEN = 10010;     // LEN 最大位数
    static const int BIT = 9;         // BIT 压位位数
    static const ll MOD = 1000000000; // MOD = 1eBIT

    ll s[LEN]; // num[0] 存储长度
    bool flag; // flag 存储正负

    void clear()
    {
        memset(s, 0, sizeof(s));
        flag = true;
        s[0] = 1;
    }

    // 重载赋值以及初始化

    BIGNUM operator=(const char *num)
    {
        int len = strlen(num);
        s[0] = 0;
        for (int i = len - 1; i >= 0; i -= BIT)
        {
            ++s[0];   // s[0] 当前操作位||位数
            ll w = 1; // w 为 s[now] 操作位置的 base
            s[s[0]] = 0;
            for (int j = i; j > i - BIT && j >= 0; j--)
            {
                s[s[0]] += (num[j] ^ 48) * w; // s[now] += num[j] * w;
                w = (w << 1) + (w << 3);      // w *= 10;
            }
        }
        return *this;
    }
    BIGNUM operator=(const int num)
    {
        char temp[LEN];
        flag = (num >= 0);
        sprintf(temp, "%d", (num > 0 ? num : -num));
        *this = temp;
        return *this;
    };
    BIGNUM()
    {
        clear();
    }
    BIGNUM(int num)
    {
        *this = num;
    }
    BIGNUM(const char *num)
    {
        *this = num;
    }

    // 重载关系运算符

    bool operator==(const BIGNUM &a)
    {
        if (s[0] != a.s[0]) return false;
        for (int i = s[0]; i >= 1; i--)
            if (s[i] != a.s[i]) return false; // 如果有不相同就是 false
        return true;
    }
    bool operator>(const BIGNUM &a)
    {
        if (s[0] != a.s[0]) return s[0] > a.s[0];
        for (int i = s[0]; i >= 1; i--)
            if (s[i] != a.s[i]) return s[i] > a.s[i];
        return false; // 相同也是 false
    }
    bool operator<(const BIGNUM &a)
    {
        if (s[0] != a.s[0]) return s[0] < a.s[0];
        for (int i = s[0]; i >= 1; i--)
            if (s[i] != a.s[i]) return s[i] < a.s[i];
        return false; // 相同也是 false
    }
    bool operator>=(const BIGNUM &a)
    {
        if (*this > a || *this == a)
            return true;
        else
            return false;
    }
    bool operator<=(const BIGNUM &a)
    {
        if (*this < a || *this == a)
            return true;
        else
            return false;
    }
    bool operator!=(const BIGNUM &a)
    {
        return !(*this == a);
    }

    // 重载算术运算符

    BIGNUM operator+(const BIGNUM &a)
    {
        BIGNUM c;
        int x = 0; // 存储进位的辅助变量
        c.s[0] = max(a.s[0], s[0]) + 1;
        for (int i = 1; i <= c.s[0]; i++)
        {
            c.s[i] = a.s[i] + s[i] + x;
            // 压位高精思想 10进制 转换为 10^BIT 进制
            x = c.s[i] / MOD;
            c.s[i] %= MOD;
        }
        while (c.s[c.s[0]] == 0 && c.s[0] > 1) c.s[0]--; // 去除前导零
        return c;
    }
    BIGNUM operator+=(const BIGNUM &a)
    {
        *this = *this + a;
        return *this;
    }
    BIGNUM operator-(const BIGNUM &a)
    {
        BIGNUM c;
        c.s[0] = max(a.s[0], s[0]) + 1;
        if (*this < a) c.flag = false; // 负数标志
        for (int i = 1; i <= c.s[0]; i++)
        {
            if (c.flag)
                c.s[i] += s[i] - a.s[i];
            else
                c.s[i] += a.s[i] - s[i];
            if (c.s[i] < 0)
            {
                c.s[i] += MOD;
                c.s[i + 1]--; // 借位
            }
        }
        while (c.s[c.s[0]] == 0 && c.s[0] > 1) c.s[0]--; // 去除前导零
        return c;
    }
    BIGNUM operator-=(const BIGNUM &a)
    {
        *this = *this - a;
        return *this;
    }
    BIGNUM operator*(const BIGNUM &a)
    {
        BIGNUM c;
        c.s[0] = s[0] + a.s[0];
        for (int i = 1; i <= s[0]; i++)
        {
            int x = 0; // 存储进位的辅助变量
            for (int j = 1; j <= a.s[0]; j++)
            {
                c.s[i + j - 1] += s[i] * a.s[j] + x;
                x = c.s[i + j - 1] / MOD;
                c.s[i + j - 1] %= MOD;
            }
            c.s[i + a.s[0]] = x;
        }
        while (c.s[c.s[0]] > 0) c.s[0]++;                // 正确调整位数
        while (c.s[c.s[0]] == 0 && c.s[0] > 1) c.s[0]--; // 去除前导零
        return c;
    }
    BIGNUM operator*=(const BIGNUM &a)
    {
        *this = *this * a;
        return *this;
    }

    // 重载位运算符
    // 倍增优化减法模拟的除法时需要用

    BIGNUM operator<<(const int &num)
    {
        s[0]++;
        for (int j = 1; j <= num; j++)
        {
            for (int i = 1; i <= s[0]; i++)
            {
                s[i] <<= 1;
                if (s[i - 1] >= MOD)
                    s[i - 1] -= MOD, ++s[i];
            }
            if (s[s[0]] > 0) s[0]++;
        }
        while (s[s[0]] == 0 && s[0] > 1) s[0]--;
        return *this;
    }
    BIGNUM operator>>(const int &num)
    {
        for (int j = 1; j <= num; j++)
        {
            for (int i = s[0]; i >= 1; i--)
            {
                if ((s[i] & 1) && i > 1) s[i - 1] += MOD;
                s[i] >>= 1;
            }
        }
        while (s[s[0]] == 0 && s[0] > 1) s[0]--;
        return *this;
    }

    BIGNUM operator/(const BIGNUM &k)
    {
        BIGNUM c = *this, temp, It, a;
        a = k;
        temp.s[1] = 1;
        // a 为 k ^ 2 ^ x , temp 为 2 ^ x
        while (c >= a)
        {
            a = a << 1;
            temp = temp << 1;
        }
        while (temp.s[0] > 1 || temp.s[1])
        {
            if (c >= a)
            {
                c -= a;
                It += temp; // It 为当前商
            }
            a = a >> 1;
            temp = temp >> 1;
        }
        c = It;                                          // 注意,此时 a 为余数
        while (c.s[c.s[0]] == 0 && c.s[0] > 1) c.s[0]--; // 去除前导零
        if (c.s[0] < 1) c.s[c.s[0] = 1] = 0;
        return c;
    }
    BIGNUM operator/=(const BIGNUM &a)
    {
        *this = *this / a;
        return *this;
    }
    BIGNUM operator%(const BIGNUM &a)
    {
        BIGNUM d = *this, c = *this / a;
        c *= a;
        return d - c;
    }
    BIGNUM operator%=(const BIGNUM &a)
    {
        *this = *this % a;
        return *this;
    }
};

ostream &operator<<(ostream &out, const BIGNUM &a)
{
    if (!a.flag) putchar('-');
    //读出时先把第一组BIT位数输出
    //之后的每一组数不足BIT位的要在左边补零
    printf("%lld", a.s[a.s[0]]);
    for (int i = a.s[0] - 1; i >= 1; i--)
        printf("%09lld", a.s[i]);
    return out;
}
istream &operator>>(istream &in, BIGNUM &a)
{
    char str[LEN];
    in >> str;
    a = str;
    return in;
}

BIGNUM a, b;

int main()
{
    cin >> a >> b;
    cout << a + b << endl;
    cout << a - b << endl;
    cout << a * b << endl;
    cout << a / b << endl;
    cout << a % b << endl;
    return 0;
}
高精模板
comment评论
Search
search