Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Ćwiczenie z pieniędzmi - nie mogę znaleźć błędu

Ostatnio zmodyfikowano 2013-01-29 18:23
Autor Wiadomość
Berux
Temat założony przez niniejszego użytkownika
Ćwiczenie z pieniędzmi - nie mogę znaleźć błędu
» 2013-01-28 22:47:01
Witam. Przed chwilą zabrałem się do pisania programu - ćwiczenia, którego zadanie polega na obliczaniu jakimi pieniędzmi należy zapłacić daną kwotę tak, aby dać najmniej "przedmiotów". Może trochę nie zrozumiale napisane, ale wytłumaczę to przykładem:

Mamy zapłacić 22.05 zł.
Możemy to zrobić np. za pomocą tych pieniędzy:
10 zł + 10 zł + 2 zł + 5 gr.
Program ma jednak za zadanie użycia,że tak powiem najmniej pieniędzy. Byłoby to więc:
20 zł + 2 zł + 5 gr.

Oto kod:

C/C++
#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
    double cena;
   
    cin >> cena;
   
    int dwiescie = 0;
    int sto = 0;
    int piecdziesiat = 0;
    int dwadziescia = 0;
    int dziesiec = 0;
    int piec = 0;
    int dwa = 0;
    int jeden = 0;
   
    int grosz50 = 0;
    int grosz20 = 0;
    int grosz10 = 0;
    int grosz5 = 0;
    int grosz2 = 0;
    int grosz1 = 0;
   
    while( true )
    {
        if( cena >= 200 )
        {
            dwiescie++;
            cena -= 200;
           
        }
       
       
        if( cena >= 100 && cena < 200 )
        {
            sto++;
            cena -= 100;
           
        }
       
        if( cena >= 50 && cena < 100 )
        {
            piecdziesiat++;
            cena -= 50;
           
        }
       
        if( cena >= 20 && cena < 50 )
        {
            dwadziescia++;
            cena -= 20;
           
        }
       
        if( cena >= 10 && cena < 20 )
        {
            dziesiec++;
            cena -= 10;
           
        }
       
        if( cena >= 5 && cena < 10 )
        {
            piec++;
            cena -= 5;
           
        }
       
        if( cena >= 2 && cena < 5 )
        {
            dwa++;
            cena -= 2;
           
        }
       
        if( cena >= 1 && cena < 2 )
        {
            jeden++;
            cena -= 1;
           
        }
       
        if( cena >= 0.5 && cena < 1 )
        {
            grosz50++;
            cena -= 0.5;
           
        }
       
        if( cena >= 0.2 && cena < 0.5 )
        {
            grosz20++;
            cena -= 0.2;
           
        }
       
        if( cena >= 0.1 && cena < 0.2 )
        {
            grosz10++;
            cena -= 0.1;
           
        }
       
        if( cena >= 0.05 && cena < 0.1 )
        {
            grosz5++;
            cena -= 0.05;
           
        }
       
        if( cena >= 0.02 && cena < 0.05 )
        {
            grosz2++;
            cena -= 0.02;
           
        }
       
        if( cena >= 0.01 && cena < 0.02 )
        {
            grosz1++;
            cena -= 0.01;
           
        }
       
        if( cena == 0 )
             break;
       
    }
   
    cout << "200zl: " << dwiescie
    << "\n100zl: " << sto
    << "\n50zl: " << piecdziesiat
    << "\n20zl: " << dwadziescia
    << "\n10zl: " << dziesiec
    << "\n5zl: " << piec
    << "\n2zl: " << dwa
    << "\n1zl: " << jeden
    << "\n50gr: " << grosz50
    << "\n20gr: " << grosz20
    << "\n10gr: " << grosz10
    << "\n5gr: " << grosz5
    << "\n2gr: " << grosz2
    << "\n1gr: " << grosz1 << endl;
   
    system( "pause" );
   
    return 0;
}

Problem polega na tym, że jak wpiszę 0.3 lub 0.7, itd. to program nic nie robi. Rozumiem, że te  ponad 150 linijek kodu może zniechęcić, jednakże proszę o wyprowadzenie mnie z błędu. Z góry dzięki.
P-75278
jsc
» 2013-01-28 23:24:21
Dziwny błąd, w ogóle wiesza się na liczbach nie z ułamkiem dziesiętnym.
P-75280
Schulze13
» 2013-01-28 23:24:35
Sprawdziłem kod i błąd jest natury logicznej, czyli najtrudniejszy do wykrycia. Proponuje Ci sprawdzić co się dzieje z ceną podczas podliczania monet: wstaw cout << cena; do pętli. Będziesz mógł zobaczyć, że problem jest z nieszczęsną 1 groszówką i dalej pokombinuj sam :). Mi udało się rozwiązać ten problem.
P-75281
crash
» 2013-01-28 23:26:10
Po pierwsze, ja też lubię klepać w klawiaturę zwłaszcza programując, ale nie odważyłbym się tyle razy z rzędu napisać int int int int. Można ładnie w jednej linijce:

int a = 0, b = 0, c = 0, d = 0, e, f, g, h = 0, i, j, k = 0;

Można mieszać deklaracje z inicjalizacjami.

