万能的高精度模板
该重载的运算符都重载了,赋值、强制类型转换都没问题。输入输出可以直接用 cin,cout
。
自带压位优化。
唯一的区别是,没有取模运算,除法会返回 pair<结果,余数>。
class Int {
public:
using ll = long long;
Int() {};
Int(const string& s);
Int(ll a) :Int(to_string(a)) {}
Int(const Int& bInt) :nums(bInt.nums), isPositive(bInt.isPositive), length(bInt.length) {}
Int(Int&& bInt) noexcept :nums(move(bInt.nums)), isPositive(bInt.isPositive), length(bInt.length) {}
Int(const vector<int>& vec, bool sign = true) :nums(vec), isPositive(sign) { cutLeadZero(); }
friend istream& operator >>(istream& is, Int& bInt) {
string s;
is >> s;
bInt = move(Int(s));
return is;
}
friend ostream& operator <<(ostream& os, const Int& bInt);
operator string() const;
const Int& operator +() const { return *this; }
Int operator -() const {
Int tmp(*this);
if (!tmp.isZero())
tmp.isPositive = !isPositive;
return tmp;
}
bool operator <(const Int& bInt) const;
bool operator <=(const Int& bInt) const;
bool operator ==(const Int& bInt) const;
Int operator +(const Int& bInt) const;
Int operator -(const Int& bInt) const;
Int operator *(const Int& bInt) const;
// 除法会返回 商和余数
pair<Int, Int> operator /(const Int& bInt) const;
int operator[](int idx) const { return nums[idx]; }
Int& operator =(const Int& bInt) {
if (bInt == *this)
return *this;
nums = bInt.nums;
isPositive = bInt.isPositive;
length = bInt.length;
return *this;
}
Int& operator =(Int&& bInt)noexcept {
nums = move(bInt.nums);
isPositive = bInt.isPositive;
length = bInt.length;
return *this;
}
size_t size() const { return nums.size(); }
void cutLeadZero();
bool isZero() const;
Int absValue() const {
return move(Int(nums));
}
static Int e(size_t n) {
if (n <= 0)
return move(Int(vector<int>(1, 1)));
int m = n / digit;
n -= m * digit;
vector<int> ans(m);
string s = "1";
s += move(string(n, '0'));
ans.push_back(stoi(s));
return move(Int(ans));
}
private:
// 低位到高位
vector<int> nums;
bool isPositive = 1;
int length = 0;
static int digit;
static int mod;
};
int Int::digit = 8;
int Int::mod = 100000000;
Int::Int(const string& s) {
int n = s.size(), minIdx = 0;
if(s[0]=='-')
isPositive = false, minIdx = 1;
else if(s[0]=='+')
isPositive = true, minIdx = 1;
for (int i = n - 1; i >= minIdx; i -= digit) {
int beg = max(minIdx, i - digit + 1);
nums.push_back(stoi(s.substr(beg, i - beg + 1)));
}
cutLeadZero();
}
ostream& operator <<(ostream& os, const Int& bInt) {
os << (string)bInt;
return os;
}
Int::operator string() const {
string ans;
if (!isPositive)
ans += "-";
int n = nums.size();
for (int i = n - 1; i >= 0; i--) {
string s = to_string(nums[i]);
if (i != n - 1)
ans += string(digit - s.size(), '0');
ans += s;
}
return ans;
}
bool Int::operator<(const Int& bInt) const {
if (isPositive && !bInt.isPositive)
return false;
if (!isPositive && bInt.isPositive)
return true;
bool flag = true;
if (!isPositive)
flag = false;
if (length < bInt.length)
return flag;
else if (length > bInt.length)
return !flag;
int n = size();
for (int i = n - 1; i >= 0; i--) {
if (nums[i] < bInt[i])
return flag;
else if (nums[i] > bInt[i])
return !flag;
}
return false;
}
bool Int::operator<=(const Int& bInt) const {
if (isPositive && !bInt.isPositive)
return false;
if (!isPositive && bInt.isPositive)
return true;
bool flag = true;
if (!isPositive)
flag = false; // 都为负数
if (length < bInt.length)
return flag;
else if (length > bInt.length)
return !flag;
int n = size();
for (int i = n - 1; i >= 0; i--) {
if (nums[i] < bInt[i])
return flag;
else if (nums[i] > bInt[i])
return !flag;
}
return true;
}
bool Int::operator==(const Int& bInt) const {
if (length != bInt.length)
return false;
int n = size();
for (int i = 0; i < n; i++)
if (nums[i] != bInt[i])
return false;
return true;
}
Int Int::operator+(const Int& bInt) const {
if (!bInt.isPositive)
return *this - (-bInt);
if (!isPositive)
return bInt - (-*this);
vector<int> ans;
int n = size(), m = bInt.size(), sum = 0, i = 0, j = 0;
while (i < n || j < m || sum)
{
if (i < n)
sum += nums[i++];
if (j < m)
sum += bInt[j++];
ans.push_back(sum % mod);
sum /= mod;
}
return move(Int(ans, isPositive));
}
Int Int::operator-(const Int& bInt) const
{
if (!bInt.isPositive)
return *this + (-bInt);
if (!isPositive)
return -((-*this) + bInt);
if (*this < bInt)
return -(bInt - *this);
vector<int> ans;
int i = 0, j = 0, n = size(), m = bInt.size(), sum = 0;
while (i < n || j < m || sum) {
if (i < n)
sum += nums[i++];
if (j < m)
sum -= bInt[j++];
int flag = 0;
if (sum < 0) {
flag = -1;
sum += mod;
}
ans.push_back(sum);
sum = flag;
}
return move(Int(ans));
}
Int Int::operator*(const Int& bInt) const {
int n = size(), m = bInt.size();
vector<int> ans(n + m);
using ll = long long;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
ll tmp = ans[i + j] + nums[i] * 1ll * bInt[j];
ans[i + j] = tmp % mod;
ans[i + j + 1] += tmp / mod;
}
}
return move(Int(ans, isPositive == bInt.isPositive));
}
pair<Int, Int> Int::operator/(const Int& bInt) const {
Int a = absValue();
Int b = bInt.absValue();
if (b.isZero())
return pair<Int, Int>(*this, move(b));
if (a < b)
return pair<Int, Int>(move(Int(0)), *this);
int len = a.length - b.length + 1;
string ans;
if (isPositive != bInt.isPositive)
ans = "-";
for (int i = 0; i < len; i++) {
Int tmp = e(len - i - 1) * b;
int times = 0;
while (tmp <= a) {
a = a - tmp;
++times;
}
ans += times + '0';
}
a.isPositive = isPositive;
return pair<Int, Int>(move(Int(ans)), move(a));
}
void Int::cutLeadZero() {
while(nums.size() > 1 && nums.back() == 0)
nums.pop_back();
if(nums.empty()) length = 0;
else length = (nums.size() - 1) * digit + to_string(nums.back()).size();
}
bool Int::isZero() const {
return nums.size() == 1 && nums.back() == 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步