From 7cfca326d8f824d3749ece6ad63a793197bf6c9d Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 16 Apr 2013 14:41:14 -0600 Subject: Full support for arbitrary radixes is in place. It computes the radix and bitwidth dynamically, we could probably speed that up another step by simply having a table of common ones, but for now it'll work for anything. --- src/number.cpp | 51 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 16 deletions(-) (limited to 'src/number.cpp') diff --git a/src/number.cpp b/src/number.cpp index b3a33dc..12a86e0 100644 --- a/src/number.cpp +++ b/src/number.cpp @@ -1,20 +1,23 @@ #include "number.h" #include +#include -#define iRadix (10) +#define RadixToBits( x ) ((int)(log((x))*0xb.8aa3b295c17fp-3+1.0)) -Number::Number( int iOrd ) : +Number::Number( int iRadix, int iOrd ) : + iRadix( iRadix ), iOrd( iOrd ), bPositive( true ), - aInt( 4 ) + aInt( RadixToBits(iRadix) ) { } -Number::Number( const Bu::String &sData, int iOrd ) : +Number::Number( const Bu::String &sData, int iRadix, int iOrd ) : + iRadix( iRadix ), iOrd( iOrd ), bPositive( true ), - aInt( 4 ) + aInt( RadixToBits( iRadix ) ) { set( sData ); } @@ -47,7 +50,7 @@ Number Number::operator-( const Number &rhs ) const Number Number::operator*( const Number &rhs ) const { - Number ret( iOrd ); + Number ret( iRadix, iOrd ); int iCnt = aInt.getSize()+rhs.aInt.getSize(); @@ -91,14 +94,14 @@ Number Number::operator*( const Number &rhs ) const Number Number::operator/( const Number &rhs ) const { - Number q( iOrd ), r( iOrd ); + Number q( iRadix, iOrd ), r( iRadix, iOrd ); divide( rhs, q, r ); return q; } Number Number::operator%( const Number &rhs ) const { - Number q( iOrd ), r( iOrd ); + Number q( iRadix, iOrd ), r( iRadix, iOrd ); divide( rhs, q, r ); return r; } @@ -244,7 +247,10 @@ void Number::set( const Bu::String &sNum ) bPositive = false; break; } - aInt.append( sNum[j]-'0' ); + if( sNum[j] >= '0' && sNum[j] <= '9' ) + aInt.append( sNum[j]-'0' ); + else + aInt.append( sNum[j]-'a'+10 ); } } @@ -259,7 +265,19 @@ Bu::String Number::toString() const { if( aInt.getSize() == 0 ) return "0"; - return (bPositive?"":"-") + aInt.toString(); + Bu::String sRet; + if( !bPositive ) + sRet += '-'; + 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'; + } + + return sRet; } int Number::digit( int iOrder ) const @@ -271,7 +289,7 @@ int Number::digit( int iOrder ) const Number Number::add( const Number &rhs, bool bSub ) const { - Number ret( iOrd ); + Number ret( iRadix, iOrd ); int iPlaces = Bu::buMax(rhs.aInt.getSize(), aInt.getSize() ); @@ -309,9 +327,10 @@ Number Number::add( const Number &rhs, bool bSub ) const // Bu::println("--method b--"); ret.bPositive = bPositive; int iRes; + int iComp = (iRadix-1); for( int j = 0; j < iPlaces; j++ ) { - iRes = digit( j ) + (9-rhs.digit( j )) + iCarry; + 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 ); @@ -332,10 +351,10 @@ Number Number::add( const Number &rhs, bool bSub ) const if( iCarry == 0 ) { ret.bPositive = false; - ret.aInt.set( 0, 9-ret.aInt.get( 0 )+1); + ret.aInt.set( 0, iComp-ret.aInt.get( 0 )+1); for( int j = 1; j < ret.aInt.getSize(); j++ ) { - ret.aInt.set( j, 9-ret.aInt.get( j )); + ret.aInt.set( j, iComp-ret.aInt.get( j )); } } else @@ -367,7 +386,7 @@ void Number::divide( const Number &rhs, Number &q, Number &r ) const do { // Bu::println("%1\n-----").arg( r.aInt.toString() ); - Number sub( iOrd ); + Number sub( iRadix, iOrd ); for(;;) { // Bu::println(" -> Anchor: %1, Sample: %2").arg( iAnchor ).arg( iSample ); @@ -387,7 +406,7 @@ void Number::divide( const Number &rhs, Number &q, Number &r ) const break; } - Number x( iOrd ); + Number x( iRadix, iOrd ); int iRes = 0; for( ; x <= sub; iRes++, x = x + rhs ) { } x = sub - (x - rhs); -- cgit v1.2.3