Calculator

Hey pals,

Check the code below :

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
  #include <iostream>
  #include <cstdlib>
  #include <conio.h>
  #include <iomanip>
 
  using namespace std;
  
    int a,b,c,o;
   
    while(1)
    {
       
        switch(_getch())
        {
            case 48: cout<<"0"; a=0; break;
            case 49: cout<<"1"; a=1; break;
            case 50: cout<<"2"; a=2; break;
            case 51: cout<<"3"; a=3; break;
            case 52: cout<<"4"; a=4; break;
            case 53: cout<<"5"; a=5; break;
            case 54: cout<<"6"; a=6; break;
            case 55: cout<<"7"; a=7; break;
            case 56: cout<<"8"; a=8; break;
            case 57: cout<<"9"; a=9; break;
           
            case 43: cout<<"+";/*  + 444  */ o=444; b=a; break;
            case 45: cout<<"-";/*  - 555  */ o=555; b=a; break;
            case 42: cout<<"*";/*  * 666  */ o=666; b=a; break;
            case 47: cout<<"/";/*  / 777  */ o=777; b=a; break;
           
            case 61: cout<<"=";
           
                   switch(o)
                   {
                         case 444: cout<<b+a<<endl; break;
                         case 555: cout<<b-a<<endl; break;
                         case 666: cout<<b*a<<endl; break;
                         case 777: cout<<double(b)/a<<endl; break;
                   }

            break;
           
            case 27: exit(0);
        }
    }

      return 0;
  }
 


that's a calc. using just digits and ( + - * /) to solve a and b equation.

We have to write a code which calculate an equation like ( a operator b) using numbers(not just digits), ensuring that :

1. user can input minim 2 digits(to create a number), no other inputs like letters, math operations , etc. (example. 2 or 23 or 233 or 2333 etc)

2. user can input just math. operations, and just 1 of it, nothing more.( ex. + or - or * or /)

3. same as nr. 1. user can input minim 2 digits(to create a number), no other inputs like letters, math operations , etc. (example. 2 or 23 or 233 or 2333 etc)

4. user have to press just the "=" symbol, in order to check the result.
Last edited on
you can just use the letters. '+' is the same as 43, and readable -- the compiler can handle that its an integer value for the switch requirement.

with the windows calculator being so bad now I guess we are all writing our own :)
I came up with this quick hack one day when the win calc made me irritable.. its a very thin replica of my beloved hp11c so its a stack based reverse polish design.

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
#include <cstdlib>
#include <iostream>
#include <string>
#include <cmath>
#include <cstring>
using namespace std;

//todo: consider xor, log2, ln, log10 

int indexx(bool geti = false, bool reverse = false)
{
  static int i = 2;  
  if(geti && reverse)
  {
	  if(i-1 < 0)
	  return 9;
      else return i-1;
  }
  if(geti)
	 return i;
 
  if(reverse){i--; if(i<0) i = 9; return i;}
  i++; i%=10;
  return i;
}

