学习笔记:压位高精
2025-09-06

把 ddxrS 吓到了,发出惊世疑问:『为什么高二机房正在激烈地讨论怎么写高精度?』


考虑 10-base 高精度,单次运算复杂度为 \(O(\log_{10}V)\)。使用 10-base 的主要原因是 std::to_string 很方便、输出也很简单。

但效率太低。实际上,一般打高精度都是 1e4-base,或更激进地,1e9-base。

注意高精乘低精是 \(O(len)\) 而非 \(O(len^2)\)

需要考虑输出。由于用的是 10-power 作为 base,所以只需要把每四位直接输出即可。注意除首位外需要补前导 0 直到四位。

struct BI {
    std::vector<int> s;
    BI() {}
    BI(int x) {
        for (; x; s.push_back(x % 10000), x /= 10000);
        return;
    }
    BI& operator= (int q) {
        return *this = (BI)q;
    }
    bool operator> (const BI &q) {
        if (s.size() != q.s.size())
            return s.size() > q.s.size();
        for (int i = (int)s.size() - 1; ~i; --i)
            if (s[i] != q.s[i])
                return s[i] > q.s[i];
        return 0;
    }
    BI operator* (int q) const {
        int lx = s.size();
        std::vector<long long> res(lx + 3);
        for (int i = 0; i < lx; ++i)
            res[i] = (long long)s[i] * q;
        BI p;
        for (int j = 0; j < lx + 2; ++j)
            res[j + 1] += res[j] / 10000, res[j] %= 10000;
        int len = lx + 2;
        for (; ~len && !res[len]; --len);
        for (int j = 0; j <= len; ++j)
            p.s.push_back(res[j]);
        return p;
    }
    void out(void) {
        for (int i = (int)s.size() - 1; ~i; --i) {
            auto p = std::to_string(s[i]);
            if (i != (int)s.size() - 1)
                for (; (int)p.size() < 4; p = "0" + p);
            std::cout << p;
        }
        std::cout << '\n';
        return;
    }
};

言论