万能的高精度模板

该重载的运算符都重载了,赋值、强制类型转换都没问题。输入输出可以直接用 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;
}
posted @   曹轩鸣  阅读(66)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起