summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Buland <mike@xagasoft.com>2013-04-19 15:36:29 -0600
committerMike Buland <mike@xagasoft.com>2013-04-19 15:36:29 -0600
commit7260c36973fc0ad7ff24294ff5540d64bf32c334 (patch)
tree72e74744a789d4c1acedfa1afd1a07219cce9931 /src
parent9ad1a65f4dcbc31b031556803d27dc688a16ff4a (diff)
downloadclic-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.cpp5
-rw-r--r--src/number.cpp147
-rw-r--r--src/number.h1
-rw-r--r--src/packedintarray.cpp17
-rw-r--r--src/packedintarray.h2
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
292int main( int , char *[] ) 295int 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
245void Number::set( const Bu::String &sNum ) 245void 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
292void Number::set( const Number &sNum ) 293void 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
581bool 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
541Bu::Formatter &operator<<( Bu::Formatter &f, const Number &n ) 600Bu::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
67void PackedIntArray::zero()
68{
69 int iSize = StoreCount(iCapacity);
70 memset( aData, 0, iSize*sizeof(Store));
71}
72
67void PackedIntArray::append( PackedIntArray::Unit i ) 73void 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
126void 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
120void PackedIntArray::set( const PackedIntArray &rSrc, int iStart, int iSize ) 137void 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 );