Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

visual c++ calculator - you like a challenge?

Status
Not open for further replies.

bakermunch

Programmer
Dec 16, 2002
3
0
0
GB
hello,
i am writing a windows based calculator and i want to make it as close to windows calc as possible. so farr i have it working on an if-else statement on the equals button. This detects which operator i(m_cOperator) pressed and returns a value to the screen. On the operator buttons, the variable is set too '+' or whichever op it is. The only problem is i cant do multiple additions without pressing equals everytime.
Also, i need to be able to do bracketed sums,but have no idea how too. At the moment, I have a button for each digit which converts a string into a double usin atof to enable calculations.
Can any body suggest a way for me to do these things,help would be most appreciated
regards
bakermunch
 
"The only problem is i cant do multiple additions without pressing equals everytime."

Get the running total with each operator button press, and display the total upon an "=" press. Include logic to reset the total to 0 if a number is pressed after an "=" press.

"Also, i need to be able to do bracketed sums,but have no idea how too."

The process is pretty involved. This is actually a future project of mine that will use such logic to create a compiler to convert stuff into mock machine code for a simulator I've already developed. (I'm excited about it, so I figured you would want to hear! :) )

Anyway, shortly after thinking about tackling this project, I noticed it was an exercise in one of my books. I haven't coded it yet, but the Deitels recommend you set everything up to convert from infix to postfix (using stacks), then calculate in one fell swoop. E.G.

( 6 + 4 ) * 5 - 9 / 4
would be converted to:
6 4 + 5 * 9 4 / -
where your function would sweep through and make calculations
on numbers according to signs that follow them.

