summaryrefslogtreecommitdiff
path: root/src/number.cpp
diff options
context:
space:
mode:
authorMike Buland <mike@xagasoft.com>2013-04-16 14:41:14 -0600
committerMike Buland <mike@xagasoft.com>2013-04-16 14:41:14 -0600
commit7cfca326d8f824d3749ece6ad63a793197bf6c9d (patch)
treefcde2eb8a7e479e6e4cfb3c88cd4c7d5828b5aa6 /src/number.cpp
parent0e95be4d89b394315a969814a77e08ed358261d6 (diff)
downloadclic-7cfca326d8f824d3749ece6ad63a793197bf6c9d.tar.gz
clic-7cfca326d8f824d3749ece6ad63a793197bf6c9d.tar.bz2
clic-7cfca326d8f824d3749ece6ad63a793197bf6c9d.tar.xz
clic-7cfca326d8f824d3749ece6ad63a793197bf6c9d.zip
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.
Diffstat (limited to 'src/number.cpp')
-rw-r--r--src/number.cpp51
1 files changed, 35 insertions, 16 deletions
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 @@
1#include "number.h" 1#include "number.h"
2 2
3#include <bu/sio.h> 3#include <bu/sio.h>
4#include <math.h>
4 5
5#define iRadix (10) 6#define RadixToBits( x ) ((int)(log((x))*0xb.8aa3b295c17fp-3+1.0))
6 7
7Number::Number( int iOrd ) : 8Number::Number( int iRadix, int iOrd ) :
9 iRadix( iRadix ),
8 iOrd( iOrd ), 10 iOrd( iOrd ),
9 bPositive( true ), 11 bPositive( true ),
10 aInt( 4 ) 12 aInt( RadixToBits(iRadix) )
11{ 13{
12} 14}
13 15
14Number::Number( const Bu::String &sData, int iOrd ) : 16Number::Number( const Bu::String &sData, int iRadix, int iOrd ) :
17 iRadix( iRadix ),
15 iOrd( iOrd ), 18 iOrd( iOrd ),
16 bPositive( true ), 19 bPositive( true ),
17 aInt( 4 ) 20 aInt( RadixToBits( iRadix ) )
18{ 21{
19 set( sData ); 22 set( sData );
20} 23}
@@ -47,7 +50,7 @@ Number Number::operator-( const Number &rhs ) const
47 50
48Number Number::operator*( const Number &rhs ) const 51Number Number::operator*( const Number &rhs ) const
49{ 52{
50 Number ret( iOrd ); 53 Number ret( iRadix, iOrd );
51 54
52 int iCnt = aInt.getSize()+rhs.aInt.getSize(); 55 int iCnt = aInt.getSize()+rhs.aInt.getSize();
53 56
@@ -91,14 +94,14 @@ Number Number::operator*( const Number &rhs ) const
91 94
92Number Number::operator/( const Number &rhs ) const 95Number Number::operator/( const Number &rhs ) const
93{ 96{
94 Number q( iOrd ), r( iOrd ); 97 Number q( iRadix, iOrd ), r( iRadix, iOrd );
95 divide( rhs, q, r ); 98 divide( rhs, q, r );
96 return q; 99 return q;
97} 100}
98 101
99Number Number::operator%( const Number &rhs ) const 102Number Number::operator%( const Number &rhs ) const
100{ 103{
101 Number q( iOrd ), r( iOrd ); 104 Number q( iRadix, iOrd ), r( iRadix, iOrd );
102 divide( rhs, q, r ); 105 divide( rhs, q, r );
103 return r; 106 return r;
104} 107}
@@ -244,7 +247,10 @@ void Number::set( const Bu::String &sNum )
244 bPositive = false; 247 bPositive = false;
245 break; 248 break;
246 } 249 }
247 aInt.append( sNum[j]-'0' ); 250 if( sNum[j] >= '0' && sNum[j] <= '9' )
251 aInt.append( sNum[j]-'0' );
252 else
253 aInt.append( sNum[j]-'a'+10 );
248 } 254 }
249} 255}
250 256
@@ -259,7 +265,19 @@ Bu::String Number::toString() const
259{ 265{
260 if( aInt.getSize() == 0 ) 266 if( aInt.getSize() == 0 )
261 return "0"; 267 return "0";
262 return (bPositive?"":"-") + aInt.toString(); 268 Bu::String sRet;
269 if( !bPositive )
270 sRet += '-';
271 for( int j = aInt.getSize()-1; j >= 0; j-- )
272 {
273 int x = aInt.get( j );
274 if( x >= 10 )
275 sRet += x-10+'a';
276 else
277 sRet += x+'0';
278 }
279
280 return sRet;
263} 281}
264 282
265int Number::digit( int iOrder ) const 283int Number::digit( int iOrder ) const
@@ -271,7 +289,7 @@ int Number::digit( int iOrder ) const
271 289
272Number Number::add( const Number &rhs, bool bSub ) const 290Number Number::add( const Number &rhs, bool bSub ) const
273{ 291{
274 Number ret( iOrd ); 292 Number ret( iRadix, iOrd );
275 293
276 int iPlaces = Bu::buMax(rhs.aInt.getSize(), aInt.getSize() ); 294 int iPlaces = Bu::buMax(rhs.aInt.getSize(), aInt.getSize() );
277 295
@@ -309,9 +327,10 @@ Number Number::add( const Number &rhs, bool bSub ) const
309// Bu::println("--method b--"); 327// Bu::println("--method b--");
310 ret.bPositive = bPositive; 328 ret.bPositive = bPositive;
311 int iRes; 329 int iRes;
330 int iComp = (iRadix-1);
312 for( int j = 0; j < iPlaces; j++ ) 331 for( int j = 0; j < iPlaces; j++ )
313 { 332 {
314 iRes = digit( j ) + (9-rhs.digit( j )) + iCarry; 333 iRes = digit( j ) + (iComp-rhs.digit( j )) + iCarry;
315// Bu::println(" Place: %1 + %2 + (%3) = %4"). 334// Bu::println(" Place: %1 + %2 + (%3) = %4").
316// arg( digit(j) ).arg( 9-rhs.digit( j ) ).arg( iCarry ) 335// arg( digit(j) ).arg( 9-rhs.digit( j ) ).arg( iCarry )
317// .arg( iRes ); 336// .arg( iRes );
@@ -332,10 +351,10 @@ Number Number::add( const Number &rhs, bool bSub ) const
332 if( iCarry == 0 ) 351 if( iCarry == 0 )
333 { 352 {
334 ret.bPositive = false; 353 ret.bPositive = false;
335 ret.aInt.set( 0, 9-ret.aInt.get( 0 )+1); 354 ret.aInt.set( 0, iComp-ret.aInt.get( 0 )+1);
336 for( int j = 1; j < ret.aInt.getSize(); j++ ) 355 for( int j = 1; j < ret.aInt.getSize(); j++ )
337 { 356 {
338 ret.aInt.set( j, 9-ret.aInt.get( j )); 357 ret.aInt.set( j, iComp-ret.aInt.get( j ));
339 } 358 }
340 } 359 }
341 else 360 else
@@ -367,7 +386,7 @@ void Number::divide( const Number &rhs, Number &q, Number &r ) const
367 do 386 do
368 { 387 {
369// Bu::println("%1\n-----").arg( r.aInt.toString() ); 388// Bu::println("%1\n-----").arg( r.aInt.toString() );
370 Number sub( iOrd ); 389 Number sub( iRadix, iOrd );
371 for(;;) 390 for(;;)
372 { 391 {
373// Bu::println(" -> Anchor: %1, Sample: %2").arg( iAnchor ).arg( iSample ); 392// 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
387 break; 406 break;
388 } 407 }
389 408
390 Number x( iOrd ); 409 Number x( iRadix, iOrd );
391 int iRes = 0; 410 int iRes = 0;
392 for( ; x <= sub; iRes++, x = x + rhs ) { } 411 for( ; x <= sub; iRes++, x = x + rhs ) { }
393 x = sub - (x - rhs); 412 x = sub - (x - rhs);