![]() |
Problem mit aneinandergereihten while-Schleifen
Hallo liebes Delphi-Praxis Team,
in der Schule sollen wir ein Programm schreiben, welches einen Eurobetrag einliest und dem Nutzer dann anzeigt, wieviel Scheine und Münzen mindestens benötigt werden, um die eingegebene Summe zu erreichen. Soweit so gut. Ich habe das ganze versucht mit while- Schleifen umzusetzen (x sind die Scheine, y die Münzen, b der Geldbetrag): Zitat:
Beträgen die Anzeige der benötigten Münzen nicht stimmt und meist zu wenig sind (z.B. bei 3,01; 3,56; 23,56). Ich weiß aber absolut nicht woran es liegt. Meistens funktioniert es ja. Besonders auffällig ist, dass solche Fehler eben bei 3,xx auftreten oder x3,xx, was mich zunächst vermuten ließ, dass es an den Abschnitten, in denen 1€ und 2€ Beträge behandelt werden, liegt, bzw. auch 1ct Beträge. So wird bei der eingabe 0,01€ auch angezeigt, dass 0 Münzen benötigt werden. Aber warum? :wall: Ich hoffe, ihr könnt einem Anfänger weiterhelfen. Ich bin natürlich auch offen für while-Alternativen. Trotzdem hätte ich gern gewusst, wo mein Fehler liegt :) Liebe Grüße das verzweifelte Giertier ^^ |
Re: Problem mit aneinandergereihten while-Schleifen
Hallo
Das liegt an der internen Genauigkeit... Versuch mal
Delphi-Quellcode:
und
function RealComp(r1,r2:real):boolean;
Var S1,S2 : shortstring; begin if r2 = 0.0 then r1 := abs(R1); Str(R1:10:2,S1); Str(R2:10:2,S2); RealComp := Boolean( S1 = S2 ); end;
Delphi-Quellcode:
Dann funktioniert es!
WHILE (b>0.01) or realcomp(b,0.01) DO BEGIN
Grüsse Mavarik :coder: |
Re: Problem mit aneinandergereihten while-Schleifen
Cool, vielen dank. Funktioniert prima. Jetzt hätte ich nur noch eine riesengroße
Bitte :-D . Könntest du mir erklären, was insbesondere die function genau macht? Bin echt noch Anfänger, würde aber gern verstehen, was du da gemacht hast und vor allem, warum es jetzt funktioniert ;) (zu realcomp finde ich z.B. nicht mal was in der Hilfe :(, kann aber auch sein, dass ich mich einfach zu blöd anstelle ;) ) Zitat:
überall hinzuschreiben? Vielen Dank nochmal für deine schnelle und hilfreiche Antwort :) |
Re: Problem mit aneinandergereihten while-Schleifen
Hi!
hmm, einfach ausgedrückt: Die interne Speicherung der Real-Werte hat zwar ein Hohe Genaueigkeit, aber kann bei einem Vergleich auch genau die Tücke sein. Das liegt an der Abbildung der Zahlen. Eigentlich wäre es so: A = 0.01000000001 if A = 0.01 then Verstanden? Daher "Runde" ich die Real-Werte durch die Umwandlung in einen String und Vergleiche dann die Strings... Daher auch der Vergeleich mit 0.0 da eine Real-Variable gerne mal -0.00 ist.. A = -0.00 if A = 0.0 then ggf. False! Grüsse Mavarik |
Re: Problem mit aneinandergereihten while-Schleifen
Hallo Giertier,
ich sehe folgende zwei Möglichkeiten für dich. du nimmst CompareValue, da läßt sich die Genauigkeit beim Vergeich als Parameter mit angeben, oder du rechnest alle Beträge in Cent um, dann kannst du wiederum mit Integervariablen rechnen und das Problem mit der Genauigkeit ist weg (natürlich unter der Voraussetzung, dass der zu untersuchende Betrag immer höchstens auf den Cent genau ist und nicht noch genauer). Viele Grüße Delphiano :coder: |
Re: Problem mit aneinandergereihten while-Schleifen
Zitat:
Sollte das nicht besser sein als 2 Stringoperationen? |
Re: Problem mit aneinandergereihten while-Schleifen
Hallo Giertier,
du solltest, wie schon in einem vorhergehenden Beitrag vorgeschlagen, den Betrag in Cent umrechnen und in eine Integer-Variable stellen. Als Optimierung kannst du, statt in While-Schleifen den Betrag um den Wert einer Banknote/Münze zu senken und x/y zu erhöhen, so vorgehen : 1) x, bzw y, um (betrag div WertDerMünze) erhöhen. 2) betrag = (betrag mod WertDerMünze) setzen. Bei deiner Methode, kannst du bei sehr hohen Beträgen mit einem etwas höheren Zeitbedarf rechnen. Beispiel :
Delphi-Quellcode:
PROCEDURE TMain.Test;
const cnotes:array[0..6] of integer=(5,10,20,50,100,200,500); ccoins:array[0..7] of integer=(1,2,5,10,20,50,100,200); var i,amount,coins,notes:integer; FUNCTION DivMod(var value:integer; divisor:integer):integer; begin result:=value div divisor; value:=value mod divisor; end; begin amount:=Trunc(StrToFloat(edit1.text)+0.5); coins:=0; notes:=0; for i:=high(cnotes) downto 0 do inc(notes,DivMod(amount,cnotes[i]*100)); for i:=high(ccoins) downto 0 do inc(coins,DivMod(amount,ccoins[i])); edit2.text:=IntToStr(notes); edit3.text:=IntToStr(coins); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:54 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 by Thomas Breitkreuz