Created
April 4, 2015 11:15
-
-
Save skyzh/33358fc9432671cdba19 to your computer and use it in GitHub Desktop.
Big Number Calculation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Big Number Calculation | |
//You can Add, Subtract or Multiply a BigNumber. | |
//What's more, all the calculations are done in base 10000 system. SPEED UP!!! | |
//You can adjust base system by changing NUM_PER_BIT and NUM_PER_BIT_BIT. | |
#include<iostream> | |
#include<sstream> | |
#include<iomanip> | |
#include<string> | |
#include<cstring> | |
using namespace std; | |
const int MAX_BITS=1000; | |
const int NUM_PER_BIT=10000; | |
const int NUM_PER_BIT_BIT=4; | |
class Tool | |
{ | |
public: | |
static int toInt(string s) | |
{ | |
int tmp=0; | |
for(int i=0;i<s.size();i++) | |
{ | |
tmp=tmp*10+int(s[i]-'0'); | |
} | |
return tmp; | |
} | |
}; | |
class Number | |
{ | |
public: | |
int bits; | |
int n[MAX_BITS]; | |
bool symbol; | |
Number() | |
{ | |
symbol=true; | |
bits=1; | |
memset(n,0,sizeof(n)); | |
} | |
~Number() | |
{ | |
} | |
int fromString(string s) | |
{ | |
string tmp; | |
memset(n,0,sizeof(n)); | |
bits=0; | |
for(int i=s.size()-1;i>=0;i-=NUM_PER_BIT_BIT) | |
{ | |
int tmpSize=NUM_PER_BIT_BIT; | |
int tmpI=i-NUM_PER_BIT_BIT+1; | |
if(tmpI<0) | |
{ | |
tmpI=0; | |
tmpSize=i+1; | |
} | |
tmp=s.substr(tmpI,tmpSize); | |
n[bits++]=Tool::toInt(tmp); | |
} | |
Settle(); | |
return 0; | |
} | |
string toString() | |
{ | |
stringstream stream; | |
for(int i=bits-1;i>=0;i--) | |
{ | |
if(i!=bits-1) | |
{ | |
stream<<setw(NUM_PER_BIT_BIT)<<setfill('0')<<n[i]; | |
} | |
else | |
{ | |
stream<<n[i]; | |
} | |
} | |
string tmp; | |
stream >>tmp; | |
if(symbol==false) | |
{ | |
tmp="-"+tmp; | |
} | |
return tmp; | |
} | |
void Settle() | |
{ | |
for(int i=MAX_BITS-1;i>=0;i--) | |
{ | |
if(n[i]!=0) | |
{ | |
bits=i+1; | |
return; | |
} | |
} | |
bits=1; | |
return; | |
} | |
}; | |
Number _operatorAdd(Number &a,Number &b) | |
{ | |
Number c; | |
int calcBits=max(a.bits,b.bits); | |
for(int i=0;i<calcBits;i++) | |
{ | |
c.n[i]+=a.n[i]+b.n[i]; | |
c.n[i+1]+=c.n[i]/NUM_PER_BIT; | |
c.n[i]%=NUM_PER_BIT; | |
} | |
c.Settle(); | |
return c; | |
} | |
Number _operatorMulti(Number &a,Number &b) | |
{ | |
Number c; | |
for(int i=0;i<a.bits;i++) | |
{ | |
for(int j=0;j<b.bits;j++) | |
{ | |
c.n[i+j]+=a.n[i]*b.n[j]; | |
c.n[i+j+1]+=c.n[i+j]/NUM_PER_BIT; | |
c.n[i+j]%=NUM_PER_BIT; | |
int k=i+j+1; | |
while(c.n[k]>=NUM_PER_BIT) | |
{ | |
c.n[k+1]+=c.n[k]/NUM_PER_BIT; | |
c.n[k]%=NUM_PER_BIT; | |
k++; | |
} | |
} | |
} | |
c.Settle(); | |
return c; | |
} | |
Number _operatorSub(Number &a,Number &b) | |
{ | |
Number c; | |
for(int i=0;i<a.bits;i++) | |
{ | |
c.n[i]+=a.n[i]-b.n[i]; | |
while(c.n[i]<0) | |
{ | |
c.n[i]+=NUM_PER_BIT; | |
c.n[i+1]--; | |
} | |
} | |
c.Settle(); | |
return c; | |
} | |
int _operatorCompare(Number &a,Number &b) | |
{ | |
//a>b 1 a<b -1 | |
if(a.bits==b.bits) | |
{ | |
for(int i=a.bits;i>=0;i--) | |
{ | |
if(a.n[i]==b.n[i])continue; | |
if(a.n[i]>b.n[i]) | |
{ | |
return 1; | |
} | |
if(a.n[i]<b.n[i]) | |
{ | |
return -1; | |
} | |
} | |
} | |
else | |
{ | |
if(a.bits<b.bits) | |
{ | |
return -1; | |
} | |
if(a.bits>b.bits) | |
{ | |
return 1; | |
} | |
} | |
return 0; | |
} | |
bool operator<(Number &a,Number &b) | |
{ | |
return _operatorCompare(a,b)==-1; | |
} | |
bool operator>(Number &a,Number &b) | |
{ | |
return _operatorCompare(a,b)==1; | |
} | |
bool operator==(Number &a,Number &b) | |
{ | |
return _operatorCompare(a,b)==0; | |
} | |
Number operator+(Number &a,Number &b) | |
{ | |
return _operatorAdd(a,b); | |
} | |
Number operator-(Number &a,Number &b) | |
{ | |
if(a<b) | |
{ | |
Number tmp=_operatorSub(b,a); | |
tmp.symbol=!tmp.symbol; | |
return tmp; | |
} | |
else | |
{ | |
return _operatorSub(a,b); | |
} | |
} | |
Number operator*(Number &a,Number &b) | |
{ | |
return _operatorMulti(a,b); | |
} | |
string s1="",s2=""; | |
int main() | |
{ | |
Number numa,numb; | |
cin >>s1>>s2; | |
numa.fromString(s1); | |
numb.fromString(s2); | |
cout <<(numa*numb).toString()<<endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment