Unterschiede bei der Ausgabe von round() in Python2.6/2.7

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
Reg
User
Beiträge: 10
Registriert: Samstag 9. Januar 2010, 15:25

Hallo,

mir aufgefallen, dass in Python2.6 Zahlen mit Nachkommastellen anders ausgegeben werden als in Python2.7.

Python2.6:

Code: Alles auswählen

Python 2.6.7 (r267:88850, Jul 10 2011, 08:11:54) 
[GCC 4.6.1] on linux2
>>> a = 11.123456
>>> round(a,2)
11.119999999999999
>>> round(a)
11.0
Python2.7:

Code: Alles auswählen

Python 2.7.2+ (default, Aug 16 2011, 09:23:59) 
[GCC 4.6.1] on linux2
>>> a = 11.123456
>>> round(a, 2)
11.12
>>> round(a)
11.0
Ich finde in der Dokumentation keinen Hinweis auf eine unterschiedliche Handhabung der Funktion.
Betriebsystem falls relevevant: Debian (testing, 64bit).

Hat jemand einen Hinweis?

Vielen Dank vorab!

Gruß
Reg
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Kann ich unter OS/X mit Python 2.5 bis 2.7 nicht nachvollziehen. Ist aber auch egal, denn es ist in beiden Fällen die selbe Zahl, die eben im Dezimalsystem nicht besser dargestellt werden kann (intern werden Fließkommazahlen im Binärsysteme repräsentiert, wo es für Zahlen wie z.B. 0.3 keine endliche Darstellung gibt). Wenn du eine Zahl für die Ausgabe auf eine bestimmte Anzahl von Stellen runden willst, kannst du nicht round() benutzen, sondern musst eine eine passende Format-Funktion, z.B. "%.2f" % 11.123456 oder "{0:.2f}".format(11.123456) benutzen.

Stefan
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Das hat wohl nichts mit round() zu tun, sondern mit der "string representation" von Floats (z.B. 11.119999999999999) und damit mit der Implementierung von `float.__repr__`.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Ich bin nicht ganz glücklich mit der kurzen Representation. Gaukelt sie einem doch eine genauere Darstellung vor.

Code: Alles auswählen

>>> 0.6 + 0.6 == 1.2
True
>>> 0.6+0.7 == 1.3
False
>>> 0.7+0.7 == 1.4
True
>>> .7+1-1
0.7
>>> .6+1-1
0.6000000000000001
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Was soll der Hinweis auf den Bugtracker. Das ist normal bei Fließkommazahlen. Die sind halt so. Einige im Dezimalsystem simpel aussehende Zahlen haben keine exakte Repräsentation als Bruch im Binärsystem. Wenn man das wieder zurück ins Dezimalsystem konvertiert, kommen "falsche" Ergebnisse.

Exakt rechnen kann man mit Fließkommazahlen nicht. Dazu nimmt man besser int, fraction oder decimal.

Stefan
lunar

@jbs: Im Gegenteil, die kurze Darstellung schneidet doch all die Nachkommastellen ab, die ohnehin nicht mehr exakt sind. Natürlich ist die resultierende Darstellung selbst nicht exakt, doch das ist eine inhärente Eigenschaft von Fließkommazahlen, und gehört zum Grundwissen jedes Entwicklers. Wer ungerundete Fließkommazahlen auf exakte Gleichheit prüft, hat sowieso schon verloren…
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Auch wenn es zum Grundwissen gehören mag, sollte Python nicht verwirren. Damit verlagert man das Problem auf, wers nicht schnallt ist einfach zu doof. Meiner Meinung nach sollte die Ungenauigkeit transparent sein. In gewissen fällen klappt es, in anderen nicht. Gerade der Anfänger fragt sich: warum? Wieso versucht mir Python vorzugaukeln, dass es 0.6 als exakt 0.6 abspeichern kann? Und wo ist da der Mehrwert?
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
lunar

@jbs: Die Darstellung "0.6" bedeutet nicht, dass es sich um die exakte rationale Zahl 0.6 handelt. Die Darstellung von Fließkommazahlen ist nie exakt. Vielmehr besagt diese Darstellung nur, dass es sich um die Fließkommazahl mit der geringsten Abweichung zur rationalen Zahl 0.6 handelt, genau dasselbe also, was man der Darstellung "0.6000001" entnehmen kann. Die Ungenauigkeit ist in "0.60000001" nicht transparenter als in "0.6", beides sind fehlerbehaftete Werte.

Die Behauptung, Python würde hier etwas vorgaukeln, gründet also letztlich nur in einer Fehlinterpretation der Darstellung von Fließkommazahlen.
Reg
User
Beiträge: 10
Registriert: Samstag 9. Januar 2010, 15:25

Hallo,

danke für die Hinweise.
Ich stelle bislang keine Unterschiede fest und verwende daher wie vorgeschlagen die format().

Gruß
Reg
Antworten