int main(int argc, char **argv)
{

string i;
double s[10]= {0};
double r;
bool done = false;
bool inverse = false;

do
{
	cin >> i;	
	switch (i[0])
	{
		case 'h': case 'H':
		case '?':
		cout << "i inverse next\ns sin\nc cos\nt tan\np pi\ne e\n^ power\nd delete entry\nx  1/x\n| swap top 2\nv view all\n\n";
		break;
		case 's': case 'S':
		if(inverse)		
	    r = asin(s[indexx(1)]);		
       else
	   r = sin(s[indexx(1)]);
	   s[indexx()] = r;
	   printf("%1.15f\n",r);
	   inverse = false;
	  break;	  
	  	case 'c': case 'C':
		if(inverse)		
		r = acos(s[indexx(1)]);
	    else
	    r = cos(s[indexx(1)]);
	   s[indexx()] = r;
	   printf("%1.15f\n",r);
	   inverse = false;
	  break;
	  	case 't': case 'T':
		if(inverse)		
		r = atan(s[indexx(1)]);
		else
	   r = tan(s[indexx(1)]);
	   s[indexx()] = r;
	   printf("%1.15f\n",r);
	   inverse = false;
	  break;
	  
	case 'i': case 'I':
	   inverse = !inverse;	   
	  break;		
		
	  case 'p': case 'P':
	   r = 3.1415926535897932384626433832795;
	   s[indexx()] = r;
	   printf("%1.15f\n",r);
	  break;
	  case 'e': case 'E':
	   r = 2.7182818284590452353602874713527;
	   s[indexx()] = r;
	   printf("%1.15f\n",r);
	  break;
	  case '*': 	
		 r = s[indexx(1,1)] * s[indexx(1)];
		 s[indexx(0,1)] = r;
		 printf("%1.15f\n",r);
		 break;
	  case '/': 	
		 r = s[indexx(1,1)] / s[indexx(1)];
		 s[indexx(0,1)] = r;
		 printf("%1.15f\n",r);
		 break;
	  case '-': //detects whether its an operation or a negative number. 
         if(i.length() == 1)
         {			 
			 r = s[indexx(1,1)] - s[indexx(1)];
			 s[indexx(0,1)] = r;
			 printf("%1.15f\n",r);
		 }
		 else
		 {
			try 
			{
				s[indexx()] = stod(i);
			}
			catch (const std::invalid_argument& ia) 
			{
				done = true;
			}
		 }					 
		 break;
	  case '+': 			 
		 r = s[indexx(1,1)] + s[indexx(1)];		 
		 s[indexx(0,1)] = r;		 
		 printf("%1.15f\n",r);
		 break;
	  case '^': 	
	  if(inverse)		
	  {
		  inverse = false;
		  r =   pow(s[indexx(1,1)],1.0/s[indexx(1)]);
	  }
		  else
		  {
			 r = pow(s[indexx(1,1)],s[indexx(1)]);
		  }
		 s[indexx(0,1)] = r;
		 printf("%1.15f\n",r);		  
		 break;	
      case 'd': case 'D': //delete topmost stack value. 
	     s[indexx(1)] = 0.0;
		 r = s[indexx(0,1)];
		 printf("%1.15f\n",r);
         break;	  
	  case 'x': case 'X': // 1/x button
	     r = 1.0/s[indexx(1)];
		 s[indexx(1)] = r;
		 printf("%1.15f\n",r);
	  break;
	  case '|':  // swap top 2 stack entries. 
	  r = s[indexx(1)];
	  s[indexx(1)] = s[indexx(1,1)];
	  s[indexx(1)-1] = r;
	  printf("%1.15f\n", s[indexx(1,1)]);
	  printf("%1.15f\n", s[indexx(1)]);
	  break;
	  
	  case 'v':
	  for(int dx = 0; dx < 10; dx++)
		  cout << s[dx]<<endl;
	  break;
	  
	  default: //if its a number, proceed, else consider input to mean 'quit'
		try 
		{
			s[indexx()] = stod(i);
		}
		catch (const std::invalid_argument& ia) 
		{
			done = true;
		}
	}
}
	while(!done);
	return 0;
}


lots to clean up there -- it is as I said a quick fix to an immediate need one day -- but it works pretty well for the things I need most often. And yea, I said something about readability and then posted gibberish...
Last edited on
@jonnin, many thanks mate, you did a great job, I will try to implement some of yours into my code, hope to be properly
thanks!
be sure you run it before you get too fired up about borrowing from it. Its reverse polish, as I said, and just in case you did not know what that means (yours is NOT RP, so I wanted to be very clear):

what normal people think of on a normal calculator is
2+2 = (machine results on equals key).
RP says
2 2 + (result displays after the + key).
or a little more complex example:
2* (3+3) =
is solved by:
3 3 + 2 *
once you get used to it, its a lot less keystrokes and writing code to process this way is much, much easier. It works off the simple rule: if its a number, push it onto the stack. If it is an operation, pop the stack to get the operands, perform the operation, push result back onto stack.
Last edited on
2*(3+4) by RPN with xyzt stack as HP calculators

2 push, 3 push, 4 add, multiply
or,
2 Enter, 3 Enter, 4 +, *
that works too. the (11C) stack isnt big enough for long equations and I got in the habit of doing them from the inside out because of that. For the short example, its probably better your way. 3 4 + 2* is the same result, 7*2

on the PC the stack can be much, much bigger, but I left it at 10. Never needed more.

running it both ways on mine for fun:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
4
3
+
7.000000000000000
2
*
14.000000000000000
2
3
4
+
7.000000000000000
*
14.000000000000000
Last edited on
It's a little difficult to interpret but if it's
(((43 + 72) *14 ) + ( 234 + 7 ))*14 = 25914, then HP-speak gives:

43
Enter
72
+
14
*
234
Enter
7
+
+
14
*

Only 3 of the 4 stack registers are used.
yea that is what I call inside out approach. you get used to it.
you need a fair amount more button presses to do that on a = sign calculator
Last edited on
‘inside out’ or, as some often say ‘arse (ass) up’ when they go searching for the ‘=‘ button and never find it. The approach is actually intuitively correct in that the data is fed in from the formula from left to right.

