Problem z instrukcją warunkową "?"

0

Cześć!
Staram się wykonać program imitujący działanie prostego kalkulatora. Algorytm działa dla każdej opcji z wyjątkiem reszty z dzielenia.
Na początku użytkownik wprowadza 3 zmienne: pierwszą liczbę (float), drugą liczbę (float) oraz znak działania (char). Następnie napisałem instrukcję switch- case dla każdego przypadku oraz default, gdy wprowadzona operacja jest nieprawidłowa. Tutaj fragment programu, którego działanie jest nieprawidłowe, a nie umiem dojść do tego, dlaczego tak jest:

case '%' :
            bool isNumberOneInt, isNumberTwoInt;
            isNumberOneInt = (numberOne == int(numberOne));
            isNumberTwoInt = (numberTwo == int(numberTwo));
            (isNumberOneInt && isNumberTwoInt) ? cout << numberOne << sign << numberTwo << "= " 
            << int(numberOne) % int(numberTwo) :
            cout << "Can't handle that";
            break;

W momencie, w którym użytkownik wprowadza liczby o typie float, program powinien zwrócić tekst "can't handle that", a tak się nie dzieje. Po prostu oblicza wprowadzone działanie. Czy ktoś ma pomysł, dlaczego tak jest?

0

eh, @Shalom mnie wyprzedził :(
To ja dodam tylko, że masz dwie opcje na naprawę:

  • Albo wyciągnąć cout przed ? :
  • Albo użyć if else zamiast ? :
    </del>
1

? jest ok. Pewnie problem jest z wczytywaniem floata albo konwersją/sprawdzaniem:

            isNumberOneInt = (numberOne == int(numberOne));
            isNumberTwoInt = (numberTwo == int(numberTwo));

Zobacz dla numberOne = 3 i 3.3
https://godbolt.org/z/hzWcb543G

0
alagner napisał(a):

? jest ok. Pewnie problem jest z wczytywaniem floata albo konwersją/sprawdzaniem:

            isNumberOneInt = (numberOne == int(numberOne));
            isNumberTwoInt = (numberTwo == int(numberTwo));

Kurde, fakt, wrzuciłem to w kompilator Online i wszystko jest w porządku. Kod który wrzuciłem:

#include <iostream>

using namespace std;

int main()
{
    float numberOne = 1.;
    float numberTwo = 2.;
    char sign = '/';
    
            bool isNumberOneInt, isNumberTwoInt;
            isNumberOneInt = (numberOne == int(numberOne));
            isNumberTwoInt = (numberTwo == int(numberTwo));
            (isNumberOneInt && isNumberTwoInt) ? cout << numberOne << sign << numberTwo << "= " 
            << int(numberOne) % int(numberTwo) :
            cout << "Can't handle that";

    return 0;
}

Zwraca

1/2= 1

A kod:

#include <iostream>

using namespace std;

int main()
{
    float numberOne = 1.2;
    float numberTwo = 2.3;
    char sign = '/';
    
            bool isNumberOneInt, isNumberTwoInt;
            isNumberOneInt = (numberOne == int(numberOne));
            isNumberTwoInt = (numberTwo == int(numberTwo));
            (isNumberOneInt && isNumberTwoInt) ? cout << numberOne << sign << numberTwo << "= " 
            << int(numberOne) % int(numberTwo) :
            cout << "Can't handle that";

    return 0;
}

Zwraca

Can't handle that

Polecam zapoznać się z debugerem bo tak z dego wycinka trudno coś zgadnąć :(

3

W jakim celu tutaj w ogóle używasz ?: zamiast normalnego ifa? Jest to bardzo nieczytelne i utrudnia debugowanie.

1

Zróbże normalnie if i tyle.

Owszem, ternary ?: ma drobne zastosowania, ale nie są tak powszechne jak if. Można na palcach jednej ręki policzyć miejsca gdzie faktycznie poprawiłyby czytelność i użyteczność.

case '%':
    if (numberOne == int(numberOne) && numberTwo == int(numberTwo)) {
      cout << numberOne << sign << numberTwo << "= " << int(numberOne) % int(numberTwo);
    } else {
      cout << "Can't handle that";
    }
    break;

PS: Swoją drogą switch też bym nie używał. Raczej if, polimorfizm albo mapy.

6
emek3444 napisał(a):

W momencie, w którym użytkownik wprowadza liczby o typie float, program powinien zwrócić tekst "can't handle that", a tak się nie dzieje. Po prostu oblicza wprowadzone działanie. Czy ktoś ma pomysł, dlaczego tak jest?

Wszyscy rzucili się na ten koślawe użycie ternary operator, ale problem leży gdzie indziej. Niestety podany fragment kodu jest zbyt zdawkowy i brak konkretnych danych wejściowych nie pozwala na jednoznaczne określenie co autor ma na myśli.
Jako, że autor próbuje odróżnić wprowadzanie typów całkowitych i zmiennoprzecinkowych przez sprawdzanie zaokrągleń wszystko jest możliwe, a takie rozwiązanie jest fundamentalnie nieprawidłowe.

0

Zamiast robić takie skomplikowane warunki spójrz na to https://www.cplusplus.com/reference/cmath/fmod/
Jeżeli zaś chcesz się uprzeć i sprawdzać czy to jest int to https://www.cplusplus.com/reference/cmath/mod

2

Problem z instrukcją warunkową "?"

a) Problem jest taki, ze to nie jest instrukcja a wyrażenie warunkowe.

emek3444 napisał(a):
case '%' :
            bool isNumberOneInt, isNumberTwoInt;
            isNumberOneInt = (numberOne == int(numberOne));
            isNumberTwoInt = (numberTwo == int(numberTwo));
            (isNumberOneInt && isNumberTwoInt) ? cout << numberOne << sign << numberTwo << "= " 
            << int(numberOne) % int(numberTwo) :
            cout << "Can't handle that";
            break;

b) Jak widzę taki styl deklaracji zmiennych w case, to mi się scyzoryk sam otwiera.

c) lada chwila cię kopnie w ..ę porównywanie liczb zmiennoprzecinkowych
https://www.google.com/search?q=por%C3%B3wnania+zmiennoprzecinkowe

1 użytkowników online, w tym zalogowanych: 0, gości: 1