无符号整数压位高精板子

include <bits/stdc++.h>

using namespace std;

///继承vector解决位数限制,操作方便
struct Huge_Int:vector{

static const int WIDTH = 4;///压位数
static const long long BASE = 1e4;///单位基

///初始化,同时也可以将低精度转高精度、字符串转高精度
///无需单独写高精度数和低精度数的运算函数,十分方便
Huge_Int(long long n = 0){
    *this = n;
}
Huge_Int(const string &str){
    *this = str;
}

///格式化,包括进位和去前导0,用的地方很多,先写一个
Huge_Int & format(){
    while(!empty() && !back()) pop_back();//去除最高位可能存在的0
    if(empty())return *this;
    for(int i=1; i<size(); ++i)
    {
        (*this)[i]+=(*this)[i-1]/BASE;
        (*this)[i-1]%=BASE;
    }//位内进位
    while(back()>=BASE)
    {
        push_back(back()/BASE);
        (*this)[size()-2]%=BASE;
    }//位外进位
    return *this;//为使用方便,将进位后的自身返回引用
}

///重载等于,初始化、赋值、输入都用得到
Huge_Int operator=(long long n){
    clear();
    push_back(n);
    format();
    return *this;
}
Huge_Int operator=(const string &str){
    clear();
    if(str.empty()) push_back(0);
    for(int i = str.length() - 1;i>=0;i-=WIDTH){
        long long tmp = 0;
        for(int j = max(i-WIDTH+1,0);j<=i;j++)
            tmp = (tmp<<3) + (tmp<<1) + (str[j]^48);
        push_back(tmp);
    }
    return *this;
}

///重载输入输出
friend istream & operator>>(istream &is, Huge_Int &tmp){
    string str;
    if(!(is>>str)) return is;
    tmp = str;
    return is;
}
friend ostream & operator<<(ostream &os, const Huge_Int &tmp){
    if(tmp.empty()) os<<0;
    else os<<tmp[tmp.size()-1];
    for(int i = tmp.size() - 2;i>=0;i--){
        os<<setfill('0')<<setw(WIDTH)<<tmp[i];
    }
    return os;
}

///重载逻辑运算符,只需要写两个,其他的直接代入即可
///常量引用当参数,避免拷贝更高效
friend bool operator!=(const Huge_Int &a,const Huge_Int &b){
    if(a.size()!=b.size()) return 1;
    for(int i=a.size()-1; i>=0; i--)
        if(a[i]!=b[i]) return 1;
    return 0;
}
friend bool operator==(const Huge_Int &a,const Huge_Int &b){
    return !(a!=b);
}
friend bool operator<(const Huge_Int &a,const Huge_Int &b){
    if(a.size()!=b.size()) return a.size()<b.size();
    for(int i=a.size()-1; i>=0; i--)
        if(a[i]!=b[i])return a[i]<b[i];
    return 0;
}
friend bool operator>=(const Huge_Int &a,const Huge_Int &b){
    return !(a<b);
}
friend bool operator>(const Huge_Int &a,const Huge_Int &b){
    return b<a;
}
friend bool operator<=(const Huge_Int &a,const Huge_Int &b){
    return !(a>b);
}

///加法,先实现+=,这样更简洁高效
friend Huge_Int & operator+=(Huge_Int &a,const Huge_Int &b){
    if(a.size()<b.size()) a.resize(b.size());
    for(int i=0; i!=b.size(); i++) a[i]+=b[i];//被加数要最大位,并且相加时不要用未定义区间相加
    return a.format();
}
friend Huge_Int operator+(Huge_Int a,const Huge_Int &b){
    return a+=b;
}
friend Huge_Int & operator++(Huge_Int &a){
    return a+=1;
}
friend Huge_Int operator++(Huge_Int &a,int){
    Huge_Int old = a;
    ++a;
    return old;
}

///减法,返回差的绝对值,由于后面有交换,故参数不用引用
friend Huge_Int & operator-=(Huge_Int &a,Huge_Int b){
    if(a<b){
        Huge_Int t = a;
        a = b;
        b = t;
    }
    for(int i=0; i!=b.size(); a[i]-=b[i],i++){
        if(a[i]<b[i]){//需要借位
            int j=i+1;
            while(!a[j]) j++;
            while(j>i){
                a[j--]--;
                a[j]+=BASE;
            }
        }
    }
    return a.format();
}
friend Huge_Int operator-(Huge_Int a,const Huge_Int &b){
    return a-=b;
}
friend Huge_Int & operator--(Huge_Int &a){
    return a-=1;
}
friend Huge_Int operator--(Huge_Int &a,int){
    Huge_Int old = a;
    --a;
    return old;
}


///乘法,不能先实现*=,因为是类多项式相乘,每位都需要保留,不能覆盖
friend Huge_Int operator*(const Huge_Int &a,const Huge_Int &b){
    Huge_Int n;
    n.assign(a.size()+b.size()-1,0);
    for(int i=0; i!=a.size(); i++)
        for(int j=0; j!=b.size(); j++)
            n[i+j]+=a[i]*b[j];
    return n.format();
}
friend Huge_Int & operator*=(Huge_Int &a,const Huge_Int &b){
    return a=a*b;
}

///带余除法函数,方便除法和模运算,会改变a的值,所以先实现/尽量不多余地修改原来变量
///O(base/width*logn),待修改
friend Huge_Int divmod(Huge_Int &a,const Huge_Int &b){
    Huge_Int ans;
    for(int i=a.size()-b.size(); a>=b; i--){//减法代替除法
        Huge_Int d;
        d.assign(i+1,0);
        d.back() = 1;
        Huge_Int c=b*d;//提高除数位数进行减法
        while(a>=c) a-=c,ans+=d;
    }
    return ans;
}
friend Huge_Int operator/(Huge_Int a,const Huge_Int &b){
    return divmod(a,b);
}
friend Huge_Int & operator/=(Huge_Int &a,const Huge_Int &b){
    return a = a/b;
}
friend Huge_Int & operator%=(Huge_Int &a,const Huge_Int &b){
    divmod(a,b);
    return a;
}
friend Huge_Int operator%(Huge_Int a,const Huge_Int &b){
    return a%=b;
}

};

int main(){
std::ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
string n;
long long m;
cin>>n>>m;
Huge_Int a(n),b(m);
cout<<a<<endl
<<b<<endl
<<(a<b)<<endl
<<(a==b)<<endl
<<a+b<<endl
<<a-b<<endl
<<a*b<<endl
<<a/b<<endl
<<a%b<<endl;
++a+=b;
a++;
cout<<a<<endl;
--a-=b;
a--;
cout<<a<<endl;
return 0;
}

上一篇:关于axios请求配置, request的封装, 请求拦截器和响应拦截器的拦截范围, 使用express临时后台测试


下一篇:C++翁恺学习17-const