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/number.cpp | 147 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 103 insertions(+), 44 deletions(-) (limited to 'src/number.cpp') 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 ) -- cgit v1.2.3