#include #include #include #include #include #include "calculator.h" typedef struct { double data[100]; int top; } Stack; void stack_init(Stack* stack) { stack->top = -1; } void push(Stack* stack, double value) { stack->data[++stack->top] = value; } double delet(Stack* stack) { return stack->data[stack->top--]; } int isOperator(char op) { return (op == '+' || op == '-' || op == '*' || op == '/' || op == 's' || op == 'c' || op == 'l' || op == 'r' || op == 'k' || op == '^' || op == 'L'); } int precedence(char op) { switch(op) { case '+': case '-': return 1; case '*': case '/': return 2; case '^': return 3; case 's': case 'c': case 'l': case 'L': case 'r': case 'k': return 4; default: return 0; } } double applyOperator(double a, double b, char op) { switch(op) { case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': return (b != 0) ? (a / b) : 0; // Деление (проверка на деление на ноль) case '^': return pow(a, b); case 's': return sin(a); case 'c': return cos(a); case 'l': return (a > 0) ? log(a) : 0; // Проверка на отрицательное число для натурального логарифма case 'L': return (a > 0) ? log10(a) : 0; // Десятичный логарифм(проверка на отрицательное число) case 'r': if (a >= 0) { return sqrt(a); } else { printf("Argument entered incorrectly: %lf\n", a); // Если квадратный корень вводится с "-" то ошибка return 0; } case 'k': return sqrt(a); // Квадратный корень default: return 0; } } double evaluateExpression(char* expression, int configuration) { Stack operandStack; Stack operatorStack; stack_init(&operandStack); stack_init(&operatorStack); int i = 0; int unary = 1; // Изначально знак операнда - положительный while (expression[i] != '\0') { if (expression[i] == ' ' || expression[i] == '\n') { i++; continue; } else if (isdigit(expression[i]) || expression[i] == '.') { double operand = strtod(&expression[i], NULL) * unary; push(&operandStack, operand); while (isdigit(expression[i]) || expression[i] == '.') { i++; } unary = 1; // Сброс унарного минуса continue; } else if (expression[i] == '(') { if (i > 0 && expression[i - 1] == '-') { unary *= -1; // Смена знака } push(&operatorStack, expression[i]); i++; } else if (expression[i] == ')') { while (operatorStack.data[operatorStack.top] != '(') { char op = pop(&operatorStack); double b = delet(&operandStack); double a = delet(&operandStack); push(&operandStack, applyOperator(a, b, op)); } delet(&operatorStack); // Pop '(' i++; } else if (isOperator(expression[i])) { if (expression[i] == '-' && (i == 0 || expression[i-1] == '(')) { unary = -1; i++; continue; } else if ((configuration == 1 && (expression[i] == '*' || expression[i] == '-' || expression[i] == '+' || expression[i] == '/' || expression[i] == '^')) || (configuration == 2)) { while (operatorStack.top != -1 && precedence(operatorStack.data[operatorStack.top]) >= precedence(expression[i])) { char op = delet(&operatorStack); double b = delet(&operandStack); double a = delet(&operandStack); push(&operandStack, applyOperator(a, b, op)); } push(&operatorStack, expression[i]); } else if (expression[i] == 'k') { while (operatorStack.top != -1 && precedence(operatorStack.data[operatorStack.top]) >= precedence(expression[i])) { char op = delet(&operatorStack); double a = delet(&operandStack); push(&operandStack, applyOperator(a, 0, op)); // Так как корень одиночный оператор, второй операнд будет игнорироваться } push(&operatorStack, expression[i]); } else { printf("Invalid character: %c\n", expression[i]); return 0; } i++; } else { char function[10]; int j = i; // Запоминаем начальный индекс для функции int k = 0; while (isalpha(expression[j])) { function[k++] = expression[j++]; } function[k] = '\0'; if ((configuration == 1) && (strcmp(function, "sin") != 0 && strcmp(function, "cos") != 0 && strcmp(function, "sqrt") != 0 && strcmp(function, "log") != 0 && strcmp(function, "log10") != 0)) { printf("Unavailable operation: %s\n", function); return 0; } else if ((configuration == 2)) { if (strcmp(function, "sqrt") == 0 || strcmp(function, "sin") == 0 || strcmp(function, "cos") == 0 || strcmp(function, "log") == 0 || strcmp(function, "log10") == 0) { push(&operatorStack, expression[i]); } else { printf("Error: %s\n", function); return 0; } i = j; // Перемещаем индекс на символ после функции } else { printf("Invalid character: %c\n", expression[i]); return 0; } } } while (operatorStack.top != -1) { char op = delet(&operatorStack); double b = delet(&operandStack); double a = delet(&operandStack); push(&operandStack, applyOperator(a, b, op)); } return operandStack.data[operandStack.top]; }