头文件BigNumber.h
#ifndef BIGNUMBER_H
#define BIGNUMBER_H
#include<iostream>
#include<string>
using namespace std;
class BigNumber
{
private:
string Num;
string Code;
public:
BigNumber(){}
BigNumber(int num);
BigNumber(string nNum){Num=nNum;simplify();GetCode();}
BigNumber(const BigNumber& B){Num=B.Num;Code=B.Code;}
~BigNumber(){}
void InNum(){cin>>Num;simplify();GetCode();}
void SetNum(string nNum){Num=nNum;simplify();GetCode();}
void Print(){cout<<Num<<endl;}
bool Check();
void simplify();
void GetCode();
friend BigNumber abs(const BigNumber);
friend BigNumber pow(const BigNumber,const int);
friend BigNumber fac(const BigNumber);
friend BigNumber operator -(const BigNumber tNum);
BigNumber operator =(const BigNumber tNum);
BigNumber operator =(const int tNum);
BigNumber& operator ++();
BigNumber& operator --();
BigNumber operator ++(int);
BigNumber operator --(int);
friend bool operator ==(const BigNumber,const BigNumber);
friend bool operator !=(const BigNumber,const BigNumber);
friend bool operator >(const BigNumber,const BigNumber);
friend bool operator <(const BigNumber,const BigNumber);
friend bool operator >=(const BigNumber,const BigNumber);
friend bool operator <=(const BigNumber,const BigNumber);
friend BigNumber operator +(const BigNumber fNum,const BigNumber sNum);
friend BigNumber operator -(const BigNumber fNum,const BigNumber sNum);
friend BigNumber operator *(const BigNumber fNum,const BigNumber sNum);
friend BigNumber operator /(const BigNumber fNum,const BigNumber sNum);
friend BigNumber operator %(const BigNumber fNum,const BigNumber sNum);
friend BigNumber operator +=(BigNumber& fNum,const BigNumber sNum);
friend BigNumber operator -=(BigNumber& fNum,const BigNumber sNum);
friend BigNumber operator *=(BigNumber& fNum,const BigNumber sNum);
friend BigNumber operator /=(BigNumber& fNum,const BigNumber sNum);
friend BigNumber operator %=(BigNumber& fNum,const BigNumber sNum);
friend ostream& operator <<(ostream &os,BigNumber &num);
friend istream& operator >>(istream &is,BigNumber &num);
};
#endif
实现文件BigNumber.cpp
#include"BigNumber.h"
const BigNumber ZERO(0);
const BigNumber ONE(1);
const BigNumber TEN(10);
const BigNumber ERROR(0);
BigNumber::BigNumber(int num)
{
Num = "0";
Num[0] = (abs(num)%10) + '0';
for (num /= 10; num; num /= 10)
Num.insert(0, 1, (abs(num))%10 + '0');
if (num < 0)
Num.insert(0, 1, '-');
GetCode();
}
void BigNumber::simplify()
{
if(Check())
{
if(Num[0] == '+') Num.erase(0,1);
unsigned sta = 0,i = 0;
if(Num[0] == '-') sta = 1;
for(; i < Num.length() - sta - 1; i++)
if(Num[sta + i] != '0') break;
if(i) Num.erase(sta, i);
if(Num == "-0") Num = "0";
}
else Num = "0";
}
void BigNumber::GetCode()
{
Code = Num;
if(Code[0] == '-')
{
Code.erase(0, 1);
for(unsigned i = 0; i < Code.length(); i++)
Code[i]=2 * '0' - Code[i];
}
}
bool BigNumber::Check()
{
unsigned i = 0;
for(; i < Num.length(); i++)
{
if (i == 0 && (Num[0] == '-' || Num[0] == '+')) continue;
if (Num[i] <= '9' && Num[i] >= '0') continue;
else break;
}
if (Num == "-" || Num == "+") return false;
else if (i == Num.length()) return true;
else return false;
}
BigNumber abs(const BigNumber tNum)
{
BigNumber Abs(tNum);
if(Abs.Num[0] == '-')
Abs = -Abs;
return Abs;
}
BigNumber pow(const BigNumber tNum,const int n)
{
BigNumber Pow(ONE);
if(tNum == ONE) Pow = ONE;
else if (tNum == -ONE)
{
if (n % 2) Pow = -ONE;
else Pow = ONE;
}
else if (tNum == ZERO) Pow = ZERO;
else
{
if (n >= 0)
{
BigNumber temp(tNum);
for(int i = n; i > 0; i /= 2)
{
if (i % 2)
Pow *= temp;
temp *= temp;
}
}
else Pow = ZERO;
}
return Pow;
}
BigNumber fac(const BigNumber tNum)
{
BigNumber Fac;
if(tNum.Num[0] != '-')
{
if (tNum != ZERO)
{
Fac = tNum;
for (BigNumber count(tNum - ONE); count > ONE; count -= ONE)
Fac *= count;
}
else Fac = ONE;
Fac.simplify();
Fac.GetCode();
}
else Fac = ERROR;
return Fac;
}
BigNumber operator -(const BigNumber tNum)
{
BigNumber temp(tNum);
if(tNum.Num[0]!='-') temp.Num.insert(0,"-");
else temp.Num.assign(temp.Num,1,temp.Num.length()-1);
temp.simplify();
temp.GetCode();
return temp;
}
BigNumber BigNumber::operator =(const BigNumber tNum)
{
Num = tNum.Num;
Code = tNum.Code;
return *this;
}
BigNumber BigNumber::operator =(const int num)
{
Num = "0";int n = num;
Num[0] = (abs(n) % 10) + '0';
for (n /= 10; n; n /= 10)
Num.insert(0, 1, (abs(n)) % 10 + '0');
if (num < 0)
Num.insert(0, 1, '-');
GetCode();
return *this;
}
BigNumber& BigNumber::operator ++()
{
(*this) += ONE;
return *this;
}
BigNumber& BigNumber::operator --()
{
(*this) -= ONE;
return *this;
}
BigNumber BigNumber::operator ++(int)
{
BigNumber temp(*this);
*this += ONE;
return temp;
}
BigNumber BigNumber::operator --(int)
{
BigNumber temp(*this);
*this -= ONE;
return temp;
}
bool operator ==(const BigNumber fNum,const BigNumber sNum)
{
if (fNum.Num == sNum.Num) return true;
else return false;
}
bool operator !=(const BigNumber fNum,const BigNumber sNum)
{
if (fNum.Num == sNum.Num) return false;
else return true;
}
bool operator >(const BigNumber fNum,const BigNumber sNum)
{
if ((fNum - sNum).Num[0] == '-') return false;
else return true;
}
bool operator <(const BigNumber fNum,const BigNumber sNum)
{
if ((fNum - sNum).Num[0] == '-') return true;
else return false;
}
bool operator >=(const BigNumber fNum,const BigNumber sNum)
{
if (fNum < sNum) return false;
else return true;
}
bool operator <=(const BigNumber fNum,const BigNumber sNum)
{
if(fNum > sNum) return false;
else return true;
}
BigNumber operator +(const BigNumber fNum,const BigNumber sNum)
{
BigNumber fn(fNum),sn(sNum),Add;
if (fn.Code.length() < sn.Code.length())
fn.Code.swap(sn.Code);
string temp(fn.Code);
temp.insert(0,1,'0');
for(unsigned i=1;i<=fn.Code.length();i++)
if(i<=sn.Code.length())
temp[temp.length()-i]+=sn.Code[sn.Code.length()-i]-'0';
int t=0;
for(unsigned i=0;i<temp.length();i++)
{
if(temp[i]!='0')
{
if(temp[i]>'0') t=1;
else t=-1;
break;
}
}
if(t==-1) for(unsigned i=1;i<=temp.length();i++)
temp[temp.length()-i]=2*'0'-temp[temp.length()-i];
for(unsigned i=1;i<temp.length();i++)
{
if(temp[temp.length()-i]>'9')
{ temp[temp.length()-i]-=10;temp[temp.length()-i-1]+=1; }
else if(temp[temp.length()-i]<'0')
{ temp[temp.length()-i]+=10;temp[temp.length()-i-1]-=1; }
}
Add.Num=temp;
if(t==-1) Add=-Add;
Add.simplify();
Add.GetCode();
return Add;
}
BigNumber operator -(const BigNumber fNum,const BigNumber sNum)
{
BigNumber Minus,fn(fNum),sn(sNum);
sn=-sn;
return Minus=fn+sn;
}
BigNumber operator *(const BigNumber fNum,const BigNumber sNum)
{
BigNumber Multiply,tNum,temp;
string fn(abs(fNum).Num),sn(abs(sNum).Num);
if(fn.length()<sn.length()) fn.swap(sn);
temp.Num.resize(fn.length()+sn.length(),32);
tNum.Num.resize(fn.length()+sn.length(),'0');
for(unsigned i=1;i<=sn.length();i++)
{
for(unsigned j=1;j<=fn.length();j++)
//32之前的字符属于特殊符号,所以+32?
temp.Num[temp.Num.length()-j-i+1]=(sn[sn.length()-i]-'0')*(fn[fn.length()-j]-'0')+32;
for(unsigned j=1;j<=temp.Num.length();j++)
{
if(temp.Num[temp.Num.length()-j]>41)
{
while(temp.Num[temp.Num.length()-j]>41)
{
temp.Num[temp.Num.length()-j]-=10;
temp.Num[temp.Num.length()-j-1]+=1;
}
}
//但是32之前的符号有问题的话为什么这里-32再储存
tNum.Num[tNum.Num.length()-j]+=temp.Num[temp.Num.length()-j]-32;
if(tNum.Num[temp.Num.length()-j]>'9')
{
tNum.Num[tNum.Num.length()-j]-=10;
tNum.Num[tNum.Num.length()-j-1]+=1;
}
}
temp.Num.replace(0,temp.Num.length(),temp.Num.length(),32);
}
Multiply=tNum;Multiply.simplify();Multiply.GetCode();
if((fNum.Num[0]=='-'&&sNum.Num[0]!='-')||(sNum.Num[0]=='-'&&fNum.Num[0]!='-'))
Multiply=-Multiply;
return Multiply;
}
BigNumber operator /(const BigNumber fNum,const BigNumber sNum)
{
BigNumber Divide;
if(sNum!=ZERO)
{
BigNumber fn(abs(fNum)),sn(abs(sNum));
if(fn>sn)
{
BigNumber temp,Ans;
temp.Num.assign(fn.Num,0,sn.Num.length());
Ans.Num.assign(fn.Num.length()-sn.Num.length()+1,'0');
for(unsigned i=0;i<Ans.Num.length();i++)
{
temp.Code=temp.Num;
while(temp>=sn)
{
temp-=sn;
Ans.Num[i]+=1;
}
temp*=TEN;
if(i!=Ans.Num.length()-1)
temp.Num[temp.Num.length()-1]=fn.Num[sn.Num.length()+i];
}
Divide=Ans;
if((fNum.Num[0]=='-'&&sNum.Num[0]!='-')||(sNum.Num[0]=='-'&&fNum.Num[0]!='-'))
Divide=-Divide;
}
else if(fn==sn) Divide=ONE;
else Divide=ZERO;
}
else Divide=ERROR;
return Divide;
}
BigNumber operator %(const BigNumber fNum,const BigNumber sNum)
{
BigNumber Mod;
if(sNum!=ZERO)
{
BigNumber fn(abs(fNum)),sn(abs(sNum));
while(fn>=sn) fn=fn-sn;
Mod=fn;
if(fNum.Num[0]=='-') Mod=-Mod;
Mod.GetCode();
}
else Mod=ERROR;
return Mod;
}
BigNumber operator +=(BigNumber& fNum,const BigNumber sNum)
{
fNum=fNum+sNum;
return fNum;
}
BigNumber operator -=(BigNumber& fNum,const BigNumber sNum)
{
fNum=fNum-sNum;
return fNum;
}
BigNumber operator *=(BigNumber& fNum,const BigNumber sNum)
{
fNum=fNum*sNum;
return fNum;
}
BigNumber operator /=(BigNumber& fNum,const BigNumber sNum)
{
fNum=fNum/sNum;
return fNum;
}
BigNumber operator %=(BigNumber& fNum,const BigNumber sNum)
{
fNum=fNum%sNum;
return fNum;
}
ostream &operator <<(ostream &os,BigNumber &num)
{
os<<num.Num;
return os;
}
istream &operator >>(istream &is,BigNumber &num)
{
string in; cin>>in;
if(is) num.Num=in;
num.simplify();
num.GetCode();
return is;
}