C++大整数类

4 阅读2分钟

 使用结构体实现高精度加减乘除运算,但是除法运算的复杂度较高,(其实乘法也是),更优的方法涉及到数学方法,在此没有采用,参考《算法竞赛入门经典第二版》

解释写在代码中

加减乘除均为模拟列竖式的过程

#include<iostream>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
using namespace std;

struct BigInteger{
    static const int BASE=1e8;
    static const int WIDTH=8;   //下面的vector<int> s中,每个s[i]储存的位数,现在是8位,所以BASE=10^8
    vector<int> s;
    //初始化
    BigInteger(long long num=0) {*this=num;}    //构造函数,用于初始化BigInteger变量,默认值为0
    //赋值
    BigInteger operator = (long long num){  //赋值操作:long long to BigInteger
        s.clear();              //s中,数的低位保存在前,高位保存在后
        do{
            s.push_back(num%BASE);
            num/=BASE;
        }while(num>0);
        return *this;
    }
    BigInteger operator = (const string& str){
        s.clear();
        int x,len=(str.length()-1)/WIDTH+1; //len:vector保存的元素数量
        for(int i=0;i<len;i++){
            int endd=str.length()-i*WIDTH;
            int start=max(0,endd-WIDTH);
            sscanf(str.substr(start,endd-start).c_str(),"%d",&x);   //从start开始,截取endd-start长度的字符串
            s.push_back(x);
        }
        return *this;
    }
    //比较(实现小于,等于,也就实现了全部比较)
    bool operator < (const BigInteger& b) const {
        if(s.size()!=b.s.size()) return s.size()<b.s.size();
        for(int i=s.size()-1;i>=0;i--)
            if(s[i]!=b.s[i]) return s[i]<b.s[i];
        return false;
    }
    bool operator == (const BigInteger&b) const {
        return s==b.s;
    }
    //加减乘除运算
    BigInteger operator + (const BigInteger& b) const{
        BigInteger c;
        c.s.clear();
        for(int i=0,g=0;;i++){
            if(g==0 && i>=s.size() && i>=b.s.size()) break;
            int x=g;
            if(i<s.size()) x+=s[i];
            if(i<b.s.size()) x+=b.s[i];
            c.s.push_back(x%BASE);
            g=x/BASE;
        }
        return c;
    }
    BigInteger operator - (const BigInteger& b) const {     //只适用于结果大于等于0的情况(即若要计算a-b,则需要保证a>=b)
        BigInteger c;
        c.s.clear();
        int g = 0; // 借位
        for (int i = 0; ; i++) {
            if (i >= s.size()) break;
            int x = g;
            x += s[i];
            if(i<b.s.size()) x -= b.s[i];
            if (x < 0) {
                x += BASE;
                g = -1;
            } else {
                g = 0;
            }
            c.s.push_back(x);
        }
        // Remove leading zeros
        while (c.s.size() > 1 && c.s.back() == 0) {
            c.s.pop_back();
        }
        return c;
    }
    BigInteger operator * (const BigInteger& b) const {
        BigInteger c;
        c.s.resize(s.size() + b.s.size(), 0);   //a*b乘法结果的位数最多是:a的位数+b的位数,将每一个s中的元素初始化为0
        for (int i = 0; i < s.size(); i++) {
            for (int j = 0; j < b.s.size(); j++) {
                long long mul = (long long)s[i] * b.s[j] + c.s[i + j];
                c.s[i + j] = mul % BASE;
                c.s[i + j + 1] += mul / BASE;
            }
        }
        // remove leading zeros
        while (c.s.size() > 1 && c.s.back() == 0) {
            c.s.pop_back();
        }
        return c;
    }
    BigInteger operator / (const BigInteger& b) const {
        BigInteger c;
        c.s.resize(s.size(), 0);
        BigInteger remainder;
        for (int i = s.size() - 1; i >= 0; i--) {
            remainder.s.insert(remainder.s.begin(), s[i]);
            int quotient = 0;
            while (b<remainder || b==remainder) {
                remainder = remainder - b;
                quotient++;
            }
            c.s[i] = quotient;
        }
        // Remove leading zeros
        while (c.s.size() > 1 && c.s.back() == 0) {
            c.s.pop_back();
        }
        return c;
    }
};

ostream& operator << (ostream& out,const BigInteger& x){
    out<<x.s.back();
    for(int i=x.s.size()-2;i>=0;i--){
        char buf[20];
        sprintf(buf,"%08d",x.s[i]);
        for(int j=0;j<strlen(buf);j++) out<<buf[j];
    }
    return out;
}


istream& operator >>(istream& in,BigInteger& x) {
    string s;
    if(!(in>>s)) return in;
    x=s;
    return in;
}

int main()
{
    BigInteger a,b;
    while(cin>>a>>b){
        cout<<a+b<<"\n";
        cout<<a-b<<"\n";
        cout<<a*b<<"\n";
        cout<<a/b<<"\n";
    }
    return 0;
}