#include "calculator.h" #include #include #include #include #include #define MAX 256 #define DEG_TO_RAD(x) ((x) * M_PI / 180.0) typedef struct { double data[MAX]; int top; } DoubleStack; typedef struct { char data[MAX][10]; int top; } StringStack; //funckie stacku void push_double(DoubleStack *s, double v) { s->data[++s->top] = v; } double pop_double(DoubleStack *s) { return s->data[s->top--]; } void push_string(StringStack *s, const char *v) { strcpy(s->data[++s->top], v); } char *pop_string(StringStack *s) { return s->data[s->top--]; } char *peek_string(StringStack *s) { return s->data[s->top]; } //priority operatorov int priority(const char *op) { if (!strcmp(op, "+") || !strcmp(op, "-")) return 1; if (!strcmp(op, "*") || !strcmp(op, "/")) return 2; if (!strcmp(op, "sin") || !strcmp(op, "cos") || !strcmp(op, "sqrt") || !strcmp(op, "log") || !strcmp(op, "pow")) return 3; return 0; } //infix na postfix int infix_to_postfix(const char *infix, char postfix[][10]) { StringStack ops = {.top = -1}; int k = 0; for (int i = 0; infix[i]; ) { if (isspace(infix[i])) { i++; continue; } if (isdigit(infix[i]) || infix[i] == '.') { char num[10]; int j = 0; while (isdigit(infix[i]) || infix[i] == '.') num[j++] = infix[i++]; num[j] = '\0'; strcpy(postfix[k++], num); } else if (isalpha(infix[i])) { char func[10]; int j = 0; while (isalpha(infix[i])) func[j++] = infix[i++]; func[j] = '\0'; push_string(&ops, func); } else if (infix[i] == '(') { char t[2] = "("; push_string(&ops, t); i++; } else if (infix[i] == ')') { while (ops.top != -1 && strcmp(peek_string(&ops), "(")) strcpy(postfix[k++], pop_string(&ops)); pop_string(&ops); i++; } else { char op[2] = {infix[i++], '\0'}; while (ops.top != -1 && priority(peek_string(&ops)) >= priority(op)) strcpy(postfix[k++], pop_string(&ops)); push_string(&ops, op); } } while (ops.top != -1) strcpy(postfix[k++], pop_string(&ops)); return k; } //vypocet postfixu double evaluate_postfix(char postfix[][10], int n) { DoubleStack s = {.top = -1}; for (int i = 0; i < n; i++) { if (isdigit(postfix[i][0]) || postfix[i][0] == '.') { push_double(&s, atof(postfix[i])); } else { double b = pop_double(&s); double a = (!strcmp(postfix[i], "sin") || !strcmp(postfix[i], "cos") || !strcmp(postfix[i], "sqrt") || !strcmp(postfix[i], "log")) ? 0 : pop_double(&s); if (!strcmp(postfix[i], "+")) push_double(&s, a + b); else if (!strcmp(postfix[i], "-")) push_double(&s, a - b); else if (!strcmp(postfix[i], "*")) push_double(&s, a * b); else if (!strcmp(postfix[i], "/")) push_double(&s, a / b); else if (!strcmp(postfix[i], "sin")) push_double(&s, sin(DEG_TO_RAD(b))); else if (!strcmp(postfix[i], "cos")) push_double(&s, cos(DEG_TO_RAD(b))); else if (!strcmp(postfix[i], "sqrt")) push_double(&s, sqrt(b)); else if (!strcmp(postfix[i], "log")) push_double(&s, log10(b)); else if (!strcmp(postfix[i], "pow")) push_double(&s, pow(a, b)); } } return pop_double(&s); } double evaluate_expression(const char *expression) { char postfix[MAX][10]; int n = infix_to_postfix(expression, postfix); return evaluate_postfix(postfix, n); }