高精度(有符号)
高精度小数: 国王饮水记
这份高精度模板采用了 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;
}```