// kalk-05.cpp
//
// Calculator program that runs in console.
// Type M for menu.
//
// This is the original from PSW book Using C++
// I have used it as a basis to learn C++
//
// I have kept is at the following modifications will
// be easier to understand as the program becomes more sophisticated.
//
// Mods
// 01 Change command short cuts to alpha characters so that they are simple to
// key. Trivial change.
// 02 Add extra functions again trivial.
// 03 Add Memory functions
// MEM IN .. loads memory with current value
// MEM PLUS .. adds current value to memory
// Note: Mem Minus achieved by typing n (negative) to make current
// value negative and MEM PLUS. If required redo n to make current
// value positive.
// MEM SWITCH switches current value! and memory.
// 03a Added code to change negative current value to positive when
// Power function AND exponent is less than 1 (e.g. 0.5 for square root)
// as even roots of negative numbers are imaginary
// 04 Add capability to use mem value in function, e.g. to subtract value in
// in memory from current value, but keep memory value.
// This was a bit complicated and required writing function to replace CIN
// and use of STRING to DOUBLE function
// 05 Improve by checking that values entered are numbers and not garbage.
//
// Planned mods
// 06 Capability to undo up to last 5 commands. Code with Vector?
// 07 Log comands to file so that they can be audited.
// Have default log KALKLOG.DAT in C:|MyDATA which is backed up to
// KALKLOG.BAK start of new program, overwriting previous version.
// 08 Allow user to change log file name and locaton.
// ! 09 Take data file in LOG format and run as batch program.
//
// Also plan to use as test for compiling in Linux and with other systems.
// May try to convert to Java and Ruby??
// When I have learned widows programming may try to convert to windows type.
//
// I know it is all old hat but it helps me to learn and may even help others.
//
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cctype>
#include <string>
using namespace std;
void display_menu();
// int is_menu_choice(char choice);
void process_choice (char choice, // IN
double& num, // IN-OUT
double& mem); // IN-OUT
void cin_number(double& num, // IN-OUT
double& mem); // IN-OUT
char RT_Num_Check(string& digit);
int main()
{
char choice; // menu choice
double curr_val; // current value of calculator
dou! ble mem; // Calculator Mem function
display_menu();
cout << setprecision(15);
curr_val = 0;
mem = 0;
do {
cin >> choice;
choice = toupper(choice);
process_choice (choice, curr_val, mem);
}
while (choice != 'Q');
return 0;
}
void display_menu()
{
cout << "Calculator functions:\n"
<< " (A)add, (S)ubtract X(mult), (D)ivide , (N)egative,\n"
<< " (R)eciprocal, (I)nitialize, (P)ower [positive only], Q)uit,\n"
<< " (M)em in, mem p(L)us, mem (O)ut, mem s(W)itch \n"
<< " use mem to refer to memory in calculations"
<< " (H)elp show this menu again.\n\n";
}
void process_choice (char choice, // IN
double& curr_val, // IN-OUT
double& mem) // IN-OUT
{
// double mem;
double work; // required for memor! y sWitch function
double num; // numeric value entered by user
num = 0;
// mem=0;
switch (choice)
{
case 'A': cin_number(num, mem);
curr_val += num;
break;
case 'D': cin_number(num, mem);
curr_val = curr_val/num;
break;
case 'H': break;
case 'I': cin_number(num, mem);
curr_val = num;
break;
case 'L': mem += curr_val;
break;
case 'M': mem = curr_val;
break;
case 'N': curr_val *= (-1);
break;
case 'O': curr_val = mem;
break;
case 'P': cin_number(num, mem);
if (num < 1) curr_val = fabs(curr_val);
//stops possibilty roots of negative values causing errors
curr_val = pow(curr_val, num);
! break;
case 'Q': break;
case 'R': curr_val = 1/curr_val;
break;
case 'S': cin_number(num, mem);
curr_val -= num;
break;
case 'W': work = curr_val;
curr_val = mem;
mem = work;
break;
case 'X': cin_number(num, mem);
curr_val *= num;
break;
default: cout << "\tInvalid operation!\n";
} // end switch
if (choice=='H') display_menu();
if (choice != ('Q' || 'H' ))
cout << setw(16) << ' ' << curr_val
<< endl;
}
void cin_number(double& num,
double& mem) // IN-OUT
{
string input;
char ValidNumber = 'N';
while (ValidNumber == 'N')
{
cin >> input;
if (input == "mem")
{ num = mem;
ValidNumber = 'Y';
! }
else
{
ValidNumber=RT_Num_Check(input);
if (ValidNumber=='Y')
num = strtod(input.c_str(), NULL);
else
{
cout << input <<" Not a proper number\n Re-enter number\n";
}
}
}
return;
}
char RT_Num_Check(string& digit)
{
char NumOK; // result
int p; // digit position
char decimal = 'N'; // used to make sure not more than 1 decimal point
string sign = "0"; // used to check for negative
// cout << "The length of str is " << digit.length() << " characters.\n";
if (digit.substr(0,1) == "-") // sign -1
{
digit=digit.substr (1,(digit.length()-1)); // strip sign
sign= "-"; // to check so that neg restored at end
}
for (p=0;p<digit.length();p++)
{
if ((digit.substr(p,1) >="0") && (digit.substr(p,1) <="9"))
NumOK='Y';
else
{
if ((digit.substr(p,1) ==".") && (decimal=='N'))
{
NumOK='Y';
decimal='Y'; // so that later positions checked for erraneous 2nd decimal point
}
else
{
NumOK='N'; // if we reach here must be an incorrect number
break;
}
}
// cout <<"p is " <<p<< " number is "<< digit.substr(p,1)<<endl;
}
if (sign == "-")
digit = sign+digit; // put back negative if necessary
return (NumOK);
}
/*A typical run:
Calculator functions:\n"
(A)add, (S)ubtract X(! mult), ( D)ivide , (N)egative,\n"
(R)eciprocal, (I)nitialize, (P)ower, Q)uit,\n"
(H)elp show this menu again.\n\n";
I 2.5
2.5
P 3
15.625
R
0.064
x 100
6.4
n
-6.4
a 10
3.6
s 1.12
2.48
H
Calculator functions:\n"
(A)add, (S)ubtract X(mult), (D)ivide , (N)egative,\n"
(R)eciprocal, (I)nitialize, (P)ower, Q)uit,\n"
(H)elp show this menu again.\n\n";
2.48
d 2.5
0.992
i 4
4
p 0.5
2
n
-2
p 0.5
1.4142135623731
i10
10
m
10
r
0.1
w
10
o
0.1
x1000
100
l
100
l
100o
200.1
i 2
2
m
2
i5
5
amem
7
p mem
49
d mem
24.5
a 5..2
5..2 Not a proper number
Re-enter number
5.2
29.7
q
------------------------
Note you do not need to leave space,
e.g. you can enter "d 2.5" or "d2.5"
*/
q function calculator
No comments:
Post a Comment