BigInteger 大整数类(C++)



有时候需要用到大整数,这里放一个自己写的大整数结构体(BigInteger),实现的功能如下:

  • 输入输出;
  • 四则运算;
  • 比较运算;
  • 幂运算;

其中乘法运算和除法运算都是 O ( n 2 ) O(n^2) O(n2) 的复杂度。

struct BigInteger
{
    #define SIZE(x) ((int)x.size())
    std::vector<int> x; // 从低位往高位存储
    bool sign;  // 0:+  1:-

    // 构造
    BigInteger(std::vector<int> y) {this->x=y;}
    BigInteger(const BigInteger &y) {*this=y;}
    BigInteger(const BigInteger *y) {*this=*y;}
    BigInteger(const std::string &y) {*this=y;}
    BigInteger(long long y=0) {*this=y;}

    void squeeze()
    {
        while(SIZE(x) && x[SIZE(x)-1]==0) x.pop_back();
        if(SIZE(x)==0) sign=0;
    }

    BigInteger abs() const
    {
        BigInteger ret(this);
        ret.sign=0;
        return ret;
    }

    // 赋值
    BigInteger &operator = (const BigInteger &y)
    {
        this->x=y.x;
        this->sign=y.sign;
        squeeze();
        return *this;
    }
    BigInteger &operator = (const std::string &y)
    {
        x.clear();
        sign=(y[0]=='-');
        for(int i=SIZE(y)-1;i>=sign;i--)
            x.push_back(y[i]-'0');
        squeeze();
        return *this;
    }
    BigInteger &operator = (long long y)
    {
        x.clear();
        sign=y<0;
        y=std::abs(y);
        while(y)
        {
            x.push_back(y%10);
            y/=10;
        }
        squeeze();
        return *this;
    }

    // 取负号
    BigInteger operator - () const
    {
        BigInteger ret(this);
        ret.sign=sign^1;
        return ret;
    }

    // 四则运算
    BigInteger operator + (const BigInteger &y) const
    {
        if(y.sign==1) {return *this-(-y);}
        if(sign==1) {return y-(-*this);}
        BigInteger ret;
        int i=0,j=0;
        while(i<SIZE(x) && j<SIZE(y.x)) ret.x.push_back(x[i++]+y.x[j++]);
        while(i<SIZE(x)) ret.x.push_back(x[i++]);
        while(j<SIZE(y.x)) ret.x.push_back(y.x[j++]);
        ret.x.push_back(0);
        for(i=0;i+1<SIZE(ret.x);i++) ret.x[i+1]+=ret.x[i]/10,ret.x[i]%=10;
        ret.squeeze();
        return ret;
    }
    BigInteger operator - (const BigInteger &y) const
    {
        if(y.sign==1) {return *this+(-y);}
        if(sign==1) {return -((-*this)+y);}
        if(*this<y) {return -(y-*this);}
        BigInteger ret;
        int i=0,j=0;
        while(j<SIZE(y.x)) ret.x.push_back(x[i++]-y.x[j++]);
        while(i<SIZE(x)) ret.x.push_back(x[i++]);
        for(int i=0;i+1<SIZE(ret.x);i++) if(ret.x[i]<0) ret.x[i]+=10,ret.x[i+1]--;
        ret.squeeze();
        return ret;
    }
    BigInteger operator * (const BigInteger &y) const
    {
        BigInteger ret;
        ret.sign=sign^y.sign;
        for(int i=0;i<(SIZE(x)+SIZE(y.x))*2;i++) ret.x.push_back(0);
        for(int i=0;i<SIZE(x);i++)
            for(int j=0;j<SIZE(y.x);j++)
                ret.x[i+j]+=x[i]*y.x[j];
        for(int i=0;i<SIZE(ret.x) && (ret.x[i]>9 || ret.x[i+1]>0);i++)
            ret.x[i+1]+=ret.x[i]/10, ret.x[i]%=10;
        ret.squeeze();
        return ret;
    }
    BigInteger operator / (const BigInteger &y) const
    {
        std::stack<int> st;
        BigInteger tmp(0ll),ten(10ll);
        assert(y!=tmp);
        BigInteger t1=this->abs(),t2=y.abs();
        for(int i=SIZE(t1.x)-1;i>=0;i--)
        {
            tmp=tmp*ten+t1.x[i];
            int s=0;
            while(tmp>=t2)
            {
                tmp=tmp-t2;
                s++;
            }
            st.push(s);
        }
        tmp.x.clear();
        while(!st.empty()) tmp.x.push_back(st.top()),st.pop();
        delete &st; delete &t1; delete &t2;
        tmp.sign=sign^y.sign;
        tmp.squeeze();
        return tmp;
    }
    BigInteger operator % (const BigInteger &y) const
    {
        return *this-*this/y*y;
    }

    BigInteger operator += (const BigInteger &y) {*this=*this+y; return *this;}
    BigInteger operator -= (const BigInteger &y) {*this=*this-y; return *this;}
    BigInteger operator *= (const BigInteger &y) {*this=*this*y; return *this;}
    BigInteger operator /= (const BigInteger &y) {*this=*this/y; return *this;}
    BigInteger operator %= (const BigInteger &y) {*this=*this%y; return *this;}
    BigInteger operator ++ () {*this=*this+1; return *this;}
    BigInteger operator -- () {*this=*this-1; return *this;}

    BigInteger operator ^ (const BigInteger &y) const
    {
        BigInteger ret(1ll),k(y),a(this),zero(0ll);
        while(k>zero)
        {
            if(k%2==1) ret*=a;
            a*=a;
            k/=2;
        }
        return ret;
    }

    // 比较
    bool operator < (const BigInteger &y) const
    {
        if(sign==0 && y.sign==1) return 0;
        if(sign==1 && y.sign==0) return 1;
        if(sign==1 && y.sign==1) {return (-y)<(-*this);}
        if(SIZE(x)<SIZE(y.x)) return 1;
        else if(SIZE(x)>SIZE(y.x)) return 0;
        for(int i=SIZE(x)-1;i>=0;i--)
        {
            if(x[i]<y.x[i]) return 1;
            else if(x[i]>y.x[i]) return 0;
        }
        return 0;
    }
    bool operator > (const BigInteger &y) const {return y<*this;}
    bool operator <= (const BigInteger &y) const {return !(y<*this);}
    bool operator >= (const BigInteger &y) const {return !(*this<y);}
    bool operator == (const BigInteger &y) const {return *this<=y && *this>=y;}
    bool operator != (const BigInteger &y) const {return !(*this==y);}

    // 输入输出
    friend std::ostream &operator << (std::ostream &out,const BigInteger &y)
    {
        if(y.sign) out<<'-';
        for(int i=SIZE(y.x)-1;i>=0;i--) out<<y.x[i];
        if(SIZE(y.x)==0) out<<'0';
        return out;
    }
    friend std::istream &operator >> (std::istream &in,BigInteger &y)
    {
        std::string s;
        in>>s;
        y=s;
        return in;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值