高精度求除法&hack(悬赏关注)
  • 板块学术版
  • 楼主FlowerAccepted
  • 当前回复5
  • 已保存回复5
  • 发布时间2025/1/19 19:31
  • 上次更新2025/1/19 22:05:20
查看原帖
高精度求除法&hack(悬赏关注)
1023732
FlowerAccepted楼主2025/1/19 19:31

蒟蒻我手撸高精度带符号整数快300行代码,结构体+重载,加减乘都写了,就差除,求大佬教一教,多谢多谢!(悬赏关注)

另外如果在三则运算中看出问题,也请给个hack和解决补丁(悬赏关注++)

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

#define digit short
#define pos 1
#define zero 0
#define nag -1

const int MAXN = 1000 /*Max digits here*/ + 5;

struct Big_int {
    digit a[MAXN] = {};
    short sign = zero;
    int n = 0;
    
    digit& operator [] (int i) {
        return a[i];
    }
    
    void operator = (int x) {
        memset(a, 0, sizeof(a));
        if (x == 0) {
            sign = zero;
            n = 0;
            return;
        } else if (x < 0) {
            x = abs(x);
            sign = nag;
        } else {
            sign = pos;
        }
        for (n = 1; x; n ++) {
            a[n] = x % 10;
            x /= 10;
        }
        n --;
    }
    
    void operator = (string x) {
        memset(a, 0, sizeof(a));
        if (x == "0") {
            sign = zero;
            n = 0;
            return;
        } else if (x[0] == '-') {
            x = x.substr(1);
            sign = nag;
        } else {
            sign = pos;
        }
        n = (int)x.size();
        for (int i = 1, j = n - 1; i <= n; i ++, j --) {
            a[i] = x[j] - '0';
        }
    }
    
    void operator = (Big_int x) {
        memset(a, 0, sizeof(a));
        sign = x.sign;
        n = x.n;
        for (int i = 1; i <= n; i ++) {
            a[i] = x[i];
        }
    }
    
    void read() {
        string x;
        cin >> x;
        memset(a, 0, sizeof(a));
        if (x == "0") {
            sign = zero;
            n = 0;
            return;
        } else if (x[0] == '-') {
            x = x.substr(1);
            sign = nag;
        } else {
            sign = pos;
        }
        n = (int)x.size();
        for (int i = 1, j = n - 1; i <= n; i ++, j --) {
            a[i] = x[j] - '0';
        }
    }
    
    void print() {
        if (sign == zero) {
            putchar('0');
            return;
        }
        if (sign == nag) {
            putchar('-');
        }
        for (int i = n; i; i --) {
            putchar(a[i] + '0');
        }
    }
    
    void printw(int w, char fill = '0') {
        if (sign == nag) {
            putchar('-');
        }
        for (int i = 1; i <= w - n - (sign == pos ? 0 : 1); i ++) {
            putchar(fill);
        }
        if (sign == zero) {
            putchar('0');
            return;
        }
        for (int i = n; i; i --) {
            putchar(a[i] + '0');
        }
    }
    
    void fix() {
        for (int i = 1; i <= n; i ++) {
            a[i + 1] += a[i] / 10;
            a[i] %= 10;
        }
        while (a[n + 1]) {
            n ++;
            a[n + 1] += a[n] / 10;
            a[n] %= 10;
        }
        while (!a[n]) {
            n --;
        }
    }
};

bool operator == (Big_int x, Big_int y) {
    if (x.sign != y.sign || x.n != y.n) {
        return 0;
    }
    for (int i = 1; i <= x.n; i ++) {
        if (x[i] != y[i]) {
            return 0;
        }
    }
    return 1;
}

bool operator < (Big_int x, Big_int y) {
    if (x.sign < y.sign || x.n < y.n) {
        return 1;
    }
    if (x.sign > y.sign || x.n > y.n) {
        return 0;
    }
    for (int i = 1; i <= x.n; i ++) {
        if (x[i] < y[i]) {
            return 1;
        }
        if (x[i] > y[i]) {
            return 0;
        }
    }
    return 0;
}

