1. 程式人生 > >C++實現大整數類及其讀入、輸出、加法、乘法運算

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結構體依然可以正確的運算,並可以方便的讀入和輸出。