From 7bb55b03c393b5d00914d328a16d238d17f6aa0f Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 16 Apr 2013 13:57:57 -0600 Subject: Added /, %, and = operators. Division now works just fine, but by long division. There are apparently much faster ways of doing division, but as long as it works I feel like that's a great start :) --- src/number.cpp | 107 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 91 insertions(+), 16 deletions(-) (limited to 'src/number.cpp') diff --git a/src/number.cpp b/src/number.cpp index 9b6ec55..b3a33dc 100644 --- a/src/number.cpp +++ b/src/number.cpp @@ -29,7 +29,11 @@ Number &Number::operator=( const Bu::String &sNum ) return *this; } -template t tabs( t x ) { return (x<(t)0)?(-x):x; } +Number &Number::operator=( const Number &rhs ) +{ + set( rhs ); + return *this; +} Number Number::operator+( const Number &rhs ) const { @@ -87,24 +91,18 @@ Number Number::operator*( const Number &rhs ) const Number Number::operator/( const Number &rhs ) const { - if( rhs.aInt.getSize() > aInt.getSize() ) - return Number( iOrd ); - - Number q( iOrd ); - - int iMinWidth = rhs.aInt.getSize(); - - Bu::println("%1\n-----").arg( aInt.toString() ); - for( int j = aInt.getSize(); j > iMinWidth; j-- ) - { - Number sub( iOrd ); - sub.aInt.set( aInt, j-iMinWidth, iMinWidth ); - Bu::println("%1\n%2\n----").arg( sub.toString() ).arg( rhs.toString() ); - } - + Number q( iOrd ), r( iOrd ); + divide( rhs, q, r ); return q; } +Number Number::operator%( const Number &rhs ) const +{ + Number q( iOrd ), r( iOrd ); + divide( rhs, q, r ); + return r; +} + Number Number::operator-() const { Number neg( *this ); @@ -250,6 +248,13 @@ void Number::set( const Bu::String &sNum ) } } +void Number::set( const Number &sNum ) +{ + aInt.set( sNum.aInt ); + bPositive = sNum.bPositive; + iOrd = sNum.iOrd; +} + Bu::String Number::toString() const { if( aInt.getSize() == 0 ) @@ -272,6 +277,7 @@ Number Number::add( const Number &rhs, bool bSub ) const int iZeros = 0; int iCarry = 0; +// Bu::println("::: %1 + %2:").arg( toString() ).arg( rhs.toString() ); if( bPositive == (bSub?!rhs.bPositive:rhs.bPositive)) { @@ -332,8 +338,77 @@ Number Number::add( const Number &rhs, bool bSub ) const ret.aInt.set( j, 9-ret.aInt.get( j )); } } + else + { + ret.aInt.trim(); + } } return ret; } +void Number::divide( const Number &rhs, Number &q, Number &r ) const +{ + q.aInt.clear(); + r = *this; + + if( rhs.aInt.getSize() > aInt.getSize() ) + return; + + if( bPositive == rhs.bPositive ) + q.bPositive = true; + else + q.bPositive = false; + + int iMinWidth = rhs.aInt.getSize(); + + int iAnchor = r.aInt.getSize()-iMinWidth; + int iSample = iMinWidth; + do + { +// Bu::println("%1\n-----").arg( r.aInt.toString() ); + Number sub( iOrd ); + for(;;) + { +// Bu::println(" -> Anchor: %1, Sample: %2").arg( iAnchor ).arg( iSample ); + sub.aInt.set( r.aInt, iAnchor, iSample ); +// Bu::println("%1\n%2\n----").arg( sub.toString() ).arg( rhs.toString() ); + if( sub < rhs ) + { + iSample++; + iAnchor--; + if( iAnchor < 0 ) + { +// Bu::println("[Inner exit] Complete: q = %1, r = %2").arg( q.toString() ).arg( r.toString() ); + return; + } + } + else + break; + } + + Number x( iOrd ); + int iRes = 0; + for( ; x <= sub; iRes++, x = x + rhs ) { } + x = sub - (x - rhs); + for( int j = 0; iAnchor+j >= 0 && j < x.aInt.getSize(); j++ ) + r.aInt.set( iAnchor+j, x.aInt.get( j ) ); + while( r.aInt.getSize() > iAnchor+x.aInt.getSize() ) + r.aInt.remove(); +// Bu::println(" -> Post remainder patch: %1 -> %2"). +// arg( x.toString() ).arg( r.toString() ); + +// Bu::println("%1 (%2)").arg( iRes-1 ).arg( x.toString() ); + while( q.aInt.getSize() <= iAnchor ) + q.aInt.append(0); + q.aInt.set( iAnchor, iRes-1 ); + + iSample = iMinWidth; + iAnchor = r.aInt.getSize()-iMinWidth; +// Bu::println(" -> new Anchor: %1, Sample: %2").arg( iAnchor ). +// arg( iSample ); + } while( iAnchor >= 0 ); + +// Bu::println("Complete: q = %1, r = %2").arg( q.toString() ).arg( r.toString() ); +} + -- cgit v1.2.3