RPN calculator The RPN calculator program can only add and subtract. Other opera
ID: 3814814 • Letter: R
Question
RPN calculator
The RPN calculator program can only add and subtract. Other operations need to be added in. Your tasks are to do the following:
• Create a file lab11rpn.cppdirectory and copy the contents of rpnCalculator.cpp (rpnCalculator.cpp code at bottom) into that.
• Build the executable and test the program
• Add multiplication ( * ) and division ( / ) operations to the calculator • Add an operation ( : ) that displays the contents of the operand stack in the order they were pushed. Here is a sample run of the program:
No operands in the stack
1
2
3
:
Operand: 1
Operand: 2
Operand: 3
+
-----
5
:
Operand: 1
Operand: 5
+
-----
6
:
Operand: 6
• Build the executable and test your new functions.
// file: rpnCalculator.cpp
// Simple RPN Calculator
// This is an in-lab exercise and is incomplete
#include <iostream> // used in main()
#include <vector>
#include <stack>
using namespace std;
int
main()
// Simple interactive RPN calculator
// Library facilities used: cin, cout, peek(), ignore() from stream.h
// vector, stack, push(), top(), pop() from the STL
{
stack<double> operands;
stack<double> temp;
double nextNumber;
char nextOperation;
double operand1;
double operand2;
cout << "Type "q" when you are done ";
while ( cin && cin.peek() != EOF )
{
char ch = cin.peek();
switch ( ch )
{
// digit or decimal point
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
cin >> nextNumber;
operands.push( nextNumber );
break;
// arithmetic operation
case '+':
case '-':
// case '*':
// case '/':
cin >> nextOperation;
// handle unary minus
if ( ( cin.peek() >= '0' && cin.peek() <= '9' ) || cin.peek() == '.' )
{
cin >>nextNumber;
operands.push( -nextNumber );
break;
}
// do binary operation
if ( operands.size() < 2 )
{
cout << "Not enough operands for " << nextOperation << " ";
}
else
{
operand2 = operands.top();
operands.pop();
operand1 = operands.top();
operands.pop();
switch ( nextOperation )
{
case '+':
operands.push( operand1 + operand2 );
break;
case '-':
operands.push( operand1 - operand2 );
break;
}
cout << "----- ";
cout << operands.top() << " ";
}
break;
// display stack operation
// case ':':
// ignore other characters
default:
cin.ignore();
break;
}
if (ch == 'q')
break;
}
// report errors
if ( operands.size() > 1 )
{
cout << "Left over operands in the stack ";
return -1;
}
return 0; // normal exit code
}
Explanation / Answer
//main.cpp
#include <iostream> // used in main()
#include <cctype>
#include <stack>
#include "Complex.h"
using namespace std;
typedef Complex rpnType;
bool isOperator( char nextChar );
// Post: returns true if nextChar is an arithmetic operator; false otherwise
int opSize( char nextOperation );
// Pre: nextOperation is a valid binary operand
// Post: number of operands required is returned
// been pushed onto stack
template <typename valueType>
void doOp( stack< valueType >& operands, char nextOperation );
// Pre: nextOperation is a valid binary operand and size of operands stack is at least 2
// Post: operation has been applied to first two operands popped from stack and result has
// been pushed onto stack
template <typename valueType>
void displayStack( stack< valueType >& operands );
// Post: operands stack has been displayed on screen in order in which items were
// pushed onto stack; "No operands in stack" printed if stack is empty
int main()
{
const char SHOWSTACK = ':'; // show stack operator
stack< rpnType > operands; // stack of operands
rpnType nextNumber;
char nextOperation;
cout << "Type "ctrl-Z" ("ctrl-D" on Unix) to terminate ";
while ( cin.peek() != EOF )
{
if( isdigit( cin.peek() ) )
{
cin >> nextNumber;
operands.push( nextNumber );
}
else if( isOperator( cin.peek() ) )
{
cin >> nextOperation;
// handle unary minus
if ( isdigit( cin.peek() ) || cin.peek() == '.' )
{
cin.putback( nextOperation );
cin >> nextNumber;
operands.push( nextNumber ); // unary minus is handled by input
}
// do binary operation
else if ( operands.size() < opSize( nextOperation ) )
{
cout << "Not enough operands for " << nextOperation << " ";
}
else
{
doOp( operands, nextOperation );
cout << "----- ";
cout << operands.top() << " ";
}
}
else if( cin.peek() == SHOWSTACK )
{
// display stack operation
cin >> nextOperation; // remove ':' from input stream
displayStack( operands );
}
else
{
cin.ignore();
}
}
// report errors
if ( operands.size() > 1 )
{
cout << "Left over operands on the stack ";
return -1;
}
return 0; // normal exit code
}
bool isOperator( char nextChar )
// Post: returns true if nextChar is an arithmetic operator; false otherwise
{
return( nextChar == '+' || nextChar == '-' || nextChar == '*' || nextChar == '/' || nextChar == '~'
|| nextChar == '#');
}
int opSize( char nextOperation )
// Pre: nextOperation is a valid binary operand
// Post: number of operands required is returned
// been pushed onto stack
{
switch ( nextOperation )
{
case '+':
case '-':
case '*':
case '/':
return 2;
case '#':
case '~':
return 1;
}
}
template <typename valueType>
void doOp( stack< valueType >& operands, char nextOperation )
{
valueType leftOperand;
valueType rightOperand;
rightOperand = operands.top();
operands.pop();
if ( opSize( nextOperation ) == 2 )
{
leftOperand = operands.top();
operands.pop();
}
switch ( nextOperation )
{
case '+':
operands.push( leftOperand + rightOperand );
break;
case '-':
operands.push( leftOperand - rightOperand );
break;
case '*':
operands.push( leftOperand * rightOperand );
break;
case '/':
operands.push( leftOperand / rightOperand );
break;
case '#':
operands.push( - rightOperand );
break;
case '~':
double tempImag1 = rightOperand.getImag();
double tempReal1 = rightOperand.getReal();
tempReal1 = -tempReal1;
rightOperand.setComplex( tempReal1, tempImag1 );
operands.push( - rightOperand );
break;
}
}
template <typename valueType>
void displayStack( stack< valueType >& operands )
{
if (operands.empty()) cout << "No operands in the stack" << endl;
stack< valueType> tempStack;
tempStack = operands;
while(!tempStack.empty()) {
cout << "Operand: "<< tempStack.top() << endl;
tempStack.pop();
}
}
===========================================================================
// File: Complex.cpp
#include <iostream>
#include <cmath>
#include "Complex.h"
using namespace std;
Complex::Complex()
// Default constructor
//
// PRE: (none)
//
// POST: complex number is 0 + 0*i
{
realPart = imagPart = 0.0;
}
Complex::Complex( double real, double imag )
// Parameterized constructor
//
// PRE: (none)
//
// POST: complex number is real + imag*i
{
realPart = real;
imagPart = imag;
}
Complex::Complex( double real )
// Convert constructor
//
// PRE: (none)
//
// POST: complex number is real + 0 * i
{
realPart = real;
imagPart = 0.0;
}
void Complex::setComplex( double real, double imag )
// Mutator
//
// PRE: (none)
//
// POST: complex number is real + imag*i
{
realPart = real;
imagPart = imag;
}
double Complex::getReal() const
// Accessor
//
// PRE: (none)
//
// POST: real part is returned
{
return realPart;
}
double Complex::getImag() const
// Accessor
//
// PRE: (none)
//
// POST: imaginary part is returned
{
return imagPart;
}
const Complex Complex::operator+( const Complex& rComplex ) const
// Accessor -- Member operator function
//
// PRE: (none)
//
// POST: the sum of this Complex and rComplex is returned
{
Complex sum;
sum.realPart = realPart + rComplex.realPart;
sum.imagPart = imagPart + rComplex.imagPart;
return sum;
}
const Complex operator-( const Complex& lComplex, const Complex& rComplex )
// Non-member friend operator function
//
// PRE: (none)
//
// POST: the difference of this Complex and rComplex is returned
{
Complex difference;
difference.realPart = lComplex.realPart - rComplex.realPart;
difference.imagPart = lComplex.imagPart - rComplex.imagPart;
return difference;
}
const Complex operator/( const Complex& lComplex, const Complex& rComplex )
// Non-member non-friend operator function
//
// PRE: (none)
//
// POST: the quotient of this Complex and rComplex is returned
{
double divisor = rComplex.getReal()*rComplex.getReal()
+ rComplex.getImag()*rComplex.getImag();
double realNum = lComplex.getReal()*rComplex.getReal()
+ lComplex.getImag()*rComplex.getImag();
double imagNum = lComplex.getImag()*rComplex.getReal()
- lComplex.getReal()*rComplex.getImag();
return Complex( realNum/divisor, imagNum/divisor );
}
const Complex& Complex::operator++()
// Mutator -- Member prefix operator function
//
// PRE: (none)
//
// POST: the real part of the Complex is incremented by one and
// the new value is returned
{
realPart += 1.0;
return *this;
}
const Complex Complex::operator--( int )
// Mutator -- Member postfix operator function
//
// PRE: (none)
//
// POST: the real part of the Complex is decremented by one and
// the original value is returned
{
Complex value( *this );
realPart -= 1.0;
return value;
}
ostream& operator<<( ostream& outStream, const Complex& number )
// Non-member function
//
// PRE: (none)
//
// POST: number is output to the given ostream in the form
// [realPart] +/- [imagPart]i
//
// outStream is a valid ostream
// Uses cout and << from iostream library
// Uses abs() from cmath library
{
outStream << number.realPart << ( number.imagPart < 0 ? "-" : "+" )
<< fabs( number.imagPart ) << "i";
return outStream;
}
istream& operator>>( istream& inStream, Complex& number )
// Non-member function
//
// PRE: (none)
//
// POST: number has been read from the keyboard with format:
// [realPart]+/-[imagPart]i with no spaces
//
// inStream is a valid istream
// Uses cin and >> from iostream library
{
char iChar; // used to read 'i'
inStream >> number.realPart >> number.imagPart >> iChar;
return inStream;
}
const Complex operator-( const Complex& value )
// Non-member non-friend operator function
//
// PRE: (none)
//
// POST: the unary minus (negative) is returned
{
return Complex( -value.getReal(), -value.getImag() );
}
============================================================
// File: Complex.h
#ifndef COMPLEX_H
#define COMPLEX_H
#include <iostream> // used by operator<<
using namespace std;
// The Complex class defines a complex number composed of a real and
// imaginary part, both represented by doubles.
// Note: this version implements a convert constructor to convert
// from type double to type Complex rather than supplying several
// different versions of operator+
// Class Invariants:
// - The real and imaginary parts of a Complex are always defined
class Complex
{
public:
Complex();
// Default constructor
// PRE: (none)
// POST: complex number is 0 + 0*i
Complex( double real, double imag );
// Parameterized constructor
// PRE: (none)
// POST: complex number is real + imag*i
Complex( double real );
// Convert constructor
// PRE: (none)
// POST: complex number is real + 0*i
void setComplex( double real, double imag );
// Mutator
// PRE: (none)
// POST: complex number is real + imag*i
double getReal() const;
// Accessor
// PRE: (none)
// POST: real part is returned
double getImag() const;
// Accessor
// PRE: (none)
// POST: imaginary part is returned
const Complex operator+( const Complex& rComplex ) const;
// Accessor -- Member operator function
// PRE: (none)
// POST: the sum of this Complex and rComplex is returned
friend const Complex operator-( const Complex& lComplex,
const Complex& rComplex );
// Non-member friend operator function
// PRE: (none)
// POST: the difference of lComplex and rComplex is returned
inline const Complex operator*( const Complex& rComplex ) const
// Accessor -- In-line member operator function
// PRE: (none)
// POST: the product of this Complex and rComplex is returned
{
return Complex( realPart*rComplex.realPart
- imagPart*rComplex.imagPart,
realPart*rComplex.imagPart
+ imagPart*rComplex.realPart );
}
inline const Complex operator~() const
// Accessor -- In-line member operator function
// PRE: (none)
// POST: the complex conjugate is returned
{
return Complex( realPart, -imagPart );
}
const Complex& operator++();
// Mutator -- Member prefix operator function
// PRE: (none)
// POST: the real part of the Complex is incremented by one and
// the new value is returned
const Complex operator--( int );
// Mutator -- Member postfix operator function
// PRE: (none)
// POST: the real part of the Complex is decremented by one and
// the original value is returned
friend ostream& operator<<( ostream& outStream, const Complex& number );
// Non-member function
// PRE: (none)
// POST: number is output to the given ostream in the form
// [realPart] + [imaginaryPart]i
friend istream& operator>>( istream& inStream, Complex& number );
// Non-member function
// PRE: (none)
// PRE: (none)
// POST: number has been read from the keyboard with format:
// [realPart]+/-[imagPart]i with no spaces
private:
double realPart;
double imagPart;
};
const Complex operator/( const Complex& lComplex, const Complex& rComplex );
// Non-member non-friend operator function
// PRE: (none)
// POST: the quotient of lComplex and rComplex is returned
const Complex operator-( const Complex& value );
// Non-member non-friend operator function
// PRE: (none)
// POST: the unary minus (negative) is returned
#endif
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.