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/main.cpp | 24 ++++++++++- src/number.cpp | 107 +++++++++++++++++++++++++++++++++++++++++-------- src/number.h | 4 ++ src/packedintarray.cpp | 20 +++++++++ src/packedintarray.h | 2 + 5 files changed, 139 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 3678278..d436a20 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -157,6 +157,26 @@ void numbertest1() arg( a.toString() ). arg( b.toString() ). arg( (a / b).toString() ); + + a = "12345"; + b = "45"; + + println("%1 / %2 = %3"). + arg( a.toString() ). + arg( b.toString() ). + arg( (a / b).toString() ); + + a = "3007103450821050020096034077958224700"; + b = "898239467"; + + println("%1 / %2 = %3"). + arg( a.toString() ). + arg( b.toString() ). + arg( (a / b).toString() ); + println("%1 %% %2 = %3"). + arg( a.toString() ). + arg( b.toString() ). + arg( (a % b).toString() ); } #define compcheck( anum, op, bnum ) \ @@ -230,8 +250,8 @@ int main( int , char *[] ) println("CliC"); // packedtest1(); -// numbertest1(); - numbertestcomp(); + numbertest1(); +// numbertestcomp(); return 0; } 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() ); +} + diff --git a/src/number.h b/src/number.h index 7d65096..9cb16b0 100644 --- a/src/number.h +++ b/src/number.h @@ -12,11 +12,13 @@ public: virtual ~Number(); Number &operator=( const Bu::String &sNum ); + Number &operator=( const Number &rhs ); Number operator+( const Number &rhs ) const; Number operator-( const Number &rhs ) const; Number operator*( const Number &rhs ) const; Number operator/( const Number &rhs ) const; + Number operator%( const Number &rhs ) const; Number operator-() const; bool operator==( const Number &rhs ) const; @@ -27,6 +29,7 @@ public: bool operator<=( const Number &rhs ) const; void set( const Bu::String &sNum ); + void set( const Number &sNum ); operator Bu::String() const { @@ -39,6 +42,7 @@ public: private: Number add( const Number &rhs, bool bSub ) const; + void divide( const Number &rhs, Number &q, Number &r ) const; private: int iOrd; diff --git a/src/packedintarray.cpp b/src/packedintarray.cpp index 7c54063..0e137bf 100644 --- a/src/packedintarray.cpp +++ b/src/packedintarray.cpp @@ -127,6 +127,26 @@ void PackedIntArray::set( const PackedIntArray &rSrc, int iStart, int iSize ) } } +void PackedIntArray::set( const PackedIntArray &rSrc ) +{ + delete[] aData; + + iBitWidth = rSrc.iBitWidth; + iCapacity = rSrc.iCapacity; + iCount = rSrc.iCount; + uMask = rSrc.uMask; + + int iSize = StoreCount(iCapacity); + aData = new Store[iSize]; + memcpy( aData, rSrc.aData, iSize*sizeof(Store) ); +} + +void PackedIntArray::trim() +{ + while( iCount > 0 && get( iCount-1 ) == 0 ) + iCount--; +} + Bu::String PackedIntArray::toBitString() const { Bu::String sRet; diff --git a/src/packedintarray.h b/src/packedintarray.h index a865df5..de26a6a 100644 --- a/src/packedintarray.h +++ b/src/packedintarray.h @@ -20,6 +20,8 @@ public: void set( int idx, Unit i ); int getSize() const { return iCount; } void set( const PackedIntArray &rSrc, int iStart, int iSize ); + void set( const PackedIntArray &rSrc ); + void trim(); Bu::String toBitString() const; Bu::String toString() const; -- cgit v1.2.3