![]() |
Delphi-Version: 5
Geldautomat
Liste der Anhänge anzeigen (Anzahl: 1)
Hey Leute,
Im Anhang findet ihr einen von mir programmierten kleinen "Geldautomat". (Hausaufgabe) Man gibt einen Preis ein und einen Schein, mit dem man bezahlt. Mit Hilfe von While-Do-Schleifen soll dann der "Automat" Kleingeld in einer Listbox ausgeben, mit möglichst wenig Münzen. Dies klappt auch soweit, aber wenn man z.B. den Preis von 4,98€ eingibt (10-Euroschein) vergisst er einen cent. Und bei 4,99 ebenfalls. Bei 4.97 stimmts allerdings wieder. Woran könnte das liegen? Hier mein Quelltext:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var S:integer; Preis:real; R:real; begin Preis:=strtofloat(edit1.text); S:=strtoint(edit2.text); listbox1.clear; R:=S-Preis; if (R<9.99) then begin While R>=2 Do begin listbox1.Items.add('2-Euro-Stück'); R:=R-2; end; While R>=1 Do begin listbox1.Items.add('1-Euro-Stück'); R:=R-1; end; While R>=0.5 Do begin listbox1.Items.add('50-cent-Stück'); R:=R-0.5; end; While R>=0.2 Do begin listbox1.Items.add('20-cent-Stück'); R:=R-0.2; end; While R>=0.1 Do begin listbox1.Items.add('10-cent-Stück'); R:=R-0.1; end; While R>=0.05 Do begin listbox1.Items.add('5-cent-Stück'); R:=R-0.05; end; While R>=0.02 Do begin listbox1.Items.add('2-cent-Stück'); R:=R-0.02; end; While R>=0.01 Do begin listbox1.Items.add('1-cent-Stück'); R:=R-0.01; end; end else application.messagebox('Der Automat gibt ausschließlich Kleingeld und nur bis 9,99€.','Stop!',mb_ok) end; end. p.s. R = Rückgeld S = Schein |
AW: Geldautomat
Bei 4,97 stimmt es, weil dabei keinerlei Ein-Cent-Stück ausbezahlt werden. War schon ein Wink mit dem Zaunpfahl, wo das Problem liegt, oder? ;)
--EDIT Noch ein Tipp: Gleitkommazahlen sollte man nie mit "=" vergleichen (also z.B. [delphi]a = 0.01[/delphi)), ![]() Wenn du dennoch mit Real-Werten arbeiten willst, dann schau dir mal die CompareValue-Methoden an. Vielleicht musst du dazu die Math-Unit einbinden. |
AW: Geldautomat
Oder halt Currency als Datentyp nutzen?! :-D
PS: Man könnte die fast immer gleiche Schleife auch in eine Funktion auslagern ... macht's vlt. übersichtlicher. |
AW: Geldautomat
|
AW: Geldautomat
Und bei 4,96 stimmts auch? - Wenn nicht liegts an der Genauigkeit deiner Zahlen.
Bernhard |
AW: Geldautomat
Ok danke für die schnellen Antworten...
aber @s.h.a.r.k: Ich meinte mit 4.97 den Preis d.h. das Rückgeld beträgt 5.03 und da wird ein cent ausgezahlt... Es klappt wirklich alles wies klappen soll außer das er manchmal n cent verschluckt... Ich glaube kaum das das was mit Real und Currency zutun hat...aber danke für den Hinweis ;) Frage mich immer noch woran das hängen könnte... Gruß Edit: Wie ich sehe hat noch niemand das Programm sich angeschaut, ich würds empfelen vll. kommt ihr dann drauf... |
AW: Geldautomat
Zitat:
EDIT: Wenn du das gemacht hast, können wir evtl. nochmal über Genauigkeit diskutieren. |
AW: Geldautomat
Ok ich muss mich entschuldigen :D
Ihr hattet recht...unglaublich das das DARAN jetzt was geändert hat...ich versteh allerdings immer noch nicht warum ?! gruß |
AW: Geldautomat
Einige Zahlen die im Dezimalsystem ohne nicht periodisch sind, sind periodisch in der Binärdarstellung (genau wie 1/3 = 0,3 im Dezimalsystem):
0,1d = 0,0000110b Da man aber nur einen bestimmten Platz hat, kann man nicht alle Stellen speichern. Deshalb gibt es Ungenauigkeiten. ![]() Currency vermeidet diese Ungenauigkeit, indem es die Nachkommastellen ![]() |
AW: Geldautomat
ahh ok danke ;)
|
AW: Geldautomat
Um genau zu sein ist Currency eine
![]() Und wie gesagt: Die Schleifen bieten sich geradezu an, in eine Funktion ausgelagert zu werden. Und auch die Strings wie "2-Euro-Stück" könnte man automatisch erzeugen. :-D |
AW: Geldautomat
Kann man nicht das ganze mit nur einer Schleife lösen?
Delphi-Quellcode:
Mach den Code jetzt auch nicht schöner, aber man hat nur eine Schleife...
while R<> 0 do
begin if R>2 then begin listbox.Add ...; R=R-2; end else if R>1 then begin listbox.Add ...; R=R-1; end else if ... end Oder hab ich da jetzt einen Denkfehler drin? |
AW: Geldautomat
Zitat:
|
AW: Geldautomat
@Jumpy:
Mh, sollte gehen. Aber was hat man davon? Es sind immer noch zig Redundanzen drin. Darum sagte ich ja auch auslagern in eine Funktion ^^ |
AW: Geldautomat
Evtl. so?
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
//aus Bequemlichkeitsgründen Konstanten definiert statt Eingaben auszuwerten const Preis = 5.01; Einwurf = 10; var Rest: Currency; begin ListBox1.Items.BeginUpdate; try Rest := Einwurf - Preis; Rueckgabe(trunc(Rest * 100)); finally ListBox1.Items.EndUpdate; end; end; procedure TForm1.Rueckgabe(WertInCent: integer); begin if WertInCent > 0 then case WertInCent of 1: begin ListBox1.Items.Add('1 Cent'); Rueckgabe(WertInCent - 1); end; 2 .. 4: begin ListBox1.Items.Add('2 Cent'); Rueckgabe(WertInCent - 2); end; 5 .. 9: begin ListBox1.Items.Add('5 Cent'); Rueckgabe(WertInCent - 5); end; 10 .. 19: begin ListBox1.Items.Add('10 Cent'); Rueckgabe(WertInCent - 10); end; 20 .. 49: begin ListBox1.Items.Add('20 Cent'); Rueckgabe(WertInCent - 20); end; 50 .. 99: begin ListBox1.Items.Add('50 Cent'); Rueckgabe(WertInCent - 50); end; 100 .. 199: begin ListBox1.Items.Add('1 Euro'); Rueckgabe(WertInCent - 100); end; else begin ListBox1.Items.Add('2 Euro'); Rueckgabe(WertInCent - 200); end; end; end; |
AW: Geldautomat
Zitat:
Delphi-Quellcode:
Ungetestet, aber so ist meine Vorstellung :-D
procedure TForm1.WechselgeldAusgeben(var ABetrag: Currency; AMuenzwert: Currency);
begin While ABetrag >= AMuenzwert do begin ABetrag := ABetrag - AMuenzwert; If AMuenzwert >= 1 then ListBox1.Items.Add(Format('%d-Euro-Stück', [Round(AMuenzwert)])) else ListBox1.Items.Add(Format('%d-Cent-Stück', [Round(AMuenzwert * 100)])); end; end; procedure TForm1.Button1Click(Sender: TObject); var S: Integer; Preis, R: Currency; begin Preis := StrToCurr(Edit1.Text); S := StrToInt(Edit2.Text); ListBox1.Clear; R := S - Preis; If R > 9.99 then raise Exception.Create('Der Automat gibt ausschließlich Kleingeld und nur bis 9,99€.'); WechselgeldAusgeben(R, 2.00); WechselgeldAusgeben(R, 1.00); WechselgeldAusgeben(R, 0.50); WechselgeldAusgeben(R, 0.20); WechselgeldAusgeben(R, 0.10); WechselgeldAusgeben(R, 0.05); WechselgeldAusgeben(R, 0.02); WechselgeldAusgeben(R, 0.01); end; So kann man einfach verfügbare Münzen hinzufügen, entfernen oder ändern, ohne die Schleife in dem der Münzwert drei mal redundant vorkommt anfassen zu müssen. Durch die Redundanz in der ursprünglichen Implementation schleichen sich sonst seeehr leicht Fehler ein. |
AW: Geldautomat
Wenn man den Betrag in Cent hat (also Eingabe*100) und das dann irgendwie in Integer umwandelt ginge auch:
Delphi-Quellcode:
var
R,a : Integer; M : array[1..8] begin M[1]=200;M[2]=100;M[3]=50;M[4]=20;M[5]=10;M[6]=5;M[7]=2;M[8]=1; R=CurrencyToInt(RückgeldInEuro * 100); //CurrencyToInt ??? s.o. for i = 1 To 8 do begin a:=R div M[i]; R:=R-a; if a > 0 then begin if M[i] >= 100 then ListBox1.Items.Add(IntToStr(M[i]/100)+'-Euro-Stück: '+IntToSTr(a)+'x') else ListBox1.Items.Add(IntToStr(M[i])+'-Cent-Stück: '+IntToSTr(a)+'x'); end; end; end |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:20 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz