Wydawanie reszty - program się nie kończy

0
 
#include<iostream>
using namespace std;

struct nominal
{
    double value;
    string name;
};

int main()
{

    struct nominal values[14];
    values[0].value = 200;
    values[0].name = "200z";
    values[1].value = 100;
    values[1].name = "100z";
    values[2].value = 50;
    values[2].name = "50z";
    values[3].value = 20;
    values[3].name = "20z";
    values[4].value = 10;
    values[4].name = "10z";
    values[5].value = 5;
    values[5].name = "5z";
    values[6].value = 2;
    values[6].name = "2z";
    values[7].value = 1;
    values[7].name = "1z";
    values[8].value = 0.5;
    values[8].name = "50g";
    values[9].value = 0.2;
    values[9].name = "20g";
    values[10].value = 0.1;
    values[10].name = "10g";
    values[11].value = 0.05;
    values[11].name = "5g";
    values[12].value = 0.02;
    values[12].name = "2g";
    values[13].value = 0.01;
    values[13].name = "1g";
    double n;
    cin>>n;
    double cash = n/100;
    cout<<cash<<endl;
    while(cash>0)
    {
        for(int i=0;i<14;i++)
        {
            if(cash>=values[i].value)
            {
                cash-=values[i].value;
                cout<<values[i].name<<endl;
                break;
            }
        }
    }
    return 0;
}

dlaczego program się po porostu nie kończy jak juz wszystko wypisze?

0

Po pobieżnym przeanalizowaniu uważam, że problem leży w pętli while- zapewne skopałeś ten warunek. Pętla for na pewno zostanie przerwana po 14 obiegach - więc problem powinien być wyżej..

0

no właśnie nie. ten warunek musi tak wyglądać. Co ciekawe program sie zatrzymuje gdy wpiszę się resztę np. 179 groszy przy okrągłej kwocie nie ma problemu o.O

0

Najwyraźniej nie musi,skoro jak sam stwierdziłeś program się nie kończy. Pętla for na pewno się zakończy. Pozostaje tylko while.

2

Nie rozumiesz jak działają liczby zmiennoprzecinkowe. One nie są dokładne - na pewno nie wolno ich używać do reprezentacji pieniędzy. Dodaj sobie linijkę cout << "cash = " << cash << endl; pod koniec pętli i zobacz co się stanie. Reprezentuj wszystkie kwoty w groszach (int), a problemu nie będzie.

Poza tym, ten kod aż się prosi o mały refaktor + zmianę algorytmu na zachłanny.

#include <iostream>
using namespace std;

struct nominal {
    int value;
    string name;
};

int main() {
    static const nominal NOMINALS[] = {
        { 20000, "200 zl" }, { 10000, "100 zl" }, { 5000, "50 zl" },
        { 2000, "20 zl" }, { 1000, "10 zl" }, { 500, "5 zl" }, { 200, "2 zl" },
        { 100, "1 zl" }, { 50, "50 gr" }, { 20, "20 gr" }, { 10, "10 gr" },
        { 5, "5 gr" }, { 2, "2 gr" }, { 1, "1 gr" },
    };

    cout << "Podaj kwote w groszach: " << flush;

    int kwota;
    if (!(cin >> kwota)) {
        cerr << "Podales niewlasciwa kwote." << endl;
        return 9;
    }
    if (kwota < 0) {
        cerr << "Podales ujemna kwote." << endl;
        return 7;
    }

    for (const nominal &nom : NOMINALS) {
        while (kwota >= nom.value) {
            cout << nom.name << endl;
            kwota -= nom.value;
        }
    }

    return 0;
}
1

A dopisz sobie po pętli for

cout << cash << endl;

Co się ukaże? Dużo razy powtórzone coś w stylu 1.23e-06. Czyli jakaś bardzo mała wartość. Dlaczego? Musiałbyś spojrzeć dokładniej na to jak procesor liczy liczby zmienno przecionkowe. Jednym słowem, niedokładnie. Jeżeli wszystkie obliczenia będziesz wykonywał na int ( na groszach ), problem się nie powtórzy :)
Jeżeli nie jest to niezbędne, unikaj licz zmiennoprzecinkowych jak ognia. Rozwiązaniem alternatywnym jest

while(cash<0.01)

</del> ```cpp while(cash>0.01) ``` Ale, mam nadzieję, sam przyznasz że wygląda to trochę nieelegancko :)

UP
Za wolno piszę posty... :/

0

ok macie racje z liczbami zmiennoprzecinkowymi. zapomniełem o tym ze matematyka w komputerze nie jest ciągła.. dzięki :)

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