C++實現大整數類及其讀入、輸出、加法、乘法運算
阿新 • • 發佈:2019-02-13
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結構體依然可以正確的運算,並可以方便的讀入和輸出。