Seite 1 von 1

Falsche Ergebnisse mit round()

Verfasst: Dienstag 14. Februar 2017, 10:00
von Pykons
Hallo an alle! :D

Ich arbeite jetzt seit knapp einem halben Jahr mit Python und bisher mache ich (eigentlich) gut und schnell Fortschritte und bin von Python begeistert!
Während ich ein neues Programm geschrieben habe bin ich nun auf folgendes Problem gestoßen, was ich mir nicht erklären und auch leider nicht lösen kann:

Die Funktion round() rundet bei mir nicht immer ab 5 auf, sondern gerne auch mal ab. Habe dazu mal ein kurzes Testprogramm geschrieben, das mein Problem verdeutlichen soll:

Code: Alles auswählen

i=50
while i<=1000:
    print(str(i)+"\t-->\t"+str(round(i,-2)))
    i=i+100
Als Ergebnis bekomme ich:
  • 50 --> 0
    150 --> 200
    250 --> 200
    350 --> 400
    450 --> 400
    550 --> 600
    650 --> 600
    750 --> 800
    850 --> 800
    950 --> 1000
Nehmen wir z.B. die Werte 150 und 250. Bei 150 rundet Python brav auf 200 auf, allerdings bei 250 nicht auf 300 auf, sondern auf 200 ab.
Hat jemand eine Idee, woran das liegen könnte? Und vor allem, wie kann ich das beheben? :K

(Ich arbeite mit Python 3.5.3, habe extra grad nochmal Python upgedatet, um ausschließen zu können, dass es an einer veralteten Version liegt...allerdings ohne Erfolg)

Vielen Dank schonmal für eure Hilfe!!

Re: Falsche Ergebnisse mit round()

Verfasst: Dienstag 14. Februar 2017, 10:22
von kbr
Pykons hat geschrieben:Nehmen wir z.B. die Werte 150 und 250. Bei 150 rundet Python brav auf 200 auf, allerdings bei 250 nicht auf 300 auf, sondern auf 200 ab.
Hat jemand eine Idee, woran das liegen könnte? Und vor allem, wie kann ich das beheben?
Das kannst Du nicht beheben, da dies ein Feature ist, das mit Python 3.5 eingeführt wurde. Gerundet wird alternierend stets auf die nächste gerade Zahl. Dieses Vorgehen kommt aus der Finanzbranche und dient dazu, bei der Akkumulation von gerundeten Werten den Gesamtfehler möglichst gering zu halten.

Re: Falsche Ergebnisse mit round()

Verfasst: Dienstag 14. Februar 2017, 10:29
von Pykons
Hallo kbr, danke für die schnelle Antwort!

Hab das Problem jetzt für mich soweit umgangen:

Code: Alles auswählen

i=50
while i<=1000:
    if i%100==50:
        print(str(i)+"\t-->\t"+str(i+50))
    else:
        print(str(i)+"\t-->\t"+str(round(i,-2)))
    i=i+100
Das funktioniert für meinen Anwendungsfall gut. Allerdings frage ich mich jetzt grade, ob es in Python noch eine weitere Funktion neben round() gibt, die mathematisch korrekt rundet und eben nicht wirtschaftsmathematisch (wenn man das so sagen kann)...?!

Und wann rundet round() auf und ab? Steckt dahinter ein Prinzip, oder ist das reiner Zufall, ob bei 150 auf 200 oder 100 gerundet wird?

Re: Falsche Ergebnisse mit round()

Verfasst: Dienstag 14. Februar 2017, 10:43
von Sirius3
@Pykons: was richtiges Runden ist, ist eben Definitionssache. Das Runden, das man aus der Schule kennt, hat eben unschöne Eigenschaften: gerundete Zahlen sind, statistisch gesehen, größer. Das bessere Runden heißt, zur nächsten geraden Zahl runden; so weder statistisch gesehen die Hälfte der Zahlen größer und die andere Hälfte kleiner. Die Frage ist also, warum Du unbedingt auf dieses unschöne Runden beharren willst.

Re: Falsche Ergebnisse mit round()

Verfasst: Dienstag 14. Februar 2017, 10:56
von BlackJack
Zum warum und warum das nicht falsch ist: Die Dokumentation zu `round()` dokumentiert das Verhalten ausdrücklich so und dann sollte sich die Funktion auch wirklich so Verhalten. Sonst wär's ein Bug. :-)

Re: Falsche Ergebnisse mit round()

Verfasst: Dienstag 14. Februar 2017, 12:50
von Pykons
Sirius3 hat geschrieben:Die Frage ist also, warum Du unbedingt auf dieses unschöne Runden beharren willst.
Ich möchte einen Graphen plotten, dazu bestimme ich den maximalen Y-Wert und möchte den aufrunden, um die Y-Achse sauber zu beschriften. Daher reicht meine Lösung, wie oben beschrieben, auch vollkommen aus und ich löse das "Problem" auf meine Weise. Wollte aber für zukünftige Berechnungen in Python einfach mal erfragen, weshalb round() die besagten Ergebnisse ausspuckt.
BlackJack hat geschrieben:Die Dokumentation zu `round() dokumentiert das Verhalten ausdrücklich so und dann sollte sich die Funktion auch wirklich so Verhalten. Sonst wär's ein Bug. :-)
Da hast du recht, die hatte ich nicht gelesen. Bisher habe ich immer mit einem Buch gelernt und dort recherchiert. Dort war nur von "runden" die Rede, daher meine Annahme, dass es sich um das Runden, was man aus der Schulzeit kennt, handeln würde. :D

Re: Falsche Ergebnisse mit round()

Verfasst: Dienstag 14. Februar 2017, 13:42
von Sirius3
@Pykons: wenn Du immer aufrunden möchtest, dann willst Du vielleicht `math.ceil` verwenden.

Re: Falsche Ergebnisse mit round()

Verfasst: Dienstag 14. Februar 2017, 14:13
von Pykons
Das Problem ist aber, dass ich die zweite Stelle vor dem Komma runden möchte. Also beispielsweise von 350 auf 400. Ich kann bei ceil im Gegensatz zu round aber nur ein Argument angeben. Den Vorteil, den ich bei round gesehen habe war, dass ich auch angeben kann, auf welche Stelle ich runden möchte - also:

Code: Alles auswählen

round(350,-2)
Oder geht das bei ceil auch und ich hab es bisher einfach nicht geschnallt/richtig gemacht?

Re: Falsche Ergebnisse mit round()

Verfasst: Dienstag 14. Februar 2017, 15:18
von BlackJack
@Pykons: Man muss halt noch ein bisschen rechnen wenn man `ceil()` verwendet. Kann man ja in einer eigenen Rundungsfunktion ”verstecken”.

Re: Falsche Ergebnisse mit round()

Verfasst: Sonntag 26. Februar 2017, 16:03
von pixewakb
BlackJack hat geschrieben:Kann man ja in einer eigenen Rundungsfunktion ”verstecken”.
In dem Fall würde ich direkt eine eigene Rundungsfunktion schreiben, die fas für mich sinnvoll löst...