Problem mit Kommazahlen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Tyroun
User
Beiträge: 16
Registriert: Montag 27. April 2020, 17:14

Guten Abend,

ich habe ein Problem mit meinem Code, welcher hier drunter steht:

Code: Alles auswählen

def countCoins(pay, cost):
    coins = [2, 1, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01]
    changemoney = pay - cost
    count = 0

    while changemoney > 0.1:
        for x in coins:
            r = divmod(changemoney, x)
            count = count + r[0]
            changemoney = r[1]

    return count

print(countCoins(2.0, 1.30))
Die Funktion soll, am Ende zurückgeben wie viele Münzen man benötigt um das Wechselgeld rauszugeben. Nun meine Frage und zwar, ist in de Variable changemoney das Wechselgeld gespeichert, was in den meisten Fällen eine Kommazahl ist. in dem Beispiel oben ist dann das Problem, dass wenn divmod durchgelaufen ist mit 0.5 zum Beispiel ist der neue Wert von changemoney dann 0.199999999 .... obwohl es ja eigentlich 0.2 sind. Dadurch das der wert so komisch ist kommt da auch nie das richtige Ergebnis raus. Kann mir jemand helfen, wie ich das richtig hinbekomme?

MfG
Tyroun
Benutzeravatar
snafu
User
Beiträge: 6870
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Schau dir das decimal-Modul an. Das ist genau für solche Probleme gedacht. Ganz wichtig dabei ist, dass du die Kommazahlen als Strings übergeben musst. Andernfalls ist die Zahl schon "falsch", noch bevor sie beim Decimal-Objekt ankommt und damit wäre nichts gewonnen.

Alternativ dazu könntest du die Ergebnisse auch runden lassen mit round(). Dann aber sinnvollerweise wirklich jedes Zwischenergebnis, damit es zu keinen größeren Ungenauigkeiten kommt.
narpfel
User
Beiträge: 691
Registriert: Freitag 20. Oktober 2017, 16:10

Oder einfach in Cents rechnen. 1,495 € wird man ja eher nicht mit Münzen bezahlen müssen. :)
Benutzeravatar
snafu
User
Beiträge: 6870
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

narpfel hat geschrieben: Montag 26. Oktober 2020, 22:39 Oder einfach in Cents rechnen.
Ganz genau. Klassischer Erstsemester-Stoff im Informatik-Studium und anderswo. :geek:
Sirius3
User
Beiträge: 18273
Registriert: Sonntag 21. Oktober 2012, 17:20

Die while-Schleife ist falsch und überflüssig. Funktionsnamen schreibt man wie Variablennamen komplett klein count_coins. `x` ist ein schlechter Name für einen coin.

Code: Alles auswählen

COINS = [200, 100, 50, 20, 10, 5, 2, 1]
def count_coins(pay, cost):
    changemoney = round(100 * (pay - cost))
    count = 0
    for coin in COINS:
        amount, changemoney = divmod(changemoney, coin)
        count += amount
    return count
Tyroun
User
Beiträge: 16
Registriert: Montag 27. April 2020, 17:14

Sirius3 hat geschrieben: Montag 26. Oktober 2020, 23:03 Die while-Schleife ist falsch und überflüssig. Funktionsnamen schreibt man wie Variablennamen komplett klein count_coins. `x` ist ein schlechter Name für einen coin.

Code: Alles auswählen

COINS = [200, 100, 50, 20, 10, 5, 2, 1]
def count_coins(pay, cost):
    changemoney = round(100 * (pay - cost))
    count = 0
    for coin in COINS:
        amount, changemoney = divmod(changemoney, coin)
        count += amount
    return count
Vielen Dank :)
So wie du es geschrieben hast ist natürlich smarter und ich habe es kapiert :D

MFG
Tyroun
User
Beiträge: 16
Registriert: Montag 27. April 2020, 17:14

snafu hat geschrieben: Montag 26. Oktober 2020, 22:17 Schau dir das decimal-Modul an. Das ist genau für solche Probleme gedacht. Ganz wichtig dabei ist, dass du die Kommazahlen als Strings übergeben musst. Andernfalls ist die Zahl schon "falsch", noch bevor sie beim Decimal-Objekt ankommt und damit wäre nichts gewonnen.

Alternativ dazu könntest du die Ergebnisse auch runden lassen mit round(). Dann aber sinnvollerweise wirklich jedes Zwischenergebnis, damit es zu keinen größeren Ungenauigkeiten kommt.
Hallo, danke ich werde mir das Modul man anschauen und durchlesen :)

MfG
Antworten