VB icon

RPN Calulator v2 - 28/9/2016

Email
Submitted on: 9/27/2016 11:35:31 PM
By: Ben128  
Level: Beginner
User Rating: Unrated
Compatibility: C++ (general), Microsoft Visual C++
Views: 2054
 
     This is a small Reverse Polish Notation calulator it takes in RPN expression such as 2 2 + and gives the result. It supports ints and floats and the basic math operators +-*/ UPDATE 28/9/2016 support for new operators added & % ^ ! limited support for variables, done error check for division by zero, Hope you find it usfull please vote. Comments welcome.

 
code:
Can't Copy and Paste this?
Click here for a copy-and-paste friendly version of this code!
				
//**************************************
// Name: RPN Calulator v2 - 28/9/2016
// Description:This is a small Reverse Polish Notation calulator it takes in RPN expression such as 2 2 + and gives the result. It supports ints and floats and the basic math operators +-*/ UPDATE 28/9/2016 support for new operators added & % ^ ! limited support for variables, done error check for division by zero, Hope you find it usfull please vote. Comments welcome.
// By: Ben128
//**************************************

// Reverse Polish notation demo 2
// Basic calulator for RPN expressions
// Operators
// General + - * / ^
// Bitwise & % |
// Allows ints and floats
// Supports upto 26 variables A to Z
// By DreamVB 1:28 PM 27-Sep-16
#include <iostream>
//
using namespace std;
using std::cout;
using std::endl;
//Prototypes
int GetVarIdx(char var);
//Variables A-Z
float Variables[26];
//Stack code
#define MAX_STACK 196
float _stack[MAX_STACK];
int tos = 0;
bool Full(){
	return tos >= MAX_STACK - 1;
}
bool Empty(){
	return tos == 0;
}
void Push(float value){
	if (Full()){
		return;
	}
	tos++;
	_stack[tos] = value;
}
float Pop(){
	float t = _stack[tos];
	tos--;
	return t;
}
//Enf of stack code
bool IsOp(char c){
	//Check for operators.
	switch (c){
	case '+':
	case '-':
	case '*':
	case '/':
	case '^':
	case '|':
	case '&':
	case '%':
		return true;
	default:
		return false;
	}
}
double RPN(string expression){
	int i = 0;
	int var_idx = -1;
	float v1, v2, ret;
	v1 = ret = v2 = 0.0;
	string tok = "";
	while (i < expression.length()){
		//Skip white space
		while (isspace(expression[i])){
			i++;
		}
		//Check for digits and .
		if (isdigit(expression[i]) | expression[i] == '.'){
			while (isdigit(expression[i]) | expression[i] == '.'){
				tok += expression[i];
				i++;
			}
			//Push on stack number.
			Push(atof(tok.c_str()));
			tok = "";
		}
		else if (isalpha(expression[i])){
			while (isalpha(expression[i])){
				tok += toupper(expression[i]);
				i++;
			}
			//Get var index
			var_idx = GetVarIdx(tok[0]);
			//Check for variable
			if (var_idx != -1){
				//Push value onto stack
				Push(Variables[var_idx]);
			}
			//Clear token
			tok.clear();
		}
		//Check for operator
		else if (IsOp(expression[i])){
			if (expression[i] == '+'){
				v1 = Pop();
				v2 = Pop();
				ret = (v1 + v2);
			}
			if (expression[i] == '-'){
				v1 = Pop();
				v2 = Pop();
				ret = v2 - v1;
			}
			if (expression[i] == '*'){
				v1 = Pop();
				v2 = Pop();
				ret = (v1 * v2);
			}
			if (expression[i] == '/'){
				v1 = Pop();
				v2 = Pop();
				//Check for divide by zerp
				if (v1 == 0){
					cout << "Division by zero" << endl;
				}
				else{
					ret = (v2 / v1);
				}
			}
			if (expression[i] == '^'){
				v1 = Pop();
				v2 = Pop();
				ret = pow((int)v2, v1);
			}
			if (expression[i] == '|'){
				v1 = Pop();
				v2 = Pop();
				ret = (int)v1 | (int)v2;
			}
			if (expression[i] == '&'){
				v1 = Pop();
				v2 = Pop();
				ret = (int)v1 & (int)v2;
			}
			if (expression[i] == '%'){
				v1 = Pop();
				v2 = Pop();
				ret = (int)v2 % (int)v1;
			}
			//INC Counter
			i++;
			//Push result onto stack
			Push(ret);
		}
		else{
			cout << "Invaild Expression." << endl;
			break;
		}
	}
	//Return answer
	return Pop();
}
int GetVarIdx(char var){
	char *var_set = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	int idx = -1;
	for (int x = 0; x < strlen(var_set); x++){
		if (var == var_set[x]){
			idx = x;
			break;
		}
	}
	return idx;
}
int main(int argc, char *argv[]){
	Variables[0] = 10;
	Variables[1] = 20;
	Variables[2] = 1024 * 2;
	Variables[3] = log(9);
	system("title RPN Calulator Demo");
	string expr = "4 12 3 + * 2 / 5 5 + * 100 2 * - 2 /";
	cout << "Expression: " << expr.c_str() << endl;
	cout << "Answer: " << RPN(expr) << endl << endl;
	cout << "Expression: " << "22 7 /" << endl;
	cout << "PI: " << RPN("22 7 /") << endl;
	cout << "----------------------------------------------------------" << endl;
	//VARIABLE SUPPORT
	cout << "VARIABLE SUPPORT" << endl;
	cout << "Variables A=10 , B = 20 , C = 1020*2 , D = log(9)" << endl;
	cout << "----------------------------------------------------------" << endl;
	cout << "C : " << RPN("C") << endl;
	cout << "A B + : " << RPN("A B +") << endl;
	cout << "D 2 * : " << RPN("D 2 *") << endl;
	cout << "A B + 2 * B + : " << RPN("A B + 2 * B +") << endl;
	system("pause");
	return 0;
}


Other 50 submission(s) by this author

 


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this code (in the Beginner category)?
(The code with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments


 There are no comments on this submission.
 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular code, please click here instead.)
 

To post feedback, first please login.