The process sounds tricky, and I must learn it myself before I can explain it (it is a project I'm putting off temporarily in order to learn other things), but if you'd like, I need to do it anyway, and will be happy to work on it and go through it with you as I build. Otherwise, there was a discussion about this not too long ago, and you can cheat, find it, and follow the included link to source code that will do it all for you.

If you opt for the second plan, the discussion was in one of the C++ forums, and I believe it was the last C++ discussion mentioning FoxPro, so you can search for it using that text.
 
omg,

i remember doing this very exercise but i cant for the life of me remember the details. all i remember is using a stack and pushing items on until i reached certain characters such as ')'. then popping off the stack until i encountered a matching '('. then continuing to push...

musta been using two stacks...

[ponytails2]
 
BoulderBum and bakermunch, I believe the implementation you are talking about is called 'reverse polish notation' used for its simplicity to program and named after its polish inventor I searched the net for some source code, the first one I found was in Java I found another in C There is probably one out there using all fancy c++ techniques, but I am tired. Hope this helps.
 
thank you for youe time, links and tips, i will try these ideas out.

"Get the running total with each operator button press, and display the total upon an "=" press" - how would you do this,i mean, get a running total?
i can only assign 1 variable to the edit box,then i asign it to another when i press the + button. I need to be able to inout aniother variablr before i do the sum,so if the sum is in the OnAdd()function i used to assign editbox var to,it just adds itself, doubling every num i enter. kniw this is prib really simple,but i just cant seem to get it to work. At the moment i have added a switch statement to the add button to increment when it is pressd,and on case 2 to add stored variable to the next screen input. i think this should work,but havent fully tested it yet. also i beleive this is to complicated for a simple operation such as this
thx again
bakermunch.
 
Have an int runningTotal. For each calculation, add to this total. E.G.

onAdd()
{
runningTotal += //value from textbox;
//clear the textbox
}

Then when you hit the "=" button:

//textbox text = runningTotal
runningTotal = 0; //unless you would like to implement logic
//to continue calculation under certain circumstances

If you'd rather display the running total in the textbox with each step, then all of the clearing will have to come with keypress events, and you'll have to ask someone else how to handle that with C++. Really, all I'm equipped to do is help with the underlying calculation logic.

Tell me if I can help further. [nosmiley]

 
Thank you yet again,this makes more sense. i had tried this but in the wrong order,i just couldn't think:).
ok, 1 other thing, the brackets,if i want to bracket sums by input ing brackets like on windows calc to do more complicated mathematics,how would you suggest i do this - i'm not to hot on the logic
regards,
bakemunch,
ps
are there any chat rooms or irc channels that r for visual c++ programmers to discuss issues,eg c# and new .net technologies?
 
About the brackets...

Option 1: rip the code off using the above links, or the ones found at the bottom of the following thread.

thread116-412706

Option 2: tell me you're interested in building the code yourself, then I will start building it and tell you the how-to details as I learn them.

If you have the Deitel & Deitel "C++ How to Program" text, the exercise I will base my code off of is 15.12 found on page 830 (Third Edition).
 
For anyone who comes across this thread in the future with some questions about evaluating a string as an expression, here is what you must do:

1. Convert from infix to postfix, which is a way of getting the expression into a more readable form for the computer.
E.G. for 2 + 2 --postfix is-- 2 2 +
for 3 - 2 * 5 --postfix is-- 3 2 5 * -
for ( 1 + 3 ) * 4 --postfix is-- 1 3 + 4 *

Conversion can be accomplished with a stack( stk ) and a
string( postfix ). The algorithm follows:

I. Push a '(' onto stk (the stack)
II. Add a ')' to the end of the infix input string.
III. While stk is not empty
If current character in infix string is a digit
copy it to postfix
If current char is '(' push it onto stk
If current char is an operator ( +, *, etc. )
*pop operators of equal or higher precedence, and put them
in postfix
*push the operator onto stk
If current char is ')'
*pop all operators (adding them to postfix) until
'(' is encountered
*pop and ignore ')'

So for 3 + 2 * 4:
at beginning:
postfix = empty
stk = (
infix = 3 + 2 * 4 )
loop 1:
postfix = 3
stk = (
infix = + 2 * 4 )
loop 2:
postfix = 3
stk = ( +
infix = 2 * 4 )
loop 3:
postfix = 3 2
stk = ( +
infix = * 4 )
loop 4:
postfix = 3 2
stk = ( + *
infix = 4 )
loop 5:
postfix = 3 2 4
stk = ( + *
infix = )
loop 6:
first:
postfix = 3 2 4 *
stk = ( +
infix = )
then:
postfix = 3 2 4 * +
stk = (
infix = )
then:
'(' and ')' cancel each other out.


I'll explain how postfix may be calculated a little later when I have time. Following is the source code for my postfix converter. Of note is that the current implementation only handles single digit integers.

-----------------Header File--------------------------------------
//this header contains functions to convert a string to postfix
//problem 15.12 p 830 Deitel & Deitel

#ifndef POSTFIXCONVERTER_H
#define POSTFIXCONVERTER_H

#include<string>
using std::string;

#include<stack>

namespace PostfixConverter
{
string pfConvert( string );
bool isOperator( char );
}

#endif

------------------Source File------------------------------------
//function definitions for PostfixConverter namespace

#include &quot;PostfixConverter.h&quot;

//see d & d p 830 for explaination
string PostfixConverter::pfConvert( string infix )
{
const int precedence( char, char );

std::stack< char > signStack;
string postfix = &quot;&quot;;
int i = 0;

infix += ')'; //add parenthesis around
signStack.push( '(' ); //the entire equation

while( !signStack.empty() )
{
char current = infix.at( i ); //the current character in infix being evaluated

if( current == ' ' )
;//do nothing
else if( isdigit( current ) )
postfix += current;
else if( current == '(' )
signStack.push( current );
else if( isOperator( current ) )
{
//while there are operators on the stack with equal or higher precedence than current
while( isOperator( signStack.top() ) && precedence( signStack.top(), current ) != -1 )
{
//add the operator to postfix, and pop it
postfix += signStack.top();
signStack.pop();
}
signStack.push( current );
}
else if( current == ')' )
{
//pop until a left parenthesis is found (adding char to postfix)
while( signStack.top() != '(' )
{
postfix += signStack.top();
signStack.pop();
}
//now pop the left parenthesis (discarding it)
signStack.pop();
}
++i;
}

return postfix;
}

bool PostfixConverter::isOperator( char c )
{
return ( c == '+' || c == '-' || c == '*' || c == '/' || c == '%' || c == '^' );
}

const int precedence( char op1, char op2 ) //PostfixConverter::
{
const int pVal( char );

if( pVal( op1 ) > pVal( op2 ) )
return 1;
else if ( pVal( op1 ) == pVal( op2 ) )
return 0;
else
return -1;
}

const int pVal( char op ) //PostfixConverter::
{
int val;

switch( op )
{
case '^':
val = 3;
break;
case '*':
case '/':
case '%':
val = 2;
break;
case '+':
case '-':
val = 1;
break;
default:
val = -1;
}

return val;
}
 
Hi

I wanted to say there are two other &quot;..Fix&quot; there is as mentioned Postorder, but there is also preorder and inorder one i can't remember, But what i can say i've done an exercise about it, the best way would be a binary tree!!
and this is often shown in books.
once you get your head around it it is fairly clear.

If you are using binary trees-- the Root or entry point would be the = sign. but recursion would also be needed!!

Just my two cents
 
That sounds like a cool implementation of a binary tree! It is of note, however, that compilers make use of stacks &quot;to help in the process of evaluating expressions and generating machine language code&quot;, which you can see if you ever get sucked into that darned disassembly window during debugging. The book exercises I base my code on are used to build a compiler, and demonstrate compiling behaivior.

Anyhoo, here's how the postfix evaluator works. It's less complicated than the converter.

You have two containers,
1. The postfix expression (which I implemented as a string)
-and-
2. A stack (implemented as a char stack)

To evaluate:
First- add a terminating NULL character to the end of the postfix expression
Then-
while you have not hit the '\0' character
if the character is an integer
push it onto the stack
otherwise you have an operator...
pop the top 2 values off the stack and assign them to 2 variables
( y then x )
calculate x operator y and...
push it onto the stack
when you hit '/0', you have the total


So for &quot;3 2 4 * +&quot; where the character in parenthesis will be the current character

at beginning:
String = 3 2 4 * + '\0'
Stack = empty

loop 1:
String = (3) 2 4 * + '\0'
Stack = 3

loop 2:
String = 3 (2) 4 * + '\0'
Stack = 3 2

loop 3:
String = 3 2 (4) * + '\0'
Stack = 3 2 4

loop 4:
String = 3 2 4 (*) + '\0'

Stack = 3 2 //after popping 4 and assigning it to y
y = 4
Stack = 3 //after popping 2
x = 2

x operator y = 8 //which is pushed onto the stack
-so-
Stack = 3 8

loop 5:
String = 3 2 4 * (+) '\0'
Stack = 3 //after popping 8
y = 8
Stack = empty //after popping 3
x = 3

x operator y = 11 //which is pushed onto the stack
-so-
Stack = 11

loop 6:
String = 3 2 4 * + ('\0')

NULL character is encountered so the value on the stack (11) is the total


Here's my code:

-----------------Header File--------------------------------------

//defines postfix calculator function in PostfixReader namespace

#ifndef POSTFIX_READER_H
#define POSTFIX_READER_H

#include <string>
using std::string;

namespace PostfixReader
{
int postCalc( string );
}

#endif



------------------Source File------------------------------------

//contains function for calculating a postfix expression passed to
//postCalc as a string

#include <stack>
#include <cmath>
#include<string>
using std::string;

#include&quot;postfixReader.h&quot;

int PostfixReader::postCalc( string postfix )
{
int calculate( const int, const int, const char );

std::stack<int> nums;

int x,
y,
i = 0;

char curChar;

postfix += '\0';

while( ( curChar = postfix.at( i ) ) != '\0' )
{
if( isdigit( curChar ) )
nums.push( curChar - '0' );
else
{
x = nums.top();
nums.pop();
y = nums.top();
nums.pop();

nums.push( calculate( y, x, curChar ) );
}
++i;
}
return nums.top();
}

int calculate( const int arg1, const int arg2, const char op )
{
switch( op )
{
case '^':
return pow( arg1, arg2 );
break;
case '*':
return arg1 * arg2;
break;
case '/':
return arg1 / arg2;
break;
case '+':
return arg1 + arg2;
break;
case '-':
return arg1 - arg2;
break;
}
}





 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top