Last active
August 29, 2015 14:21
-
-
Save gnitnaw/79ccbac48a22e14b67c4 to your computer and use it in GitHub Desktop.
Class to estimate extra long number
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
#include <vector> | |
#include <iostream> | |
#include <sstream> | |
#include <math.h> | |
#include <sys/time.h> | |
using namespace std; | |
class BigNumber { | |
private : | |
vector <unsigned long> blocks; | |
static const unsigned long limitBlock = 10000000000; | |
const unsigned int nB = log10l(limitBlock); | |
public : | |
BigNumber(unsigned long n){ | |
blocks.push_back(n%limitBlock); | |
if (n>=limitBlock) blocks.push_back(n/limitBlock); | |
} | |
size_t getNBlocks() const { | |
return blocks.size(); | |
} | |
string getStringBlock(size_t i) const{ | |
stringstream ss; | |
ss << blocks[i]; | |
string convert_str; | |
ss >> convert_str; | |
if (blocks.size() == 1) return convert_str; | |
else { | |
if (i == blocks.size()-1) return convert_str; | |
else { | |
if (blocks[i]==0) { | |
for (unsigned int j(0); j<nB-1; ++j) { | |
convert_str += "0"; | |
} | |
} else if (convert_str.size() < nB) { | |
for (unsigned int j(0); j<=(nB-convert_str.size()); ++j) { | |
convert_str = "0" + convert_str; | |
} | |
} | |
} | |
return convert_str; | |
} | |
} | |
int getNDigit() const { | |
int a=0; | |
for (size_t i(0); i<blocks.size(); ++i) { | |
a += getStringBlock(i).size(); | |
} | |
return a; | |
} | |
void print(ostream& out) const { | |
for (int i(blocks.size()-1); i>=0; --i) { | |
cout << getStringBlock(i); | |
} | |
} | |
void Carry() { | |
for (unsigned int i(0); i<blocks.size(); ++i){ | |
if (blocks[i]>=limitBlock) { | |
if (i!=blocks.size()-1) { | |
blocks[i+1] += blocks[i]/limitBlock; | |
} else { | |
blocks.push_back(blocks[i]/limitBlock); | |
} | |
blocks[i] = blocks[i]%limitBlock; | |
} | |
} | |
} | |
void Pop() { | |
while (blocks[getNBlocks()-1] == 0) { | |
blocks.pop_back(); | |
} | |
} | |
BigNumber& operator+=(const BigNumber& c) { | |
while (c.getNBlocks()>blocks.size()) { | |
blocks.push_back(0); | |
} | |
for (unsigned int i(0); i<c.getNBlocks(); ++i) { | |
blocks[i]+=c.blocks[i]; | |
} | |
Carry(); | |
return *this; | |
} | |
BigNumber& operator-=(const BigNumber& c) { | |
if (c.getNBlocks()>blocks.size() || (c.getNBlocks()==blocks.size() and c.blocks[c.getNBlocks()-1]>blocks[getNBlocks()-1])) { | |
blocks.clear(); | |
blocks.push_back(0); | |
} else { | |
for (unsigned int i(0); i<c.getNBlocks(); ++i) { | |
if (blocks[i]<c.blocks[i]) { | |
blocks[i+1] -= 1; | |
blocks[i] += limitBlock; | |
} | |
blocks[i]-=c.blocks[i]; | |
} | |
} | |
Pop(); | |
return *this; | |
} | |
BigNumber& operator*=(const unsigned int n) { | |
for (unsigned int i(0); i<blocks.size(); ++i) { | |
blocks[i]*=n; | |
} | |
Carry(); | |
return *this; | |
} | |
BigNumber& operator/=(const unsigned int n) { | |
if (n==0) { | |
cout << "Cannot divide by 0!" << endl; | |
return *this; | |
} | |
for (int i(blocks.size()-1); i>=0; --i) { | |
if (i>0) { | |
blocks[i-1] += (blocks[i]%n) * limitBlock; | |
} | |
blocks[i] /= n; | |
} | |
Pop(); | |
return *this; | |
} | |
}; | |
const BigNumber operator+(BigNumber a, const BigNumber& b) { | |
a += b; | |
return a; | |
} | |
const BigNumber operator-(BigNumber a, const BigNumber& b) { | |
a -= b; | |
return a; | |
} | |
const BigNumber operator*(unsigned int a, const BigNumber& b) { | |
BigNumber c(b); | |
c *= a; | |
return c; | |
} | |
const BigNumber operator*(const BigNumber& b, const unsigned int a) { | |
BigNumber c(b); | |
c *= a; | |
return c; | |
} | |
const BigNumber operator/(const BigNumber& b, const unsigned int a) { | |
BigNumber c(b); | |
c /= a; | |
return c; | |
} | |
const BigNumber operator%(const BigNumber& b, const unsigned int a) { | |
BigNumber c(b); | |
c /= a; | |
c *= a; | |
return BigNumber(b - c); | |
} | |
ostream& operator<<(ostream&out, const BigNumber& n) { | |
n.print(out); | |
return out; | |
} | |
const BigNumber Fibonacci(unsigned int i); | |
int main(){ | |
struct timeval start_time, end_time; | |
vector <BigNumber> Fib; | |
vector <BigNumber> duration; | |
cout << "Fibonacci Number : " << endl; | |
cout << "N:\tFibonacci(N)\tTime of estimation (us)"<< endl; | |
for (unsigned long i(0); i<=35; ++i) { | |
gettimeofday(&start_time,0); | |
BigNumber f = Fibonacci(i); | |
gettimeofday(&end_time,0); | |
duration.push_back(BigNumber(1000000*(end_time.tv_sec - start_time.tv_sec) + (end_time.tv_usec - start_time.tv_usec))); | |
Fib.push_back(f); | |
if (i>=2) { | |
cout << i << "\t"<< f << "\t" << duration[i]<< endl; | |
} | |
} | |
for (unsigned long i(36); i<=100; ++i) { | |
Fib.push_back(Fib[i-1]+Fib[i-2]); | |
duration.push_back(duration[i-1]+duration[i-2]); | |
cout << i << "\t"<< Fib[i] << "\t" << duration[i] << endl; | |
} | |
cout << endl; | |
cout << "Factorial" << endl; | |
BigNumber a(1); | |
for (unsigned int i(1); i<=100; ++i) { | |
a *= i; | |
cout << i<<"!= "<< a << endl; | |
} | |
return 0; | |
} | |
const BigNumber Fibonacci(unsigned int i) { | |
if (i==0) return BigNumber(0); | |
if (i==1) return BigNumber(1); | |
return Fibonacci(i-1)+Fibonacci(i-2); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment