summaryrefslogtreecommitdiff
path: root/src/number.cpp
diff options
context:
space:
mode:
authorMike Buland <mike@xagasoft.com>2013-04-16 13:57:57 -0600
committerMike Buland <mike@xagasoft.com>2013-04-16 13:57:57 -0600
commit7bb55b03c393b5d00914d328a16d238d17f6aa0f (patch)
tree4d9a0547b105e1867f8118f2f00548e1e05589ad /src/number.cpp
parent25989c6d3911b1d29a5866e668bff52537893afb (diff)
downloadclic-7bb55b03c393b5d00914d328a16d238d17f6aa0f.tar.gz
clic-7bb55b03c393b5d00914d328a16d238d17f6aa0f.tar.bz2
clic-7bb55b03c393b5d00914d328a16d238d17f6aa0f.tar.xz
clic-7bb55b03c393b5d00914d328a16d238d17f6aa0f.zip
Added /, %, and = operators.
Division now works just fine, but by long division. There are apparently much faster ways of doing division, but as long as it works I feel like that's a great start :)
Diffstat (limited to '')
-rw-r--r--src/number.cpp107
1 files changed, 91 insertions, 16 deletions
diff --git a/src/number.cpp b/src/number.cpp
index 9b6ec55..b3a33dc 100644
--- a/src/number.cpp
+++ b/src/number.cpp
@@ -29,7 +29,11 @@ Number &Number::operator=( const Bu::String &sNum )
29 return *this; 29 return *this;
30} 30}
31 31
32template<typename t> t tabs( t x ) { return (x<(t)0)?(-x):x; } 32Number &Number::operator=( const Number &rhs )
33{
34 set( rhs );
35 return *this;
36}
33 37
34Number Number::operator+( const Number &rhs ) const 38Number Number::operator+( const Number &rhs ) const
35{ 39{
@@ -87,24 +91,18 @@ Number Number::operator*( const Number &rhs ) const
87 91
88Number Number::operator/( const Number &rhs ) const 92Number Number::operator/( const Number &rhs ) const
89{ 93{
90 if( rhs.aInt.getSize() > aInt.getSize() ) 94 Number q( iOrd ), r( iOrd );
91 return Number( iOrd ); 95 divide( rhs, q, r );
92
93 Number q( iOrd );
94
95 int iMinWidth = rhs.aInt.getSize();
96
97 Bu::println("%1\n-----").arg( aInt.toString() );
98 for( int j = aInt.getSize(); j > iMinWidth; j-- )
99 {
100 Number sub( iOrd );
101 sub.aInt.set( aInt, j-iMinWidth, iMinWidth );
102 Bu::println("%1\n%2\n----").arg( sub.toString() ).arg( rhs.toString() );
103 }
104
105 return q; 96 return q;
106} 97}
107 98
99Number Number::operator%( const Number &rhs ) const
100{
101 Number q( iOrd ), r( iOrd );
102 divide( rhs, q, r );
103 return r;
104}
105
108Number Number::operator-() const 106Number Number::operator-() const
109{ 107{
110 Number neg( *this ); 108 Number neg( *this );
@@ -250,6 +248,13 @@ void Number::set( const Bu::String &sNum )
250 } 248 }
251} 249}
252 250
251void Number::set( const Number &sNum )
252{
253 aInt.set( sNum.aInt );
254 bPositive = sNum.bPositive;
255 iOrd = sNum.iOrd;
256}
257
253Bu::String Number::toString() const 258Bu::String Number::toString() const
254{ 259{
255 if( aInt.getSize() == 0 ) 260 if( aInt.getSize() == 0 )
@@ -272,6 +277,7 @@ Number Number::add( const Number &rhs, bool bSub ) const
272 277
273 int iZeros = 0; 278 int iZeros = 0;
274 int iCarry = 0; 279 int iCarry = 0;
280// Bu::println("::: %1 + %2:").arg( toString() ).arg( rhs.toString() );
275 281
276 if( bPositive == (bSub?!rhs.bPositive:rhs.bPositive)) 282 if( bPositive == (bSub?!rhs.bPositive:rhs.bPositive))
277 { 283 {
@@ -332,8 +338,77 @@ Number Number::add( const Number &rhs, bool bSub ) const
332 ret.aInt.set( j, 9-ret.aInt.get( j )); 338 ret.aInt.set( j, 9-ret.aInt.get( j ));
333 } 339 }
334 } 340 }
341 else
342 {
343 ret.aInt.trim();
344 }
335 } 345 }
336 346
337 return ret; 347 return ret;
338} 348}
339 349
350void Number::divide( const Number &rhs, Number &q, Number &r ) const
351{
352 q.aInt.clear();
353 r = *this;
354
355 if( rhs.aInt.getSize() > aInt.getSize() )
356 return;
357
358 if( bPositive == rhs.bPositive )
359 q.bPositive = true;
360 else
361 q.bPositive = false;
362
363 int iMinWidth = rhs.aInt.getSize();
364
365 int iAnchor = r.aInt.getSize()-iMinWidth;
366 int iSample = iMinWidth;
367 do
368 {
369// Bu::println("%1\n-----").arg( r.aInt.toString() );
370 Number sub( iOrd );
371 for(;;)
372 {
373// Bu::println(" -> Anchor: %1, Sample: %2").arg( iAnchor ).arg( iSample );
374 sub.aInt.set( r.aInt, iAnchor, iSample );
375// Bu::println("%1\n%2\n----").arg( sub.toString() ).arg( rhs.toString() );
376 if( sub < rhs )
377 {
378 iSample++;
379 iAnchor--;
380 if( iAnchor < 0 )
381 {
382// Bu::println("[Inner exit] Complete: q = %1, r = %2").arg( q.toString() ).arg( r.toString() );
383 return;
384 }
385 }
386 else
387 break;
388 }
389
390 Number x( iOrd );
391 int iRes = 0;
392 for( ; x <= sub; iRes++, x = x + rhs ) { }
393 x = sub - (x - rhs);
394 for( int j = 0; iAnchor+j >= 0 && j < x.aInt.getSize(); j++ )
395 r.aInt.set( iAnchor+j, x.aInt.get( j ) );
396 while( r.aInt.getSize() > iAnchor+x.aInt.getSize() )
397 r.aInt.remove();
398// Bu::println(" -> Post remainder patch: %1 -> %2").
399// arg( x.toString() ).arg( r.toString() );
400
401// Bu::println("%1 (%2)").arg( iRes-1 ).arg( x.toString() );
402 while( q.aInt.getSize() <= iAnchor )
403 q.aInt.append(0);
404 q.aInt.set( iAnchor, iRes-1 );
405
406 iSample = iMinWidth;
407 iAnchor = r.aInt.getSize()-iMinWidth;
408// Bu::println(" -> new Anchor: %1, Sample: %2").arg( iAnchor ).
409// arg( iSample );
410 } while( iAnchor >= 0 );
411
412// Bu::println("Complete: q = %1, r = %2").arg( q.toString() ).arg( r.toString() );
413}
414