From 44542adf023315d60a8ffc4863f2b161b3c1eb90 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Mon, 15 Apr 2013 23:45:48 -0600 Subject: Addition, subtraction, and multiplication work now Division isn't working yet, there are too many options, I'll figure out something eventually :-P --- src/number.cpp | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 152 insertions(+), 14 deletions(-) (limited to 'src/number.cpp') diff --git a/src/number.cpp b/src/number.cpp index e64be94..ac29c61 100644 --- a/src/number.cpp +++ b/src/number.cpp @@ -6,45 +6,110 @@ Number::Number( int iOrd ) : iOrd( iOrd ), - aInt( 4 ) + aInt( 4 ), + bPositive( true ) { } Number::Number( const Bu::String &sData, int iOrd ) : iOrd( iOrd ), - aInt( 4 ) + aInt( 4 ), + bPositive( true ) { - for( int j = sData.getSize()-1; j >= 0; j-- ) - aInt.append( sData[j]-'0' ); + set( sData ); } Number::~Number() { } +Number &Number::operator=( const Bu::String &sNum ) +{ + set( sNum ); + return *this; +} + +template t tabs( t x ) { return (x<(t)0)?(-x):x; } + Number Number::operator+( const Number &rhs ) const +{ + return add( rhs, false ); +} + +Number Number::operator-( const Number &rhs ) const +{ + return add( rhs, true ); +} + +Number Number::operator*( const Number &rhs ) const { Number ret( iOrd ); - int iPlaces = Bu::buMax(rhs.aInt.getSize(), aInt.getSize() )+1; + int iPlaces = Bu::buMax(rhs.aInt.getSize(), aInt.getSize() ); + int iCnt = aInt.getSize()+rhs.aInt.getSize(); int iCarry = 0; - for( int j = 0; j < iPlaces; j++ ) + int iZeros = 0; + for( int j = 0; j < iCnt || iCarry > 0; j++ ) { - int iRes = iCarry + digit( j ) + rhs.digit( j ); - Bu::println(" Place: %1 + %2 + (%3) = %4"). - arg( digit(j) ).arg( rhs.digit( j ) ).arg( iCarry ) - .arg( iRes ); - ret.aInt.append( (iRes%iRadix) ); - if( iRes < iRadix ) - iCarry = 0; +// Bu::println("Pos %1").arg(j); + int iPos = iCarry; + iCarry = 0; + for( int k = 0; k < rhs.aInt.getSize(); k++ ) + { + if( j-k < 0 ) + break; + + int iRes = digit(j-k)*rhs.digit(k); + iPos += iRes; + +// Bu::println(" [%1] %2 * [%3] %4 = %5 -> %6"). +// arg( j-k ).arg( digit(j-k) ).arg( k ).arg( rhs.digit(k) ). +// arg( iRes ).arg( iPos ).arg( iCarry ); + } + if( (iPos%iRadix) == 0 ) + iZeros++; else - iCarry = iRes/iRadix; + { + for(; iZeros > 0; iZeros-- ) + ret.aInt.append( 0 ); + ret.aInt.append( iPos%iRadix ); + } + iCarry += iPos/iRadix; } + if( bPositive == rhs.bPositive ) + ret.bPositive = true; + else + ret.bPositive = false; + return ret; } +void Number::set( const Bu::String &sNum ) +{ + aInt.clear(); + bPositive = true; + for( int j = sNum.getSize()-1; j >= 0; j-- ) + { + if( sNum[j] == '+' ) + break; + if( sNum[j] == '-' ) + { + bPositive = false; + break; + } + aInt.append( sNum[j]-'0' ); + } +} + +Bu::String Number::toString() const +{ + if( aInt.getSize() == 0 ) + return "0"; + return (bPositive?"":"-") + aInt.toString(); +} + int Number::digit( int iOrder ) const { if( iOrder >= aInt.getSize() ) @@ -52,3 +117,76 @@ int Number::digit( int iOrder ) const return aInt[iOrder]; } +Number Number::add( const Number &rhs, bool bSub ) const +{ + Number ret( iOrd ); + + int iPlaces = Bu::buMax(rhs.aInt.getSize(), aInt.getSize() ); + + int iZeros = 0; + int iCarry = 0; + + if( bPositive == (bSub?!rhs.bPositive:rhs.bPositive)) + { + ret.bPositive = bPositive; + for( int j = 0; j < iPlaces || iCarry > 0; j++ ) + { + int iRes = iCarry + digit( j ) + rhs.digit( j ); +// Bu::println(" Place: %1 + %2 + (%3) = %4"). +// arg( digit(j) ).arg( rhs.digit( j ) ).arg( iCarry ) +// .arg( iRes ); + if( iRes == 0 ) + { + iZeros++; + continue; + } + for(; iZeros > 0; iZeros-- ) + ret.aInt.append( 0 ); + + ret.aInt.append( (iRes%iRadix) ); + if( iRes < iRadix ) + iCarry = 0; + else + iCarry = iRes/iRadix; + } + } + else + { + iCarry = 1; +// Bu::println("--method b--"); + ret.bPositive = bPositive; + int iRes; + for( int j = 0; j < iPlaces; j++ ) + { + iRes = digit( j ) + (9-rhs.digit( j )) + iCarry; +// Bu::println(" Place: %1 + %2 + (%3) = %4"). +// arg( digit(j) ).arg( 9-rhs.digit( j ) ).arg( iCarry ) +// .arg( iRes ); + if( iRes == 0 ) + { + iZeros++; + continue; + } + for(; iZeros > 0; iZeros-- ) + ret.aInt.append( 0 ); + + ret.aInt.append( (iRes%iRadix) ); + if( iRes < iRadix ) + iCarry = 0; + else + iCarry = iRes/iRadix; + } + if( iCarry == 0 ) + { + ret.bPositive = false; + ret.aInt.set( 0, 9-ret.aInt.get( 0 )+1); + for( int j = 1; j < ret.aInt.getSize(); j++ ) + { + ret.aInt.set( j, 9-ret.aInt.get( j )); + } + } + } + + return ret; +} + -- cgit v1.2.3