summaryrefslogtreecommitdiff
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
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.
-rw-r--r--src/main.cpp104
-rw-r--r--src/number.cpp51
-rw-r--r--src/number.h5
3 files changed, 141 insertions, 19 deletions
diff --git a/src/main.cpp b/src/main.cpp
index d436a20..6674075 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,5 +1,7 @@
1#include "number.h" 1#include "number.h"
2#include "packedintarray.h" 2#include "packedintarray.h"
3#include <math.h>
4#include <sys/time.h>
3 5
4#include <bu/sio.h> 6#include <bu/sio.h>
5using namespace Bu; 7using namespace Bu;
@@ -177,6 +179,18 @@ void numbertest1()
177 arg( a.toString() ). 179 arg( a.toString() ).
178 arg( b.toString() ). 180 arg( b.toString() ).
179 arg( (a % b).toString() ); 181 arg( (a % b).toString() );
182
183 a = "983429807324875233421784598754987439873472349875329853298732";
184 b = "18446744073709551615";
185
186 println("%1 / %2 = %3").
187 arg( a.toString() ).
188 arg( b.toString() ).
189 arg( (a / b).toString() );
190 println("%1 %% %2 = %3").
191 arg( a.toString() ).
192 arg( b.toString() ).
193 arg( (a % b).toString() );
180} 194}
181 195
182#define compcheck( anum, op, bnum ) \ 196#define compcheck( anum, op, bnum ) \
@@ -245,13 +259,101 @@ void numbertestcomp()
245 compcheck( 123, <=, -122 ); 259 compcheck( 123, <=, -122 );
246} 260}
247 261
262int getHob( int x )
263{
264 for( int j = 31; j >= 0; j-- )
265 {
266 if( x&(1<<j) )
267 {
268 return j+1;
269 }
270 }
271 return 0;
272}
273
274int getOrd( int x )
275{
276 return (int)(log(x)*0xb.8aa3b295c17fp-3+1.0);
277}
278
279double getTime()
280{
281 timeval t;
282 gettimeofday( &t, NULL );
283 return (double)t.tv_sec + (double)(t.tv_usec*.000001);
284}
285
286void ordertest()
287{
288 for( int j = 2; j < 64; j++ )
289 {
290 if( getOrd( j ) != getHob(j-1) )
291 println("Failure on radix %1").arg( j );
292 }
293
294 double dStart, dEnd;
295
296 dStart = getTime();
297 for( int k = 0; k < 100000; k++ )
298 {
299 for( int j = 2; j < 32; j++ )
300 {
301 getOrd( j );
302 }
303 }
304 dEnd = getTime();
305
306 println("getOrd: %1 in %2 (%3 cps)").arg( 30*100000 ).arg( dEnd-dStart ).
307 arg( (30*100000)/(dEnd-dStart) );
308
309 dStart = getTime();
310 for( int k = 0; k < 100000; k++ )
311 {
312 for( int j = 2; j < 32; j++ )
313 {
314 getHob( j-1 );
315 }
316 }
317 dEnd = getTime();
318
319 println("getHob: %1 in %2 (%3 cps)").arg( 30*100000 ).arg( dEnd-dStart ).
320 arg( (30*100000)/(dEnd-dStart) );
321}
322
323void radixtest()
324{
325 Number a( 16 ), b( 16 );
326
327 a = "f8a72bce3";
328 b = "9ea8cb3";
329 println("%1 + %2 = %3").
330 arg( a.toString() ).
331 arg( b.toString() ).
332 arg( (a + b).toString() );
333 println("%1 - %2 = %3").
334 arg( a.toString() ).
335 arg( b.toString() ).
336 arg( (a - b).toString() );
337 println("%1 / %2 = %3").
338 arg( a.toString() ).
339 arg( b.toString() ).
340 arg( (a / b).toString() );
341 println("%1 * %2 = %3").
342 arg( a.toString() ).
343 arg( b.toString() ).
344 arg( (a * b).toString() );
345}
346
248int main( int , char *[] ) 347int main( int , char *[] )
249{ 348{
250 println("CliC"); 349 println("CliC");
251 350
252// packedtest1(); 351// packedtest1();
253 numbertest1(); 352// numbertest1();
254// numbertestcomp(); 353// numbertestcomp();
354 radixtest();
355
356// ordertest();
255 357
256 return 0; 358 return 0;
257} 359}
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);
diff --git a/src/number.h b/src/number.h
index ee000a8..8d98a1b 100644
--- a/src/number.h
+++ b/src/number.h
@@ -7,8 +7,8 @@
7class Number 7class Number
8{ 8{
9public: 9public:
10 Number( int iOrd=0 ); 10 Number( int iRadix=10, int iOrd=0 );
11 Number( const Bu::String &sData, int iOrd=0 ); 11 Number( const Bu::String &sData, int iRadix=10, int iOrd=0 );
12 virtual ~Number(); 12 virtual ~Number();
13 13
14 Number &operator=( const Bu::String &sNum ); 14 Number &operator=( const Bu::String &sNum );
@@ -46,6 +46,7 @@ private:
46 Number add( const Number &rhs, bool bSub ) const; 46 Number add( const Number &rhs, bool bSub ) const;
47 47
48private: 48private:
49 int iRadix;
49 int iOrd; 50 int iOrd;
50 bool bPositive; 51 bool bPositive;
51 PackedIntArray aInt; 52 PackedIntArray aInt;