c++ Berechnung funktioniert nicht richtig (falsches ergebnis)
-
Hallo zusammen.
Vorweg möchte ich sagen, das ich weis, das ich das ganze anders machen sollte, wie z.B. anstatt getch() - cin.get() oder anstatt if else - switch case verwenden sollte usw..
Aber bevor ich das ganze anpasse. Will ich erstmal den fehler wegbekommen, der da drin ist. Zudem gitb die Aufgabenstellung vor, das nur das Hauptmenu in int main() sein soll, alles andere soll in der funktion zahlvorgang() drin sein.
das Hauptmenu und alle eingaben funktionieren. aber in der Funktion zahlvorgang()
ergibt "zurueck=bezahlt-betrag" nicht 0, wenn ich im Hauptmenu den Kaffee oder Kakao auswähle und dann 7mal bzw. 8 mal "z" drücke.
Eigendlich müsste beim kaffee ("bezahlt-betrag" -> "0.7-0.7") 0 ergeben. es kommt aber 5.96046e-006 raus. Beim "Zitronentee" also 6 mal die "z" druecken kommt das richtige ergebniss raus.Lasse ich am Ende bezahlt und betrag ausgeben, steht auch 0.7 beim kaffee.
Was aber komisch ist, wähle ich Kaffee und bezahle einmal 50 Cent und dann 20 Cent also taste "w" und "f" dann kommt 0 raus.Ich hoffe mein Problem wurde gut genug geschildert.
Hier noch mein quellcode:
main.cpp#include <iostream> #include <conio.h> void zahlvorgang(float betrag); using namespace std; int main() { int pressed=0; int auswahl; float betrag=0; do { cout << "[1] Kaffee 0.70 Euro\n" "[2] Kakao 0.80 Euro\n" "[3] Zitronentee 0.60 Euro\n" " Bitte waehlen Sie ...\n"; pressed = getch(); if(pressed==27) { auswahl=false; } else { if(pressed==49) { betrag=0.7; auswahl=true; } else { if(pressed==50) { betrag=0.8; auswahl=true; } else { if(pressed==51) { betrag=0.6; auswahl=true; } else { cout << "\nfalsche Taste!!!\n\n"; auswahl=false; } } } } if(auswahl==true) { zahlvorgang(betrag); pressed=48; } }while(pressed!=27); return 0; } void zahlvorgang(float betrag) { float zahlung=0, bezahlt=0, nbezahlt=betrag, zurueck=0; int pressed; cout << "Wieviel moechten Sie einwerfen?\n" "z = 10 Cent\n" "w = 20 Cent\n" "f = 50 Cent\n" "1 = 1 Euro\n" "2 = 2 Euro\n"; do { pressed=getch();; if(pressed==122) { zahlung=0.1; } else { if(pressed==119) { zahlung=0.2; } else { if(pressed==102) { zahlung=0.5; } else { if(pressed==49) { zahlung=1; } else { if(pressed==50) { zahlung=2; } else { zahlung=0; } } } } } bezahlt=bezahlt+zahlung; nbezahlt=betrag-bezahlt; if(bezahlt<betrag) { cout << "Sie haben bisher bezahlt : " << bezahlt << " Euro \n" "Sie haben noch zu bezahlen : " << nbezahlt << " Euro \n" "Bitte werfen Sie eine Muenze in den Automaten !\n"; } }while(bezahlt<betrag); cout << "------------------------------------------------\n"; zurueck=bezahlt-betrag; if(zurueck==0) { cout << "Sie erhalten nichts zurueck.\n" "Bitte nehmen Sie Ihr Getraenk aus dem Automaten.\n"; } else { if(zurueck<1) { zurueck=zurueck*100; cout << "Sie erhalten " << zurueck << " Cent zurueck.\n" "Bitte nehmen Sie Ihr Getraenk aus dem Automaten.\n"; } else { cout << "Sie erhalten " << zurueck << " Euro zurueck.\n" "Bitte nehmen Sie Ihr Getraenk aus dem Automaten.\n"; } } getch(); }Ich verwende Dev-c++ 4.9.9.2 mit dem mitgelieferten Mingw compiler
-
Rechne mit Integer-Werten (Cent) statt Float-Werten (Euro), dann hast Du keine Probleme mit der Dir nicht vertrauten Float-Arithmetik.
-
Verändere in Zeile 122 die Abfrage nach
if(zurueck<=0.005)Das hat damit zu tun, dass ein Rechner, der intern binär arbeitet, z.B. die Zahl 0,1 nicht exakt darstellen kann. Wir hatten vor kurzem einen Thread zum Thema.
Beispiel:float betrag = 1.; for( int i=0; i<10; ++i ) betrag -= 0.1; if( betrag != 0.0 ) cout << "betrag = " << betrag << endl;.. das wird nie wieder ==0.0 - auch nicht wenn Du double benutzt.
In Deinem Fall ist es wohl am einfachsten, Du stellst intern auf Euro-Cent und den Datentyp int um. Ansonsten musst Du bei jedem Vergleich zweier Beträge die Rechenungenauigkeit einkalkulieren.
Gruß
Werner
-
Vielen dank, funktioniert. Was mir irgendwie nich einleuchtet, warum 0.7-0.7 nicht exakt 0 ergibt ^^. Naja mit der zeit werde ich das auch begreifen.
-
Thelo schrieb:
Vielen dank, funktioniert. Was mir irgendwie nich einleuchtet, warum 0.7-0.7 nicht exakt 0 ergibt ^^. Naja mit der zeit werde ich das auch begreifen.
Nun - weil 0,7-0,7 wirklich exakt 0 ist; in Deinem Programm aber 0,7-0,1-0,1-0,1-0,1-0,1-0,1-0,1 gerechnet wird; und das ist aus dem selben Grund nicht exakt 0, weil
0,5 - 1/6 - 1/6 - 1/6 = 0,5 - 0,1666667 - 0,1666667 - 0,1666667 = -0,0000001auch nicht exakt 0 ist.
Die Zahl 0,1 ist in Binärdarstellung %0,0(0011) - die () stehen für die Periode - z.B. 1/6 = 0,1(6) im Dezimalsystem
Gruß
Werner