高精度(有符号)

高精度小数: 国王饮水记
这份高精度模板采用了 RAII 风格
满足 平凡类型、可复制构造、可移动构造、可移动赋值、可复制赋值
可以满足 可小于比较

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
struct big_base{
	static const int L = 1E4, MOD = 10, B = 1;
	//attention 除法效率 位数^2*MOD 谨慎压位
	//O(n ^2 * (10^B/B^2)) 最优效率为B = 0.75, B = 1即可
	int a[L];
	int& operator [](int x){
		return a[x];
	}
	int operator [](int x)const{
		return a[x];
	}
	big_base(){
		clear();
	}
	void clear(){
		memset(a, 0, sizeof(a));
	}
	big_base (int val) : big_base(to_string(val)) {}
	big_base (ll  val) : big_base(to_string(val)){}
	big_base (string str){
		clear();
		reverse(str.begin(), str.end());
		a[0] = int(str.length() - 1)/ B + 1;
		for(int i = 0, j = 1; i < str.length(); ++i, j *= 10){
			if(j == MOD) j = 1;
			int b = i / B + 1;
			a[b] = (a[b] + (str[i] - '0') * j);
		}
	}
	friend int cmp(const big_base& a, const big_base& b){ // a - b
		if(a[0] != b[0]) return a[0] < b[0] ? -1 : 1;
		for(int i = a[0]; i >= 1; --i){
			if(a[i] != b[i]) return a[i] < b[i] ? -1 : 1;
		}
		return 0;
	}
	friend big_base operator +(const big_base&a , const big_base& b){
		big_base c;
		c[0] = max(a[0], b[0]);
		for(int i = 1; i <= c[0]; ++i){
			c[i] += (a[i] + b[i]);
			c[i + 1] += c[i] / MOD;
			c[i] %= MOD;
		}
		if(c[c[0] + 1]) ++c[0];
		return c;
	}
	friend big_base operator - (const big_base& a, const big_base& b){
		big_base c;
		c[0] = a[0];
		for(int i = 1; i <= a[0]; ++i){
			c[i] += a[i] - b[i];
			if(c[i] < 0){
				c[i] += MOD;
				c[i + 1] -= 1;
			}
		}
		while(c[0] > 1 && c[c[0]] == 0) --c[0];
		return c;
	}
	friend big_base operator * (const big_base& a, const big_base& b){
		big_base c;
		c[0] = a[0] + b[0];
		for(int i = 1; i <= a[0]; ++i){
			for(int j = 1; j <= b[0]; ++j){
				c[i + j - 1] += a[i] * b[j];
				c[i + j] += c[i + j - 1] / MOD;
				c[i + j - 1] %= MOD;
			}
		}
		while(c[0] > 1 && c[c[0]] == 0) --c[0];
		return c;
	}
	friend big_base lshift(big_base c, int x){ // 左移x位( * BASE)
		c[0] = c[0] + x;
		for(int i = c[0]; i - x >= 1; --i)
			c[i] = c[i - x];
		for(int i = 1; i <= x; ++i)
			c[i] = 0;
		return c;
	}
	friend big_base rshift(big_base c, int x){
		c[0] = c[0] - x;
		for(int i = 1; i <= c[0]; ++i)
			c[i] = c[i + x];
		return c;
	}
	friend pair<big_base, big_base> divide(big_base a, big_base b){
		if(a[0] < b[0]) return {big_base("0"), a};
		big_base c;
		c[0] = a[0] - b[0] + 1;
		for(int i = c[0]; i >= 1; --i){
			big_base val = lshift(b, i - 1);
			while(cmp(a, val) >= 0){
				a = a - val;
				++c[i];
			}
		}
		while(c[0] > 1 && c[c[0]] == 0) --c[0];
		if(c[0] == 0) c[0]++;
		return {c, a};
	}
	friend big_base operator % (const big_base& a,const big_base& b){
		return divide(a, b).second;
	}
	friend big_base operator / (const big_base& a, const big_base& b){
		return divide(a, b).first;
	}
	operator string(){
		stringstream ss;
		ss << a[a[0]];
		for(int i = a[0] - 1; i >= 1; --i){
			ss << setw(B) << setfill('0') << a[i];
		}
		string ret;
		ss >> ret;
		return ret;
	}
	bool ckzero() const {
		return a[0] == 1 && a[1] == 0;
	}
};
struct big{
	int sgn;
	big_base val;
	void clear(){
		val.clear();
		sgn = 1;
	}
	big(){
		clear();
	}
	big(int val) : big(to_string(val)) {}
	big(ll val) : big(to_string(val)){}
	big(string str){
		clear();
		if(str[0] == '-') {
			str.erase(str.begin());
			sgn = -1;
		}else{
			sgn = 1;
		}
		val = big_base(str);
	}
	big (int sgn_, big_base val_) : sgn(sgn_), val(val_){
		if(val.ckzero()) sgn = 1;
	}
	friend big operator +(big a, big b){
		if(a.sgn == b.sgn)
			return {a.sgn, a.val + b.val};
		if(a.sgn == -1) swap(a, b);
		if(cmp(a.val, b.val) >= 0){
			return {+1, a.val - b.val};
		}else{
			return {-1, b.val - a.val};
		}
	}
	friend big operator - (const big& a, big b){
		b.sgn *= -1;
		return a + b;
	}
	friend big operator * (const big& a, const big& b){
		if(a.sgn == b.sgn){
			return {+1, a.val * b.val};
		}else{
			return {-1, a.val * b.val};
		}
	}
	friend big operator / ( const big& a, const big& b){
		if(a.sgn == b.sgn){
			return {+1, a.val / b.val};
		}else{
			return {-1, a.val / b.val};
		}
	}
	friend big operator % (const big& a, const big& b){
		return a - (a / b) * b;
	}
	operator string(){
		if(sgn == -1) return '-' + string(val);
		else return string(val);
	}
	friend int cmp(const big& a,const big& b){
		if(a.sgn != b.sgn) return a.sgn < b.sgn ? -1 : 1;
		return cmp(a.val, b.val) * a.sgn;
	}
	friend big lshift(big c, int x){ // 左移x位( * BASE)
		return {c.sgn, lshift(c.val, x)};
	}
};
int main(){
	string sa, sb;
	cin >> sa >> sb;
	big a = sa, b = sb;
	return 0;
}```
posted @ 2023-01-28 16:40  CDsidi  阅读(32)  评论(0编辑  收藏  举报