From 7260c36973fc0ad7ff24294ff5540d64bf32c334 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Fri, 19 Apr 2013 15:36:29 -0600 Subject: Fractional divisoin works. It doesn't round yet, and there's a chance I should be increasing the precision, right now it keeps the precision of the left hand side number. --- src/main.cpp | 5 +- src/number.cpp | 147 ++++++++++++++++++++++++++++++++++--------------- src/number.h | 1 + src/packedintarray.cpp | 17 ++++++ src/packedintarray.h | 2 + 5 files changed, 127 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index fe9a1fe..a9b0072 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -281,12 +281,15 @@ void fractest() Number a( 8 ), b( 8 ); a = "123.456"; - println("%1").arg( a ); b = "0.987"; println("%1 + %2 = %3").arg( a ).arg( b ).arg( a + b ); println("%1 - %2 = %3").arg( a ).arg( b ).arg( a - b ); println("%1 * %2 = %3").arg( a ).arg( b ).arg( a * b ); println("%1 / %2 = %3").arg( a ).arg( b ).arg( a / b ); + + a = "12"; + b = "4"; + println("%1 / %2 = %3").arg( a ).arg( b ).arg( a / b ); } int main( int , char *[] ) diff --git a/src/number.cpp b/src/number.cpp index b923d5f..15cad95 100644 --- a/src/number.cpp +++ b/src/number.cpp @@ -244,8 +244,9 @@ bool Number::operator<=( const Number &rhs ) const void Number::set( const Bu::String &sNum ) { - Bu::println("Parsing: '%1'").arg( sNum ); +// Bu::println("Parsing: '%1'").arg( sNum ); aInt.clear(); + aFrac.zero(); bPositive = true; int iPt; for( iPt = 0; iPt < sNum.getSize() && sNum[iPt] != '.'; iPt++ ) { } @@ -262,7 +263,7 @@ void Number::set( const Bu::String &sNum ) for( int j = iPt-1; j >= iEnd; j-- ) { - Bu::println(" -> '%1'").arg( sNum[j] ); +// Bu::println(" -> '%1'").arg( sNum[j] ); if( sNum[j] == '.' ) break; if( sNum[j] >= '0' && sNum[j] <= '9' ) @@ -276,7 +277,7 @@ void Number::set( const Bu::String &sNum ) int iFrac = 0; for( int j = iPt+1; j < sNum.getSize(); j++ ) { - Bu::println(" => '%1'").arg( sNum[j] ); +// Bu::println(" => '%1'").arg( sNum[j] ); if( sNum[j] >= '0' && sNum[j] <= '9' ) aFrac.set( iFrac++, sNum[j]-'0' ); else @@ -286,7 +287,7 @@ void Number::set( const Bu::String &sNum ) } } - Bu::println("done."); +// Bu::println("done."); } void Number::set( const Number &sNum ) @@ -447,25 +448,28 @@ void Number::divide( const Number &rhs, Number &q, Number &r ) const Number newbase = Number( iScale, iRadix ); int iOff; for( iOff = -iScale; iOff < 0 && rhs.digit( iOff ) == 0; iOff++ ) { } - for( int j = iOff; j < rhs.aInt.getSize(); j++ ) + if( iOff < 0 ) { - newrhs.aInt.append( rhs.digit( j ) ); - newbase.aInt.append( digit( j ) ); - } - for( int j = 0; j < aInt.getSize(); j++ ) - { - newbase.aInt.append( aInt.get( j ) ); - } - for( int j = iScale+iOff; j >= -iOff; j-- ) - { - newbase.aFrac.set( j+iOff, aFrac.get( j ) ); - } + for( int j = iOff; j < rhs.aInt.getSize(); j++ ) + { + newrhs.aInt.append( rhs.digit( j ) ); + newbase.aInt.append( digit( j ) ); + } + for( int j = 0; j < aInt.getSize(); j++ ) + { + newbase.aInt.append( aInt.get( j ) ); + } + for( int j = iScale+iOff; j >= -iOff; j-- ) + { + newbase.aFrac.set( j+iOff, aFrac.get( j ) ); + } - Bu::println("Conv %1 => %2 (iOff = %3)").arg( rhs ).arg( newrhs ).arg( iOff ); - Bu::println("Conv %1 => %2 (iOff = %3)").arg( *this ).arg( newbase ).arg( iOff ); +// Bu::println("Conv %1 => %2 (iOff = %3)").arg( rhs ).arg( newrhs ).arg( iOff ); +// Bu::println("Conv %1 => %2 (iOff = %3)").arg( *this ).arg( newbase ).arg( iOff ); - newbase.divide( newrhs, q, r ); - return; + newbase.divide( newrhs, q, r ); + return; + } } q = Number( iScale, iRadix ); @@ -482,60 +486,115 @@ void Number::divide( const Number &rhs, Number &q, Number &r ) const int iSample = iMinWidth; do { - Bu::println("%1\n-----").arg( r.aInt.toString() ); - Number sub( iScale, iRadix ); +// Bu::println("%1\n-----").arg( r.aInt.toString() ); + Number sub( 0, iRadix ); + if( iAnchor < 0 ) + { + sub = r; + sub.aInt.insert(0,0); + } 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() ); +// Bu::println(" -> Anchor: %1, Sample: %2").arg( iAnchor ).arg( iSample ); + if( iAnchor >= 0 ) + { + sub.aInt.set( r.aInt, iAnchor, iSample ); + } + else + { +/* sub.aInt.clear(); + for( int j = iAnchor; j < r.aInt.getSize(); j++ ) + { + sub.aInt.append( r.digit( j ) ); + } + */ + } +// 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; + if( r.isZero() || iAnchor < -iScale ) + { +// Bu::println("[Inner exit] Complete: q = %1, r = %2").arg( q.toString() ).arg( r.toString() ); + return; + } + sub.aInt.insert(0, 0); } } else break; } - Number x( rhs.iScale, iRadix ); + Number x( 0, iRadix ); int iRes = -1; - Bu::println("{x = %1, sub=%2, rhs=%4, iRes=%3}").arg( x ).arg(sub).arg(iRes).arg(rhs); +// Bu::println("{x = %1, sub=%2, rhs=%4, iRes=%3}").arg( x ).arg(sub).arg(iRes).arg(rhs); for( ; x <= sub; iRes++, x = x + rhs ) { - Bu::println("{x = %1, sub=%2, rhs=%4, iRes=%3, x+rhs=%5}").arg( x ).arg(sub).arg(iRes).arg(rhs).arg(x+rhs); +// Bu::println("{x = %1, sub=%2, rhs=%4, iRes=%3, x+rhs=%5}").arg( x ).arg(sub).arg(iRes).arg(rhs).arg(x+rhs); } x = sub - (x - rhs); if( !x.bPositive ) { iSample++; iAnchor--; - Bu::println("What? it's negative? %1").arg( x ); +// Bu::println("What? it's negative? %1").arg( x ); continue; } - 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() ) + if( iAnchor < 0 ) + { + r = x; + } + else + { + for( int j = 0; j < x.aInt.getSize(); j++ ) + r.aInt.set( iAnchor+j, x.aInt.get( j ) ); + } + + while( r.aInt.getSize() > Bu::buMax(0,iAnchor)+x.aInt.getSize() ) r.aInt.remove(); - Bu::println(" -> Post remainder patch: %1 -> %2"). - arg( x.toString() ).arg( r.toString() ); +// Bu::println(" -> Post remainder patch: %1 -> %2"). +// arg( x.toString() ).arg( r.toString() ); - Bu::println("%1 (%2)").arg( iRes ).arg( x.toString() ); +// Bu::println("%1 (%2)").arg( iRes ).arg( x.toString() ); while( q.aInt.getSize() <= iAnchor ) q.aInt.append(0); - q.aInt.set( iAnchor, iRes ); - + if( iAnchor >= 0 ) + q.aInt.set( iAnchor, iRes ); + else + q.aFrac.set( -1-iAnchor, iRes ); + iSample = iMinWidth; - iAnchor = r.aInt.getSize()-iMinWidth; - Bu::println(" -> new Anchor: %1, Sample: %2").arg( iAnchor ). - arg( iSample ); - } while( iAnchor >= 0 ); + if( iAnchor > 0 ) + iAnchor -= rhs.aInt.getSize()-x.aInt.getSize(); + else + iAnchor--; +// iAnchor = r.aInt.getSize()-iMinWidth; +// Bu::println(" -> new Anchor: %1, Sample: %2").arg( iAnchor ). +// arg( iSample ); + } while( iAnchor >= -iScale ); + +// Bu::println("Complete: q = %1, r = %2").arg( q.toString() ).arg( r.toString() ); +} + +bool Number::isZero() const +{ + if( aInt.getSize() == 0 && iScale == 0 ) + return true; - Bu::println("Complete: q = %1, r = %2").arg( q.toString() ).arg( r.toString() ); + for( int j = 0; j < aInt.getSize(); j++ ) + { + if( aInt[j] ) + return false; + } + for( int j = 0; j < aFrac.getSize(); j++ ) + { + if( aFrac[j] ) + return false; + } + + return true; } Bu::Formatter &operator<<( Bu::Formatter &f, const Number &n ) diff --git a/src/number.h b/src/number.h index c16dd55..3806300 100644 --- a/src/number.h +++ b/src/number.h @@ -32,6 +32,7 @@ public: void set( const Number &sNum ); void divide( const Number &rhs, Number &q, Number &r ) const; + bool isZero() const; operator Bu::String() const { diff --git a/src/packedintarray.cpp b/src/packedintarray.cpp index bcd2f66..5397a73 100644 --- a/src/packedintarray.cpp +++ b/src/packedintarray.cpp @@ -64,6 +64,12 @@ void PackedIntArray::clear() iCount = 0; } +void PackedIntArray::zero() +{ + int iSize = StoreCount(iCapacity); + memset( aData, 0, iSize*sizeof(Store)); +} + void PackedIntArray::append( PackedIntArray::Unit i ) { iCount++; @@ -117,6 +123,17 @@ void PackedIntArray::set( int idx, PackedIntArray::Unit i ) } } +void PackedIntArray::insert( int idx, Unit i ) +{ + iCount++; + checkCapacity(); + for( int j = iCount-1; j > idx; j-- ) + { + set( j, get( j-1 ) ); + } + set( idx, i ); +} + void PackedIntArray::set( const PackedIntArray &rSrc, int iStart, int iSize ) { iCount = iSize; diff --git a/src/packedintarray.h b/src/packedintarray.h index 457acf5..4ac0bc7 100644 --- a/src/packedintarray.h +++ b/src/packedintarray.h @@ -13,11 +13,13 @@ public: virtual ~PackedIntArray(); void clear(); + void zero(); void append( Unit i ); void remove(); Unit operator[]( int idx ) const { return get( idx ); } Unit get( int idx ) const; void set( int idx, Unit i ); + void insert( int idx, Unit i ); int getSize() const { return iCount; } void set( const PackedIntArray &rSrc, int iStart, int iSize ); void set( const PackedIntArray &rSrc ); -- cgit v1.2.3