Files
Data-Structure/模板/其他/高精度.cpp
2025-12-16 20:36:27 +08:00

180 lines
5.0 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
#include <algorithm>
using namespace std;
/*
* 高精度整数 BigInteger正数
* 存储方式vector<int> d低位在前little-endian
* 每位存储 BASE = 10^4 = 10000 的一个“数字块”,即四位十进制
* 这样可以大幅提升运算效率
*/
struct BigInteger {
static const int BASE = 10000; // 一个“数字块”的进制
static const int WIDTH = 4; // 每个块的十进制位数(用于输出补零)
vector<int> d; // 数字块存储,低位在 d[0]
/* -------- 构造函数部分 -------- */
BigInteger(long long num = 0) { *this = num; }
BigInteger& operator = (long long num) {
d.clear();
do {
d.push_back(num % BASE);
num /= BASE;
} while (num > 0);
return *this;
}
BigInteger(const string& s) { *this = s; }
BigInteger& operator = (const string& s) {
d.clear();
int len = s.size();
// 每 WIDTH 位作为一个数字块从后往前解析
for (int i = len; i > 0; i -= WIDTH) {
int x = 0;
int l = max(0, i - WIDTH);
for (int j = l; j < i; j++) x = x * 10 + (s[j] - '0');
d.push_back(x);
}
trim();
return *this;
}
/* -------- 删除高位的前导零 -------- */
void trim() {
while (d.size() > 1 && d.back() == 0) d.pop_back();
}
/* -------- 比较运算符 -------- */
bool operator < (const BigInteger& b) const {
if (d.size() != b.d.size()) return d.size() < b.d.size();
for (int i = d.size() - 1; i >= 0; i--) {
if (d[i] != b.d[i]) return d[i] < b.d[i];
}
return false; // 相等则不小于
}
bool operator > (const BigInteger& b) const { return b < *this; }
bool operator <= (const BigInteger& b) const { return !(b < *this); }
bool operator >= (const BigInteger& b) const { return !(*this < b); }
bool operator == (const BigInteger& b) const { return d == b.d; }
bool operator != (const BigInteger& b) const { return !(*this == b); }
/* -------- 高精度加法 -------- */
BigInteger operator + (const BigInteger& b) const {
BigInteger c;
c.d.clear();
int carry = 0;
for (size_t i = 0; i < d.size() || i < b.d.size() || carry; i++) {
int x = carry;
if (i < d.size()) x += d[i];
if (i < b.d.size()) x += b.d[i];
c.d.push_back(x % BASE);
carry = x / BASE;
}
return c;
}
/* -------- 高精度减法(默认 *this >= b -------- */
BigInteger operator - (const BigInteger& b) const {
BigInteger c;
c.d.clear();
int borrow = 0;
for (size_t i = 0; i < d.size(); i++) {
int x = d[i] - borrow - (i < b.d.size() ? b.d[i] : 0);
if (x < 0) { x += BASE; borrow = 1; }
else borrow = 0;
c.d.push_back(x);
}
c.trim();
return c;
}
/* -------- 高精度 * int -------- */
BigInteger operator * (int m) const {
BigInteger c;
long long carry = 0;
for (size_t i = 0; i < d.size() || carry; i++) {
long long x = carry + (long long)(i < d.size() ? d[i] : 0) * m;
c.d.push_back(x % BASE);
carry = x / BASE;
}
c.trim();
return c;
}
/* -------- 高精度乘法 O(n^2) -------- */
BigInteger operator * (const BigInteger& b) const {
BigInteger c;
c.d.assign(d.size() + b.d.size(), 0);
for (size_t i = 0; i < d.size(); i++) {
long long carry = 0;
for (size_t j = 0; j < b.d.size() || carry; j++) {
long long cur = c.d[i+j] +
(long long)d[i] * (j < b.d.size() ? b.d[j] : 0) +
carry;
c.d[i+j] = cur % BASE;
carry = cur / BASE;
}
}
c.trim();
return c;
}
/* -------- 高精度 / int返回商并把余数存入 r -------- */
BigInteger operator / (int m) const {
BigInteger c;
c.d.resize(d.size());
long long r = 0;
for (int i = d.size() - 1; i >= 0; i--) {
long long x = d[i] + r * BASE;
c.d[i] = x / m;
r = x % m;
}
c.trim();
return c;
}
int operator % (int m) const {
long long r = 0;
for (int i = d.size() - 1; i >= 0; i--) {
long long x = d[i] + r * BASE;
r = x % m;
}
return r;
}
/* -------- 输入输出重载 -------- */
friend ostream& operator << (ostream& os, const BigInteger& x) {
os << x.d.back();
for (int i = x.d.size() - 2; i >= 0; i--) {
os << setw(WIDTH) << setfill('0') << x.d[i];
}
return os;
}
friend istream& operator >> (istream& is, BigInteger& x) {
string s;
is >> s;
x = s;
return is;
}
};