diff options
author | Mike Buland <mike@xagasoft.com> | 2013-04-16 13:57:57 -0600 |
---|---|---|
committer | Mike Buland <mike@xagasoft.com> | 2013-04-16 13:57:57 -0600 |
commit | 7bb55b03c393b5d00914d328a16d238d17f6aa0f (patch) | |
tree | 4d9a0547b105e1867f8118f2f00548e1e05589ad /src | |
parent | 25989c6d3911b1d29a5866e668bff52537893afb (diff) | |
download | clic-7bb55b03c393b5d00914d328a16d238d17f6aa0f.tar.gz clic-7bb55b03c393b5d00914d328a16d238d17f6aa0f.tar.bz2 clic-7bb55b03c393b5d00914d328a16d238d17f6aa0f.tar.xz clic-7bb55b03c393b5d00914d328a16d238d17f6aa0f.zip |
Added /, %, and = operators.
Division now works just fine, but by long division. There are
apparently much faster ways of doing division, but as long as it works I
feel like that's a great start :)
Diffstat (limited to 'src')
-rw-r--r-- | src/main.cpp | 24 | ||||
-rw-r--r-- | src/number.cpp | 107 | ||||
-rw-r--r-- | src/number.h | 4 | ||||
-rw-r--r-- | src/packedintarray.cpp | 20 | ||||
-rw-r--r-- | src/packedintarray.h | 2 |
5 files changed, 139 insertions, 18 deletions
diff --git a/src/main.cpp b/src/main.cpp index 3678278..d436a20 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
@@ -157,6 +157,26 @@ void numbertest1() | |||
157 | arg( a.toString() ). | 157 | arg( a.toString() ). |
158 | arg( b.toString() ). | 158 | arg( b.toString() ). |
159 | arg( (a / b).toString() ); | 159 | arg( (a / b).toString() ); |
160 | |||
161 | a = "12345"; | ||
162 | b = "45"; | ||
163 | |||
164 | println("%1 / %2 = %3"). | ||
165 | arg( a.toString() ). | ||
166 | arg( b.toString() ). | ||
167 | arg( (a / b).toString() ); | ||
168 | |||
169 | a = "3007103450821050020096034077958224700"; | ||
170 | b = "898239467"; | ||
171 | |||
172 | println("%1 / %2 = %3"). | ||
173 | arg( a.toString() ). | ||
174 | arg( b.toString() ). | ||
175 | arg( (a / b).toString() ); | ||
176 | println("%1 %% %2 = %3"). | ||
177 | arg( a.toString() ). | ||
178 | arg( b.toString() ). | ||
179 | arg( (a % b).toString() ); | ||
160 | } | 180 | } |
161 | 181 | ||
162 | #define compcheck( anum, op, bnum ) \ | 182 | #define compcheck( anum, op, bnum ) \ |
@@ -230,8 +250,8 @@ int main( int , char *[] ) | |||
230 | println("CliC"); | 250 | println("CliC"); |
231 | 251 | ||
232 | // packedtest1(); | 252 | // packedtest1(); |
233 | // numbertest1(); | 253 | numbertest1(); |
234 | numbertestcomp(); | 254 | // numbertestcomp(); |
235 | 255 | ||
236 | return 0; | 256 | return 0; |
237 | } | 257 | } |
diff --git a/src/number.cpp b/src/number.cpp index 9b6ec55..b3a33dc 100644 --- a/src/number.cpp +++ b/src/number.cpp | |||
@@ -29,7 +29,11 @@ Number &Number::operator=( const Bu::String &sNum ) | |||
29 | return *this; | 29 | return *this; |
30 | } | 30 | } |
31 | 31 | ||
32 | template<typename t> t tabs( t x ) { return (x<(t)0)?(-x):x; } | 32 | Number &Number::operator=( const Number &rhs ) |
33 | { | ||
34 | set( rhs ); | ||
35 | return *this; | ||
36 | } | ||
33 | 37 | ||
34 | Number Number::operator+( const Number &rhs ) const | 38 | Number Number::operator+( const Number &rhs ) const |
35 | { | 39 | { |
@@ -87,24 +91,18 @@ Number Number::operator*( const Number &rhs ) const | |||
87 | 91 | ||
88 | Number Number::operator/( const Number &rhs ) const | 92 | Number Number::operator/( const Number &rhs ) const |
89 | { | 93 | { |
90 | if( rhs.aInt.getSize() > aInt.getSize() ) | 94 | Number q( iOrd ), r( iOrd ); |
91 | return Number( iOrd ); | 95 | divide( rhs, q, r ); |
92 | |||
93 | Number q( iOrd ); | ||
94 | |||
95 | int iMinWidth = rhs.aInt.getSize(); | ||
96 | |||
97 | Bu::println("%1\n-----").arg( aInt.toString() ); | ||
98 | for( int j = aInt.getSize(); j > iMinWidth; j-- ) | ||
99 | { | ||
100 | Number sub( iOrd ); | ||
101 | sub.aInt.set( aInt, j-iMinWidth, iMinWidth ); | ||
102 | Bu::println("%1\n%2\n----").arg( sub.toString() ).arg( rhs.toString() ); | ||
103 | } | ||
104 | |||
105 | return q; | 96 | return q; |
106 | } | 97 | } |
107 | 98 | ||
99 | Number Number::operator%( const Number &rhs ) const | ||
100 | { | ||
101 | Number q( iOrd ), r( iOrd ); | ||
102 | divide( rhs, q, r ); | ||
103 | return r; | ||
104 | } | ||
105 | |||
108 | Number Number::operator-() const | 106 | Number Number::operator-() const |
109 | { | 107 | { |
110 | Number neg( *this ); | 108 | Number neg( *this ); |
@@ -250,6 +248,13 @@ void Number::set( const Bu::String &sNum ) | |||
250 | } | 248 | } |
251 | } | 249 | } |
252 | 250 | ||
251 | void Number::set( const Number &sNum ) | ||
252 | { | ||
253 | aInt.set( sNum.aInt ); | ||
254 | bPositive = sNum.bPositive; | ||
255 | iOrd = sNum.iOrd; | ||
256 | } | ||
257 | |||
253 | Bu::String Number::toString() const | 258 | Bu::String Number::toString() const |
254 | { | 259 | { |
255 | if( aInt.getSize() == 0 ) | 260 | if( aInt.getSize() == 0 ) |
@@ -272,6 +277,7 @@ Number Number::add( const Number &rhs, bool bSub ) const | |||
272 | 277 | ||
273 | int iZeros = 0; | 278 | int iZeros = 0; |
274 | int iCarry = 0; | 279 | int iCarry = 0; |
280 | // Bu::println("::: %1 + %2:").arg( toString() ).arg( rhs.toString() ); | ||
275 | 281 | ||
276 | if( bPositive == (bSub?!rhs.bPositive:rhs.bPositive)) | 282 | if( bPositive == (bSub?!rhs.bPositive:rhs.bPositive)) |
277 | { | 283 | { |
@@ -332,8 +338,77 @@ Number Number::add( const Number &rhs, bool bSub ) const | |||
332 | ret.aInt.set( j, 9-ret.aInt.get( j )); | 338 | ret.aInt.set( j, 9-ret.aInt.get( j )); |
333 | } | 339 | } |
334 | } | 340 | } |
341 | else | ||
342 | { | ||
343 | ret.aInt.trim(); | ||
344 | } | ||
335 | } | 345 | } |
336 | 346 | ||
337 | return ret; | 347 | return ret; |
338 | } | 348 | } |
339 | 349 | ||
350 | void Number::divide( const Number &rhs, Number &q, Number &r ) const | ||
351 | { | ||
352 | q.aInt.clear(); | ||
353 | r = *this; | ||
354 | |||
355 | if( rhs.aInt.getSize() > aInt.getSize() ) | ||
356 | return; | ||
357 | |||
358 | if( bPositive == rhs.bPositive ) | ||
359 | q.bPositive = true; | ||
360 | else | ||
361 | q.bPositive = false; | ||
362 | |||
363 | int iMinWidth = rhs.aInt.getSize(); | ||
364 | |||
365 | int iAnchor = r.aInt.getSize()-iMinWidth; | ||
366 | int iSample = iMinWidth; | ||
367 | do | ||
368 | { | ||
369 | // Bu::println("%1\n-----").arg( r.aInt.toString() ); | ||
370 | Number sub( iOrd ); | ||
371 | for(;;) | ||
372 | { | ||
373 | // Bu::println(" -> Anchor: %1, Sample: %2").arg( iAnchor ).arg( iSample ); | ||
374 | sub.aInt.set( r.aInt, iAnchor, iSample ); | ||
375 | // Bu::println("%1\n%2\n----").arg( sub.toString() ).arg( rhs.toString() ); | ||
376 | if( sub < rhs ) | ||
377 | { | ||
378 | iSample++; | ||
379 | iAnchor--; | ||
380 | if( iAnchor < 0 ) | ||
381 | { | ||
382 | // Bu::println("[Inner exit] Complete: q = %1, r = %2").arg( q.toString() ).arg( r.toString() ); | ||
383 | return; | ||
384 | } | ||
385 | } | ||
386 | else | ||
387 | break; | ||
388 | } | ||
389 | |||
390 | Number x( iOrd ); | ||
391 | int iRes = 0; | ||
392 | for( ; x <= sub; iRes++, x = x + rhs ) { } | ||
393 | x = sub - (x - rhs); | ||
394 | for( int j = 0; iAnchor+j >= 0 && j < x.aInt.getSize(); j++ ) | ||
395 | r.aInt.set( iAnchor+j, x.aInt.get( j ) ); | ||
396 | while( r.aInt.getSize() > iAnchor+x.aInt.getSize() ) | ||
397 | r.aInt.remove(); | ||
398 | // Bu::println(" -> Post remainder patch: %1 -> %2"). | ||
399 | // arg( x.toString() ).arg( r.toString() ); | ||
400 | |||
401 | // Bu::println("%1 (%2)").arg( iRes-1 ).arg( x.toString() ); | ||
402 | while( q.aInt.getSize() <= iAnchor ) | ||
403 | q.aInt.append(0); | ||
404 | q.aInt.set( iAnchor, iRes-1 ); | ||
405 | |||
406 | iSample = iMinWidth; | ||
407 | iAnchor = r.aInt.getSize()-iMinWidth; | ||
408 | // Bu::println(" -> new Anchor: %1, Sample: %2").arg( iAnchor ). | ||
409 | // arg( iSample ); | ||
410 | } while( iAnchor >= 0 ); | ||
411 | |||
412 | // Bu::println("Complete: q = %1, r = %2").arg( q.toString() ).arg( r.toString() ); | ||
413 | } | ||
414 | |||
diff --git a/src/number.h b/src/number.h index 7d65096..9cb16b0 100644 --- a/src/number.h +++ b/src/number.h | |||
@@ -12,11 +12,13 @@ public: | |||
12 | virtual ~Number(); | 12 | virtual ~Number(); |
13 | 13 | ||
14 | Number &operator=( const Bu::String &sNum ); | 14 | Number &operator=( const Bu::String &sNum ); |
15 | Number &operator=( const Number &rhs ); | ||
15 | 16 | ||
16 | Number operator+( const Number &rhs ) const; | 17 | Number operator+( const Number &rhs ) const; |
17 | Number operator-( const Number &rhs ) const; | 18 | Number operator-( const Number &rhs ) const; |
18 | Number operator*( const Number &rhs ) const; | 19 | Number operator*( const Number &rhs ) const; |
19 | Number operator/( const Number &rhs ) const; | 20 | Number operator/( const Number &rhs ) const; |
21 | Number operator%( const Number &rhs ) const; | ||
20 | Number operator-() const; | 22 | Number operator-() const; |
21 | 23 | ||
22 | bool operator==( const Number &rhs ) const; | 24 | bool operator==( const Number &rhs ) const; |
@@ -27,6 +29,7 @@ public: | |||
27 | bool operator<=( const Number &rhs ) const; | 29 | bool operator<=( const Number &rhs ) const; |
28 | 30 | ||
29 | void set( const Bu::String &sNum ); | 31 | void set( const Bu::String &sNum ); |
32 | void set( const Number &sNum ); | ||
30 | 33 | ||
31 | operator Bu::String() const | 34 | operator Bu::String() const |
32 | { | 35 | { |
@@ -39,6 +42,7 @@ public: | |||
39 | 42 | ||
40 | private: | 43 | private: |
41 | Number add( const Number &rhs, bool bSub ) const; | 44 | Number add( const Number &rhs, bool bSub ) const; |
45 | void divide( const Number &rhs, Number &q, Number &r ) const; | ||
42 | 46 | ||
43 | private: | 47 | private: |
44 | int iOrd; | 48 | int iOrd; |
diff --git a/src/packedintarray.cpp b/src/packedintarray.cpp index 7c54063..0e137bf 100644 --- a/src/packedintarray.cpp +++ b/src/packedintarray.cpp | |||
@@ -127,6 +127,26 @@ void PackedIntArray::set( const PackedIntArray &rSrc, int iStart, int iSize ) | |||
127 | } | 127 | } |
128 | } | 128 | } |
129 | 129 | ||
130 | void PackedIntArray::set( const PackedIntArray &rSrc ) | ||
131 | { | ||
132 | delete[] aData; | ||
133 | |||
134 | iBitWidth = rSrc.iBitWidth; | ||
135 | iCapacity = rSrc.iCapacity; | ||
136 | iCount = rSrc.iCount; | ||
137 | uMask = rSrc.uMask; | ||
138 | |||
139 | int iSize = StoreCount(iCapacity); | ||
140 | aData = new Store[iSize]; | ||
141 | memcpy( aData, rSrc.aData, iSize*sizeof(Store) ); | ||
142 | } | ||
143 | |||
144 | void PackedIntArray::trim() | ||
145 | { | ||
146 | while( iCount > 0 && get( iCount-1 ) == 0 ) | ||
147 | iCount--; | ||
148 | } | ||
149 | |||
130 | Bu::String PackedIntArray::toBitString() const | 150 | Bu::String PackedIntArray::toBitString() const |
131 | { | 151 | { |
132 | Bu::String sRet; | 152 | Bu::String sRet; |
diff --git a/src/packedintarray.h b/src/packedintarray.h index a865df5..de26a6a 100644 --- a/src/packedintarray.h +++ b/src/packedintarray.h | |||
@@ -20,6 +20,8 @@ public: | |||
20 | void set( int idx, Unit i ); | 20 | void set( int idx, Unit i ); |
21 | int getSize() const { return iCount; } | 21 | int getSize() const { return iCount; } |
22 | void set( const PackedIntArray &rSrc, int iStart, int iSize ); | 22 | void set( const PackedIntArray &rSrc, int iStart, int iSize ); |
23 | void set( const PackedIntArray &rSrc ); | ||
24 | void trim(); | ||
23 | 25 | ||
24 | Bu::String toBitString() const; | 26 | Bu::String toBitString() const; |
25 | Bu::String toString() const; | 27 | Bu::String toString() const; |