Listing 6: Other BigNum routines
//raise bignum to the nth power
BigNum BigNum::operator^(const long n){
if (n>0){
if (n==2) return ((*this) * (*this));
if (n%2==0) return (((*this)^(n/2))^2);
else return (*this * ((*this)^(n-1)));
}else{
if (!n) return BigNum(1); else return BigNum(long(0));
}
}
//construct BigNum from char string; only works if BASE == 10000
BigNum::BigNum(char *s){
int k,ind,l = strlen(s);
exp = l/4;
if (l%4==0) exp--;
x = new int[exp+1];
char *d, *s2;
d = new char[l]; s2 = new char[l];
strcpy(s2,s); //make copy of s so that we don't trash original
l--; k = l - 3; if (k<0) k = 0; ind = l-k+1;
for (int i = 0;i<=exp;i++){
d = s2+k;
d[ind] = '\0'; x[i] = atoi(d)
l -=4; k-=4; if (k<0) k = 0;
ind = l-k+1;
}
delete[] d; delete[] s2;
}
//construct BigNum from long; new_sz param allows one to create
//a larger than necessary array of ints
BigNum::BigNum(long k,long new_sz){
long k2 = k/BASE; int sz = 1;
while(k2){sz++; k2 /= BASE;} //determine size of int array
if (sz >= new_sz) x = new int[sz]; else x = new int[new_sz];
if (k>=0) positive = 1;
else{ k = -k; positive = 0;}
long carry = k; exp = -1;
while (carry){ x[++exp] = carry % BASE; carry /= BASE;}
}
//copy constructor
BigNum::BigNum(const BigNum &b,long new_sz){
if (b.exp+1 >= new_sz) x = new int[b.exp+1];
else x = new int[new_sz];
positive = b.positive; exp = b.exp;
for (int i=0;i<=exp;i++)x[i] = b.x[i];
}
//assign a long to a bignum
BigNum & BigNum::operator=(long k){
delete[] x;
long k2 = k/BASE; int sz = 1;
while(k2){sz++; k2 /= BASE;}
x = new int[sz];
if (k>=0)positive = 1;
else{ k = -k; positive = 0;}
long carry = k;
exp = -1;
while (carry){x[++exp] = carry % BASE; carry /= BASE;}
return *this;
}
//assign a bignum to a bignum
BigNum & BigNum::operator=(const BigNum &b){
delete[] x;
x = new int[b.exp+1];
exp = b.exp; positive = b.positive;
for (int i = 0;i<=exp; i++) x[i] = b.x[i];
return *this;
}
//allow easy printing of bignums
ostream& operator<<(ostream & os, BigNum &b){
if (!b.positive){ os << "-";}
int j = 0;
for (int i = b.exp; i >=0; i--){
if (++j % 15 == 0) os << "\n";
os.fill('0');os.width(4);os << b.x[i];
}
return os;
}
//End of File