summaryrefslogtreecommitdiff
path: root/src/number.cpp
diff options
context:
space:
mode:
authorMike Buland <mike@xagasoft.com>2013-04-19 20:15:19 -0600
committerMike Buland <mike@xagasoft.com>2013-04-19 20:15:19 -0600
commit868af20101c99649b41489e8fcd2e118e20e76ec (patch)
treecf3ab6febeca66b670b030b5e5eb7549cda039af /src/number.cpp
parent06e46b0e904ca279e6e397c9f9040cf0f059b930 (diff)
downloadclic-868af20101c99649b41489e8fcd2e118e20e76ec.tar.gz
clic-868af20101c99649b41489e8fcd2e118e20e76ec.tar.bz2
clic-868af20101c99649b41489e8fcd2e118e20e76ec.tar.xz
clic-868af20101c99649b41489e8fcd2e118e20e76ec.zip
Added routines to get/set scale.
Diffstat (limited to 'src/number.cpp')
-rw-r--r--src/number.cpp300
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
304Bu::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
342int 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
356Number 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
445void Number::divide( const Number &rhs, Number &q, Number &r ) const 304void 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
461Bu::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
499int 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
513void 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
531Number 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
602Bu::Formatter &operator<<( Bu::Formatter &f, const Number &n ) 620Bu::Formatter &operator<<( Bu::Formatter &f, const Number &n )
603{ 621{
604 return f << n.toString(); 622 return f << n.toString();