• 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

+2 głosów
58 wizyt
pytanie zadane 16 października w C i C++ przez MKolaj15 Obywatel (1,070 p.)
zamknięte 16 października 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 przez j23 Mędrzec (166,180 p.)

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

komentarz 16 października przez Oscar Pasjonat (20,310 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 przez TOM_CPP Pasjonat (20,180 p.)
wybrane 16 października 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 przez MKolaj15 Obywatel (1,070 p.)
Działa, niezmierne dzięki!

Podobne pytania

0 głosów
1 odpowiedź 314 wizyt
0 głosów
1 odpowiedź 5,643 wizyt
0 głosów
1 odpowiedź 384 wizyt
pytanie zadane 20 stycznia 2020 w PHP przez TeslaX93 Gaduła (3,570 p.)

85,802 zapytań

134,588 odpowiedzi

298,790 komentarzy

56,697 pasjonatów

Advent of Code 2021

Top 15 użytkowników

  1. 494p. - rucin93
  2. 482p. - CC PL
  3. 463p. - nidomika
  4. 385p. - Whistleroosh
  5. 379p. - ScriptyChris
  6. 372p. - adrian17
  7. 340p. - TheLukaszNs
  8. 339p. - WhiskeyTaster
  9. 321p. - Argeento
  10. 318p. - Dagohar
  11. 287p. - Anonim 1794483
  12. 281p. - Klaudia
  13. 278p. - B4mbus
  14. 269p. - b0mbix
  15. 246p. - tokox
Szczegóły i pełne wyniki

Motyw:

Akcja Pajacyk

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

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...