C++实现大整数类及其读入、输出、加法、乘法运算

来源:互联网 发布:js怎么将div隐藏 编辑:程序博客网 时间:2024/06/02 18:52

C/C++并没有内置高精度整数类,就算使用long long,也无法满足我们的需求。要实现高精度正整数,我们需要使用特别的方法。

下面的C++代码实现了高精度正整数结构体。它把一个长的整数分割成许多部分,在内部倒序存储以便于运算。由于重载了”<<”和”>>”运算符,它可以使用C++内置的iostream,即cin和cout来像普通的整数一样存储。

代码如下:

#include <cstdio>#include <iostream>#include <algorithm>#include <vector>#include <cstring>#include <sstream>#define FOR(x,f,t) for(x=f;x<=t;++x)#define RFOR(x,f,t) for(x=f;x>=t;--x)#define oo 2147483647typedef long long ll;using namespace std;struct BigInt{    static const int P=10000;     static const int L=4;     vector<int> prt;    BigInt(const string &s) { //读入        this->operator=(s);    }    BigInt(const int &i) {        stringstream ss;        ss<<i;        string s1 = ss.str();        this->operator=(s1);    }    BigInt operator = (const string &s) {        prt.clear();        int x,i,len=(s.length()-1)/L+1;        FOR(i,0,len-1) {            int end=s.length()-i*L;            int start=max(0,end-L);            sscanf(s.substr(start,end-start).c_str(),"%d",&x);            prt.push_back(x);        }        return *this;    }    friend ostream &operator << (ostream &out, const BigInt& x) {        out<<x.prt.back();        int i,j;        RFOR(i,x.prt.size()-2,0) {            char buf[20];            sprintf(buf,"%04d",x.prt[i]);            FOR(j,0,strlen(buf)-1) out<<buf[j];        }        return out;    }    friend istream &operator >> (istream &in, BigInt &x) {        string s;        if (!(in>>s)) return in;        x=s;        return in;    }    BigInt operator + (const BigInt &b) const {        BigInt c;c.prt.clear();        int i,g;        for(i=0,g=0;;++i) {            if (g==0&&i>=prt.size()&&i>=b.prt.size()) break;            int x=g;            if (i<prt.size()) x+=prt[i];            if (i<b.prt.size()) x+=b.prt[i];            c.prt.push_back(x%P);            g=x/P;        }        return c;    }    BigInt operator * (const BigInt &b) const {        BigInt c;c.prt.clear();        if ((prt.size()==1&&prt[0]==0)||(b.prt.size()==1&&b.prt[0]==0)) {             // 特判乘数是否为0,节约计算时间            c="0";return c;        }        int cl=prt.size()+b.prt.size();        int i,j;        FOR(i,0,cl) c.prt.push_back(0);        FOR(i,0,prt.size()-1) {            FOR(j,0,b.prt.size()-1) {                c.prt[i+j]+=prt[i]*b.prt[j];                if (c.prt[i+j]>=P) {                    c.prt[i+j+1]+=c.prt[i+j]/P;                    c.prt[i+j]%=P;                }            }        }        while(c.prt.size()>=2&c.prt[cl-1]==0)cl--;        c.prt.resize(cl);        return c;    }    bool operator < (const BigInt &b) {        if (prt.size()!=b.prt.size()) return prt.size()<b.prt.size();        int i;        RFOR(i,prt.size()-1,0) if (prt[i]!=b.prt[i]) return prt[i]<b.prt[i];        return false; //两数相等,返回false    }};int main() {    BigInt a,b;    cin>>a>>b;    cout<<a+b<<endl;    cout<<a*b<<endl;    return 0;}

测试输入:

233444555667888111222 99988877766655544321

测试输出:

33343343343454365554323341859141967680097077623303426998470262

我们可以看到,就算位数超过long long范围,使用BigInt结构体依然可以正确的运算,并可以方便的读入和输出。

0 0
原创粉丝点击