diff options
author | Mike Buland <mike@xagasoft.com> | 2013-04-15 23:45:48 -0600 |
---|---|---|
committer | Mike Buland <mike@xagasoft.com> | 2013-04-15 23:45:48 -0600 |
commit | 44542adf023315d60a8ffc4863f2b161b3c1eb90 (patch) | |
tree | 3500c1d6cfa3e5670bde199e24125c4b8e0c33db /src/number.cpp | |
parent | f34eb76357fdfc314d6451fd11a2e4d6fcfce434 (diff) | |
download | clic-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 'src/number.cpp')
-rw-r--r-- | src/number.cpp | 166 |
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 | ||
7 | Number::Number( int iOrd ) : | 7 | Number::Number( int iOrd ) : |
8 | iOrd( iOrd ), | 8 | iOrd( iOrd ), |
9 | aInt( 4 ) | 9 | aInt( 4 ), |
10 | bPositive( true ) | ||
10 | { | 11 | { |
11 | } | 12 | } |
12 | 13 | ||
13 | Number::Number( const Bu::String &sData, int iOrd ) : | 14 | Number::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 | ||
21 | Number::~Number() | 22 | Number::~Number() |
22 | { | 23 | { |
23 | } | 24 | } |
24 | 25 | ||
26 | Number &Number::operator=( const Bu::String &sNum ) | ||
27 | { | ||
28 | set( sNum ); | ||
29 | return *this; | ||
30 | } | ||
31 | |||
32 | template<typename t> t tabs( t x ) { return (x<(t)0)?(-x):x; } | ||
33 | |||
25 | Number Number::operator+( const Number &rhs ) const | 34 | Number Number::operator+( const Number &rhs ) const |
26 | { | 35 | { |
36 | return add( rhs, false ); | ||
37 | } | ||
38 | |||
39 | Number Number::operator-( const Number &rhs ) const | ||
40 | { | ||
41 | return add( rhs, true ); | ||
42 | } | ||
43 | |||
44 | Number 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 | ||
89 | void 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 | |||
106 | Bu::String Number::toString() const | ||
107 | { | ||
108 | if( aInt.getSize() == 0 ) | ||
109 | return "0"; | ||
110 | return (bPositive?"":"-") + aInt.toString(); | ||
111 | } | ||
112 | |||
48 | int Number::digit( int iOrder ) const | 113 | int 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 | ||
120 | Number 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 | |||