diff options
Diffstat (limited to '')
-rw-r--r-- | src/number.cpp | 300 |
1 files changed, 159 insertions, 141 deletions
diff --git a/src/number.cpp b/src/number.cpp index f9fab26..d16bd98 100644 --- a/src/number.cpp +++ b/src/number.cpp | |||
@@ -301,147 +301,6 @@ void Number::set( const Number &sNum ) | |||
301 | iRadix = sNum.iRadix; | 301 | iRadix = sNum.iRadix; |
302 | } | 302 | } |
303 | 303 | ||
304 | Bu::String Number::toString() const | ||
305 | { | ||
306 | int iSigDig = iScale-1; | ||
307 | for( ; iSigDig >= 0 && aFrac.get( iSigDig ) == 0; iSigDig-- ) { } | ||
308 | if( aInt.getSize() == 0 && iSigDig <= 0 ) | ||
309 | return "0"; | ||
310 | Bu::String sRet; | ||
311 | if( !bPositive ) | ||
312 | sRet += '-'; | ||
313 | if( aInt.getSize() > 0 ) | ||
314 | { | ||
315 | for( int j = aInt.getSize()-1; j >= 0; j-- ) | ||
316 | { | ||
317 | int x = aInt.get( j ); | ||
318 | if( x >= 10 ) | ||
319 | sRet += x-10+'a'; | ||
320 | else | ||
321 | sRet += x+'0'; | ||
322 | } | ||
323 | } | ||
324 | else | ||
325 | sRet += "0"; | ||
326 | if( iSigDig >= 0 ) | ||
327 | { | ||
328 | sRet += '.'; | ||
329 | for( int j = 0; j <= iSigDig; j++ ) | ||
330 | { | ||
331 | int x = aFrac.get( j ); | ||
332 | if( x >= 10 ) | ||
333 | sRet += x-10+'a'; | ||
334 | else | ||
335 | sRet += x+'0'; | ||
336 | } | ||
337 | } | ||
338 | |||
339 | return sRet; | ||
340 | } | ||
341 | |||
342 | int Number::digit( int iIdx ) const | ||
343 | { | ||
344 | if( iIdx < 0 ) | ||
345 | { | ||
346 | if( iIdx <= -iScale ) | ||
347 | return 0; | ||
348 | else | ||
349 | return aFrac[-1-iIdx]; | ||
350 | } | ||
351 | if( iIdx >= aInt.getSize() ) | ||
352 | return 0; | ||
353 | return aInt[iIdx]; | ||
354 | } | ||
355 | |||
356 | Number Number::add( const Number &rhs, bool bSub ) const | ||
357 | { | ||
358 | Number ret( iScale, iRadix ); | ||
359 | |||
360 | int iPlaces = Bu::buMax(rhs.aInt.getSize(), aInt.getSize() ); | ||
361 | |||
362 | int iZeros = 0; | ||
363 | int iCarry = 0; | ||
364 | // Bu::println("::: %1 + %2:").arg( toString() ).arg( rhs.toString() ); | ||
365 | |||
366 | if( bPositive == (bSub?!rhs.bPositive:rhs.bPositive)) | ||
367 | { | ||
368 | ret.bPositive = bPositive; | ||
369 | for( int j = -iScale; j < iPlaces || iCarry > 0; j++ ) | ||
370 | { | ||
371 | int iRes = iCarry + digit( j ) + rhs.digit( j ); | ||
372 | // Bu::println(" [%5] Place: %1 + %2 + (%3) = %4"). | ||
373 | // arg( digit(j) ).arg( rhs.digit( j ) ).arg( iCarry ) | ||
374 | // .arg( iRes ).arg( j ); | ||
375 | if( j < 0 ) | ||
376 | ret.aFrac.set( -1-j, (iRes%iRadix) ); | ||
377 | else | ||
378 | { | ||
379 | if( iRes == 0 ) | ||
380 | { | ||
381 | iZeros++; | ||
382 | continue; | ||
383 | } | ||
384 | for(; iZeros > 0; iZeros-- ) | ||
385 | ret.aInt.append( 0 ); | ||
386 | |||
387 | ret.aInt.append( (iRes%iRadix) ); | ||
388 | } | ||
389 | if( iRes < iRadix ) | ||
390 | iCarry = 0; | ||
391 | else | ||
392 | iCarry = iRes/iRadix; | ||
393 | } | ||
394 | } | ||
395 | else | ||
396 | { | ||
397 | iCarry = 1; | ||
398 | // Bu::println("--method b--"); | ||
399 | ret.bPositive = bPositive; | ||
400 | int iRes; | ||
401 | int iComp = (iRadix-1); | ||
402 | for( int j = -iScale; j < iPlaces; j++ ) | ||
403 | { | ||
404 | iRes = digit( j ) + (iComp-rhs.digit( j )) + iCarry; | ||
405 | // Bu::println(" Place: %1 + %2 + (%3) = %4"). | ||
406 | // arg( digit(j) ).arg( 9-rhs.digit( j ) ).arg( iCarry ) | ||
407 | // .arg( iRes ); | ||
408 | if( j < 0 ) | ||
409 | ret.aFrac.set( -1-j, (iRes%iRadix) ); | ||
410 | else | ||
411 | { | ||
412 | if( iRes == 0 ) | ||
413 | { | ||
414 | iZeros++; | ||
415 | continue; | ||
416 | } | ||
417 | for(; iZeros > 0; iZeros-- ) | ||
418 | ret.aInt.append( 0 ); | ||
419 | |||
420 | ret.aInt.append( (iRes%iRadix) ); | ||
421 | } | ||
422 | if( iRes < iRadix ) | ||
423 | iCarry = 0; | ||
424 | else | ||
425 | iCarry = iRes/iRadix; | ||
426 | } | ||
427 | if( iCarry == 0 ) | ||
428 | { | ||
429 | ret.bPositive = false; | ||
430 | ret.aInt.set( 0, iComp-ret.aInt.get( 0 )+1); | ||
431 | for( int j = 1; j < ret.aInt.getSize(); j++ ) | ||
432 | { | ||
433 | ret.aInt.set( j, iComp-ret.aInt.get( j )); | ||
434 | } | ||
435 | } | ||
436 | else | ||
437 | { | ||
438 | ret.aInt.trim(); | ||
439 | } | ||
440 | } | ||
441 | |||
442 | return ret; | ||
443 | } | ||
444 | |||
445 | void Number::divide( const Number &rhs, Number &q, Number &r ) const | 304 | void Number::divide( const Number &rhs, Number &q, Number &r ) const |
446 | { | 305 | { |
447 | if( rhs.iScale > 0 ) | 306 | if( rhs.iScale > 0 ) |
@@ -599,6 +458,165 @@ bool Number::isZero() const | |||
599 | return true; | 458 | return true; |
600 | } | 459 | } |
601 | 460 | ||
461 | Bu::String Number::toString() const | ||
462 | { | ||
463 | int iSigDig = iScale-1; | ||
464 | for( ; iSigDig >= 0 && aFrac.get( iSigDig ) == 0; iSigDig-- ) { } | ||
465 | if( aInt.getSize() == 0 && iSigDig <= 0 ) | ||
466 | return "0"; | ||
467 | Bu::String sRet; | ||
468 | if( !bPositive ) | ||
469 | sRet += '-'; | ||
470 | if( aInt.getSize() > 0 ) | ||
471 | { | ||
472 | for( int j = aInt.getSize()-1; j >= 0; j-- ) | ||
473 | { | ||
474 | int x = aInt.get( j ); | ||
475 | if( x >= 10 ) | ||
476 | sRet += x-10+'a'; | ||
477 | else | ||
478 | sRet += x+'0'; | ||
479 | } | ||
480 | } | ||
481 | else | ||
482 | sRet += "0"; | ||
483 | if( iSigDig >= 0 ) | ||
484 | { | ||
485 | sRet += '.'; | ||
486 | for( int j = 0; j <= iSigDig; j++ ) | ||
487 | { | ||
488 | int x = aFrac.get( j ); | ||
489 | if( x >= 10 ) | ||
490 | sRet += x-10+'a'; | ||
491 | else | ||
492 | sRet += x+'0'; | ||
493 | } | ||
494 | } | ||
495 | |||
496 | return sRet; | ||
497 | } | ||
498 | |||
499 | int Number::digit( int iIdx ) const | ||
500 | { | ||
501 | if( iIdx < 0 ) | ||
502 | { | ||
503 | if( iIdx <= -iScale ) | ||
504 | return 0; | ||
505 | else | ||
506 | return aFrac[-1-iIdx]; | ||
507 | } | ||
508 | if( iIdx >= aInt.getSize() ) | ||
509 | return 0; | ||
510 | return aInt[iIdx]; | ||
511 | } | ||
512 | |||
513 | void Number::setScale( int iNewScale ) | ||
514 | { | ||
515 | if( iNewScale == 0 ) | ||
516 | aFrac.clear(); | ||
517 | else if( iScale == iNewScale ) | ||
518 | return; | ||
519 | else if( iScale < iNewScale ) | ||
520 | { | ||
521 | for(; iScale < iNewScale; iNewScale-- ) | ||
522 | aFrac.remove(); | ||
523 | } | ||
524 | else | ||
525 | { | ||
526 | for(; iScale > iNewScale; iNewScale++ ) | ||
527 | aFrac.append(0); | ||
528 | } | ||
529 | } | ||
530 | |||
531 | Number Number::add( const Number &rhs, bool bSub ) const | ||
532 | { | ||
533 | Number ret( Bu::buMax(iScale,rhs.iScale), iRadix ); | ||
534 | |||
535 | int iPlaces = Bu::buMax(rhs.aInt.getSize(), aInt.getSize() ); | ||
536 | |||
537 | int iZeros = 0; | ||
538 | int iCarry = 0; | ||
539 | // Bu::println("::: %1 + %2:").arg( toString() ).arg( rhs.toString() ); | ||
540 | |||
541 | if( bPositive == (bSub?!rhs.bPositive:rhs.bPositive)) | ||
542 | { | ||
543 | ret.bPositive = bPositive; | ||
544 | for( int j = -iScale; j < iPlaces || iCarry > 0; j++ ) | ||
545 | { | ||
546 | int iRes = iCarry + digit( j ) + rhs.digit( j ); | ||
547 | // Bu::println(" [%5] Place: %1 + %2 + (%3) = %4"). | ||
548 | // arg( digit(j) ).arg( rhs.digit( j ) ).arg( iCarry ) | ||
549 | // .arg( iRes ).arg( j ); | ||
550 | if( j < 0 ) | ||
551 | ret.aFrac.set( -1-j, (iRes%iRadix) ); | ||
552 | else | ||
553 | { | ||
554 | if( iRes == 0 ) | ||
555 | { | ||
556 | iZeros++; | ||
557 | continue; | ||
558 | } | ||
559 | for(; iZeros > 0; iZeros-- ) | ||
560 | ret.aInt.append( 0 ); | ||
561 | |||
562 | ret.aInt.append( (iRes%iRadix) ); | ||
563 | } | ||
564 | if( iRes < iRadix ) | ||
565 | iCarry = 0; | ||
566 | else | ||
567 | iCarry = iRes/iRadix; | ||
568 | } | ||
569 | } | ||
570 | else | ||
571 | { | ||
572 | iCarry = 1; | ||
573 | // Bu::println("--method b--"); | ||
574 | ret.bPositive = bPositive; | ||
575 | int iRes; | ||
576 | int iComp = (iRadix-1); | ||
577 | for( int j = -iScale; j < iPlaces; j++ ) | ||
578 | { | ||
579 | iRes = digit( j ) + (iComp-rhs.digit( j )) + iCarry; | ||
580 | // Bu::println(" Place: %1 + %2 + (%3) = %4"). | ||
581 | // arg( digit(j) ).arg( 9-rhs.digit( j ) ).arg( iCarry ) | ||
582 | // .arg( iRes ); | ||
583 | if( j < 0 ) | ||
584 | ret.aFrac.set( -1-j, (iRes%iRadix) ); | ||
585 | else | ||
586 | { | ||
587 | if( iRes == 0 ) | ||
588 | { | ||
589 | iZeros++; | ||
590 | continue; | ||
591 | } | ||
592 | for(; iZeros > 0; iZeros-- ) | ||
593 | ret.aInt.append( 0 ); | ||
594 | |||
595 | ret.aInt.append( (iRes%iRadix) ); | ||
596 | } | ||
597 | if( iRes < iRadix ) | ||
598 | iCarry = 0; | ||
599 | else | ||
600 | iCarry = iRes/iRadix; | ||
601 | } | ||
602 | if( iCarry == 0 ) | ||
603 | { | ||
604 | ret.bPositive = false; | ||
605 | ret.aInt.set( 0, iComp-ret.aInt.get( 0 )+1); | ||
606 | for( int j = 1; j < ret.aInt.getSize(); j++ ) | ||
607 | { | ||
608 | ret.aInt.set( j, iComp-ret.aInt.get( j )); | ||
609 | } | ||
610 | } | ||
611 | else | ||
612 | { | ||
613 | ret.aInt.trim(); | ||
614 | } | ||
615 | } | ||
616 | |||
617 | return ret; | ||
618 | } | ||
619 | |||
602 | Bu::Formatter &operator<<( Bu::Formatter &f, const Number &n ) | 620 | Bu::Formatter &operator<<( Bu::Formatter &f, const Number &n ) |
603 | { | 621 | { |
604 | return f << n.toString(); | 622 | return f << n.toString(); |