diff options
| -rw-r--r-- | src/main.cpp | 104 | ||||
| -rw-r--r-- | src/number.cpp | 51 | ||||
| -rw-r--r-- | src/number.h | 5 |
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> |
| 5 | using namespace Bu; | 7 | using 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 | ||
| 262 | int 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 | |||
| 274 | int getOrd( int x ) | ||
| 275 | { | ||
| 276 | return (int)(log(x)*0xb.8aa3b295c17fp-3+1.0); | ||
| 277 | } | ||
| 278 | |||
| 279 | double getTime() | ||
| 280 | { | ||
| 281 | timeval t; | ||
| 282 | gettimeofday( &t, NULL ); | ||
| 283 | return (double)t.tv_sec + (double)(t.tv_usec*.000001); | ||
| 284 | } | ||
| 285 | |||
| 286 | void 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 | |||
| 323 | void 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 | |||
| 248 | int main( int , char *[] ) | 347 | int 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 | ||
| 7 | Number::Number( int iOrd ) : | 8 | Number::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 | ||
| 14 | Number::Number( const Bu::String &sData, int iOrd ) : | 16 | Number::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 | ||
| 48 | Number Number::operator*( const Number &rhs ) const | 51 | Number 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 | ||
| 92 | Number Number::operator/( const Number &rhs ) const | 95 | Number 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 | ||
| 99 | Number Number::operator%( const Number &rhs ) const | 102 | Number 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 | ||
| 265 | int Number::digit( int iOrder ) const | 283 | int Number::digit( int iOrder ) const |
| @@ -271,7 +289,7 @@ int Number::digit( int iOrder ) const | |||
| 271 | 289 | ||
| 272 | Number Number::add( const Number &rhs, bool bSub ) const | 290 | Number 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 @@ | |||
| 7 | class Number | 7 | class Number |
| 8 | { | 8 | { |
| 9 | public: | 9 | public: |
| 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 | ||
| 48 | private: | 48 | private: |
| 49 | int iRadix; | ||
| 49 | int iOrd; | 50 | int iOrd; |
| 50 | bool bPositive; | 51 | bool bPositive; |
| 51 | PackedIntArray aInt; | 52 | PackedIntArray aInt; |
