diff options
author | Mike Buland <mike@xagasoft.com> | 2013-04-16 13:57:57 -0600 |
---|---|---|
committer | Mike Buland <mike@xagasoft.com> | 2013-04-16 13:57:57 -0600 |
commit | 7bb55b03c393b5d00914d328a16d238d17f6aa0f (patch) | |
tree | 4d9a0547b105e1867f8118f2f00548e1e05589ad /src/number.cpp | |
parent | 25989c6d3911b1d29a5866e668bff52537893afb (diff) | |
download | clic-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 'src/number.cpp')
-rw-r--r-- | src/number.cpp | 107 |
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 | ||
32 | template<typename t> t tabs( t x ) { return (x<(t)0)?(-x):x; } | 32 | Number &Number::operator=( const Number &rhs ) |
33 | { | ||
34 | set( rhs ); | ||
35 | return *this; | ||
36 | } | ||
33 | 37 | ||
34 | Number Number::operator+( const Number &rhs ) const | 38 | Number Number::operator+( const Number &rhs ) const |
35 | { | 39 | { |
@@ -87,24 +91,18 @@ Number Number::operator*( const Number &rhs ) const | |||
87 | 91 | ||
88 | Number Number::operator/( const Number &rhs ) const | 92 | Number 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 | ||
99 | Number Number::operator%( const Number &rhs ) const | ||
100 | { | ||
101 | Number q( iOrd ), r( iOrd ); | ||
102 | divide( rhs, q, r ); | ||
103 | return r; | ||
104 | } | ||
105 | |||
108 | Number Number::operator-() const | 106 | Number 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 | ||
251 | void Number::set( const Number &sNum ) | ||
252 | { | ||
253 | aInt.set( sNum.aInt ); | ||
254 | bPositive = sNum.bPositive; | ||
255 | iOrd = sNum.iOrd; | ||
256 | } | ||
257 | |||
253 | Bu::String Number::toString() const | 258 | Bu::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 | ||
350 | void 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 | |||