diff options
author | Mike Buland <mike@xagasoft.com> | 2013-04-19 15:36:29 -0600 |
---|---|---|
committer | Mike Buland <mike@xagasoft.com> | 2013-04-19 15:36:29 -0600 |
commit | 7260c36973fc0ad7ff24294ff5540d64bf32c334 (patch) | |
tree | 72e74744a789d4c1acedfa1afd1a07219cce9931 /src/number.cpp | |
parent | 9ad1a65f4dcbc31b031556803d27dc688a16ff4a (diff) | |
download | clic-7260c36973fc0ad7ff24294ff5540d64bf32c334.tar.gz clic-7260c36973fc0ad7ff24294ff5540d64bf32c334.tar.bz2 clic-7260c36973fc0ad7ff24294ff5540d64bf32c334.tar.xz clic-7260c36973fc0ad7ff24294ff5540d64bf32c334.zip |
Fractional divisoin works.
It doesn't round yet, and there's a chance I should be increasing the
precision, right now it keeps the precision of the left hand side
number.
Diffstat (limited to 'src/number.cpp')
-rw-r--r-- | src/number.cpp | 147 |
1 files changed, 103 insertions, 44 deletions
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 ) |