#include "number.h" #include #define iRadix (10) Number::Number( int iOrd ) : iOrd( iOrd ), aInt( 4 ), bPositive( true ) { } Number::Number( const Bu::String &sData, int iOrd ) : iOrd( iOrd ), aInt( 4 ), bPositive( true ) { set( sData ); } Number::~Number() { } Number &Number::operator=( const Bu::String &sNum ) { set( sNum ); return *this; } template t tabs( t x ) { return (x<(t)0)?(-x):x; } Number Number::operator+( const Number &rhs ) const { return add( rhs, false ); } Number Number::operator-( const Number &rhs ) const { return add( rhs, true ); } Number Number::operator*( const Number &rhs ) const { Number ret( iOrd ); int iPlaces = Bu::buMax(rhs.aInt.getSize(), aInt.getSize() ); int iCnt = aInt.getSize()+rhs.aInt.getSize(); int iCarry = 0; int iZeros = 0; for( int j = 0; j < iCnt || iCarry > 0; j++ ) { // Bu::println("Pos %1").arg(j); int iPos = iCarry; iCarry = 0; for( int k = 0; k < rhs.aInt.getSize(); k++ ) { if( j-k < 0 ) break; int iRes = digit(j-k)*rhs.digit(k); iPos += iRes; // Bu::println(" [%1] %2 * [%3] %4 = %5 -> %6"). // arg( j-k ).arg( digit(j-k) ).arg( k ).arg( rhs.digit(k) ). // arg( iRes ).arg( iPos ).arg( iCarry ); } if( (iPos%iRadix) == 0 ) iZeros++; else { for(; iZeros > 0; iZeros-- ) ret.aInt.append( 0 ); ret.aInt.append( iPos%iRadix ); } iCarry += iPos/iRadix; } if( bPositive == rhs.bPositive ) ret.bPositive = true; else ret.bPositive = false; return ret; } void Number::set( const Bu::String &sNum ) { aInt.clear(); bPositive = true; for( int j = sNum.getSize()-1; j >= 0; j-- ) { if( sNum[j] == '+' ) break; if( sNum[j] == '-' ) { bPositive = false; break; } aInt.append( sNum[j]-'0' ); } } Bu::String Number::toString() const { if( aInt.getSize() == 0 ) return "0"; return (bPositive?"":"-") + aInt.toString(); } int Number::digit( int iOrder ) const { if( iOrder >= aInt.getSize() ) return 0; return aInt[iOrder]; } Number Number::add( const Number &rhs, bool bSub ) const { Number ret( iOrd ); int iPlaces = Bu::buMax(rhs.aInt.getSize(), aInt.getSize() ); int iZeros = 0; int iCarry = 0; if( bPositive == (bSub?!rhs.bPositive:rhs.bPositive)) { ret.bPositive = bPositive; for( int j = 0; j < iPlaces || iCarry > 0; j++ ) { int iRes = iCarry + digit( j ) + rhs.digit( j ); // Bu::println(" Place: %1 + %2 + (%3) = %4"). // arg( digit(j) ).arg( rhs.digit( j ) ).arg( iCarry ) // .arg( iRes ); 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; for( int j = 0; j < iPlaces; j++ ) { iRes = digit( j ) + (9-rhs.digit( j )) + iCarry; // Bu::println(" Place: %1 + %2 + (%3) = %4"). // arg( digit(j) ).arg( 9-rhs.digit( j ) ).arg( iCarry ) // .arg( iRes ); 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, 9-ret.aInt.get( 0 )+1); for( int j = 1; j < ret.aInt.getSize(); j++ ) { ret.aInt.set( j, 9-ret.aInt.get( j )); } } } return ret; }