HP as you probably know capitulated to the =‘s and ()’s crowd like Casio and produced their =‘s versions, none of which is probably relevant to @OP an your solution.
yea. I don't care I have my original 11c still works (used since the early 80s) and a backup that is brand new if it dies, and a gx if I need to do symbolic or a matrix. Im all set. They also tried to corner the junk laptop market. Not sure what happened to the company.
@jonnin , I am really stuck now;

I've got your code in front of me but to me its a little too complex since , we are not using the syntax you use and there are so many other things we don't use for now since we are just at the beginning.

Can you help me doing the tasks that were given starting from my code.

I am stuck since digits from 0-9 can be seen in ASCII table as decimals, for example "48"=0, "49"=1 and so on.

Now the main question is what is the value of number 10 then ? or 1589929? and so on since it can't be found in ASCII table...

Further more, if we go step by step it gets more complicated :

1. user input minim 2 digits(to create a number), no other inputs like letters, math operations , etc. (example. 2 or 23 or 233 or 2333 etc)

2. user input just math. operations, and just 1 of it must be visible on app( i guess the last one he inputs) .( ex. + or - or * or /)

3. same as nr. 1. user input minim 2 digits(to create a number), no other inputs like letters, math operations , etc. (example. 2 or 23 or 233 or 2333 etc)

4. user have to press just the "=" symbol, in order to check the result.

I now I am too stubborn , but I am stuck adn really need help, thankss
I am stuck since digits from 0-9 can be seen in ASCII table as decimals, for example "48"=0, "49"=1 and so on.

its a direct conversion, char-48 == number
eg '0' - 48 is 0. If you look at it in hex, it makes more sense why 48 is 0. (all ascii charts online will have hex and decimal side by side)

1) if you only want integers and read it one character at a time, you are typically reading the high order down to low order. so 233 is read '2', '3', '3' right? so just build a number:
int result = 0;
while(getting input)
{
result *= 10; //0 * 10 = 0, OK for first one!
result += input - 48; // '2' becomes 2. next time multiply by 10 -> 20, add '3'-48 = 3, 23.. etc
}

2) is there a question there? getche echos what the user typed, if you have it, if not getch() and cout what you got typed.

I think that will let you proceed, ask again if you need more?

That's the code, edited as it should be to fulfill the conditions:

1. user input minim 2 digits(to create a number), no other inputs like letters, math operations , etc. (example. 2 or 23 or 233 or 2333 etc)

2. user input just math. operations, and just 1 of it must be visible on app( i guess the last one he inputs) .( ex. + or - or * or /)

3. same as nr. 1. user input minim 2 digits(to create a number), no other inputs like letters, math operations , etc. (example. 2 or 23 or 233 or 2333 etc)

4. user have to press just the "=" symbol, in order to check the result.

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
  #include <iostream>
  #include <cstdlib>
  #include <conio.h>
  #include <iomanip>
 
  using namespace std;
  
  int main()
  {
  	
    int a=NULL,b,c,o=NULL;
   
    while(1)
    {

        switch(_getch())
        {
            case 48: cout<<"0";  a=a*10+0; break;
            case 49: cout<<"1"; a=a*10+1; break;
            case 50: cout<<"2"; a=a*10+2; break;
            case 51: cout<<"3"; a=a*10+3; break;
            case 52: cout<<"4"; a=a*10+4; break;
            case 53: cout<<"5"; a=a*10+5; break;
            case 54: cout<<"6"; a=a*10+6; break;
            case 55: cout<<"7"; a=a*10+7; break;
            case 56: cout<<"8"; a=a*10+8; break;
            case 57: cout<<"9"; a=a*10+9; break;
           
            case 43: if(a!=NULL && o==NULL){cout<<"+";/*  + 444  */ o=444; b=a; a=0; }break;
            case 45: if(a!=NULL && o==NULL){cout<<"-";/*  - 555  */ o=555; b=a; a=0; }break;
            case 42: if(a!=NULL && o==NULL){cout<<"*";/*  * 666  */ o=666; b=a; a=0; }break;
            case 47: if(a!=NULL && o==NULL){cout<<"/";/*  / 777  */ o=777; b=a; a=0; }break;
           
            case 61: if(a!=NULL && b!=NULL)cout<<"=";
           
                   switch(o)
                   {
                         case 444: cout<<b+a<<endl; break;
                         case 555: cout<<b-a<<endl; break;
                         case 666: cout<<b*a<<endl; break;
                         case 777: cout<<double(b)/a<<endl; break;
                   }
              a=NULL;
              b=NULL;
              o=NULL;

            break;
           
            case 27: exit(0);
        }
    }

      return 0;
  }
Last edited on
while it may work, its better to use '9' instead of "9". "9" is a string literal, '9' is a character which is a 1 byte integer -- switch requires integers.

otherwise, if it works, great!
Topic archived. No new replies allowed.