summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <mike@xagasoft.com>2015-01-29 08:49:55 -0700
committerMike Buland <mike@xagasoft.com>2015-01-29 08:49:55 -0700
commitf03026f5c2cde1eecfda273eaa52df10287f0f9e (patch)
treec3b5398bb29b848fc5fca2a87633961150d41cad
parente64cb84fe43660818f7d6eff2954147495b1ac8b (diff)
downloadclic-f03026f5c2cde1eecfda273eaa52df10287f0f9e.tar.gz
clic-f03026f5c2cde1eecfda273eaa52df10287f0f9e.tar.bz2
clic-f03026f5c2cde1eecfda273eaa52df10287f0f9e.tar.xz
clic-f03026f5c2cde1eecfda273eaa52df10287f0f9e.zip
Fixed nasty subtraction bug when dealing with fractions.0.13
It turned out to be a really simple solution, but man, that was embarassing. I forgot to include the fractional portion of a number when fixing my radix+1 compliment numbers.
-rw-r--r--src/config.h3
-rw-r--r--src/number.cpp59
-rw-r--r--src/number.h1
-rw-r--r--src/unitnumber.cpp12
-rw-r--r--src/unitnumber.h1
5 files changed, 52 insertions, 24 deletions
diff --git a/src/config.h b/src/config.h
index f55be13..482ef9e 100644
--- a/src/config.h
+++ b/src/config.h
@@ -1,11 +1,12 @@
1#ifndef CONFIG_H 1#ifndef CONFIG_H
2#define CONFIG_H 2#define CONFIG_H
3 3
4#define CLIC_VERSION "0.12" 4#define CLIC_VERSION "0.13"
5#define CLIC_VERSION_STR "Clic v" CLIC_VERSION 5#define CLIC_VERSION_STR "Clic v" CLIC_VERSION
6 6
7#define DEBUG_DIVIDE false 7#define DEBUG_DIVIDE false
8#define DEBUG_PARSE false 8#define DEBUG_PARSE false
9#define DEBUG_ADD false
9 10
10#define DBS( s, x ) if( DEBUG_ ##s ) { x; } (void)0 11#define DBS( s, x ) if( DEBUG_ ##s ) { x; } (void)0
11#define DBS_START( s ) if( DEBUG_ ##s ) { (void)0 12#define DBS_START( s ) if( DEBUG_ ##s ) { (void)0
diff --git a/src/number.cpp b/src/number.cpp
index eb803be..660ba61 100644
--- a/src/number.cpp
+++ b/src/number.cpp
@@ -610,6 +610,19 @@ int Number::digit( int iIdx ) const
610 return aInt[iIdx]; 610 return aInt[iIdx];
611} 611}
612 612
613void Number::setDigit( int iIdx, int iVal )
614{
615 if( iIdx < 0 )
616 {
617 if( iIdx >= -iScale )
618 aFrac.set( -1-iIdx, iVal );
619 return;
620 }
621 if( iIdx >= aInt.getSize() )
622 return;
623 aInt.set( iIdx, iVal );
624}
625
613void Number::setScale( int iNewScale ) 626void Number::setScale( int iNewScale )
614{ 627{
615 if( iNewScale == 0 ) 628 if( iNewScale == 0 )
@@ -680,7 +693,7 @@ Number Number::add( const Number &rhs, bool bSub ) const
680 693
681 int iZeros = 0; 694 int iZeros = 0;
682 int iCarry = 0; 695 int iCarry = 0;
683// Bu::println("::: %1 + %2:").arg( toString() ).arg( rhs.toString() ); 696 DBS( ADD, Bu::println("::: %1 + %2:").arg( toString() ).arg( rhs.toString() ) );
684 697
685 if( bPositive == (bSub?!rhs.bPositive:rhs.bPositive)) 698 if( bPositive == (bSub?!rhs.bPositive:rhs.bPositive))
686 { 699 {
@@ -688,9 +701,10 @@ Number Number::add( const Number &rhs, bool bSub ) const
688 for( int j = -iScale; j < iPlaces || iCarry > 0; j++ ) 701 for( int j = -iScale; j < iPlaces || iCarry > 0; j++ )
689 { 702 {
690 int iRes = iCarry + digit( j ) + rhs.digit( j ); 703 int iRes = iCarry + digit( j ) + rhs.digit( j );
691// Bu::println(" [%5] Place: %1 + %2 + (%3) = %4"). 704 DBS( ADD,
692// arg( digit(j) ).arg( rhs.digit( j ) ).arg( iCarry ) 705 Bu::println(" [%5] Place: %1 + %2 + (%3) = %4").
693// .arg( iRes ).arg( j ); 706 arg( digit(j) ).arg( rhs.digit( j ) ).arg( iCarry )
707 .arg( iRes ).arg( j ) );
694 if( j < 0 ) 708 if( j < 0 )
695 ret.aFrac.set( -1-j, (iRes%iRadix) ); 709 ret.aFrac.set( -1-j, (iRes%iRadix) );
696 else 710 else
@@ -714,16 +728,25 @@ Number Number::add( const Number &rhs, bool bSub ) const
714 else 728 else
715 { 729 {
716 iCarry = 1; 730 iCarry = 1;
717// Bu::println("--method b--"); 731 DBS( ADD, Bu::println("--method b--") );
718 ret.bPositive = bPositive; 732 ret.bPositive = bPositive;
719 int iRes; 733 int iRes;
720 int iComp = (iRadix-1); 734 int iComp = (iRadix-1);
735
721 for( int j = -iScale; j < iPlaces; j++ ) 736 for( int j = -iScale; j < iPlaces; j++ )
722 { 737 {
723 iRes = digit( j ) + (iComp-rhs.digit( j )) + iCarry; 738 iRes = digit( j ) + (iComp-rhs.digit( j )) + iCarry;
724// Bu::println(" Place: %1 + %2 + (%3) = %4"). 739 if( iRes < iRadix )
725// arg( digit(j) ).arg( 9-rhs.digit( j ) ).arg( iCarry ) 740 {
726// .arg( iRes ); 741 iCarry = 0;
742 }
743 else
744 iCarry = iRes/iRadix;
745
746 DBS( ADD,
747 Bu::println(" Place: %1 + %2 + (%3) = %4").
748 arg( digit(j) ).arg( iComp-rhs.digit( j ) ).arg( iCarry )
749 .arg( iRes ) );
727 if( j < 0 ) 750 if( j < 0 )
728 ret.aFrac.set( -1-j, (iRes%iRadix) ); 751 ret.aFrac.set( -1-j, (iRes%iRadix) );
729 else 752 else
@@ -738,24 +761,22 @@ Number Number::add( const Number &rhs, bool bSub ) const
738 761
739 ret.aInt.append( (iRes%iRadix) ); 762 ret.aInt.append( (iRes%iRadix) );
740 } 763 }
741 if( iRes < iRadix )
742 iCarry = 0;
743 else
744 iCarry = iRes/iRadix;
745 } 764 }
746 if( iCarry == 0 ) 765 if( iCarry == 0 )
747 { 766 {
748 ret.bPositive = false; 767 ret.bPositive = false;
749 ret.aInt.set( 0, iComp-ret.aInt.get( 0 )+1); 768 int iVal = iComp-ret.digit( -ret.iScale )+1;
750 for( int j = 1; j < ret.aInt.getSize(); j++ ) 769 iCarry = (iVal >= iRadix) ? 1 : 0;
770 ret.setDigit( -ret.iScale, iVal%iRadix );
771
772 for( int j = -iScale+1; j < ret.aInt.getSize(); j++ )
751 { 773 {
752 ret.aInt.set( j, iComp-ret.aInt.get( j )); 774 iVal = iComp-ret.digit( j )+iCarry;
775 iCarry = (iVal >= iRadix) ? 1 : 0;
776 ret.setDigit( j, iVal%iRadix );
753 } 777 }
754 } 778 }
755 else 779 ret.aInt.trim();
756 {
757 ret.aInt.trim();
758 }
759 } 780 }
760 781
761 return ret; 782 return ret;
diff --git a/src/number.h b/src/number.h
index 2f7a583..79cd5f5 100644
--- a/src/number.h
+++ b/src/number.h
@@ -45,6 +45,7 @@ public:
45 Bu::String toString() const; 45 Bu::String toString() const;
46 46
47 int digit( int iIdx ) const; 47 int digit( int iIdx ) const;
48 void setDigit( int iIdx, int iVal );
48 49
49 int getScale() const { return iScale; } 50 int getScale() const { return iScale; }
50 int getEffectiveScale() const; 51 int getEffectiveScale() const;
diff --git a/src/unitnumber.cpp b/src/unitnumber.cpp
index 985f0d9..d213ed7 100644
--- a/src/unitnumber.cpp
+++ b/src/unitnumber.cpp
@@ -136,13 +136,17 @@ void UnitNumber::number1()
136 136
137#define mathTest( anum, op, bnum, scale, answ ) \ 137#define mathTest( anum, op, bnum, scale, answ ) \
138 unitTest( (Number(anum, scale) op Number(bnum, scale)).toString() == answ ) 138 unitTest( (Number(anum, scale) op Number(bnum, scale)).toString() == answ )
139/* 139
140void UnitNumber::number2() 140void UnitNumber::number2()
141{ 141{
142 mathTest( "1", /, "17", 10, "0.0588235294" ); 142 mathTest("55", +, "-100", 0, "-45");
143 mathTest( "1", /, "177", 10, "0.0056497175" ); 143 mathTest("30.01", +, "-31.21", 2, "-1.20");
144 mathTest("55", -, "100", 0, "-45");
145 mathTest("30.01", -, "31.21", 2, "-1.20");
146// mathTest( "1", /, "17", 10, "0.0588235294" );
147// mathTest( "1", /, "177", 10, "0.0056497175" );
144} 148}
145*/ 149
146 150
147/* 151/*
148// clic 152// clic
diff --git a/src/unitnumber.h b/src/unitnumber.h
index 96d882e..097fd5b 100644
--- a/src/unitnumber.h
+++ b/src/unitnumber.h
@@ -14,6 +14,7 @@ public:
14 void multiply1(); 14 void multiply1();
15 void divide1(); 15 void divide1();
16 void number1(); 16 void number1();
17 void number2();
17 void compare1(); 18 void compare1();
18 void radix1(); 19 void radix1();
19 void fraction1(); 20 void fraction1();