diff options
| author | Mike Buland <mike@xagasoft.com> | 2014-10-30 13:15:19 -0600 |
|---|---|---|
| committer | Mike Buland <mike@xagasoft.com> | 2014-10-30 13:15:19 -0600 |
| commit | 7026b96ec807b169f7b413056e52412ae422ea9d (patch) | |
| tree | 9a597b31b8c7d6a8781b45d1bbf27c258bb6a3a4 | |
| parent | 18a2be05bfacddcb7398f1b197bd1a5876c9a0cb (diff) | |
| download | clic-7026b96ec807b169f7b413056e52412ae422ea9d.tar.gz clic-7026b96ec807b169f7b413056e52412ae422ea9d.tar.bz2 clic-7026b96ec807b169f7b413056e52412ae422ea9d.tar.xz clic-7026b96ec807b169f7b413056e52412ae422ea9d.zip | |
The new division works great!
Other minor bug fixes including scale issues, digit() access stopped a
digit before the final possible digit in the scale, >, >=, <, <= all
work correctly with mixed scale numbers now, probably other fixes.
| -rw-r--r-- | src/number.cpp | 248 | ||||
| -rw-r--r-- | src/number.h | 1 | ||||
| -rw-r--r-- | src/options.cpp | 1 | ||||
| -rw-r--r-- | src/parser.cpp | 4 | ||||
| -rw-r--r-- | src/unitnumber.cpp | 8 | ||||
| -rw-r--r-- | src/unitnumber.h | 1 | ||||
| -rw-r--r-- | src/unitparser.cpp | 4 |
7 files changed, 134 insertions, 133 deletions
diff --git a/src/number.cpp b/src/number.cpp index 0b8e07b..c23466e 100644 --- a/src/number.cpp +++ b/src/number.cpp | |||
| @@ -186,9 +186,15 @@ bool Number::operator>( const Number &rhs ) const | |||
| 186 | else if( iDiff > 0 ) | 186 | else if( iDiff > 0 ) |
| 187 | return bPositive; | 187 | return bPositive; |
| 188 | } | 188 | } |
| 189 | for( int j = 0; j < iScale; j++ ) | 189 | int iMax = iScale; |
| 190 | if( rhs.iScale > iMax ) | ||
| 191 | iMax = rhs.iScale; | ||
| 192 | // Bu::println("Max scale = %1").arg( iMax ); | ||
| 193 | for( int j = 0; j < iMax; j++ ) | ||
| 190 | { | 194 | { |
| 191 | int iDiff = aFrac[j] - rhs.aFrac[j]; | 195 | // Bu::println(" > at %1 (%2 > %3)").arg( j ) |
| 196 | // .arg( digit(-1-j) ).arg( rhs.digit(-1-j) ); | ||
| 197 | int iDiff = digit(-1-j) - rhs.digit(-1-j); | ||
| 192 | if( iDiff < 0 ) | 198 | if( iDiff < 0 ) |
| 193 | return !bPositive; | 199 | return !bPositive; |
| 194 | else if( iDiff > 0 ) | 200 | else if( iDiff > 0 ) |
| @@ -219,9 +225,12 @@ bool Number::operator<( const Number &rhs ) const | |||
| 219 | else if( iDiff < 0 ) | 225 | else if( iDiff < 0 ) |
| 220 | return bPositive; | 226 | return bPositive; |
| 221 | } | 227 | } |
| 222 | for( int j = 0; j < iScale; j++ ) | 228 | int iMax = iScale; |
| 229 | if( rhs.iScale > iMax ) | ||
| 230 | iMax = rhs.iScale; | ||
| 231 | for( int j = 0; j < iMax; j++ ) | ||
| 223 | { | 232 | { |
| 224 | int iDiff = aFrac[j] - rhs.aFrac[j]; | 233 | int iDiff = digit(-1-j) - rhs.digit(-1-j); |
| 225 | if( iDiff > 0 ) | 234 | if( iDiff > 0 ) |
| 226 | return !bPositive; | 235 | return !bPositive; |
| 227 | else if( iDiff < 0 ) | 236 | else if( iDiff < 0 ) |
| @@ -244,17 +253,18 @@ bool Number::operator>=( const Number &rhs ) const | |||
| 244 | 253 | ||
| 245 | for( int j = aInt.getSize()-1; j >= 0; j-- ) | 254 | for( int j = aInt.getSize()-1; j >= 0; j-- ) |
| 246 | { | 255 | { |
| 247 | // Bu::println(" --> %1 > %2 -> %3").arg( aInt[j] ).arg( rhs.aInt[j] ). | ||
| 248 | // arg( aInt[j] > rhs.aInt[j] ); | ||
| 249 | int iDiff = aInt[j] - rhs.aInt[j]; | 256 | int iDiff = aInt[j] - rhs.aInt[j]; |
| 250 | if( iDiff < 0 ) | 257 | if( iDiff < 0 ) |
| 251 | return !bPositive; | 258 | return !bPositive; |
| 252 | else if( iDiff > 0 ) | 259 | else if( iDiff > 0 ) |
| 253 | return bPositive; | 260 | return bPositive; |
| 254 | } | 261 | } |
| 255 | for( int j = 0; j < iScale; j++ ) | 262 | int iMax = iScale; |
| 263 | if( rhs.iScale > iMax ) | ||
| 264 | iMax = rhs.iScale; | ||
| 265 | for( int j = 0; j < iMax; j++ ) | ||
| 256 | { | 266 | { |
| 257 | int iDiff = aFrac[j] - rhs.aFrac[j]; | 267 | int iDiff = digit(-1-j) - rhs.digit(-1-j); |
| 258 | if( iDiff < 0 ) | 268 | if( iDiff < 0 ) |
| 259 | return !bPositive; | 269 | return !bPositive; |
| 260 | else if( iDiff > 0 ) | 270 | else if( iDiff > 0 ) |
| @@ -285,9 +295,12 @@ bool Number::operator<=( const Number &rhs ) const | |||
| 285 | else if( iDiff < 0 ) | 295 | else if( iDiff < 0 ) |
| 286 | return bPositive; | 296 | return bPositive; |
| 287 | } | 297 | } |
| 288 | for( int j = 0; j < iScale; j++ ) | 298 | int iMax = iScale; |
| 299 | if( rhs.iScale > iMax ) | ||
| 300 | iMax = rhs.iScale; | ||
| 301 | for( int j = 0; j < iMax; j++ ) | ||
| 289 | { | 302 | { |
| 290 | int iDiff = aFrac[j] - rhs.aFrac[j]; | 303 | int iDiff = digit(-1-j) - rhs.digit(-1-j); |
| 291 | if( iDiff > 0 ) | 304 | if( iDiff > 0 ) |
| 292 | return !bPositive; | 305 | return !bPositive; |
| 293 | else if( iDiff < 0 ) | 306 | else if( iDiff < 0 ) |
| @@ -382,140 +395,104 @@ void Number::set( int32_t iNum ) | |||
| 382 | 395 | ||
| 383 | void Number::divide( const Number &rhs, Number &q, Number &r ) const | 396 | void Number::divide( const Number &rhs, Number &q, Number &r ) const |
| 384 | { | 397 | { |
| 385 | if( rhs.iScale > 0 ) | 398 | // Bu::println("divide: %1 / %2").arg( *this ).arg( rhs ); |
| 386 | { | ||
| 387 | Number newrhs = Number( 0, iRadix ); | ||
| 388 | Number newbase = Number( iScale, iRadix ); | ||
| 389 | int iOff; | ||
| 390 | for( iOff = -iScale; iOff < 0 && rhs.digit( iOff ) == 0; iOff++ ) { } | ||
| 391 | if( iOff < 0 ) | ||
| 392 | { | ||
| 393 | for( int j = iOff; j < rhs.aInt.getSize(); j++ ) | ||
| 394 | { | ||
| 395 | newrhs.aInt.append( rhs.digit( j ) ); | ||
| 396 | newbase.aInt.append( digit( j ) ); | ||
| 397 | } | ||
| 398 | for( int j = rhs.aInt.getSize(); j < aInt.getSize(); j++ ) | ||
| 399 | { | ||
| 400 | newbase.aInt.append( aInt.get( j ) ); | ||
| 401 | } | ||
| 402 | for( int j = iScale+iOff; j >= -iOff; j-- ) | ||
| 403 | { | ||
| 404 | newbase.aFrac.set( j+iOff, aFrac.get( j ) ); | ||
| 405 | } | ||
| 406 | 399 | ||
| 407 | // Bu::println("Conv %1 => %2 (iOff = %3)").arg( rhs ).arg( newrhs ).arg( iOff ); | 400 | // iNumShift is how many digits we've shifted the entire equation, |
| 408 | // Bu::println("Conv %1 => %2 (iOff = %3)").arg( *this ).arg( newbase ).arg( iOff ); | 401 | // effectively multiplying the numerator and divisor by iRadix*iNumShift |
| 402 | int iNumShift = rhs.getEffectiveScale(); | ||
| 403 | // Bu::println("iNumShift = %1").arg( iNumShift ); | ||
| 409 | 404 | ||
| 410 | newbase.divide( newrhs, q, r ); | 405 | // Setup our divisor, this is important, it should be an integer to make |
| 411 | return; | 406 | // things easy, and it won't change once we create it. |
| 412 | } | 407 | Number nDiv( 0, iRadix ); |
| 408 | for( int j = -iNumShift; j < rhs.aInt.getSize(); j++ ) | ||
| 409 | { | ||
| 410 | // Bu::println(" -> '%1'").arg( rhs.digit( j ) ); | ||
| 411 | nDiv.aInt.append( rhs.digit( j ) ); | ||
| 413 | } | 412 | } |
| 414 | 413 | // Bu::println("New divisor: %1").arg( nDiv ); | |
| 415 | q = Number( iScale, iRadix ); | ||
| 416 | r = *this; | ||
| 417 | |||
| 418 | if( bPositive == rhs.bPositive ) | ||
| 419 | q.bPositive = true; | ||
| 420 | else | ||
| 421 | q.bPositive = false; | ||
| 422 | |||
| 423 | int iMinWidth = Bu::buMax(1,rhs.aInt.getSize()); | ||
| 424 | 414 | ||
| 425 | int iAnchor = r.aInt.getSize()-iMinWidth; | 415 | // Anchor is the position in the output the new digit will appear. |
| 426 | int iSample = iMinWidth; | 416 | // This also tells us where the ones place will be in our new numerator. |
| 427 | do | 417 | int iAnchor = (aInt.getSize()+iNumShift)-nDiv.aInt.getSize(); |
| 418 | // Bu::println("Anchor: %1").arg( iAnchor ); | ||
| 419 | |||
| 420 | // Setup our output variables | ||
| 421 | q.iRadix = r.iRadix = iRadix; | ||
| 422 | q.iScale = r.iScale = iScale; | ||
| 423 | q.bPositive = !(!bPositive ^ !rhs.bPositive); | ||
| 424 | r.bPositive = true; | ||
| 425 | q.aInt.clear(); | ||
| 426 | r.aInt.clear(); | ||
| 427 | if( q.aFrac.getSize() != iScale ) | ||
| 428 | q.aFrac = PackedIntArray( aFrac.getBitWidth(), iScale ); | ||
| 429 | if( r.aFrac.getSize() != iScale ) | ||
| 430 | r.aFrac = PackedIntArray( aFrac.getBitWidth(), iScale ); | ||
| 431 | |||
| 432 | // The numerator is re-created every step to match the divisor and | ||
| 433 | // anchor | ||
| 434 | Number nNum( iScale, iRadix ); | ||
| 435 | for( int j = iAnchor-iNumShift; | ||
| 436 | nNum.aInt.getSize() < nDiv.aInt.getSize(); j++ ) | ||
| 437 | { | ||
| 438 | // Bu::println(" ->[%1] '%2'").arg( j ).arg( digit(j) ); | ||
| 439 | nNum.aInt.append( digit( j ) ); | ||
| 440 | } | ||
| 441 | // Bu::println("New numerator: %1").arg( nNum ); | ||
| 442 | while( iAnchor > -iScale && !nNum.isZero()) // division loop | ||
| 428 | { | 443 | { |
| 429 | // Bu::println("%1\n-----").arg( r.aInt.toString() ); | 444 | // As long as the numerator is smaller than the divisor we keep |
| 430 | Number sub( 0, iRadix ); | 445 | // including new digits. |
| 431 | if( iAnchor < 0 ) | 446 | while( nNum < nDiv ) |
| 432 | { | 447 | { |
| 433 | sub = r; | 448 | iAnchor--; |
| 434 | sub.aInt.insert(0,0); | 449 | nNum.aInt.insert( 0, digit(iAnchor-iNumShift) ); |
| 450 | // Bu::println("Numerator too small, new numerator: %1").arg( nNum ); | ||
| 435 | } | 451 | } |
| 436 | for(;;) | 452 | if( iAnchor < -iScale ) |
| 453 | break; | ||
| 454 | |||
| 455 | // Bu::println(" New anchor: %1").arg( iAnchor ); | ||
| 456 | |||
| 457 | // How many times does the divisor fit into the numerator | ||
| 458 | int iCount = 0; | ||
| 459 | for(;nNum >= nDiv; iCount++ ) | ||
| 437 | { | 460 | { |
| 438 | // Bu::println(" -> Anchor: %1, Sample: %2").arg( iAnchor ).arg( iSample ); | 461 | // Bu::print(" ==> step %3: %1 - %2 = ").arg( nNum ).arg( nDiv ).arg( iCount ); |
| 439 | if( iAnchor >= 0 ) | 462 | nNum = nNum - nDiv; |
| 440 | { | 463 | // Bu::println("%1").arg( nNum ); |
| 441 | sub.aInt.set( r.aInt, iAnchor, iSample ); | ||
| 442 | } | ||
| 443 | else | ||
| 444 | { | ||
| 445 | /* sub.aInt.clear(); | ||
| 446 | for( int j = iAnchor; j < r.aInt.getSize(); j++ ) | ||
| 447 | { | ||
| 448 | sub.aInt.append( r.digit( j ) ); | ||
| 449 | } | ||
| 450 | */ | ||
| 451 | } | ||
| 452 | // Bu::println("%1\n%2\n----").arg( sub.toString() ).arg( rhs.toString() ); | ||
| 453 | if( sub < rhs ) | ||
| 454 | { | ||
| 455 | iSample++; | ||
| 456 | iAnchor--; | ||
| 457 | if( iAnchor < 0 ) | ||
| 458 | { | ||
| 459 | if( r.isZero() || iAnchor < -iScale ) | ||
| 460 | { | ||
| 461 | // Bu::println("[Inner exit] Complete: q = %1, r = %2").arg( q.toString() ).arg( r.toString() ); | ||
| 462 | return; | ||
| 463 | } | ||
| 464 | sub.aInt.insert(0, 0); | ||
| 465 | } | ||
| 466 | } | ||
| 467 | else | ||
| 468 | break; | ||
| 469 | } | 464 | } |
| 465 | // Bu::println("Total steps: %1").arg( iCount ); | ||
| 470 | 466 | ||
| 471 | Number x( 0, iRadix ); | 467 | if( iAnchor >= 0 ) |
| 472 | int iRes = -1; | ||
| 473 | // Bu::println("{x = %1, sub=%2, rhs=%4, iRes=%3}").arg( x ).arg(sub).arg(iRes).arg(rhs); | ||
| 474 | for( ; x <= sub; iRes++, x = x + rhs ) { | ||
| 475 | // Bu::println("{x = %1, sub=%2, rhs=%4, iRes=%3, x+rhs=%5}").arg( x ).arg(sub).arg(iRes).arg(rhs).arg(x+rhs); | ||
| 476 | } | ||
| 477 | x = sub - (x - rhs); | ||
| 478 | if( !x.bPositive ) | ||
| 479 | { | 468 | { |
| 480 | iSample++; | 469 | while( q.aInt.getSize() <= iAnchor ) |
| 481 | iAnchor--; | 470 | q.aInt.append( 0 ); |
| 482 | // Bu::println("What? it's negative? %1").arg( x ); | 471 | q.aInt.set( iAnchor, iCount ); |
| 483 | continue; | ||
| 484 | } | 472 | } |
| 485 | if( iAnchor < 0 ) | 473 | else |
| 486 | { | 474 | { |
| 487 | r = x; | 475 | while( q.aFrac.getSize() <= -1-iAnchor ) |
| 476 | q.aFrac.append( 0 ); | ||
| 477 | q.aFrac.set( -1-iAnchor, iCount ); | ||
| 488 | } | 478 | } |
| 489 | else | 479 | } |
| 480 | for( int j = -iAnchor; j < nNum.aInt.getSize(); j++ ) | ||
| 481 | r.aInt.append( nNum.aInt[j] ); | ||
| 482 | int jtop = 0; | ||
| 483 | for(; nNum.aInt[jtop] == 0; jtop++ ) { } | ||
| 484 | // Bu::println("Computing remainder fraction from %1 to %2") | ||
| 485 | // .arg( -iAnchor-1 ).arg( jtop ); | ||
| 486 | for( int j = -iAnchor-1, k = 0; j >= jtop && k < r.iScale; j--, k++ ) | ||
| 487 | { | ||
| 488 | if( j <= nNum.aInt.getSize() ) | ||
| 490 | { | 489 | { |
| 491 | for( int j = 0; j < x.aInt.getSize(); j++ ) | 490 | r.aFrac.set( k, nNum.aInt[j] ); |
| 492 | r.aInt.set( iAnchor+j, x.aInt.get( j ) ); | 491 | // Bu::println("setting %1 to %2").arg( k ).arg( nNum.aInt[j] ); |
| 493 | } | 492 | } |
| 494 | 493 | } | |
| 495 | while( r.aInt.getSize() > Bu::buMax(0,iAnchor)+x.aInt.getSize() ) | 494 | // Bu::println("Final numerator? %1").arg( nNum ); |
| 496 | r.aInt.remove(); | 495 | // Bu::println("Remainder? %1").arg( r ); |
| 497 | // Bu::println(" -> Post remainder patch: %1 -> %2"). | ||
| 498 | // arg( x.toString() ).arg( r.toString() ); | ||
| 499 | |||
| 500 | // Bu::println("%1 (%2)").arg( iRes ).arg( x.toString() ); | ||
| 501 | while( q.aInt.getSize() <= iAnchor ) | ||
| 502 | q.aInt.append(0); | ||
| 503 | if( iAnchor >= 0 ) | ||
| 504 | q.aInt.set( iAnchor, iRes ); | ||
| 505 | else | ||
| 506 | q.aFrac.set( -1-iAnchor, iRes ); | ||
| 507 | |||
| 508 | iSample = iMinWidth; | ||
| 509 | if( iAnchor > 0 ) | ||
| 510 | iAnchor -= rhs.aInt.getSize()-x.aInt.getSize(); | ||
| 511 | else | ||
| 512 | iAnchor--; | ||
| 513 | // iAnchor = r.aInt.getSize()-iMinWidth; | ||
| 514 | // Bu::println(" -> new Anchor: %1, Sample: %2").arg( iAnchor ). | ||
| 515 | // arg( iSample ); | ||
| 516 | } while( iAnchor >= -iScale ); | ||
| 517 | |||
| 518 | // Bu::println("Complete: q = %1, r = %2").arg( q.toString() ).arg( r.toString() ); | ||
| 519 | } | 496 | } |
| 520 | 497 | ||
| 521 | bool Number::isZero() const | 498 | bool Number::isZero() const |
| @@ -579,7 +556,7 @@ int Number::digit( int iIdx ) const | |||
| 579 | { | 556 | { |
| 580 | if( iIdx < 0 ) | 557 | if( iIdx < 0 ) |
| 581 | { | 558 | { |
| 582 | if( iIdx <= -iScale ) | 559 | if( iIdx < -iScale ) |
| 583 | return 0; | 560 | return 0; |
| 584 | else | 561 | else |
| 585 | return aFrac[-1-iIdx]; | 562 | return aFrac[-1-iIdx]; |
| @@ -608,6 +585,15 @@ void Number::setScale( int iNewScale ) | |||
| 608 | iScale = iNewScale; | 585 | iScale = iNewScale; |
| 609 | } | 586 | } |
| 610 | 587 | ||
| 588 | int Number::getEffectiveScale() const | ||
| 589 | { | ||
| 590 | if( iScale == 0 ) | ||
| 591 | return 0; | ||
| 592 | int iSigDig = iScale-1; | ||
| 593 | for( ; iSigDig >= 0 && aFrac.get( iSigDig ) == 0; iSigDig-- ) { } | ||
| 594 | return iSigDig+1; | ||
| 595 | } | ||
| 596 | |||
| 611 | int32_t Number::toInt32() const | 597 | int32_t Number::toInt32() const |
| 612 | { | 598 | { |
| 613 | int32_t ret = 0; | 599 | int32_t ret = 0; |
| @@ -632,8 +618,10 @@ Number Number::toRadix( int iNewRadix, int iNewScale ) const | |||
| 632 | n.set( iNewRadix ); | 618 | n.set( iNewRadix ); |
| 633 | while( !me.isZero() ) | 619 | while( !me.isZero() ) |
| 634 | { | 620 | { |
| 635 | ret.aInt.append( (me%n).toInt32() ); | 621 | int dig = (me%n).toInt32(); |
| 622 | ret.aInt.append( dig ); | ||
| 636 | me = me / n; | 623 | me = me / n; |
| 624 | Bu::println("New digit: %1 (%2)").arg( dig ).arg( me ); | ||
| 637 | } | 625 | } |
| 638 | 626 | ||
| 639 | return ret; | 627 | return ret; |
diff --git a/src/number.h b/src/number.h index 40dbd55..fe10788 100644 --- a/src/number.h +++ b/src/number.h | |||
| @@ -47,6 +47,7 @@ public: | |||
| 47 | int digit( int iIdx ) const; | 47 | int digit( int iIdx ) const; |
| 48 | 48 | ||
| 49 | int getScale() const { return iScale; } | 49 | int getScale() const { return iScale; } |
| 50 | int getEffectiveScale() const; | ||
| 50 | void setScale( int iNewScale ); | 51 | void setScale( int iNewScale ); |
| 51 | 52 | ||
| 52 | int32_t toInt32() const; | 53 | int32_t toInt32() const; |
diff --git a/src/options.cpp b/src/options.cpp index 6e264f9..3581500 100644 --- a/src/options.cpp +++ b/src/options.cpp | |||
| @@ -150,6 +150,7 @@ int Options::convert( Bu::StringArray aArgs ) | |||
| 150 | iToRadix = strtol( lBits.last().getStr(), 0, 10 ); | 150 | iToRadix = strtol( lBits.last().getStr(), 0, 10 ); |
| 151 | n = Number( *(lBits.begin()+1), 0, iFromRadix ); | 151 | n = Number( *(lBits.begin()+1), 0, iFromRadix ); |
| 152 | } | 152 | } |
| 153 | Bu::println("%1").arg( n.toString() ); | ||
| 153 | Bu::println("%1").arg( n.toRadix( iToRadix ).toString() ); | 154 | Bu::println("%1").arg( n.toRadix( iToRadix ).toString() ); |
| 154 | } | 155 | } |
| 155 | 156 | ||
diff --git a/src/parser.cpp b/src/parser.cpp index 607de8a..8675a7c 100644 --- a/src/parser.cpp +++ b/src/parser.cpp | |||
| @@ -232,9 +232,11 @@ void Parser::unwind() | |||
| 232 | { | 232 | { |
| 233 | Token b = tsTerminal.peekPop(); | 233 | Token b = tsTerminal.peekPop(); |
| 234 | Token a = tsTerminal.peekPop(); | 234 | Token a = tsTerminal.peekPop(); |
| 235 | Number *pProduct = new Number( deref(a) * deref(b) ); | ||
| 236 | pProduct->setScale( lex.getScale() ); | ||
| 235 | tsTerminal.push( | 237 | tsTerminal.push( |
| 236 | Token( Token::tNumber, | 238 | Token( Token::tNumber, |
| 237 | new Number( deref(a) * deref(b) ) | 239 | pProduct |
| 238 | ) | 240 | ) |
| 239 | ); | 241 | ); |
| 240 | } | 242 | } |
diff --git a/src/unitnumber.cpp b/src/unitnumber.cpp index 1d63682..4846a07 100644 --- a/src/unitnumber.cpp +++ b/src/unitnumber.cpp | |||
| @@ -15,6 +15,8 @@ UnitNumber::UnitNumber() | |||
| 15 | "parse1", Bu::UnitSuite::expectPass ); | 15 | "parse1", Bu::UnitSuite::expectPass ); |
| 16 | add( static_cast<Bu::UnitSuite::Test>(&UnitNumber::multiply1), | 16 | add( static_cast<Bu::UnitSuite::Test>(&UnitNumber::multiply1), |
| 17 | "multiply1", Bu::UnitSuite::expectPass ); | 17 | "multiply1", Bu::UnitSuite::expectPass ); |
| 18 | add( static_cast<Bu::UnitSuite::Test>(&UnitNumber::divide1), | ||
| 19 | "divide1", Bu::UnitSuite::expectPass ); | ||
| 18 | add( static_cast<Bu::UnitSuite::Test>(&UnitNumber::number1), | 20 | add( static_cast<Bu::UnitSuite::Test>(&UnitNumber::number1), |
| 19 | "number1", Bu::UnitSuite::expectPass ); | 21 | "number1", Bu::UnitSuite::expectPass ); |
| 20 | add( static_cast<Bu::UnitSuite::Test>(&UnitNumber::compare1), | 22 | add( static_cast<Bu::UnitSuite::Test>(&UnitNumber::compare1), |
| @@ -68,6 +70,12 @@ void UnitNumber::multiply1() | |||
| 68 | ); | 70 | ); |
| 69 | } | 71 | } |
| 70 | 72 | ||
| 73 | void UnitNumber::divide1() | ||
| 74 | { | ||
| 75 | unitTest(Number("4") / Number("10") == "0"); | ||
| 76 | unitTest(Number("4") % Number("10") == "4"); | ||
| 77 | } | ||
| 78 | |||
| 71 | #define mathTest( anum, op, bnum, answ ) \ | 79 | #define mathTest( anum, op, bnum, answ ) \ |
| 72 | unitTest( (Number(anum) op Number(bnum)).toString() == answ ) | 80 | unitTest( (Number(anum) op Number(bnum)).toString() == answ ) |
| 73 | 81 | ||
diff --git a/src/unitnumber.h b/src/unitnumber.h index 83da27f..96d882e 100644 --- a/src/unitnumber.h +++ b/src/unitnumber.h | |||
| @@ -12,6 +12,7 @@ public: | |||
| 12 | void packed1(); | 12 | void packed1(); |
| 13 | void parse1(); | 13 | void parse1(); |
| 14 | void multiply1(); | 14 | void multiply1(); |
| 15 | void divide1(); | ||
| 15 | void number1(); | 16 | void number1(); |
| 16 | void compare1(); | 17 | void compare1(); |
| 17 | void radix1(); | 18 | void radix1(); |
diff --git a/src/unitparser.cpp b/src/unitparser.cpp index 891f7b3..43dacfc 100644 --- a/src/unitparser.cpp +++ b/src/unitparser.cpp | |||
| @@ -33,7 +33,7 @@ void UnitParser::order1() | |||
| 33 | unitTest(parse("2+3*5") == "17"); | 33 | unitTest(parse("2+3*5") == "17"); |
| 34 | unitTest(parse("2+3-5") == "0"); | 34 | unitTest(parse("2+3-5") == "0"); |
| 35 | unitTest(parse("(2+3)*5") == "25"); | 35 | unitTest(parse("(2+3)*5") == "25"); |
| 36 | unitTest(parse("1.59*40/24*21", 5) == "55.125"); | 36 | unitTest(parse("1.59*40/24*21", 5) == "55.65"); |
| 37 | unitTest(parse("1.59*40/(24*21)", 5) == "0.125"); // bc says it's this: "0.12619"); | 37 | unitTest(parse("1.59*40/(24*21)", 5) == "0.12619"); // bc says it's this: "0.12619"); |
| 38 | } | 38 | } |
| 39 | 39 | ||
