diff --git a/du3/program.c b/du3/program.c index 52df7cf..b888cea 100644 --- a/du3/program.c +++ b/du3/program.c @@ -4,7 +4,7 @@ #include #include -#define EPSILON 0.001 // Tolerancia pre porovnanie reálnych čísel: ak je rozdiel dvoch čísel menší alebo rovný EPSILON, považujeme ich za rovnaké. +#define EPSILON 0.001 // Tolerancia pre porovnanie reálnych čísel: ak je rozdiel menší alebo rovný EPSILON, považujeme čísla za rovnaké. /* * Funkcia trim_newline @@ -36,7 +36,7 @@ void trim_newline(char *line) { * - Ukazovateľ na prvý znak, ktorý nie je whitespace. */ char* skip_spaces(char *str) { - while(*str && isspace((unsigned char)*str)) { + while (*str && isspace((unsigned char)*str)) { str++; } return str; @@ -60,7 +60,7 @@ char* skip_spaces(char *str) { * * Návratová hodnota: * - 0, ak sa parsovanie podarilo úspešne. - * - 1, ak nastala chyba (napr. nesprávny formát, chýbajúce číslo, operátor alebo '=') + * - 1, ak nastala chyba (nesprávny formát, chýbajúce číslo, operátor alebo '=') * * Príklad vstupu: * " 10.0 / 2.0 = 5.0" @@ -125,16 +125,16 @@ int parse_expression(char *line, float *num1, char *op, float *num2, float *resu * * Parametre: * - num1: Prvé číslo. - * - op: Operátor, ktorý môže byť '+', '-', '*' alebo '/'. + * - op: Operátor ('+', '-', '*' alebo '/'). * - num2: Druhé číslo. - * - error: Ukazovateľ na premennú, do ktorej sa uloží 1, ak nastane chyba (napr. delenie nulou). + * - error: Ukazovateľ, do ktorého sa uloží 1, ak nastane chyba (napr. delenie nulou). * * Návratová hodnota: * - Výsledok operácie, ak prebehne úspešne. - * - V prípade chyby (napr. delenie nulou) sa error nastaví na 1 a funkcia vráti 0. + * - Ak nastane chyba, error je nastavený na 1 a funkcia vráti 0. * * Príklad: - * calculate(10.0, '/', 2.0, &error) vráti 5.0, pričom error zostáva 0. + * calculate(10.0, '/', 2.0, &error) vráti 5.0, error zostáva 0. */ float calculate(float num1, char op, float num2, int *error) { *error = 0; // Inicializácia chyby na 0 (žiadna chyba) @@ -150,7 +150,7 @@ float calculate(float num1, char op, float num2, int *error) { res = num1 * num2; break; case '/': - // Pred delením overíme, či nedochádza k deleniu nulou + // Kontrola delenia nulou; ak num2 je takmer 0, signalizujeme chybu if (fabs(num2) < EPSILON) { *error = 1; // Chyba: delenie nulou return 0; @@ -167,18 +167,17 @@ float calculate(float num1, char op, float num2, int *error) { /* * Funkcia process_line * --------------------- - * Spracuje jeden riadok vstupu obsahujúci matematický príklad a určí, či je príklad - * zapísaný správne a či je výsledok správny. Výsledok sa uloží do parametra output. + * Spracuje jeden riadok vstupu obsahujúci matematický príklad a určí, či je zápis + * správny a či je výsledok správny. * * Postup: * 1. Skopíruje vstupný riadok do lokálneho bufferu a odstráni prípadný koncový znak nového riadku. - * 2. Predpokladá sa, že riadok nie je prázdny (kontrola prázdnoty sa vykoná v main). - * 3. Pokúsi sa rozparsovať riadok na jednotlivé časti: prvé číslo, operátor, druhé číslo a výsledok. - * 4. Ak parsovanie zlyhá, nastaví output na "CHYBA". - * 5. Vykoná operáciu a porovná vypočítaný výsledok so zadaným výsledkom s toleranciou EPSILON. - * - Ak sa výsledok zhoduje, nastaví output na "OK". - * - Ak sa výsledok nezhoduje, nastaví output na "ZLE". - * 6. V prípade delenia nulou, keď calculate vráti chybu, program nastaví output na "ZLE". + * 2. Rozparsuje riadok na časti: prvé číslo, operátor, druhé číslo a očakávaný výsledok. + * 3. Ak parsovanie zlyhá, nastaví output na "CHYBA". + * 4. Vykoná operáciu a ak nastane chyba (napr. delenie nulou), nastaví output na "ZLE". + * 5. Zaokrúhli výsledok operácie na 2 desatinné miesta, pretože čísla sú zadané na max. 2 desatinné miesta. + * 6. Porovná zaokrúhlený výsledok s očakávaným výsledkom. Ak sa líšia o viac ako EPSILON, + * nastaví output na "ZLE", inak na "OK". * * Parametre: * - line: Vstupný riadok (napr. "10.0 / 2.0 = 5.0"). @@ -207,14 +206,16 @@ void process_line(const char *line, char *output, size_t output_size) { int calcError = 0; float calculatedResult = calculate(num1, op, num2, &calcError); if (calcError) { - // V prípade delenia nulou (alebo inej chyby v calcultion) vypíšeme "ZLE" + // V prípade chyby (napr. delenie nulou) vypíšeme "ZLE" snprintf(output, output_size, "ZLE"); return; } - // Porovnáme vypočítaný výsledok so zadaným výsledkom. - // Ak je absolútny rozdiel menší alebo rovný EPSILON, považujeme príklad za správny. - if (fabs(calculatedResult - givenResult) <= EPSILON) { + // Zaokrúhľujeme výsledok operácie na 2 desatinné miesta, pretože vstupné čísla majú max. 2 desatinné miesta. + float roundedResult = round(calculatedResult * 100) / 100; + + // Porovnáme zaokrúhlený výsledok so zadaným výsledkom. + if (fabs(roundedResult - givenResult) <= EPSILON) { snprintf(output, output_size, "OK"); } else { snprintf(output, output_size, "ZLE"); @@ -233,10 +234,10 @@ void process_line(const char *line, char *output, size_t output_size) { * 1+2=3 * 3.333+4.667=8.0 * - * Program pre každý neprázdny riadok overí správnosť zápisu a výsledku a na štandardný výstup + * Pre každý neprázdny riadok program overí správnosť zápisu a výsledku a na štandardný výstup * vypíše "OK", "ZLE" alebo "CHYBA". * - * Poznámka: Ak sa načíta prázdny riadok (obsahuje iba medzery), program ho ignoruje a ukončí sa. + * Ak sa načíta prázdny riadok (iba medzery), program sa ukončí. * * Ako skompilovať: * gcc program.c -o program -lm @@ -251,7 +252,7 @@ int main(int argc, char *argv[]) { // Načítavame riadky zo štandardného vstupu (napr. z konzoly alebo súboru) while (fgets(buffer, sizeof(buffer), stdin) != NULL) { trim_newline(buffer); - // Ak je riadok prázdny (iba medzery), ukončíme cyklus a teda program + // Ak je riadok prázdny (iba medzery), ukončíme cyklus a program if (*skip_spaces(buffer) == '\0') { break; } @@ -260,4 +261,4 @@ int main(int argc, char *argv[]) { } return 0; -} +} \ No newline at end of file