From 868af20101c99649b41489e8fcd2e118e20e76ec Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Fri, 19 Apr 2013 20:15:19 -0600 Subject: Added routines to get/set scale. --- src/number.cpp | 300 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 159 insertions(+), 141 deletions(-) (limited to 'src/number.cpp') diff --git a/src/number.cpp b/src/number.cpp index f9fab26..d16bd98 100644 --- a/src/number.cpp +++ b/src/number.cpp @@ -301,147 +301,6 @@ void Number::set( const Number &sNum ) iRadix = sNum.iRadix; } -Bu::String Number::toString() const -{ - int iSigDig = iScale-1; - for( ; iSigDig >= 0 && aFrac.get( iSigDig ) == 0; iSigDig-- ) { } - if( aInt.getSize() == 0 && iSigDig <= 0 ) - return "0"; - Bu::String sRet; - if( !bPositive ) - sRet += '-'; - if( aInt.getSize() > 0 ) - { - for( int j = aInt.getSize()-1; j >= 0; j-- ) - { - int x = aInt.get( j ); - if( x >= 10 ) - sRet += x-10+'a'; - else - sRet += x+'0'; - } - } - else - sRet += "0"; - if( iSigDig >= 0 ) - { - sRet += '.'; - for( int j = 0; j <= iSigDig; j++ ) - { - int x = aFrac.get( j ); - if( x >= 10 ) - sRet += x-10+'a'; - else - sRet += x+'0'; - } - } - - return sRet; -} - -int Number::digit( int iIdx ) const -{ - if( iIdx < 0 ) - { - if( iIdx <= -iScale ) - return 0; - else - return aFrac[-1-iIdx]; - } - if( iIdx >= aInt.getSize() ) - return 0; - return aInt[iIdx]; -} - -Number Number::add( const Number &rhs, bool bSub ) const -{ - Number ret( iScale, iRadix ); - - int iPlaces = Bu::buMax(rhs.aInt.getSize(), aInt.getSize() ); - - int iZeros = 0; - int iCarry = 0; -// Bu::println("::: %1 + %2:").arg( toString() ).arg( rhs.toString() ); - - if( bPositive == (bSub?!rhs.bPositive:rhs.bPositive)) - { - ret.bPositive = bPositive; - for( int j = -iScale; j < iPlaces || iCarry > 0; j++ ) - { - int iRes = iCarry + digit( j ) + rhs.digit( j ); -// Bu::println(" [%5] Place: %1 + %2 + (%3) = %4"). -// arg( digit(j) ).arg( rhs.digit( j ) ).arg( iCarry ) -// .arg( iRes ).arg( j ); - if( j < 0 ) - ret.aFrac.set( -1-j, (iRes%iRadix) ); - else - { - 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; - int iComp = (iRadix-1); - for( int j = -iScale; j < iPlaces; j++ ) - { - iRes = digit( j ) + (iComp-rhs.digit( j )) + iCarry; -// Bu::println(" Place: %1 + %2 + (%3) = %4"). -// arg( digit(j) ).arg( 9-rhs.digit( j ) ).arg( iCarry ) -// .arg( iRes ); - if( j < 0 ) - ret.aFrac.set( -1-j, (iRes%iRadix) ); - else - { - 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, iComp-ret.aInt.get( 0 )+1); - for( int j = 1; j < ret.aInt.getSize(); j++ ) - { - ret.aInt.set( j, iComp-ret.aInt.get( j )); - } - } - else - { - ret.aInt.trim(); - } - } - - return ret; -} - void Number::divide( const Number &rhs, Number &q, Number &r ) const { if( rhs.iScale > 0 ) @@ -599,6 +458,165 @@ bool Number::isZero() const return true; } +Bu::String Number::toString() const +{ + int iSigDig = iScale-1; + for( ; iSigDig >= 0 && aFrac.get( iSigDig ) == 0; iSigDig-- ) { } + if( aInt.getSize() == 0 && iSigDig <= 0 ) + return "0"; + Bu::String sRet; + if( !bPositive ) + sRet += '-'; + if( aInt.getSize() > 0 ) + { + for( int j = aInt.getSize()-1; j >= 0; j-- ) + { + int x = aInt.get( j ); + if( x >= 10 ) + sRet += x-10+'a'; + else + sRet += x+'0'; + } + } + else + sRet += "0"; + if( iSigDig >= 0 ) + { + sRet += '.'; + for( int j = 0; j <= iSigDig; j++ ) + { + int x = aFrac.get( j ); + if( x >= 10 ) + sRet += x-10+'a'; + else + sRet += x+'0'; + } + } + + return sRet; +} + +int Number::digit( int iIdx ) const +{ + if( iIdx < 0 ) + { + if( iIdx <= -iScale ) + return 0; + else + return aFrac[-1-iIdx]; + } + if( iIdx >= aInt.getSize() ) + return 0; + return aInt[iIdx]; +} + +void Number::setScale( int iNewScale ) +{ + if( iNewScale == 0 ) + aFrac.clear(); + else if( iScale == iNewScale ) + return; + else if( iScale < iNewScale ) + { + for(; iScale < iNewScale; iNewScale-- ) + aFrac.remove(); + } + else + { + for(; iScale > iNewScale; iNewScale++ ) + aFrac.append(0); + } +} + +Number Number::add( const Number &rhs, bool bSub ) const +{ + Number ret( Bu::buMax(iScale,rhs.iScale), iRadix ); + + int iPlaces = Bu::buMax(rhs.aInt.getSize(), aInt.getSize() ); + + int iZeros = 0; + int iCarry = 0; +// Bu::println("::: %1 + %2:").arg( toString() ).arg( rhs.toString() ); + + if( bPositive == (bSub?!rhs.bPositive:rhs.bPositive)) + { + ret.bPositive = bPositive; + for( int j = -iScale; j < iPlaces || iCarry > 0; j++ ) + { + int iRes = iCarry + digit( j ) + rhs.digit( j ); +// Bu::println(" [%5] Place: %1 + %2 + (%3) = %4"). +// arg( digit(j) ).arg( rhs.digit( j ) ).arg( iCarry ) +// .arg( iRes ).arg( j ); + if( j < 0 ) + ret.aFrac.set( -1-j, (iRes%iRadix) ); + else + { + 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; + int iComp = (iRadix-1); + for( int j = -iScale; j < iPlaces; j++ ) + { + iRes = digit( j ) + (iComp-rhs.digit( j )) + iCarry; +// Bu::println(" Place: %1 + %2 + (%3) = %4"). +// arg( digit(j) ).arg( 9-rhs.digit( j ) ).arg( iCarry ) +// .arg( iRes ); + if( j < 0 ) + ret.aFrac.set( -1-j, (iRes%iRadix) ); + else + { + 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, iComp-ret.aInt.get( 0 )+1); + for( int j = 1; j < ret.aInt.getSize(); j++ ) + { + ret.aInt.set( j, iComp-ret.aInt.get( j )); + } + } + else + { + ret.aInt.trim(); + } + } + + return ret; +} + Bu::Formatter &operator<<( Bu::Formatter &f, const Number &n ) { return f << n.toString(); -- cgit v1.2.3