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

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 2147483647
typedef 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

测试输出:

333433433434543655543
23341859141967680097077623303426998470262

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

    原文作者:大整数乘法问题
    原文地址: https://blog.csdn.net/github_35559856/article/details/51871558
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