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结构体依然可以正确的运算,并可以方便的读入和输出。