Inhalt | Code | Beispiel |
C++ | Kommentare | Zeilennummern | Midnight |
main.cpp
001 /* Author Malte Pagel */
002
003 #include <cstdlib>
004 #include <iostream>
005 #include <cstdio>
006 #include <string>
007 #include <cstring>
008 #include <sstream>
009
010 using namespace std;
011
012 #include "StringInt.h"
013
014
015 string int_to_string(int);
016
017
018 string int_to_string (int number) {
019 stringstream ss;
020 ss << number;
021 return ss.str();
022 }
023
024
025 int main (int argc, const char * argv[]) {
026
027 char c = '?';
028
029 string welcome = "\t 1 - Faculties\n\t 2 - Squareroot of 2\n\t 3 - Collatz\n\t q - Quit\n";
030
031 cout << welcome;
032
033 while ( c != '1' && c != '2' && c != '3' && c != 'q' && c != 'Q' ) {
034 scanf("%s", &c);
035 if ( c != '1' && c != '2' && c != '3' && c != 'q' && c != 'Q' )
036 cout << "Once again!" << endl << welcome;
037 }
038
039 if ( c == '1' || c == '2' || c == '3' ) {
040 StringInt *s_int = new StringInt();
041
042 int i;
043 int limit = 50;
044
045 string result = "1";
046 string pow;
047
048 int choice = (int) c - 48;
049
050 switch ( choice ) {
051 case 1:
052 for ( i = 1; i <= limit; i++ ) {
053 result = s_int->calculate(result, int_to_string(i), "mul");
054 cout << i << "!\t= " << result << endl;
055 }
056 break;
057 case 2:
058 cout << "\tSQRT(2) ≈ 1.";
059 for ( i = 1; i <= limit; i++ ) {
060 result = s_int->calculate(result, "10", "mul");
061 result = s_int->calculate(result, "9", "add");
062 while (1) {
063 pow = s_int->calculate(result, result, "mul");
064 if ( pow[0] == '1' )
065 break;
066 result = s_int->calculate(result, "1", "sub");
067 }
068 cout << result[result.length() - 1];
069 }
070 break;
071 case 3:
072 cout << endl << "If x is even: x = x / 2" << endl;
073 cout << "If x is odd: x = 3 * x + 1" << endl;
074
075 result = "2602714556700227743";
076 string original_result = result;
077 int is_below_origin = 0;
078 int last_digit;
079 i = 0;
080 s_int->precision = 0;
081
082 cout << "Every number is possible, but " << result << " gives spectacular results" << endl << endl;
083 while ( result != "1" ) {
084 if ( !is_below_origin && result.length() <= original_result.length() )
085 if ( strcmp((char*) result.c_str(), (char*) original_result.c_str()) < 0 ) {
086 is_below_origin = 1;
087 cout << "\n\tCannot rise anymore!\n" << endl;
088 }
089
090 if ( is_below_origin )
091 cout << " ";
092
093 last_digit = (int) result[result.length() - 1];
094 printf("Step %4d:\t", ++i);
095 if ( last_digit % 2 == 0 ) {
096 cout << "(/ 2)\t\t= ";
097 result = s_int->calculate(result, "2", "div");
098 }
099 else {
100 cout << "(* 3 + 1)\t= ";
101 result = s_int->calculate(result, "3", "mul");
102 result = s_int->calculate(result, "1", "add");
103 }
104 cout << result << endl;
105 }
106 }
107 }
108
109 cout << endl << endl<< "Goodbye" << endl << endl;
110
111 return 0;
112 }
113
114
StringInt.h
01 // File: StringInt.h
02
03 /*
04 * Author: maltepagel
05 *
06 * Created May 2014
07 */
08
09 #ifndef __StringIntegersConsoleDemo__StringInt__
10 #define __StringIntegersConsoleDemo__StringInt__
11
12 #include <iostream>
13 #include <string>
14 #include <cstring>
15 #include <sstream>
16
17 using namespace std;
18
19
20 class StringInt {
21 public:
22 StringInt();
23
24 int precision;
25
26 string calculate(char*, char*, char operation);
27 string calculate(string, string, string);
28 private:
29 string plus(string, string);
30 string minus(string, string, int);
31 string multiplicate(string, string);
32 string divide(string, string, string, int, int);
33 string pre_divide(string, string, int);
34 string post_divide(string, int, int);
35
36 string first, second;
37 string mul_divisors[8];
38 int first_neg, second_neg;
39
40 void set_to_equal_length(string, string);
41 string trim_number(string);
42 char* to_char_pointer(string);
43 string convert_int(int);
44 string add_floating_point(string, int);
45 };
46
47
48 #endif /* defined(__StringIntegersConsoleDemo__StringInt__) */
49
StringInt.cpp
001 // File: StringInt.cpp
002
003 /*
004 * Author: maltepagel
005 *
006 * Created May 2014
007 */
008
009 #include "StringInt.h"
010
011
012 string StringInt::add_floating_point (string pseudonumber, int point_position) {
013
014 int len = (int) pseudonumber.length();
015
016 if ( point_position <= len )
017 pseudonumber.insert(len - point_position, ".");
018
019 if ( pseudonumber[0] == '.' )
020 pseudonumber.insert(0, "0");
021
022 return pseudonumber;
023 }
024
025 string StringInt::convert_int (int number) {
026 stringstream ss;
027 ss << number;
028 return ss.str();
029 }
030
031 char* StringInt::to_char_pointer (string the_string) {
032 return (char*) the_string.c_str();
033 }
034
035 string StringInt::trim_number (string string_to_trim) {
036
037 int i;
038 char c;
039 string result = "";
040
041 for ( i = 0; i < string_to_trim.length(); i++ ) {
042 if ( string_to_trim[i] != '0' ) {
043 result.append(string_to_trim, i, (string_to_trim.length() - i));
044 break;
045 }
046 }
047 if ( result[0] == '.' )
048 result.insert(0, "0");
049
050 if ( strchr(result.c_str(), '.') ) {
051 i = (int) result.length() - 1;
052 c = result[i];
053 while ( i > 0 && (result[i] == '0' || result[i] == '.') ) {
054 result[i--] = '\0';
055 }
056 result.resize(i + 1);
057 }
058
059 if ( result.empty() )
060 result = "0";
061
062 return result;
063 }
064
065 void StringInt::set_to_equal_length (string tmp_first, string tmp_second) {
066
067 int i;
068 int f_max = (int) tmp_first.length();
069 int s_max = (int) tmp_second.length();
070 int max = (f_max > s_max) ? f_max : s_max;
071
072 first_neg = 0;
073 second_neg = 0;
074
075 first = string(max, '0');
076 second = string(max, '0');
077
078 for ( i = 0; i < f_max; i++ )
079 if ( (int) tmp_first[i] >= 48 && (int) tmp_first[i] <= 57 )
080 first[i + max - f_max] = tmp_first[i];
081 else
082 if ( tmp_first[i] == '-' )
083 first_neg = 1;
084
085 for ( i = 0; i < s_max; i++ )
086 if ( (int) tmp_second[i] >= 48 && (int) tmp_second[i] <= 57 )
087 second[i + max - s_max] = tmp_second[i];
088 else
089 if ( tmp_second[i] == '-' )
090 second_neg = 1;
091 }
092
093 /* */
094
095 string StringInt::plus (string tmp_first, string tmp_second) {
096
097 int i, last_index, digit;
098 string result;
099 int overhead = 0;
100 int negative = 0;
101
102 set_to_equal_length(tmp_first, tmp_second);
103
104 if ( first_neg && second_neg )
105 negative = 1;
106 else
107 if ( !first_neg && second_neg )
108 return minus(first, second, 0);
109 else
110 if ( first_neg && !second_neg )
111 return minus(second, first, 0);
112
113 last_index = (int) first.length() - 1;
114 result = string((last_index + 2), '0');
115 for ( i = last_index; i >= 0; i-- ) {
116 digit = (int) first[i] - 48 + (int) second[i] - 48 + overhead;
117 overhead = (digit > 9) ? 1 : 0;
118 digit %= 10;
119 result[i + 1] = digit + 48;
120 }
121
122 if ( overhead )
123 result[0] = '1';
124
125 result = trim_number(result);
126
127 if ( negative ) {
128 string neg_result = "-";
129 neg_result.append(result);
130 return neg_result;
131 }
132
133 return result;
134 }
135
136 string StringInt::minus (string tmp_first, string tmp_second, int negative) {
137
138 set_to_equal_length(tmp_first, tmp_second);
139
140 if ( second_neg )
141 return plus(first, second);
142 else
143 if ( first_neg ) {
144 string zero = "0";
145 return minus(zero, plus(first, second), 0);
146 }
147
148 if ( strcmp(to_char_pointer(first), to_char_pointer(second)) < 0 )
149 return minus(second, first, (1 - negative));
150
151 int i, last_index, digit;
152 string result;
153 int overhead = 0;
154
155 last_index = (int) first.length() - 1;
156 result = string((last_index + 2), '0');
157 for ( i = last_index; i >= 0; i-- ) {
158 digit = ((int) first[i] - 48) - ((int) second[i] - 48 + overhead);
159 overhead = (digit < 0) ? 1 : 0;
160 if ( overhead )
161 digit += 10;
162 result[i + 1] = digit + 48;
163 }
164 result = trim_number(result);
165
166 if ( negative ) {
167 string neg_result = "-";
168 neg_result.append(result);
169 return neg_result;
170 }
171
172 return result;
173 }
174
175 string StringInt::multiplicate (string tmp_first, string tmp_second) {
176
177 int i, j, k, digit, zeros;
178 int overhead = 0;
179 int negative = 0;
180 string zero_string, digit_string;
181 string result = "0";
182
183 set_to_equal_length(tmp_first, tmp_second);
184
185 if ( first_neg != second_neg )
186 negative = 1;
187
188 string multiplicator = trim_number(first);
189 string multiplicand = trim_number(second);
190
191 for ( i = ((int) multiplicand.length() - 1); i >= 0; i-- ) {
192 for ( j = ((int) multiplicator.length() - 1); j >= 0; j-- ) {
193 zero_string = "";
194 digit = ((int) multiplicand[i] - 48) * ((int) multiplicator[j] - 48) + overhead;
195 overhead = (int) (digit / 10);
196 if ( j )
197 digit %= 10;
198 else
199 overhead = 0;
200 zeros = ((int) multiplicand.length() - 1 - i) + ((int) multiplicator.length() - 1 - j);
201 for ( k = 0; k < zeros; k++ )
202 zero_string.append("0");
203 digit_string = convert_int(digit);
204 digit_string.append(zero_string);
205 result = plus(result, digit_string);
206 }
207 }
208
209 if ( negative ) {
210 string neg_result = "-";
211 neg_result.append(result);
212 return neg_result;
213 }
214
215 return result;
216 }
217
218 string StringInt::pre_divide (string tmp_first, string tmp_second, int precision_to_use) {
219
220 int i;
221 int negative = 0;
222
223 set_to_equal_length(tmp_first, tmp_second);
224
225 if ( first_neg != second_neg )
226 negative = 1;
227
228 string dividend = trim_number(first);
229 string divisor = trim_number(second);
230
231 if ( dividend == divisor )
232 return post_divide("1", precision_to_use, negative);
233
234 if ( precision_to_use ) {
235 string decimal = "1";
236 for ( i = 0; i < precision_to_use; i++ )
237 decimal.append("0");
238 dividend = multiplicate(dividend, decimal);
239 }
240
241 for ( i = 0; i < 8; i++ )
242 mul_divisors[i] = "";
243
244 return divide(dividend, divisor, "0", precision_to_use, negative);
245 }
246 string StringInt::divide (string dividend, string divisor, string result, int precision_to_use, int negative) {
247
248 if ( dividend.length() < divisor.length() || (dividend.length() == divisor.length() && strcmp(to_char_pointer(dividend), to_char_pointer(divisor)) < 0) )
249 return post_divide(result, precision_to_use, negative);
250
251 int i, small_dividend, small_divisor, starting_point;
252 int overhead = 0;
253 string tmp_result, tmp_divisor;
254 string zeros_to_add = "";
255
256
257 string dividend_head(dividend, 0, divisor.length());
258 if ( strcmp(to_char_pointer(dividend_head), to_char_pointer(divisor)) < 0 ) {
259 overhead = 1;
260 dividend_head += dividend[divisor.length()];
261 }
262
263 small_divisor = (int) divisor[0] - 48;
264 if ( !overhead )
265 small_dividend = (int) dividend[0] - 48;
266 else
267 small_dividend = (int) dividend[1] - 48 + (10 * ((int) dividend[0] - 48));
268
269 for ( i = overhead; i < (dividend.length() - divisor.length()); i++ )
270 zeros_to_add.append("0");
271
272 starting_point = (int) (small_dividend / small_divisor);
273
274 for ( i = starting_point; i >= 2; i-- ) {
275 if ( mul_divisors[i - 2] == "" )
276 mul_divisors[i - 2] = multiplicate(divisor, convert_int(i));
277 tmp_result = convert_int(i) + zeros_to_add;
278 tmp_divisor = mul_divisors[i - 2] + zeros_to_add;
279
280 if ( tmp_divisor.length() <= dividend.length() && strcmp(to_char_pointer(tmp_divisor), to_char_pointer(dividend)) <= 0 )
281 break;
282 }
283 if ( i < 2 ) {
284 tmp_result = "1" + zeros_to_add;
285 tmp_divisor = divisor + zeros_to_add;
286 }
287
288 return divide(minus(dividend, tmp_divisor, 0), divisor, plus(result, tmp_result), precision_to_use, negative);
289 }
290 string StringInt::post_divide (string result, int precision_to_use, int negative) {
291
292 if ( precision_to_use )
293 result = add_floating_point(result, precision_to_use);
294
295 result = trim_number(result);
296
297 if ( negative ) {
298 string neg_result = "-";
299 neg_result.append(result);
300 return neg_result;
301 }
302
303 return result;
304 }
305
306 /* */
307
308 /**
309 * For GUI usage: char pointers as input
310 *
311 * @param <char*> tmp_first
312 * @param <char*> tmp_second
313 * @param <char> operation
314 *
315 * @return <string>
316 */
317 string StringInt::calculate (char* tmp_first, char* tmp_second, char operation) {
318
319 first = "";
320 second = "";
321 first_neg = 0;
322 second_neg = 0;
323
324 switch (operation) {
325 case '+':
326 return plus(tmp_first, tmp_second);
327 break;
328 case '-':
329 return minus(tmp_first, tmp_second, 0);
330 break;
331 case '*':
332 return multiplicate(tmp_first, tmp_second);
333 break;
334 case '/':
335 return pre_divide(tmp_first, tmp_second, precision);
336 break;
337 }
338
339 return "???";
340 }
341 /**
342 * String input
343 *
344 * @param <string> tmp_first
345 * @param <string> tmp_second
346 * @param <string> operation
347 * @return <string>
348 */
349 string StringInt::calculate (string tmp_first, string tmp_second, string operation) {
350
351 first = "";
352 second = "";
353 first_neg = 0;
354 second_neg = 0;
355
356 char c = operation[0];
357
358 switch (c) {
359 case 'a':
360 return plus(tmp_first, tmp_second);
361 break;
362 case 's':
363 return minus(tmp_first, tmp_second, 0);
364 break;
365 case 'm':
366 return multiplicate(tmp_first, tmp_second);
367 break;
368 case 'd':
369 return pre_divide(tmp_first, tmp_second, precision);
370 break;
371 }
372
373 return "0";
374 }
375
376
377 StringInt::StringInt () {
378 precision = 2;
379 }
380
381