summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <mike@xagasoft.com>2013-04-16 13:57:57 -0600
committerMike Buland <mike@xagasoft.com>2013-04-16 13:57:57 -0600
commit7bb55b03c393b5d00914d328a16d238d17f6aa0f (patch)
tree4d9a0547b105e1867f8118f2f00548e1e05589ad
parent25989c6d3911b1d29a5866e668bff52537893afb (diff)
downloadclic-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 :)
-rw-r--r--src/main.cpp24
-rw-r--r--src/number.cpp107
-rw-r--r--src/number.h4
-rw-r--r--src/packedintarray.cpp20
-rw-r--r--src/packedintarray.h2
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
32template<typename t> t tabs( t x ) { return (x<(t)0)?(-x):x; } 32Number &Number::operator=( const Number &rhs )
33{
34 set( rhs );
35 return *this;
36}
33 37
34Number Number::operator+( const Number &rhs ) const 38Number Number::operator+( const Number &rhs ) const
35{ 39{
@@ -87,24 +91,18 @@ Number Number::operator*( const Number &rhs ) const
87 91
88Number Number::operator/( const Number &rhs ) const 92Number 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
99Number Number::operator%( const Number &rhs ) const
100{
101 Number q( iOrd ), r( iOrd );
102 divide( rhs, q, r );
103 return r;
104}
105
108Number Number::operator-() const 106Number 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
251void Number::set( const Number &sNum )
252{
253 aInt.set( sNum.aInt );
254 bPositive = sNum.bPositive;
255 iOrd = sNum.iOrd;
256}
257
253Bu::String Number::toString() const 258Bu::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
350void 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
40private: 43private:
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
43private: 47private:
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
130void 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
144void PackedIntArray::trim()
145{
146 while( iCount > 0 && get( iCount-1 ) == 0 )
147 iCount--;
148}
149
130Bu::String PackedIntArray::toBitString() const 150Bu::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;