高精全家桶

Star 2022-09-05 11:38:48 2022-09-05 11:39:35

微机课摸鱼

#include <cstdio>
#include <cctype>
#include <cstring>
#include <cmath>
#include <iostream>

using namespace std;

struct Gaojing
{
    #define ll long long
    #define MAXN 22000

    int a[MAXN];
    int l, op;

    Gaojing() {
        memset(a, 0, sizeof(a));
        l = op = 1;
    }

    Gaojing mulpower(const Gaojing& _, const int& i) const { // 乘以 10^i
        Gaojing res;
        res.l = _.l + i;
        memcpy(res.a + i, _.a, _.l * 4); // 直接将数组向右偏移i位赋值即可 
        return res;
    }

    friend istream& operator >> (istream& cin, Gaojing& _) { // 读入流
        static char s[MAXN];
        scanf("%s", s);
        _.l = strlen(s);
        for (int i = 0; i < _.l; ++i) {
            _.a[i] = s[_.l - i - 1] - '0'; // 倒着存 
        }
        return cin;
    }

    friend ostream& operator << (ostream& cout, const Gaojing& _) { // 输出流
        if (_.op == -1) putchar('-'); // 特判负数 
        for (int i = _.l - 1; i >= 0; --i) { // 倒着输出 
            putchar(_.a[i] + 48);
        }
        return cout;
    }

    bool operator <(const Gaojing& _) const { // 小于号
        if (l != _.l) return l < _.l;
        else {
            for (int i = l - 1; i >= 0; --i) {
                if (a[i] != _.a[i]) return a[i] < _.a[i];
            }
        }
        return false; // 两个数一样,返回false 
    }

    bool operator <=(const Gaojing& _) const { // 小于等于
        if (l != _.l) return l < _.l;
        else {
            for (int i = l - 1; i >= 0; --i) {
                if (a[i] != _.a[i]) return a[i] < _.a[i];
            }
        }
        return true; // 两个数一样,返回true 
    }

    bool operator >(const Gaojing& _) const { // 大于号
        if (l != _.l) return l > _.l;
        else {
            for (int i = l - 1; i >= 0; --i) {
                if (a[i] != _.a[i]) return a[i] > _.a[i];
            }
        }
        return false;
    }

    bool operator >=(const Gaojing& _) const { // 大于等于
        if (l != _.l) return l > _.l;
        else {
            for (int i = l - 1; i >= 0; --i) {
                if (a[i] != _.a[i]) return a[i] > _.a[i];
            }
        }
        return true;
    }

	// 高精度加法,直接从低到高按位相加即可,注意进位 
    Gaojing operator +(const Gaojing& _) const {
        Gaojing c;
        c.l = max(l, _.l);
        for (int i = 0; i < c.l; ++i) {
            c.a[i] += a[i] + _.a[i];
            c.a[i + 1] += c.a[i] / 10;
            c.a[i] %= 10;
        }
        if (c.l && !c.a[c.l]) --c.l; // 前导零 
        ++c.l;
        return c;
    }

	// 高精度减法,直接从低到高按位相减即可,注意特判负数 
    Gaojing operator -(const Gaojing& _) const {
        Gaojing c; // 把当前的数复制给c 
        memcpy(c.a, a, l * 4);
        c.l = l;
        if (c < _) { // 特判负数 
            c = _ - c; // 我现在才发现重载运算符也能递归 
            c.op = -1;
            return c;
        }
        for (int i = 0; i < l; ++i) {
            if (c.a[i] < _.a[i]) c.a[i] += 10, c.a[i + 1] -= 1; // 不够减就向前借1
            c.a[i] -= _.a[i];
        }
        while (c.l && !c.a[c.l]) --c.l; // 前导零 
        ++c.l;
        return c;
    }

	// 高精度乘法,a的第i位和b的第j位相乘,加到答案的i + j 位上即可 ,注意进位 
    Gaojing operator *(const Gaojing& _) const {
        Gaojing c;
        c.l = l + _.l; // 最坏情况位数是 a.l + b.l - 1 
        for (int i = 0; i < l; ++i) {
            for (int j = 0; j < _.l; ++j) {
                c.a[i + j] += a[i] * _.a[j]; // 先全加上,最后进位 
            }
        }
        for (int i = 0; i < c.l; ++i) { // 进位 
            c.a[i + 1] += c.a[i] / 10;
            c.a[i] %= 10;
        }
        while (!c.a[c.l] && c.l) --c.l; // 前导零 
        ++c.l;
        return c;
    }

	// 高精除以低精,模拟除法竖式 
    Gaojing operator /(const int& b) const {
        Gaojing c;
        c.l = l;
        ll now = 0;
        for (int i = l - 1; i >= 0; --i) {
            now = now * 10 + a[i];
            if (now < b) continue;
            c.a[i] = now / b;
            now %= b;
        }
        while (c.l && !c.a[c.l]) --c.l;
        ++c.l;
        return c;
    }

	// 高精除以高精,最高位对齐,试减 
    Gaojing operator /(const Gaojing& _) const {
        if (l < _.l) return Gaojing(); // 被除数小于除数,直接输出0 
        Gaojing t, c, now;
        memcpy(t.a, a, l * 4); // 复制被除数,不破坏原数 
        t.l = c.l = l;
        for (int i = l - _.l; i >= 0; --i) {
            now = mulpower(_, i);
            while (now <= t) { // 一直减到不能减,模拟试除的过程,答案累加到当前末位上 
                t = t - now;
                c.a[i] ++;
            }
        }
        while (c.l && !c.a[c.l]) --c.l;
        ++c.l;
        return c;
    }

	// 取模和除法一样,输出减完剩下的 
    Gaojing operator %(const Gaojing& _) const {
        Gaojing t, now;
        memcpy(t.a, a, l * 4);
        t.l = l;
        for (int i = l - _.l; i >= 0; --i) {
            now = mulpower(_, i);
            while (now <= t) {
                t = t - now;
            }
        }
        while (t.l && !t.a[t.l]) --t.l;
        ++t.l;
        return t;
    }
};

int main() {
    Gaojing a, b; // 声明
    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;
}