bool operator > (Big_int x, Big_int y) {
    if (x.sign < y.sign || x.n < y.n) {
        return 0;
    }
    if (x.sign > y.sign || x.n > y.n) {
        return 1;
    }
    for (int i = 1; i <= x.n; i ++) {
        if (x[i] < y[i]) {
            return 0;
        }
        if (x[i] > y[i]) {
            return 1;
        }
    }
    return 0;
}

bool operator <= (Big_int x, Big_int y) {
    return x < y || x == y;
}

bool operator >= (Big_int x, Big_int y) {
    return x > y || x == y;
}

Big_int abs(Big_int x) {
    Big_int r = x;
    r.sign = pos;
    return r;
}

Big_int unsignedplus(Big_int x, Big_int y) { // not safe!
    Big_int r;
    r.n = max(x.n, y.n);
    for (int i = 1; i <= r.n; i ++) {
        r[i] = x[i] + y[i];
    }
    r.fix();
    return r;
}

Big_int unsignedsubt(Big_int x, Big_int y) { // not safe!
    Big_int r;
    r.n = max(x.n, y.n);
    for (int i = 1; i <= r.n; i ++) {
        if (x[i] - y[i] + r[i] < 0) {
            r[i] += x[i] + 10 - y[i];
            r[i + 1] --;
        } else {
            r[i] += x[i] - y[i];
        }
    }
    r.fix();
    return r;
}

Big_int operator + (Big_int x, Big_int y) {
    if (x.sign == zero) {
        return y;
    }
    if (y.sign == zero) {
        return x;
    }
    Big_int r;
    if (x.sign == y.sign) {
        r = unsignedplus(x, y);
        r.sign = x.sign;
    } else {
        Big_int t = abs(x), u = abs(y); // |x| |y|
        if (t > u) {
            r = unsignedsubt(t, u);
            r.sign = x.sign;
        } else if (t == u) { // x + (-x) = 0
            r = 0;
        } else {
            r = unsignedsubt(u, t);
            r.sign = y.sign;
        }
    }
    return r;
}

Big_int operator - (Big_int x, Big_int y) { // x - y = x + (-y)
    y.sign = -y.sign;
    return x + y;
}

Big_int unsignedmult(Big_int x, Big_int y) { // not safe!
    Big_int r;
    r.n = x.n + y.n - 1;
    for (int i = 1; i <= x.n; i ++) {
        for (int j = 1; j <= y.n; j ++) {
            r[i + j - 1] += x[i] * y[j];
        }
    }
    r.fix();
    return r;
}

Big_int operator * (Big_int x, Big_int y) {
    Big_int r;
    if (x.sign == zero || y.sign == zero) {
        return r;
    }
    r = unsignedmult(x, y);
    r.sign = (x.sign == y.sign ? pos : nag);
    return r;
}

Big_int operator >> (Big_int x, int y) { // x / 10 ^ y
    Big_int r;
    r.n = x.n - y;
    r.sign = x.sign;
    for (int i = x.n; i > y; i --) {
        r[i - y] = x[i];
    }
    return r;
}

Big_int operator << (Big_int x, int y) { // x * 10 ^ y
    Big_int r;
    r.n = x.n + y;
    r.sign = x.sign;
    for (int i = 1; i <= x.n; i ++) {
        r[i + y] = x[i];
    }
    return r;
}

// 这里不会写了.......第一个返回值是商,第二个是余数
pair<Big_int, Big_int> unsignedrdiv (Big_int x, Big_int y) {
    Big_int a = x, t, res, r;
    res.n = x.n - y.n + 1;
    for (int i = x.n - y.n; i; i --) {
        t = (a >> i) + (r << 1);
        a[a.n] = 0;
        a.n --;
        while (t >= y) {
            res[i + 1] ++;
            t = t - y;
        }
        r = t;
    }
    return make_pair(res, r);
}

int main() {
    Big_int a, b;
    a.read();
    b.read();
    pair<Big_int, Big_int> p;
    p = unsignedrdiv(a, b);
    p.first.print();
    cout << '\n';
    p.second.print();
    return 0;
}

2025/1/19 19:31
加载中...