diff --git a/sk2/Makefile b/sk2/Makefile index e69de29..b3d9c56 100644 --- a/sk2/Makefile +++ b/sk2/Makefile @@ -0,0 +1,17 @@ +CC = gcc +CFLAGS = -Wall -Wextra -std=c11 +LDFLAGS = -lm + +all: calculator + +calculator: main.o calculator.o + $(CC) $(CFLAGS) main.o calculator.o -o calculator $(LDFLAGS) + +main.o: main.c calculator.h + $(CC) $(CFLAGS) -c main.c + +calculator.o: calculator.c calculator.h + $(CC) $(CFLAGS) -c calculator.c + +clean: + rm -f *.o calculator diff --git a/sk2/README.md b/sk2/README.md new file mode 100644 index 0000000..4ac66d0 --- /dev/null +++ b/sk2/README.md @@ -0,0 +1,56 @@ +# Vedecká kalkulačka (Scientific Calculator) + +## Popis projektu +Tento projekt implementuje jednoduchú vedeckú kalkulačku v jazyku C. +Kalkulačka spracováva matematické výrazy zapísané v **infixnej notácii** a vyhodnocuje ich pomocou **rekurzívneho syntaktického analyzátora**. + +Program podporuje základné aritmetické operácie, zátvorky a vybrané matematické funkcie zo štandardnej knižnice jazyka C. + + + +## Podporované operácie +- práca s reálnymi číslami (`double`) s presnosťou minimálne **2 desatinné miesta** +- sčítanie (`+`) +- odčítanie (`-`) +- násobenie (`*`) +- delenie (`/`) +- zátvorky (`(`, `)`) +- goniometrické funkcie: + - `sin(x)` + - `cos(x)` +- odmocnina: + - `sqrt(x)` +- druhá mocnina (a všeobecná mocnina): + - `pow(x, y)` + (druhá mocnina sa vypočíta ako `pow(x, 2)`) +- logaritmus: + - `log(x)` (prirodzený logaritmus) + + +## Spôsob riešenia +Vyhodnocovanie výrazov je realizované **bez použitia zásobníkov**. +Použitý je **rekurzívny zostupný parser**, ktorý rešpektuje prioritu operátorov: + +- výrazy (`+`, `-`) +- termy (`*`, `/`) +- faktory (čísla, zátvorky, funkcie) + +Tento prístup umožňuje prirodzené spracovanie infixnej notácie a zátvoriek. + +## Kompilácia +Projekt sa kompiluje pomocou nástroja `make`. + +V adresári projektu spusti: + +make. + +## Priklady použitia +1) Zadaj vyraz: +(2 + 3) * 2 +10.00; +2) Zadaj vyraz: +(10 * 2) + (6 / 2) +23.00; +3) Zadaj vyraz: +pow(2, 3) + sqrt(16) +12.00; \ No newline at end of file diff --git a/sk2/calculator.c b/sk2/calculator.c index e69de29..ed6c3c8 100644 --- a/sk2/calculator.c +++ b/sk2/calculator.c @@ -0,0 +1,129 @@ +#include "calculator.h" +#include +#include +#include +#include +#include + +static const char *ptr; + + + +static void skip_spaces(void) { + while (*ptr && isspace(*ptr)) { + ptr++; + } +} + +static int match(const char *s) { + int len = strlen(s); + if (strncmp(ptr, s, len) == 0) { + ptr += len; + return 1; + } + return 0; +} + + + +static double parse_expression(void); + +static double parse_number(void) { + skip_spaces(); + char *end; + double val = strtod(ptr, &end); + ptr = end; + return val; +} + +static double parse_factor(void) { + skip_spaces(); + + + if (*ptr == '(') { + ptr++; + double val = parse_expression(); + skip_spaces(); + if (*ptr == ')') { + ptr++; + } + return val; + } + + + if (match("sin")) { + skip_spaces(); + return sin(parse_factor()); + } + if (match("cos")) { + skip_spaces(); + return cos(parse_factor()); + } + if (match("sqrt")) { + skip_spaces(); + return sqrt(parse_factor()); + } + if (match("log")) { + skip_spaces(); + return log(parse_factor()); + } + if (match("pow")) { + skip_spaces(); + if (*ptr == '(') ptr++; + double a = parse_expression(); + skip_spaces(); + if (*ptr == ',') ptr++; + double b = parse_expression(); + skip_spaces(); + if (*ptr == ')') ptr++; + return pow(a, b); + } + + + return parse_number(); +} + +static double parse_term(void) { + double val = parse_factor(); + + while (1) { + skip_spaces(); + if (*ptr == '*') { + ptr++; + val *= parse_factor(); + } else if (*ptr == '/') { + ptr++; + val /= parse_factor(); + } else { + break; + } + } + + return val; +} + +static double parse_expression(void) { + double val = parse_term(); + + while (1) { + skip_spaces(); + if (*ptr == '+') { + ptr++; + val += parse_term(); + } else if (*ptr == '-') { + ptr++; + val -= parse_term(); + } else { + break; + } + } + + return val; +} + + + +double evaluate_expression(const char *expr) { + ptr = expr; + return parse_expression(); +} diff --git a/sk2/calculator.exe b/sk2/calculator.exe new file mode 100644 index 0000000..2eca831 Binary files /dev/null and b/sk2/calculator.exe differ diff --git a/sk2/calculator.h b/sk2/calculator.h index e69de29..6ff14f9 100644 --- a/sk2/calculator.h +++ b/sk2/calculator.h @@ -0,0 +1,9 @@ +#ifndef CALCULATOR_H +#define CALCULATOR_H + +#define MAX_EXPR 512 +#define MAX_STACK 256 + +double evaluate_expression(const char *expr); + +#endif diff --git a/sk2/calculator.o b/sk2/calculator.o new file mode 100644 index 0000000..99a166d Binary files /dev/null and b/sk2/calculator.o differ diff --git a/sk2/main.c b/sk2/main.c index e69de29..a28b014 100644 --- a/sk2/main.c +++ b/sk2/main.c @@ -0,0 +1,17 @@ +#include +#include "calculator.h" + +int main(void) { + char expr[MAX_EXPR]; + + printf("Zadaj vyraz:\n"); + + if (!fgets(expr, sizeof(expr), stdin)) { + return 1; + } + + double result = evaluate_expression(expr); + + printf("%.2f\n", result); + return 0; +} diff --git a/sk2/main.o b/sk2/main.o new file mode 100644 index 0000000..3edb28f Binary files /dev/null and b/sk2/main.o differ