diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.cpp | 5 | ||||
| -rw-r--r-- | src/number.cpp | 147 | ||||
| -rw-r--r-- | src/number.h | 1 | ||||
| -rw-r--r-- | src/packedintarray.cpp | 17 | ||||
| -rw-r--r-- | src/packedintarray.h | 2 |
5 files changed, 127 insertions, 45 deletions
diff --git a/src/main.cpp b/src/main.cpp index fe9a1fe..a9b0072 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
| @@ -281,12 +281,15 @@ void fractest() | |||
| 281 | Number a( 8 ), b( 8 ); | 281 | Number a( 8 ), b( 8 ); |
| 282 | 282 | ||
| 283 | a = "123.456"; | 283 | a = "123.456"; |
| 284 | println("%1").arg( a ); | ||
| 285 | b = "0.987"; | 284 | b = "0.987"; |
| 286 | println("%1 + %2 = %3").arg( a ).arg( b ).arg( a + b ); | 285 | println("%1 + %2 = %3").arg( a ).arg( b ).arg( a + b ); |
| 287 | println("%1 - %2 = %3").arg( a ).arg( b ).arg( a - b ); | 286 | println("%1 - %2 = %3").arg( a ).arg( b ).arg( a - b ); |
| 288 | println("%1 * %2 = %3").arg( a ).arg( b ).arg( a * b ); | 287 | println("%1 * %2 = %3").arg( a ).arg( b ).arg( a * b ); |
| 289 | println("%1 / %2 = %3").arg( a ).arg( b ).arg( a / b ); | 288 | println("%1 / %2 = %3").arg( a ).arg( b ).arg( a / b ); |
| 289 | |||
| 290 | a = "12"; | ||
| 291 | b = "4"; | ||
| 292 | println("%1 / %2 = %3").arg( a ).arg( b ).arg( a / b ); | ||
| 290 | } | 293 | } |
| 291 | 294 | ||
| 292 | int main( int , char *[] ) | 295 | int main( int , char *[] ) |
diff --git a/src/number.cpp b/src/number.cpp index b923d5f..15cad95 100644 --- a/src/number.cpp +++ b/src/number.cpp | |||
| @@ -244,8 +244,9 @@ bool Number::operator<=( const Number &rhs ) const | |||
| 244 | 244 | ||
| 245 | void Number::set( const Bu::String &sNum ) | 245 | void Number::set( const Bu::String &sNum ) |
| 246 | { | 246 | { |
| 247 | Bu::println("Parsing: '%1'").arg( sNum ); | 247 | // Bu::println("Parsing: '%1'").arg( sNum ); |
| 248 | aInt.clear(); | 248 | aInt.clear(); |
| 249 | aFrac.zero(); | ||
| 249 | bPositive = true; | 250 | bPositive = true; |
| 250 | int iPt; | 251 | int iPt; |
| 251 | for( iPt = 0; iPt < sNum.getSize() && sNum[iPt] != '.'; iPt++ ) { } | 252 | for( iPt = 0; iPt < sNum.getSize() && sNum[iPt] != '.'; iPt++ ) { } |
| @@ -262,7 +263,7 @@ void Number::set( const Bu::String &sNum ) | |||
| 262 | 263 | ||
| 263 | for( int j = iPt-1; j >= iEnd; j-- ) | 264 | for( int j = iPt-1; j >= iEnd; j-- ) |
| 264 | { | 265 | { |
| 265 | Bu::println(" -> '%1'").arg( sNum[j] ); | 266 | // Bu::println(" -> '%1'").arg( sNum[j] ); |
| 266 | if( sNum[j] == '.' ) | 267 | if( sNum[j] == '.' ) |
| 267 | break; | 268 | break; |
| 268 | if( sNum[j] >= '0' && sNum[j] <= '9' ) | 269 | if( sNum[j] >= '0' && sNum[j] <= '9' ) |
| @@ -276,7 +277,7 @@ void Number::set( const Bu::String &sNum ) | |||
| 276 | int iFrac = 0; | 277 | int iFrac = 0; |
| 277 | for( int j = iPt+1; j < sNum.getSize(); j++ ) | 278 | for( int j = iPt+1; j < sNum.getSize(); j++ ) |
| 278 | { | 279 | { |
| 279 | Bu::println(" => '%1'").arg( sNum[j] ); | 280 | // Bu::println(" => '%1'").arg( sNum[j] ); |
| 280 | if( sNum[j] >= '0' && sNum[j] <= '9' ) | 281 | if( sNum[j] >= '0' && sNum[j] <= '9' ) |
| 281 | aFrac.set( iFrac++, sNum[j]-'0' ); | 282 | aFrac.set( iFrac++, sNum[j]-'0' ); |
| 282 | else | 283 | else |
| @@ -286,7 +287,7 @@ void Number::set( const Bu::String &sNum ) | |||
| 286 | } | 287 | } |
| 287 | } | 288 | } |
| 288 | 289 | ||
| 289 | Bu::println("done."); | 290 | // Bu::println("done."); |
| 290 | } | 291 | } |
| 291 | 292 | ||
| 292 | void Number::set( const Number &sNum ) | 293 | void Number::set( const Number &sNum ) |
| @@ -447,25 +448,28 @@ void Number::divide( const Number &rhs, Number &q, Number &r ) const | |||
| 447 | Number newbase = Number( iScale, iRadix ); | 448 | Number newbase = Number( iScale, iRadix ); |
| 448 | int iOff; | 449 | int iOff; |
| 449 | for( iOff = -iScale; iOff < 0 && rhs.digit( iOff ) == 0; iOff++ ) { } | 450 | for( iOff = -iScale; iOff < 0 && rhs.digit( iOff ) == 0; iOff++ ) { } |
| 450 | for( int j = iOff; j < rhs.aInt.getSize(); j++ ) | 451 | if( iOff < 0 ) |
| 451 | { | 452 | { |
| 452 | newrhs.aInt.append( rhs.digit( j ) ); | 453 | for( int j = iOff; j < rhs.aInt.getSize(); j++ ) |
| 453 | newbase.aInt.append( digit( j ) ); | 454 | { |
| 454 | } | 455 | newrhs.aInt.append( rhs.digit( j ) ); |
| 455 | for( int j = 0; j < aInt.getSize(); j++ ) | 456 | newbase.aInt.append( digit( j ) ); |
| 456 | { | 457 | } |
| 457 | newbase.aInt.append( aInt.get( j ) ); | 458 | for( int j = 0; j < aInt.getSize(); j++ ) |
| 458 | } | 459 | { |
| 459 | for( int j = iScale+iOff; j >= -iOff; j-- ) | 460 | newbase.aInt.append( aInt.get( j ) ); |
| 460 | { | 461 | } |
| 461 | newbase.aFrac.set( j+iOff, aFrac.get( j ) ); | 462 | for( int j = iScale+iOff; j >= -iOff; j-- ) |
| 462 | } | 463 | { |
| 464 | newbase.aFrac.set( j+iOff, aFrac.get( j ) ); | ||
| 465 | } | ||
| 463 | 466 | ||
| 464 | Bu::println("Conv %1 => %2 (iOff = %3)").arg( rhs ).arg( newrhs ).arg( iOff ); | 467 | // Bu::println("Conv %1 => %2 (iOff = %3)").arg( rhs ).arg( newrhs ).arg( iOff ); |
| 465 | Bu::println("Conv %1 => %2 (iOff = %3)").arg( *this ).arg( newbase ).arg( iOff ); | 468 | // Bu::println("Conv %1 => %2 (iOff = %3)").arg( *this ).arg( newbase ).arg( iOff ); |
| 466 | 469 | ||
| 467 | newbase.divide( newrhs, q, r ); | 470 | newbase.divide( newrhs, q, r ); |
| 468 | return; | 471 | return; |
| 472 | } | ||
| 469 | } | 473 | } |
| 470 | 474 | ||
| 471 | q = Number( iScale, iRadix ); | 475 | q = Number( iScale, iRadix ); |
| @@ -482,60 +486,115 @@ void Number::divide( const Number &rhs, Number &q, Number &r ) const | |||
| 482 | int iSample = iMinWidth; | 486 | int iSample = iMinWidth; |
| 483 | do | 487 | do |
| 484 | { | 488 | { |
| 485 | Bu::println("%1\n-----").arg( r.aInt.toString() ); | 489 | // Bu::println("%1\n-----").arg( r.aInt.toString() ); |
| 486 | Number sub( iScale, iRadix ); | 490 | Number sub( 0, iRadix ); |
| 491 | if( iAnchor < 0 ) | ||
| 492 | { | ||
| 493 | sub = r; | ||
| 494 | sub.aInt.insert(0,0); | ||
| 495 | } | ||
| 487 | for(;;) | 496 | for(;;) |
| 488 | { | 497 | { |
| 489 | Bu::println(" -> Anchor: %1, Sample: %2").arg( iAnchor ).arg( iSample ); | 498 | // Bu::println(" -> Anchor: %1, Sample: %2").arg( iAnchor ).arg( iSample ); |
| 490 | sub.aInt.set( r.aInt, iAnchor, iSample ); | 499 | if( iAnchor >= 0 ) |
| 491 | Bu::println("%1\n%2\n----").arg( sub.toString() ).arg( rhs.toString() ); | 500 | { |
| 501 | sub.aInt.set( r.aInt, iAnchor, iSample ); | ||
| 502 | } | ||
| 503 | else | ||
| 504 | { | ||
| 505 | /* sub.aInt.clear(); | ||
| 506 | for( int j = iAnchor; j < r.aInt.getSize(); j++ ) | ||
| 507 | { | ||
| 508 | sub.aInt.append( r.digit( j ) ); | ||
| 509 | } | ||
| 510 | */ | ||
| 511 | } | ||
| 512 | // Bu::println("%1\n%2\n----").arg( sub.toString() ).arg( rhs.toString() ); | ||
| 492 | if( sub < rhs ) | 513 | if( sub < rhs ) |
| 493 | { | 514 | { |
| 494 | iSample++; | 515 | iSample++; |
| 495 | iAnchor--; | 516 | iAnchor--; |
| 496 | if( iAnchor < 0 ) | 517 | if( iAnchor < 0 ) |
| 497 | { | 518 | { |
| 498 | Bu::println("[Inner exit] Complete: q = %1, r = %2").arg( q.toString() ).arg( r.toString() ); | 519 | if( r.isZero() || iAnchor < -iScale ) |
| 499 | return; | 520 | { |
| 521 | // Bu::println("[Inner exit] Complete: q = %1, r = %2").arg( q.toString() ).arg( r.toString() ); | ||
| 522 | return; | ||
| 523 | } | ||
| 524 | sub.aInt.insert(0, 0); | ||
| 500 | } | 525 | } |
| 501 | } | 526 | } |
| 502 | else | 527 | else |
| 503 | break; | 528 | break; |
| 504 | } | 529 | } |
| 505 | 530 | ||
| 506 | Number x( rhs.iScale, iRadix ); | 531 | Number x( 0, iRadix ); |
| 507 | int iRes = -1; | 532 | int iRes = -1; |
| 508 | Bu::println("{x = %1, sub=%2, rhs=%4, iRes=%3}").arg( x ).arg(sub).arg(iRes).arg(rhs); | 533 | // Bu::println("{x = %1, sub=%2, rhs=%4, iRes=%3}").arg( x ).arg(sub).arg(iRes).arg(rhs); |
| 509 | for( ; x <= sub; iRes++, x = x + rhs ) { | 534 | for( ; x <= sub; iRes++, x = x + rhs ) { |
| 510 | Bu::println("{x = %1, sub=%2, rhs=%4, iRes=%3, x+rhs=%5}").arg( x ).arg(sub).arg(iRes).arg(rhs).arg(x+rhs); | 535 | // Bu::println("{x = %1, sub=%2, rhs=%4, iRes=%3, x+rhs=%5}").arg( x ).arg(sub).arg(iRes).arg(rhs).arg(x+rhs); |
| 511 | } | 536 | } |
| 512 | x = sub - (x - rhs); | 537 | x = sub - (x - rhs); |
| 513 | if( !x.bPositive ) | 538 | if( !x.bPositive ) |
| 514 | { | 539 | { |
| 515 | iSample++; | 540 | iSample++; |
| 516 | iAnchor--; | 541 | iAnchor--; |
| 517 | Bu::println("What? it's negative? %1").arg( x ); | 542 | // Bu::println("What? it's negative? %1").arg( x ); |
| 518 | continue; | 543 | continue; |
| 519 | } | 544 | } |
| 520 | for( int j = 0; iAnchor+j >= 0 && j < x.aInt.getSize(); j++ ) | 545 | if( iAnchor < 0 ) |
| 521 | r.aInt.set( iAnchor+j, x.aInt.get( j ) ); | 546 | { |
| 522 | while( r.aInt.getSize() > iAnchor+x.aInt.getSize() ) | 547 | r = x; |
| 548 | } | ||
| 549 | else | ||
| 550 | { | ||
| 551 | for( int j = 0; j < x.aInt.getSize(); j++ ) | ||
| 552 | r.aInt.set( iAnchor+j, x.aInt.get( j ) ); | ||
| 553 | } | ||
| 554 | |||
| 555 | while( r.aInt.getSize() > Bu::buMax(0,iAnchor)+x.aInt.getSize() ) | ||
| 523 | r.aInt.remove(); | 556 | r.aInt.remove(); |
| 524 | Bu::println(" -> Post remainder patch: %1 -> %2"). | 557 | // Bu::println(" -> Post remainder patch: %1 -> %2"). |
| 525 | arg( x.toString() ).arg( r.toString() ); | 558 | // arg( x.toString() ).arg( r.toString() ); |
| 526 | 559 | ||
| 527 | Bu::println("%1 (%2)").arg( iRes ).arg( x.toString() ); | 560 | // Bu::println("%1 (%2)").arg( iRes ).arg( x.toString() ); |
| 528 | while( q.aInt.getSize() <= iAnchor ) | 561 | while( q.aInt.getSize() <= iAnchor ) |
| 529 | q.aInt.append(0); | 562 | q.aInt.append(0); |
| 530 | q.aInt.set( iAnchor, iRes ); | 563 | if( iAnchor >= 0 ) |
| 531 | 564 | q.aInt.set( iAnchor, iRes ); | |
| 565 | else | ||
| 566 | q.aFrac.set( -1-iAnchor, iRes ); | ||
| 567 | |||
| 532 | iSample = iMinWidth; | 568 | iSample = iMinWidth; |
| 533 | iAnchor = r.aInt.getSize()-iMinWidth; | 569 | if( iAnchor > 0 ) |
| 534 | Bu::println(" -> new Anchor: %1, Sample: %2").arg( iAnchor ). | 570 | iAnchor -= rhs.aInt.getSize()-x.aInt.getSize(); |
| 535 | arg( iSample ); | 571 | else |
| 536 | } while( iAnchor >= 0 ); | 572 | iAnchor--; |
| 573 | // iAnchor = r.aInt.getSize()-iMinWidth; | ||
| 574 | // Bu::println(" -> new Anchor: %1, Sample: %2").arg( iAnchor ). | ||
| 575 | // arg( iSample ); | ||
| 576 | } while( iAnchor >= -iScale ); | ||
| 577 | |||
| 578 | // Bu::println("Complete: q = %1, r = %2").arg( q.toString() ).arg( r.toString() ); | ||
| 579 | } | ||
| 580 | |||
| 581 | bool Number::isZero() const | ||
| 582 | { | ||
| 583 | if( aInt.getSize() == 0 && iScale == 0 ) | ||
| 584 | return true; | ||
| 537 | 585 | ||
| 538 | Bu::println("Complete: q = %1, r = %2").arg( q.toString() ).arg( r.toString() ); | 586 | for( int j = 0; j < aInt.getSize(); j++ ) |
| 587 | { | ||
| 588 | if( aInt[j] ) | ||
| 589 | return false; | ||
| 590 | } | ||
| 591 | for( int j = 0; j < aFrac.getSize(); j++ ) | ||
| 592 | { | ||
| 593 | if( aFrac[j] ) | ||
| 594 | return false; | ||
| 595 | } | ||
| 596 | |||
| 597 | return true; | ||
| 539 | } | 598 | } |
| 540 | 599 | ||
| 541 | Bu::Formatter &operator<<( Bu::Formatter &f, const Number &n ) | 600 | Bu::Formatter &operator<<( Bu::Formatter &f, const Number &n ) |
diff --git a/src/number.h b/src/number.h index c16dd55..3806300 100644 --- a/src/number.h +++ b/src/number.h | |||
| @@ -32,6 +32,7 @@ public: | |||
| 32 | void set( const Number &sNum ); | 32 | void set( const Number &sNum ); |
| 33 | 33 | ||
| 34 | void divide( const Number &rhs, Number &q, Number &r ) const; | 34 | void divide( const Number &rhs, Number &q, Number &r ) const; |
| 35 | bool isZero() const; | ||
| 35 | 36 | ||
| 36 | operator Bu::String() const | 37 | operator Bu::String() const |
| 37 | { | 38 | { |
diff --git a/src/packedintarray.cpp b/src/packedintarray.cpp index bcd2f66..5397a73 100644 --- a/src/packedintarray.cpp +++ b/src/packedintarray.cpp | |||
| @@ -64,6 +64,12 @@ void PackedIntArray::clear() | |||
| 64 | iCount = 0; | 64 | iCount = 0; |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | void PackedIntArray::zero() | ||
| 68 | { | ||
| 69 | int iSize = StoreCount(iCapacity); | ||
| 70 | memset( aData, 0, iSize*sizeof(Store)); | ||
| 71 | } | ||
| 72 | |||
| 67 | void PackedIntArray::append( PackedIntArray::Unit i ) | 73 | void PackedIntArray::append( PackedIntArray::Unit i ) |
| 68 | { | 74 | { |
| 69 | iCount++; | 75 | iCount++; |
| @@ -117,6 +123,17 @@ void PackedIntArray::set( int idx, PackedIntArray::Unit i ) | |||
| 117 | } | 123 | } |
| 118 | } | 124 | } |
| 119 | 125 | ||
| 126 | void PackedIntArray::insert( int idx, Unit i ) | ||
| 127 | { | ||
| 128 | iCount++; | ||
| 129 | checkCapacity(); | ||
| 130 | for( int j = iCount-1; j > idx; j-- ) | ||
| 131 | { | ||
| 132 | set( j, get( j-1 ) ); | ||
| 133 | } | ||
| 134 | set( idx, i ); | ||
| 135 | } | ||
| 136 | |||
| 120 | void PackedIntArray::set( const PackedIntArray &rSrc, int iStart, int iSize ) | 137 | void PackedIntArray::set( const PackedIntArray &rSrc, int iStart, int iSize ) |
| 121 | { | 138 | { |
| 122 | iCount = iSize; | 139 | iCount = iSize; |
diff --git a/src/packedintarray.h b/src/packedintarray.h index 457acf5..4ac0bc7 100644 --- a/src/packedintarray.h +++ b/src/packedintarray.h | |||
| @@ -13,11 +13,13 @@ public: | |||
| 13 | virtual ~PackedIntArray(); | 13 | virtual ~PackedIntArray(); |
| 14 | 14 | ||
| 15 | void clear(); | 15 | void clear(); |
| 16 | void zero(); | ||
| 16 | void append( Unit i ); | 17 | void append( Unit i ); |
| 17 | void remove(); | 18 | void remove(); |
| 18 | Unit operator[]( int idx ) const { return get( idx ); } | 19 | Unit operator[]( int idx ) const { return get( idx ); } |
| 19 | Unit get( int idx ) const; | 20 | Unit get( int idx ) const; |
| 20 | void set( int idx, Unit i ); | 21 | void set( int idx, Unit i ); |
| 22 | void insert( int idx, Unit i ); | ||
| 21 | int getSize() const { return iCount; } | 23 | int getSize() const { return iCount; } |
| 22 | void set( const PackedIntArray &rSrc, int iStart, int iSize ); | 24 | void set( const PackedIntArray &rSrc, int iStart, int iSize ); |
| 23 | void set( const PackedIntArray &rSrc ); | 25 | void set( const PackedIntArray &rSrc ); |