Po drugie, int przechowuje liczby całkowite i tylko całkowite! Do zmiennoprzecinkowych służą typy float oraz double.
P-75282
Schulze13
» 2013-01-28 23:29:08
@up typy są poprawne. Te wszystkie zmienne int przechowują ilość monet, a nie kwotę, ale muszę się zgodzić, można wszystko w jednej linii.
P-75283
crash
» 2013-01-28 23:45:30
Fakt, mój błąd, sorka ;p

Zmodyfikowałem kod i patrzta jaka akcja, lol:

C/C++
#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
    double cena;
   
    cin >> cena;
   
    int dwiescie = 0;
    int sto = 0;
    int piecdziesiat = 0;
    int dwadziescia = 0;
    int dziesiec = 0;
    int piec = 0;
    int dwa = 0;
    int jeden = 0;
   
    int grosz50 = 0;
    int grosz20 = 0;
    int grosz10 = 0;
    int grosz5 = 0;
    int grosz2 = 0;
    int grosz1 = 0;
   
    while( true )
    {
        cout << "\n@@@@@@\n";
        if( cena >= 200 )
        {
            dwiescie++;
            cena -= 200;
           
        }
        cout << "\n200: " << cena;
       
        if( cena >= 100 && cena < 200 )
        {
            sto++;
            cena -= 100;
           
        }
        cout << "\n100:" << cena;
        if( cena >= 50 && cena < 100 )
        {
            piecdziesiat++;
            cena -= 50;
           
        }
        cout << "\n50:" << cena;
        if( cena >= 20 && cena < 50 )
        {
            dwadziescia++;
            cena -= 20;
           
        }
        cout << "\n20:" << cena;
        if( cena >= 10 && cena < 20 )
        {
            dziesiec++;
            cena -= 10;
           
        }
        cout << "\n10:" << cena;
        if( cena >= 5 && cena < 10 )
        {
            piec++;
            cena -= 5;
           
        }
        cout << "\n5:" << cena;
        if( cena >= 2 && cena < 5 )
        {
            dwa++;
            cena -= 2;
           
        }
        cout << "\n2:" << cena;
        if( cena >= 1 && cena < 2 )
        {
            jeden++;
            cena -= 1;
           
        }
        cout << "\n1:" << cena;
        if( cena >= 0.5 && cena < 1 )
        {
            grosz50++;
            cena -= 0.5;
           
        }
        cout << "\n0.5:" << cena;
        if( cena >= 0.2 && cena < 0.5 )
        {
            grosz20++;
            cena -= 0.2;
           
        }
        cout << "\n0.2:" << cena;
        if( cena >= 0.1 && cena < 0.2 )
        {
            grosz10++;
            cena -= 0.1;
           
        }
        cout << "\n0.1:" << cena;
        if( cena >= 0.05 && cena < 0.1 )
        {
            grosz5++;
            cena -= 0.05;
           
        }
        cout << "\n0.5:" << cena;
        if( cena >= 0.02 && cena < 0.05 )
        {
            grosz2++;
            cena -= 0.02;
           
        }
        cout << "\n0.2:" << cena;
        if( cena >= 0.01 && cena < 0.02 )
        {
            grosz1++;
            cena -= 0.01;
           
        }
        cout << "\nKONIEC PRZEBIEGU:" << cena << endl << "napisz cos i enter\n";
        char c;
        cin >> c;
       
    }
   
    cout << "200zl: " << dwiescie
    << "\n100zl: " << sto
    << "\n50zl: " << piecdziesiat
    << "\n20zl: " << dwadziescia
    << "\n10zl: " << dziesiec
    << "\n5zl: " << piec
    << "\n2zl: " << dwa
    << "\n1zl: " << jeden
    << "\n50gr: " << grosz50
    << "\n20gr: " << grosz20
    << "\n10gr: " << grosz10
    << "\n5gr: " << grosz5
    << "\n2gr: " << grosz2
    << "\n1gr: " << grosz1 << endl;
   
    system( "pause" );
   
    return 0;
}

EDIT: Zdaje mi się, że najlepiej jest policzyć osobno rozkład złotówek i osobno groszy. Takie moje małe zdajemisię
P-75285
Schulze13
» 2013-01-28 23:58:02
crash, twój kod jest magiczny, a przynajmniej wyniki. Nie wiem co tam zrobiłeś, ale mniejsza. Program można poprawić zmieniając jeden if() :D (zawrze mogę się mylić bo jestem noobem)
P-75287
ison
» 2013-01-29 00:01:30
Taki już urok liczb zmiennoprzecinkowych.
if( cena == 0 )
 taki zapis niekoniecznie robi to co chcesz aby robił (tzn. sam ten zapis może i tak, ale operacje arytmetyczne użyte wcześniej powodują, że niekoniecznie daje takie wyniki jakbyś chciał).
Liczby zmiennoprzecinkowe porównuj z jakimś epsilonem
if( fabs( cena ) < 0.001 )

To samo tyczy się innych ifów gdzie używasz operatorów >= <= ==
if( cena >= 0.01 )
 taki if powinien wyglądać tak
if( cena > 0.01 || fabs( cena - 0.01 ) < 0.001 )
 (gdzie 0.001 to epsilon)


Lepiej jednak gdybyś się nie bawił w liczby zmiennoprzecinkowe i rozpatrywał złotówki i grosze osobno
C/C++
int zl = 0, gr = 0;
scanf( "%d.%d", & zl, & gr );
P-75288
« 1 » 2
  Strona 1 z 2 Następna strona