高精度亿进制模板,支持负数,支持通过整型和字符串赋值,支持加减乘除取模等算术运算符,支持比较运算符,支持+=
,-=
,*=
,/=
,%-
,支持用 cin 和 cout 直接输入输出。抄了之后直接当成 int 来用也问题不大。
也许是全网最好的 BigInteger 高精度模板。
#include <algorithm>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class BigInteger {
public:
BigInteger(long long num = 0);
BigInteger(const string &str);
~BigInteger();
BigInteger operator=(const long long num);
BigInteger operator=(const string &str);
BigInteger operator+() const;
BigInteger operator-() const;
friend BigInteger operator+(const BigInteger &a, const BigInteger &b);
friend BigInteger operator-(const BigInteger &a, const BigInteger &b);
friend BigInteger operator*(const BigInteger &a, const BigInteger &b);
friend BigInteger operator/(const BigInteger &a, const BigInteger &b);
friend BigInteger operator%(const BigInteger &a, const BigInteger &b);
BigInteger operator+=(const BigInteger &b);
BigInteger operator-=(const BigInteger &b);
BigInteger operator*=(const BigInteger &b);
BigInteger operator/=(const BigInteger &b);
BigInteger operator%=(const BigInteger &b);
friend bool operator<(const BigInteger &a, const BigInteger &b);
friend bool operator>(const BigInteger &a, const BigInteger &b);
friend bool operator==(const BigInteger &a, const BigInteger &b);
friend bool operator<=(const BigInteger &a, const BigInteger &b);
friend bool operator>=(const BigInteger &a, const BigInteger &b);
friend ostream &operator<<(ostream &out, const BigInteger &x);
friend istream &operator>>(istream &in, BigInteger &x);
private:
vector<int> s;
int sign = 1;
static const int BASE = 100000000;
static const int WIDTH = 8;
void __defragment();
friend BigInteger __BigInteger_shift(const BigInteger &b, const int &x);
};
BigInteger __BigInteger_shift(const BigInteger &b, const int &x) {
BigInteger c;
c.s.resize(b.s.size() + x);
for (int i = 0; i < b.s.size(); i++) c.s[i + x] = b.s[i];
return c;
}
BigInteger::BigInteger(long long num) { *this = num; }
BigInteger::BigInteger(const string &str) { *this = str; }
BigInteger::~BigInteger() {}
BigInteger BigInteger::operator=(long long num) {
s.clear();
if (num >= 0)
sign = 1;
else
sign = -1, num *= -1;
do {
s.push_back(num % BASE);
num /= BASE;
} while (num > 0);
return *this;
}
BigInteger BigInteger::operator=(const string &str) {
s.clear();
sign = str[0] == '-' ? -1 : 1;
int first = str[0] == '-';
while (str[first] == '0' && first < str.length()) first++;
int x = 0, start = str.length() - WIDTH;
for (; start > first; start -= WIDTH) {
sscanf(str.substr(start, WIDTH).c_str(), "%d", &x);
s.push_back(x);
}
sscanf(str.substr(first, start + WIDTH - first).c_str(), "%d", &x);
s.push_back(x);
return *this;
}
BigInteger BigInteger::operator+() const { return *this; }
BigInteger BigInteger::operator-() const {
BigInteger c(*this);
c.sign *= -1;
return c;
}
BigInteger operator+(const BigInteger &a, const BigInteger &b) {
BigInteger c;
c.s.clear();
int i = 0, g = 0, length_min = min(a.s.size(), b.s.size());
for (; i < length_min; i++) {
int x = g + a.sign * a.s[i] + b.sign * b.s[i];
c.s.push_back(x % BigInteger::BASE);
g = x / BigInteger::BASE;
}
for (; i < a.s.size(); i++) {
int x = g + a.sign * a.s[i];
c.s.push_back(x % BigInteger::BASE);
g = x / BigInteger::BASE;
}
for (; i < b.s.size(); i++) {
int x = g + b.sign * b.s[i];
c.s.push_back(x % BigInteger::BASE);
g = x / BigInteger::BASE;
}
for (; g; i++) {
c.s.push_back(g & BigInteger::BASE);
g /= BigInteger::BASE;
}
c.__defragment();
return c;
}
BigInteger operator-(const BigInteger &a, const BigInteger &b) { return a + (-b); }
BigInteger operator*(const BigInteger &a, const BigInteger &b) {
BigInteger c;
c.s.resize(a.s.size() + b.s.size());
c.sign = a.sign * b.sign;
for (int i = 0; i < a.s.size(); i++) {
int g = 0, j = 0;
for (; j < b.s.size(); j++) {
long long x = c.s[i + j] + g;
x += (long long)a.s[i] * b.s[j];
c.s[i + j] = x % BigInteger::BASE;
g = x / BigInteger::BASE;
}
while (g) {
long long x = c.s[i + j] + g;
c.s[i + j] = x % BigInteger::BASE;
g = x / BigInteger::BASE;
}
}
while (c.s.size() > 1 && !*(c.s.end() - 1)) c.s.pop_back();
return c;
}
BigInteger operator/(const BigInteger &init_a, const BigInteger &init_b) {
if (init_b.s.size() == 0 || init_b.s.size() == 1 && init_b.s[0] == 0) throw("Divided by zero.");
BigInteger a(init_a), b(init_b);
BigInteger c;
c.s.resize(a.s.size());
c.sign = a.sign * b.sign;
a.sign = b.sign = 1;
for (int i = a.s.size() - b.s.size(); i >= 0; i--) {
int l = 0, r = BigInteger::BASE - 1;
int mid = (l + r + 1) >> 1;
BigInteger d;
for (; l < r; mid = (l + r + 1) >> 1) {
d = __BigInteger_shift(b * mid, i);
if (a > d)
l = mid;
else
r = mid - 1;
}
a = a - __BigInteger_shift(b * l, i);
c.s[i] = l;
}
while (c.s.size() > 1 && !*(c.s.end() - 1)) c.s.pop_back();
return c;
}
BigInteger operator%(const BigInteger &init_a, const BigInteger &init_b) {
if (init_b.s.size() == 0 || init_b.s.size() == 1 && init_b.s[0] == 0) throw("Divided by zero.");
BigInteger a(init_a), b(init_b);
int _a_sign = a.sign;
a.sign = b.sign = 1;
for (int i = a.s.size() - b.s.size(); i >= 0; i--) {
int l = 0, r = BigInteger::BASE - 1;
int mid = (l + r + 1) >> 1;
BigInteger d;
for (; l < r; mid = (l + r + 1) >> 1) {
d = __BigInteger_shift(b * mid, i);
if (a > d)
l = mid;
else
r = mid - 1;
}
a = a - __BigInteger_shift(b * l, i);
}
while (a.s.size() > 1 && !*(a.s.end() - 1)) a.s.pop_back();
a.sign = _a_sign;
return a;
}
BigInteger BigInteger::operator+=(const BigInteger &b) { return *this = *this + b; }
BigInteger BigInteger::operator-=(const BigInteger &b) { return *this = *this - b; }
BigInteger BigInteger::operator*=(const BigInteger &b) { return *this = *this * b; }
BigInteger BigInteger::operator/=(const BigInteger &b) { return *this = *this / b; }
BigInteger BigInteger::operator%=(const BigInteger &b) { return *this = *this % b; }
bool operator<(const BigInteger &a, const BigInteger &b) {
if (a.sign < b.sign) return true;
if (a.s.size() != b.s.size())
return a.sign * a.s.size() < b.sign * b.s.size();
else
for (int i = a.s.size() - 1; i >= 0; i--)
if (a.s[i] != b.s[i]) return a.sign * a.s[i] < b.sign * b.s[i];
return false;
}
bool operator>(const BigInteger &a, const BigInteger &b) { return b < a; }
bool operator==(const BigInteger &a, const BigInteger &b) { return !(a < b) && !(b < a); }
bool operator<=(const BigInteger &a, const BigInteger &b) { return !(b < a); }
bool operator>=(const BigInteger &a, const BigInteger &b) { return !(a < b); }
ostream &operator<<(ostream &out, const BigInteger &x) {
if (x.sign == -1) out << '-';
out << x.s.back();
for (int i = x.s.size() - 2; i >= 0; i--) {
char buf[20];
sprintf(buf, "%08d", x.s[i]);
for (int j = 0; j < strlen(buf); j++) out << buf[j];
}
return out;
}
istream &operator>>(istream &in, BigInteger &x) {
string s;
if (!(in >> s)) return in;
x = s;
return in;
}
void BigInteger::__defragment() {
while (s.size() > 1 && !s[s.size() - 1]) s.pop_back();
int len = s.size();
sign = s[len - 1] >= 0 ? 1 : -1;
s[len - 1] *= sign;
for (int i = 0; i < len - 1; i++) {
s[i] *= sign;
if (s[i] >= 0) continue;
s[i + 1] -= sign; // 借位
s[i] += BASE;
}
while (s.size() > 1 && !s[s.size() - 1]) s.pop_back();
}
int main() {
BigInteger y;
BigInteger x = y;
BigInteger z = -12356789012345678ll;
cout << z << "\n";
BigInteger a, b;
cin >> a >> b;
cout << a + b << "\n";
cout << a - b << "\n";
cout << a * b << "\n";
cout << a / b << "\n";
cout << a % b << "\n";
return 0;
}
高精度算法原理简单但代码实现繁琐,编程时还得充分考虑各种特殊情况。敲一遍高精度能充分锻炼代码能力,实乃居家旅行赛前必备。