Last active
April 20, 2022 16:00
-
-
Save gonzafernan/c87086f03dfdb8f138638cacd4d9a3d5 to your computer and use it in GitHub Desktop.
Reverse Polish notation (RPN) is a mathematical notation in which operators follow their operands. This is a C implementation with a simple stack.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
============================================================================ | |
Name : rpncalc.c | |
Author : Gonzalo G. Fernandez | |
Email : [email protected] | |
Institution : Universidad El Bosque | |
Year : 2022 | |
Version : 1.0 | |
Copyright : License MIT | |
Description : Reverse Polish notation (RPN) is a mathematical notation in | |
which operators follow their operands. | |
This is a C implementation with a simple stack. | |
============================================================================ | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <math.h> | |
#define MAX_STACK_LENGTH 10 /* Max float stack length */ | |
float stack[MAX_STACK_LENGTH]; /* Float stack */ | |
int top = -1; /* Current stack index */ | |
/* Check if stack is empty (1 if true, 0 if false) */ | |
int isEmpty(void){ | |
if (top == -1){ | |
return 1; | |
} else { | |
return 0; | |
} | |
} | |
/* Check if stack is full (1 if true, 0 if false) */ | |
int isFull(void){ | |
if (top == MAX_STACK_LENGTH){ | |
return 1; | |
} else { | |
return 0; | |
} | |
} | |
/* Get next stack element without pop */ | |
float peek(void){ | |
return stack[top]; | |
} | |
/* Get next stack element | |
* If a pop is tried when the stack is empty, | |
* the program finish execution with error | |
*/ | |
float pop(void){ | |
float data; | |
if (!isEmpty()){ | |
data = stack[top]; | |
top--; | |
return data; | |
} else { | |
printf("ERROR: Pop of empty stack.\n"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
/* Put element data in stack | |
* If a push is tried when the stack is full return 1, | |
* successful push return 0 | |
*/ | |
int push(float data){ | |
if (!isFull()){ | |
top++; | |
stack[top] = data; | |
return 0; | |
} else { | |
return 1; | |
} | |
} | |
int main(int argc, char *argv[]) { | |
char *token; | |
float tmp_value1, tmp_value2; | |
// Check for input argument expression | |
if (argc < 2){ | |
printf("No expression given.\n"); | |
return EXIT_SUCCESS; | |
} | |
// Process every expression given | |
for (int i=1; i<argc; i++){ | |
// Tokenize argument and processing | |
token = strtok(argv[i], " "); | |
while (token != NULL){ | |
/* Addition operation */ | |
if (strcmp(token, "+") == 0){ | |
tmp_value2 = pop(); | |
tmp_value1 = pop(); | |
tmp_value1 = tmp_value1 + tmp_value2; | |
/* Subtraction operation */ | |
} else if (strcmp(token, "-") == 0){ | |
tmp_value1 = pop(); | |
tmp_value2 = pop(); | |
tmp_value1 = tmp_value1 - tmp_value2; | |
/* Multiplication operation */ | |
} else if (strcmp(token, "*") == 0){ | |
tmp_value1 = pop(); | |
tmp_value2 = pop(); | |
tmp_value1 = tmp_value1 * tmp_value2; | |
/* Division operation */ | |
} else if (strcmp(token, "/") == 0){ | |
tmp_value1 = pop(); | |
tmp_value2 = pop(); | |
tmp_value1 = tmp_value1 / tmp_value2; | |
/* Power operation */ | |
} else if (strcmp(token, "pow") == 0){ | |
tmp_value1 = pop(); | |
tmp_value2 = pop(); | |
tmp_value1 = pow(tmp_value1, tmp_value2); | |
/* Absolute value */ | |
} else if (strcmp(token, "abs") == 0){ | |
tmp_value1 = pop(); | |
tmp_value1 = abs(tmp_value1); | |
/* Sqruare-root operation */ | |
} else if (strcmp(token, "sqrt") == 0){ | |
tmp_value1 = pop(); | |
tmp_value1 = sqrt(tmp_value1); | |
/* Input number (always float) */ | |
} else { | |
tmp_value1 = atof(token); | |
} | |
// Push value to stack (operation result or new value) | |
if (push(tmp_value1)){ | |
printf("ERROR: Push of full stack.\n"); | |
return EXIT_FAILURE; | |
} | |
token = strtok(NULL, " "); // Get new token | |
} | |
// Check for answer | |
// If more than one element in stack, invalid expression | |
if (top > 0){ | |
printf("Invalid expression."); | |
return EXIT_SUCCESS; | |
} | |
printf("%.3f", peek()); | |
} | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment