summaryrefslogtreecommitdiff
path: root/src/number.cpp
diff options
context:
space:
mode:
authorMike Buland <mike@xagasoft.com>2013-04-15 23:45:48 -0600
committerMike Buland <mike@xagasoft.com>2013-04-15 23:45:48 -0600
commit44542adf023315d60a8ffc4863f2b161b3c1eb90 (patch)
tree3500c1d6cfa3e5670bde199e24125c4b8e0c33db /src/number.cpp
parentf34eb76357fdfc314d6451fd11a2e4d6fcfce434 (diff)
downloadclic-44542adf023315d60a8ffc4863f2b161b3c1eb90.tar.gz
clic-44542adf023315d60a8ffc4863f2b161b3c1eb90.tar.bz2
clic-44542adf023315d60a8ffc4863f2b161b3c1eb90.tar.xz
clic-44542adf023315d60a8ffc4863f2b161b3c1eb90.zip
Addition, subtraction, and multiplication work now
Division isn't working yet, there are too many options, I'll figure out something eventually :-P
Diffstat (limited to '')
-rw-r--r--src/number.cpp166
1 files changed, 152 insertions, 14 deletions
diff --git a/src/number.cpp b/src/number.cpp
index e64be94..ac29c61 100644
--- a/src/number.cpp
+++ b/src/number.cpp
@@ -6,45 +6,110 @@
6 6
7Number::Number( int iOrd ) : 7Number::Number( int iOrd ) :
8 iOrd( iOrd ), 8 iOrd( iOrd ),
9 aInt( 4 ) 9 aInt( 4 ),
10 bPositive( true )
10{ 11{
11} 12}
12 13
13Number::Number( const Bu::String &sData, int iOrd ) : 14Number::Number( const Bu::String &sData, int iOrd ) :
14 iOrd( iOrd ), 15 iOrd( iOrd ),
15 aInt( 4 ) 16 aInt( 4 ),
17 bPositive( true )
16{ 18{
17 for( int j = sData.getSize()-1; j >= 0; j-- ) 19 set( sData );
18 aInt.append( sData[j]-'0' );
19} 20}
20 21
21Number::~Number() 22Number::~Number()
22{ 23{
23} 24}
24 25
26Number &Number::operator=( const Bu::String &sNum )
27{
28 set( sNum );
29 return *this;
30}
31
32template<typename t> t tabs( t x ) { return (x<(t)0)?(-x):x; }
33
25Number Number::operator+( const Number &rhs ) const 34Number Number::operator+( const Number &rhs ) const
26{ 35{
36 return add( rhs, false );
37}
38
39Number Number::operator-( const Number &rhs ) const
40{
41 return add( rhs, true );
42}
43
44Number Number::operator*( const Number &rhs ) const
45{
27 Number ret( iOrd ); 46 Number ret( iOrd );
28 47
29 int iPlaces = Bu::buMax(rhs.aInt.getSize(), aInt.getSize() )+1; 48 int iPlaces = Bu::buMax(rhs.aInt.getSize(), aInt.getSize() );
49 int iCnt = aInt.getSize()+rhs.aInt.getSize();
30 50
31 int iCarry = 0; 51 int iCarry = 0;
32 for( int j = 0; j < iPlaces; j++ ) 52 int iZeros = 0;
53 for( int j = 0; j < iCnt || iCarry > 0; j++ )
33 { 54 {
34 int iRes = iCarry + digit( j ) + rhs.digit( j ); 55// Bu::println("Pos %1").arg(j);
35 Bu::println(" Place: %1 + %2 + (%3) = %4"). 56 int iPos = iCarry;
36 arg( digit(j) ).arg( rhs.digit( j ) ).arg( iCarry ) 57 iCarry = 0;
37 .arg( iRes ); 58 for( int k = 0; k < rhs.aInt.getSize(); k++ )
38 ret.aInt.append( (iRes%iRadix) ); 59 {
39 if( iRes < iRadix ) 60 if( j-k < 0 )
40 iCarry = 0; 61 break;
62
63 int iRes = digit(j-k)*rhs.digit(k);
64 iPos += iRes;
65
66// Bu::println(" [%1] %2 * [%3] %4 = %5 -> %6").
67// arg( j-k ).arg( digit(j-k) ).arg( k ).arg( rhs.digit(k) ).
68// arg( iRes ).arg( iPos ).arg( iCarry );
69 }
70 if( (iPos%iRadix) == 0 )
71 iZeros++;
41 else 72 else
42 iCarry = iRes/iRadix; 73 {
74 for(; iZeros > 0; iZeros-- )
75 ret.aInt.append( 0 );
76 ret.aInt.append( iPos%iRadix );
77 }
78 iCarry += iPos/iRadix;
43 } 79 }
44 80
81 if( bPositive == rhs.bPositive )
82 ret.bPositive = true;
83 else
84 ret.bPositive = false;
85
45 return ret; 86 return ret;
46} 87}
47 88
89void Number::set( const Bu::String &sNum )
90{
91 aInt.clear();
92 bPositive = true;
93 for( int j = sNum.getSize()-1; j >= 0; j-- )
94 {
95 if( sNum[j] == '+' )
96 break;
97 if( sNum[j] == '-' )
98 {
99 bPositive = false;
100 break;
101 }
102 aInt.append( sNum[j]-'0' );
103 }
104}
105
106Bu::String Number::toString() const
107{
108 if( aInt.getSize() == 0 )
109 return "0";
110 return (bPositive?"":"-") + aInt.toString();
111}
112
48int Number::digit( int iOrder ) const 113int Number::digit( int iOrder ) const
49{ 114{
50 if( iOrder >= aInt.getSize() ) 115 if( iOrder >= aInt.getSize() )
@@ -52,3 +117,76 @@ int Number::digit( int iOrder ) const
52 return aInt[iOrder]; 117 return aInt[iOrder];
53} 118}
54 119
120Number Number::add( const Number &rhs, bool bSub ) const
121{
122 Number ret( iOrd );
123
124 int iPlaces = Bu::buMax(rhs.aInt.getSize(), aInt.getSize() );
125
126 int iZeros = 0;
127 int iCarry = 0;
128
129 if( bPositive == (bSub?!rhs.bPositive:rhs.bPositive))
130 {
131 ret.bPositive = bPositive;
132 for( int j = 0; j < iPlaces || iCarry > 0; j++ )
133 {
134 int iRes = iCarry + digit( j ) + rhs.digit( j );
135// Bu::println(" Place: %1 + %2 + (%3) = %4").
136// arg( digit(j) ).arg( rhs.digit( j ) ).arg( iCarry )
137// .arg( iRes );
138 if( iRes == 0 )
139 {
140 iZeros++;
141 continue;
142 }
143 for(; iZeros > 0; iZeros-- )
144 ret.aInt.append( 0 );
145
146 ret.aInt.append( (iRes%iRadix) );
147 if( iRes < iRadix )
148 iCarry = 0;
149 else
150 iCarry = iRes/iRadix;
151 }
152 }
153 else
154 {
155 iCarry = 1;
156// Bu::println("--method b--");
157 ret.bPositive = bPositive;
158 int iRes;
159 for( int j = 0; j < iPlaces; j++ )
160 {
161 iRes = digit( j ) + (9-rhs.digit( j )) + iCarry;
162// Bu::println(" Place: %1 + %2 + (%3) = %4").
163// arg( digit(j) ).arg( 9-rhs.digit( j ) ).arg( iCarry )
164// .arg( iRes );
165 if( iRes == 0 )
166 {
167 iZeros++;
168 continue;
169 }
170 for(; iZeros > 0; iZeros-- )
171 ret.aInt.append( 0 );
172
173 ret.aInt.append( (iRes%iRadix) );
174 if( iRes < iRadix )
175 iCarry = 0;
176 else
177 iCarry = iRes/iRadix;
178 }
179 if( iCarry == 0 )
180 {
181 ret.bPositive = false;
182 ret.aInt.set( 0, 9-ret.aInt.get( 0 )+1);
183 for( int j = 1; j < ret.aInt.getSize(); j++ )
184 {
185 ret.aInt.set( j, 9-ret.aInt.get( j ));
186 }
187 }
188 }
189
190 return ret;
191}
192