-
Notifications
You must be signed in to change notification settings - Fork 0
/
calculator1.cpp
563 lines (493 loc) · 17.7 KB
/
calculator1.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
#include <iostream>
#include <cctype>
#include <cmath>
#include <math.h>
using namespace std;
////Function to add two numbers together
//double add(double num1, double num2) {
// return num1 + num2;
//}
////Function to add multiple numbers together
//void add_input() {
// double result = 0;
// string input = "";
//
// //Get numbers to add together
// do {
// cout << "Enter a number, or enter 0 to add all your numbers up: ";
// cin >> input;
//
// result += stod(input);
//
// } while (input != "0");
//
// cout << "\nThe answer is " << result << ".\n\n";
//}
//bool is_number(const std::string& s) {
// //This function checks if a string is a number.
// std::string::const_iterator it = s.begin();
//
// if (s[0] == '-') {
// it++;
// }
//
// while (it != s.end() && std::isdigit(*it)) ++it;
// return !s.empty() && it == s.end();
//}
bool is_number_revised(string input) {
//A revised function that handles decimal point numbers unlike the previous function.
int index = 0;
bool decimal_num = false;
std::string str = input;
// if (input[0] == '-') {
// cout << "This is a negative number.\n";
// }
for (char& x : str) {
// cout << x << ".\n";
if ((x < '0' || x > '9') && x >= '!') {
// cout << "x is not a number, check if it is a decimal point or negative sign. (If it is a number, we can simply continue to the next iteration.)\n";
if (x == '.') {
if (!decimal_num) {
decimal_num = true;
} else {
return false;
}
} else if (x != '-' || index != 0) { //This condition is checking if it's looking at a negative sign at the beginning of a number. If it is, we can continue, but otherwise we need to return false.
return false;
}
}
index++; //This is to signify we are at the next index in the string.
}
return true;
}
bool is_operator(string operat) {
//This is a simple operation that checks if a string is a valid operator.
return (operat == "+" || operat == "-" || operat == "*" || operat == "/" || operat == "//" || operat == "%" || operat == "%%" || operat == "^" || operat == "**");
}
bool is_trig_function(string operat) {
//This function checks if a string is a valid trigonometry function.
return (operat == "sin" || operat == "cos" || operat == "tan" || operat == "asin" || operat == "acos" || operat == "atan");
}
bool is_degrees_or_radians(string input) {
//This function checks if a string is 'r' or 'd', used for trigonometric functions
return (input == "r" || input == "d");
}
bool is_log_function(string operat) {
//This function checks if a string is a valid logarithmic function.
return (operat == "log" || operat == "ln" || operat == "logx" || operat == "e");
}
//double translate_time_to_double(string input, char delimiter) {
// //This function checks if a string is in proper time format, and translates into a double of seconds if so.
// //This function uses a delimiter to seperate hours, minutes, and seconds. For example, with a delimiter of ':', 1:20:3 would be an hour, 20 minutes, and 3 seconds.
// double hours = 0;
// double minutes = 0;
// double seconds = 0;
// int unit = 3; //Keeps track of the current unit we are iterating. 2 = hours, 1 = minutes, 0 = seconds
// std::string str = input + delimiter; //Adding a delimiter to the end of the string will make sure the last number (seconds) will be calculated.
// string input_for_current_unit = "";
//
//
// for (char& x : str) {
// cout << x << "\n";
// if (x == delimiter) { //If we meet the delimiter, we need to convert the input for current unit so far into a double, record it, and move on to the next unit
// if (unit > 0) {
// cout << "unit is greater than 0\n";
// switch(unit) {
// case 3: { //Add input_for_current_unit to hours
// if (is_number_revised(input_for_current_unit)) {
// hours = stod(input_for_current_unit);
// cout << "Hours: " << hours << "\n";
// } else {
// return NULL;
// }
// break;
// }
// case 2: { //Add input_for_current_unit to minutes
// if (is_number_revised(input_for_current_unit)) {
// minutes = stod(input_for_current_unit);
// cout << "Minutes: " << minutes << "\n";
// } else {
// return NULL;
// }
// break;
// }
// case 1: { //Add input_for_current_unit to seconds
// if (is_number_revised(input_for_current_unit)) {
// seconds = stod(input_for_current_unit);
// cout << "Seconds: " << seconds << "\n";
// } else {
// return NULL;
// }
// break;
// }
// default:
// cout << "Oops! Something went wrong...\n";
// return NULL;
// }
// unit--;
// cout << "unit is now " << unit << "\n";
// input_for_current_unit = "";
// }
// else {
// return NULL;
// }
// } else if (is_number_revised(string(1, x))) {
// input_for_current_unit += x;
// } else {
// return NULL;
// }
// }
//
// return (hours * 60 * 60) + (minutes * 60) + seconds;
//}
//
//string translate_double_to_time(double time, char delimiter) {
// string output = "";
//
// int hours = int(time / 3600);
// time -= hours * 3600;
//
// int minutes = int(time / 60);
// time -= minutes * 60;
//
// double seconds = time;
//
// return string(hours) + ":" + string(minutes) + ":" + string(seconds);
//}
double get_double_from_string(string input) {
//This function will get input and return the input as a double.
while (!is_number_revised(input) && input != "x") { //This while loop will keep the program locked until the user enters a valid input (or exits).
cout << "That's not a valid input. Please enter a number: ";
cin >> input;
}
if (input == "x") { //Input to exit the program.
return NULL;
}
return stod(input);
}
double get_root(double number, double root) {
//This function will return the root of a given number.
while (trunc(root) != root || root < 1) {
//Handle invalid values for the root.
cout << "That number is invalid as a root. Please enter an integer that is greater than 0: ";
cin >> root;
}
int int_root = int(root);
if (int_root == 1) {
return number;
}
double upper_bound = 0;
double lower_bound = 0;
if (number > 0) {
upper_bound = number;
} else if (number < 0) {
//If we are trying to find an even-numbered root of a negative number, we need to tell the user it is undefined and end the function.
if (int_root % 2 == 0) {
cout << "Cannot find the even-numbered root of a negative number.\n";
return NULL;
}
lower_bound = number;
} else {
return 0;
}
int num_of_guesses = 0;
double guess = round(number / int_root); //The initial guess to find the correct result.
// cout << "Guessing: " << guess << "\n";
// cout << "Difference: " << abs(pow(guess, root) - number);
while ((abs(pow(guess, int_root) - number) >= 0.000001) && (num_of_guesses < 1000000)) {
//Iteratively down the guess until we have the correct answer, or until we have guessed a million times, in which case we give our best guess. The million guess limit keeps the program from freezing.
if (pow(guess, int_root) < number) {
lower_bound = guess;
// cout << "New Lower Bound: " << lower_bound << "\n";
} else if (pow(guess, int_root) > number) {
upper_bound = guess;
// cout << "New Upper Bound: " << upper_bound << "\n";
} else {
return guess;
}
guess = (upper_bound + lower_bound) / 2; //Update the guess and try again.
// cout << "Guessing: " << guess << "\n";
num_of_guesses++;
}
return guess;
}
double simple_operation_from_string() { //Perform and return a simple operation using number inputs an operator input.
//After the user as performed an operation, they can keep going with more operations until they exit the function.
//Show a menu with the options the user has.
cout << "\n";
cout << "---List of Operation Inputs---\n";
cout << "Addition: '+', Subtraction: '-', Multiplication: '*', Division: '/'\n";
cout << "Exponentiation: '^' or '**', Root: '//', Modulus Division: '%', Remainder: '%%'\n";
cout << "\n";
cout << "\n";
double result = 0;
string input = "";
double num1 = 0;
double num2 = 0;
string operat = "";
cout << "Enter the first number, or enter 'x' to exit: ";
cin >> input;
num1 = get_double_from_string(input);
if (num1 == NULL) {
return num1;
}
while (true) { //This loop keeps going until the user returns the function with an exit key or an error occurs. IMPORTANT TO MAKE SURE RETURN STATEMENTS ARE ACCESSIBLE BY USER!
input = "";
num2 = 0;
operat = "";
cout << "Enter the operator, or enter 'x' to exit: ";
cin >> input;
while (!is_operator(input) && input != "x") { //This while loop will keep the program locked until the user enters a valid input or exits.
cout << "That's not a valid input. Please enter one of the operators listed above: ";
cin >> input;
}
if (input == "x") { //Input to exit the program.
return result;
}
operat = input;
cout << "Enter the next number, or enter 'x' exit: ";
cin >> input;
num2 = get_double_from_string(input);
if (num2 == NULL) {
return result;
}
if (operat == "+") { //Perform the operation.
result = num1 + num2;
}
else if (operat == "-") {
result = num1 - num2;
num1 = result;
}
else if (operat == "*") {
result = num1 * num2;
}
else if (operat == "/") {
result = num1 / num2;
}
else if (operat == "//") {
result = get_root(num1, num2);
}
else if (operat == "%") {
result = int(num1 / num2);
}
else if (operat == "%%") {
result = fmod(num1, num2);
}
else if (operat == "^" || operat == "**") {
result = pow(num1, num2);
}
else {
cout << "Oops! Something went wrong...\n";
return NULL;
}
cout << "Result so far: " << result << "\n";
num1 = result;
}
}
double trig_operation_from_string() { //Perform a trigonometric operation with a single number and an operation as input.
//Show a menu with the options the user has.
cout << "\n";
cout << "---List of Operation Inputs---\n";
cout << "sin: sine of input,\tcos: cosine of input,\t\ttan: tangent of input\n";
cout << "asin: arcsine of input,\tacos: arccosine of input,\tatan: arctangent of input\n";
cout << "\n";
cout << "\n";
string input = "";
double num = 0;
string operat = "";
string format = "";
//Get input from the user.
cout << "Enter the operator, or enter 'x' to exit: ";
cin >> input;
while (!is_trig_function(input) && input != "x") { //This while loop will keep the program locked until the user enters a valid input (or exits).
cout << "That's not a valid input. Please try again: ";
cin >> input;
}
if (input == "x") { //Input to exit the program.
return NULL;
}
operat = input;
cout << "Enter a number, or enter 'x' to exit: ";
cin >> input;
num = get_double_from_string(input);
if (num == NULL) {
return NULL;
}
cout << "Enter 'r' for radians, or 'd' for degrees: ";
cin >> format;
while(!is_degrees_or_radians(format) && input != "x") { //This while loop will keep the program locked until the user enters a valid input (or exits).)
cout << "That's not a valid input. Please try again: ";
cin >> format;
}
if (input == "x") { //Input to exit the program.
return NULL;
}
if (format == "d") { //Perform the operation.
//Return in degrees.
if (operat == "sin") {
return sin(num) * 180 / M_PI;
}
if (operat == "cos") {
return cos(num) * 180 / M_PI;
}
if (operat == "tan") {
return tan(num) * 180 / M_PI;
}
if (operat == "asin") {
return asin(num) * 180 / M_PI;
}
if (operat == "acos") {
return acos(num) * 180 / M_PI;
}
if (operat == "atan") {
return atan(num) * 180 / M_PI;
}
} else {
//Return in radians.
if (operat == "sin") {
return sin(num);
}
if (operat == "cos") {
return cos(num);
}
if (operat == "tan") {
return tan(num);
}
if (operat == "asin") {
return asin(num);
}
if (operat == "acos") {
return acos(num);
}
if (operat == "atan") {
return atan(num);
}
}
cout << "Oops! Something went wrong...\n";
return NULL;
}
double log_operation_from_string() { //Perform a logarithmic operation with a single number and an operation as input.
//Show a menu with the options the user has.
cout << "\n";
cout << "---List of Operation Inputs---\n";
cout << "log: base 10 log,\t\tln: natural log\n";
cout << "logx: log with custom base,\te: 'e' raised to specified power\n";
cout << "\n";
cout << "\n";
string input = "";
double num = 0;
double base = 0;
string operat = "";
//Get input from the user.
cout << "Enter the operator, or enter 'x' to exit: ";
cin >> input;
while (!is_log_function(input) && input != "x") { //This while loop will keep the program locked until the user enters a valid input (or exits).
cout << "That's not a valid input. Please try again: ";
cin >> input;
}
if (input == "x") { //Input to exit the program.
return NULL;
}
operat = input;
//If the user inputed a custom log function, get the base.
if (operat == "logx") {
cout << "Enter the log base, or enter 'x' to exit: ";
cin >> input;
base = get_double_from_string(input);
if (base == NULL) {
return NULL;
}
}
cout << "Enter a number, or enter 'x' to exit: ";
cin >> input;
num = get_double_from_string(input);
if (num == NULL) {
return NULL;
}
if (operat == "log") {
return log10(num);
}
if (operat == "ln") {
return log(num);
}
if (operat == "logx") {
return log10(num) / log10(base);
}
if (operat == "e") {
return exp(num);
}
else {
cout << "Oops! Something went wrong...\n";
return NULL;
}
}
int main() {
// cout << add(3, 5.78) << "\n";
int choice = -1; //The value for when the user is deciding what to do
while (choice != 0) {
//Show menu
cout << "-----MAIN MENU-----\n";
cout << "\n";
cout << "1: Perform a simple operation. (addition, division, etc.)\n";
cout << "2: Perform a trigonometric operation. (sine, cosine, etc.)\n";
cout << "3: Perform a logarithmic operation. (log, ln, etc.)\n";
cout << "0: Exit the program.\n";
cout << "\n";
//Process user choice
cout << "Enter your choice: ";
cin >> choice;
switch(choice) {
case 0: { //Exit
cout << "Goodbye!";
break;
}
case 1: //Simple operation
{
double result = simple_operation_from_string();
cout << "\n";
cout << "\nResult: " << result << "\n";
cout << "\n";
cout << "\n";
break;
}
case 2: //Trigonometric operation
{
double result = trig_operation_from_string();
cout << "\n";
cout << "\nResult: " << result << "\n";
cout << "\n";
cout << "\n";
break;
}
case 3: //Logarithmic operation
{
double result = log_operation_from_string();
cout << "\n";
cout << "\n";
cout << "\nResult: " << result << "\n";
cout << "\n";
cout << "\n";
break;
}
// case 4: //Time operation
// {
// string input;
// cout << "Enter a time: ";
// cin >> input;
//
// double result = translate_time_to_double(input, ':');
// cout << "\n";
// cout << "\n";
// cout << "\nResult: " << result << "\n";
// cout << "\n";
// cout << "\n";
// break;
// }
default:
{
cout << "That was not a valid option. Please try again.\n";
}
}
}
return 0;
}