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 | |
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')
-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 ); |