// 181/C++examples/huge/HugeInt.cc -bds mods to // Fig. 8.8: hugeint1.cpp // Member and friend function definitions for class HugeInt #include #include "HugeInt.h" // static const members const int HugeInt::SIZE = 30; const int HugeInt::MAX_INDEX = SIZE - 1; const int HugeInt::BASE = 10; const int HugeInt::HALF_BASE = BASE/2; const int HugeInt::MAX_DIGIT = BASE - 1; // Default constructor HugeInt::HugeInt(){ integer = new short[SIZE]; for ( int i = 0; i < SIZE; i++ ) integer[ i ] = 0; // initialize array to zero } // Copy constructor HugeInt::HugeInt( HugeInt& source ){ HugeInt::HugeInt(); for ( int i = 0; i < SIZE; i++ ) integer[ i ] = source.integer[ i ]; } // Conversion constructors HugeInt::HugeInt( long v ) { HugeInt::HugeInt(); long val = v >= 0 ? v : -v; // idea use clock arithmetic in the style of hardware for ( int i = MAX_INDEX; val != 0 && i >= 0; i-- ) { integer[ i ] = val % BASE; val /= BASE; } if ( v < 0 ) negate(); } HugeInt::HugeInt( const char *string ) { HugeInt::HugeInt(); if ( string[0] == '-' ) {// assuming non-null string. HugeInt::HugeInt( string + 1 ); negate(); } else { int i, j; for ( i = SIZE - strlen( string ), j = 0; i <= MAX_INDEX; i++, j++ ) integer[ i ] = string[ j ] - '0'; } // debugging display: char* s = new char[20 + strlen(string)]; // s = "HugeInt( "; strcpy( s, "HugeInt( " ); strcat( s, string ); strcat( s, " )" ); debug( s ); } // Addition HugeInt HugeInt::operator+( HugeInt &op2 ) { // incorrect for now HugeInt temp; int carry = 0; for ( int i = MAX_INDEX; i >= 0; i-- ) { temp.integer[ i ] = integer[ i ] + op2.integer[ i ] + carry; if ( temp.integer[ i ] > MAX_DIGIT ) { temp.integer[ i ] -= BASE; carry = 1; } else carry = 0; } return temp; } HugeInt HugeInt::operator+( int op2 ) { return *this + HugeInt( op2 ); } HugeInt HugeInt::operator+( const char *op2 ) { return *this + HugeInt( op2 ); } // subtraction HugeInt HugeInt::operator-( HugeInt &op2 ) { op2.negate(); HugeInt ans = *this + op2; op2.negate(); return ans; } HugeInt HugeInt::operator-( int op2 ) { return *this - HugeInt( op2 ); } HugeInt HugeInt::operator-( const char *op2 ) { return *this - HugeInt( op2 ); } // negation and complement void HugeInt::negate() { debug( "negate start = " ); complement(); debug( "negate complemented = " ); add1(); debug( "negate add1-ed = " ); } void HugeInt::add1() { int i; for ( i = MAX_INDEX; i >= 0 && integer[ i ] == MAX_DIGIT; i-- ) integer[ i ] = 0; if ( i >= 0 ) integer[ i ] += 1; } void HugeInt::complement() { for ( int i = 0; i < SIZE; i++ ) integer[ i ] = MAX_DIGIT - integer[ i ]; } // the friends HugeInt operator+( int op1, HugeInt& op2 ) { return op2 + op1; } HugeInt operator-( int op1, HugeInt& op2 ) { return HugeInt(op1) - op2; } HugeInt abs( HugeInt& op ) { HugeInt ans(op); if ( ans.integer[0] >= HugeInt::HALF_BASE ) ans.negate(); return ans; } // output operator only works for BASE <= 10. ostream& operator<<( ostream &output, HugeInt &num ) { if ( num.integer[0] >= HugeInt::HALF_BASE ) output << "-" << abs( num ); else { int i; for ( i = 0; ( num.integer[ i ] == 0 ) && ( i < HugeInt::SIZE ); i++ ) ; // skip leading zeros if ( i == HugeInt::SIZE ) output << 0; // the number is zero else for ( ; i <= HugeInt::MAX_INDEX; i++ ) output << num.integer[ i ]; } return output; } void HugeInt::debug( char* s ) { cerr << s; for(int k = 0; k < SIZE; k++) cerr << integer[k]; cerr << ", BASE is " << BASE << ", SIZE is " << SIZE << endl; }