• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Kalkulator odwrotnej notacji polskiej

Object Storage Arubacloud
+2 głosów
532 wizyt
pytanie zadane 16 października 2021 w C i C++ przez MKolaj15 Bywalec (2,270 p.)
zamknięte 16 października 2021 przez MKolaj15

Witam, dostałem jako zadanie zmodyfikować podany kod kalkulatora odwrotnej notacji polskiej tak, aby wyliczał także mnożenie, dzielenie, potęgowanie, dzielenie liczby całkowitych, resztę z dzielenia, pierwiastek kwadratowy oraz logarytm o podstawie 10. Z większością sobie poradziłem, lecz problem pojawia się przy stworzeniu funkcji obliczających resztę z dzielenia oraz dzielenie liczb całkowitych. Wielu elementów tego kodu nie rozumiem, lecz wiem, że funkcje w tym kodzie operują na typach double, a do wyżej wymienionych działań potrzebne są typy int. Ma ktoś może pomysł jak takie działania wprowadzić do kodu, żeby wszystko działało? Przykład działania programu:

/.program 2 2 + p

4

Kod:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <stack>
#include <stdexcept>
#include <string>
#include <vector>
#include <cmath>
#include <iomanip>
#include <math.h>


auto pop_top(std::stack<double>& stack) -> double
{
    if (stack.empty()) {
        throw std::logic_error{"empty stack"};
    }
    auto element = std::move(stack.top());
    stack.pop();
    return element;
}

auto evaluate_addition(std::stack<double>& stack) -> void
{
    if (stack.size() < 2) {
        throw std::logic_error{"not enough operands for +"};
    }
    auto const b = pop_top(stack);
    auto const a = pop_top(stack);
    stack.push(a + b);
}

auto evaluate_subtraction(std::stack<double>& stack) -> void
{
    if (stack.size() < 2) {
        throw std::logic_error{"not enough operands for -"};
    }
    auto const b = pop_top(stack);
    auto const a = pop_top(stack);
    stack.push(a - b);
}


auto evaluate_multiplication(std::stack<double>& stack) -> void
{
    if (stack.size() < 2) {
        throw std::logic_error{"not enough operands for *"};
    }
    auto const b = pop_top(stack);
    auto const a = pop_top(stack);
    stack.push(a * b);
}

auto evaluate_division(std::stack<double>& stack) -> void
{
    if (stack.size() < 2) {
        throw std::logic_error{"not enough operands for /"};
    }
    auto const b = pop_top(stack);
    auto const a = pop_top(stack);
    stack.push(a / b);
}

/*auto evaluate_division_of_integers(std::stack<double>& stack) -> void
{
    if (stack.size() < 2) {
        throw std::logic_error{"not enough operands for "};
    }
    auto const b = pop_top(stack);
    auto const a = pop_top(stack);
    stack.push(a  b);
}

auto evaluate_modulo(std::stack<double>& stack) -> void
{
    if (stack.size() < 2) {
        throw std::logic_error{"not enough operands for %"};
    }
    auto const b = pop_top2(stack);
    auto const a = pop_top2(stack);
    stack.push(a % b);
}
*/
auto evaluate_exponentiation(std::stack<double>& stack) -> void
{
    if (stack.size() < 2) {
        throw std::logic_error{"not enough operands for **"};
    }
    auto const b = pop_top(stack);
    auto const a = pop_top(stack);
    stack.push(pow(a,b));
}

auto evaluate_square_root(std::stack<double>& stack) -> void
{
    if (stack.size() < 1) {
        throw std::logic_error{"not enough operands for sqrt"};
    }
    auto const a = pop_top(stack);
    stack.push(sqrt(a));
}

auto evaluate_logarithm(std::stack<double>& stack) -> void       //funkcja zwracająca logarytm o podstawie 10 z podanej liczby
{
    if (stack.size() < 1) {
        throw std::logic_error{"not enough operands for log"};
    }
    auto const a = pop_top(stack);
    stack.push(log10(a));
}



auto make_args(int argc, char* argv[]) -> std::vector<std::string>
{
    auto args = std::vector<std::string>{};
    std::copy_n(argv, argc, std::back_inserter(args));
    return args;
}

auto main(int argc, char* argv[]) -> int
{
    auto const args = make_args(argc - 1, argv + 1);

    auto stack = std::stack<double>{};
    for (auto const each : args) {
        try {
            if (each == "p") {
                std::cout << pop_top(stack) << "\n";
            } else if (each == "+") {
                evaluate_addition(stack);
            } else if (each == "-") {
                evaluate_subtraction(stack);
            } else if (each == "*") {
                evaluate_multiplication(stack);
            } else if (each == "/") {
                evaluate_division(stack);
            } else if (each == "%") {
                evaluate_modulo(stack);
            }  else if (each == "**") {
                evaluate_exponentiation(stack);
            } else if (each == "sqrt") {
                evaluate_square_root(stack);
            } else if (each == "log") {
                evaluate_logarithm(stack);
            }
              else {
                stack.push(std::stod(each));
            }
        } catch (std::logic_error const& e) {
            std::cerr << "error: " << each << ": " << e.what() << "\n";
        }
    }

    return 0;
}

Byłbym bardzo wdzięczny za jakiekolwiek wskazówki. Z góry dziękuję!

komentarz zamknięcia: uzyskałem odpowiedź
1
komentarz 16 października 2021 przez j23 Mędrzec (194,920 p.)

No a zwykłe rzutowanie static_cast<int>(wartość_double) nie wystarczy?

komentarz 16 października 2021 przez Oscar Nałogowiec (29,290 p.)

@MKolaj15, Zawsze mnie zastanawiało jak działa funkcja fmod. Nigdy nie używałem, ale natrafiłem w jakiś manualach.

1 odpowiedź

+3 głosów
odpowiedź 16 października 2021 przez TOM_CPP Pasjonat (22,640 p.)
wybrane 16 października 2021 przez MKolaj15
 
Najlepsza

Operację modulo można wykonać tylko na liczbach całkowitych.  Natomiast na stosie stack<double> składowane są liczby zmiennoprzecinkowe, stąd potrzebne jest jawne rzutowanie na typ int - na przykład przy pomocy szablonu static_cast<>.

auto evaluate_modulo(std::stack<double>& stack) -> void
{
    if (stack.size() < 2) {
        throw std::logic_error{"not enough operands for %"};
    }
    auto const b = static_cast<int>(pop_top(stack));
    auto const a = static_cast<int>(pop_top(stack));
    stack.push(a % b);
}

 

komentarz 16 października 2021 przez MKolaj15 Bywalec (2,270 p.)
Działa, niezmierne dzięki!

Podobne pytania

0 głosów
1 odpowiedź 814 wizyt
0 głosów
2 odpowiedzi 504 wizyt
0 głosów
1 odpowiedź 7,456 wizyt

92,553 zapytań

141,399 odpowiedzi

319,534 komentarzy

61,938 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...