Wer nicht fragt, bleibt dumm
Hallo Liste, heute überraschte mich ein Kollege ;-) mit folgender Frage: Wieso ist bei Python 1.5.2 ...
4.0 - 0.1 3.9
aber bei 2.1.3 und später ...
4.0 - 0.1 3.8999999999999999
Ich befürchte ja, dass diese Frage zu den FAQs gehört, habe aber trotz intensivem Wühlen in Listen und Sites nichts wirklich erklärendes gefunden - bin also für jeden Hinweis dankbar. Gruß, - bringi _______________________________________________ Python-de maillist - Python-de@python.net http://python.net/mailman/listinfo/python-de
<http://www.python.org/doc/current/tut/node14.html> -aj --On Montag, 24. November 2003 17:01 Uhr +0100 Axel Bringenberg <A.Bringenberg@srz-berlin.de> wrote:
Hallo Liste,
heute überraschte mich ein Kollege ;-) mit folgender Frage:
Wieso ist bei Python 1.5.2 ...
4.0 - 0.1 3.9
aber bei 2.1.3 und später ...
4.0 - 0.1 3.8999999999999999
Ich befürchte ja, dass diese Frage zu den FAQs gehört, habe aber trotz intensivem Wühlen in Listen und Sites nichts wirklich erklärendes gefunden - bin also für jeden Hinweis dankbar.
Gruß, - bringi
_______________________________________________ Python-de maillist - Python-de@python.net http://python.net/mailman/listinfo/python-de
_______________________________________________ Python-de maillist - Python-de@python.net http://python.net/mailman/listinfo/python-de
Ähem, vielen Dank für die schnellen, kurzen und langen Antworten. Mir war die Frage schon peinlich genug, deshalb war sie wahrscheinlich auch so dumm gestellt. Ok, nachdem ich mich jetzt als kompletter Neuling geoutet habe (Chris, rette mich!) gebe ich noch einen 'drauf und formuliere die Frage mal anders: Sind Python 1.5.2 und älter nicht IEEE-754 konform? Das war mir irgendwie nie so bewußt. War das der Grund für die Änderung? Hat jemand ein Beispiel für mich, das bei 1.5.2 und älter "falsche" Ergebnisse liefert? Ich kann mir nicht vorstellen, dass diese Änderung ohne vorangegangene Diskussion vorgenommen worden ist. Aber wenn man danach google't, bekommt man leider nur tonnen von Erklärungen und Beispielen bzgl. Floating-Point _ab_ 2.0. Auch finde ich Detlefs Bemerkung "die Anwender mit der Nase auf die bekannten Floating-Point-Probleme zu stoßen" zwar passend, aber für mich klingt das nach "fishing for faqs" ;-) Gab es denn vorher keine Diskussion über die zu erwartende Verwirrrung? Danke nochmals, - bringi _______________________________________________ Python-de maillist - Python-de@python.net http://python.net/mailman/listinfo/python-de
Axel Bringenberg wrote:
Sind Python 1.5.2 und älter nicht IEEE-754 konform?
Hast du die empfohlenen Referenzen gelesen? Intern ist jede Version von Python exakt so "IEEE-754 konform" wie die zugrundeliegende C-Bibliothek. Daran ist mit vernuenftigem Aufwand auch nichts zu aendern.
Das war mir irgendwie nie so bewußt. War das der Grund für die Änderung?
Hat jemand ein Beispiel für mich, das bei 1.5.2 und älter "falsche" Ergebnisse liefert?
Das Beispiel hast du schon selber geliefert. Die Aenderung bezieht sich *ausschliesslich* darauf, wie bei der Umwandlung von float zu string durch die Funktion repr() die Formatierung vorgenommen wird. Da diese Funktion auch bei der interaktiven Ausgabe zum Zuge kommt, faellt der Unterschied dort manchmal auch ansonsten unaufmerksamen Programmierern auf.
Ich kann mir nicht vorstellen, dass diese Aenderung ohne vorangegangene Diskussion vorgenommen worden ist. Aber wenn man danach google't, bekommt man leider nur tonnen von Erklaerungen und Beispielen bzgl. Floating-Point _ab_ 2.0.
Da musst du wahrscheinlich in den Archiven von python-dev suchen. Eine so triviale Aenderung wird kaum im grossen Kreis diskutiert.
Auch finde ich Detlefs Bemerkung "die Anwender mit der Nase auf die bekannten Floating-Point-Probleme zu stoßen" zwar passend, aber für mich klingt das nach "fishing for faqs" ;-) Gab es denn vorher keine Diskussion über die zu erwartende Verwirrrung?
Die exakt identischen Fragen und Antworten gibt es als FAQ zu jeder anderen Programmiersprache auch. Wenn du als Entwickler mit gebrochenen Zahlen hantierst, dann musst du die grundsaetzlichen Einschraenkungen der binaeren Repraesentation kennen, sonst wirst du irgendwann mit unangenehmen Ueberraschungen konfrontiert. Die Aenderung sollte wohl mithelfen, dass die entsprechenden Fragen moeglichst frueh auftauchen, und nicht erst nachdem dein Programm schon zwei Jahre "mission-critical" im Einsatz war. Ein weiterer Grund, warum Python eine gute Sprache ist, um damit programmieren zu lernen... -schorsch -- Georg Mischler -- simulations developer -- schorsch at schorsch com +schorsch.com+ -- lighting design tools -- http://www.schorsch.com/ _______________________________________________ Python-de maillist - Python-de@python.net http://python.net/mailman/listinfo/python-de
Axel Bringenberg wrote:
Ähem, vielen Dank für die schnellen, kurzen und langen Antworten.
Mir war die Frage schon peinlich genug, deshalb war sie wahrscheinlich auch so dumm gestellt. Ok, nachdem ich mich jetzt als kompletter Neuling geoutet habe (Chris, rette mich!) gebe ich noch einen 'drauf und formuliere die Frage mal anders:
Sind Python 1.5.2 und älter nicht IEEE-754 konform?
Das war mir irgendwie nie so bewußt. War das der Grund für die Änderung?
Vieleicht gibt Guido's Kommentar im Source einen Hinweis: /* Precisions used by repr() and str(), respectively. The repr() precision (17 significant decimal digits) is the minimal number that is guaranteed to have enough precision so that if the number is read back in the exact same binary value is recreated. This is true for IEEE floating point by design, and also happens to work for all other modern hardware. The str() precision is chosen so that in most cases, the rounding noise created by various operations is suppressed, while giving plenty of precision for practical use. */ #define PREC_REPR 17 #define PREC_STR 12
[...]
MaW, um eval(repr(foo)) == foo für float sicherzustellen, braucht man 17 Stellen. Bis demnächst, Walter Dörwald _______________________________________________ Python-de maillist - Python-de@python.net http://python.net/mailman/listinfo/python-de
Axel Bringenberg wrote:
Hallo Liste,
heute überraschte mich ein Kollege ;-) mit folgender Frage:
Wieso ist bei Python 1.5.2 ...
4.0 - 0.1 3.9
aber bei 2.1.3 und später ...
4.0 - 0.1 3.8999999999999999
Ich befürchte ja, dass diese Frage zu den FAQs gehört, habe aber trotz intensivem Wühlen in Listen und Sites nichts wirklich erklärendes gefunden - bin also für jeden Hinweis dankbar.
Richtig geraten, schlecht gesucht... ;) http://www.python.org/cgi-bin/moinmoin/Python20FrequentlyAskedQuestions -schorsch -- Georg Mischler -- simulations developer -- schorsch at schorsch com +schorsch.com+ -- lighting design tools -- http://www.schorsch.com/ _______________________________________________ Python-de maillist - Python-de@python.net http://python.net/mailman/listinfo/python-de
:: :: Hallo Liste, :: :: heute überraschte mich ein Kollege ;-) mit folgender Frage: :: :: Wieso ist bei Python 1.5.2 ... :: :: >>> 4.0 - 0.1 :: 3.9 :: :: aber bei 2.1.3 und später ... :: :: >>> 4.0 - 0.1 :: 3.8999999999999999 :: Ganz einfach ;-) 1/10 hat im Binärsystem keine endliche Darstellung, analog zu 1/3 im Zehnersystem. Da Rechner ja nur endlich viele Bytes zur Darstellung von Zahlen zur Verfügung stellen können, wird 0.1 durch Abbruch der Binärdarstellung nach einer gewissen Anzahl Ziffern angenähert. Solche Approximationen beinträchtigen Rechnungen in der Regel nicht sonderlich stark, auch wenn es praxisrelevante Beispiele gibt, die bei "naiver" Implementierung ziemlich in die Hose gehen: der Darstellungsfehler wirkt sich so stark auf das Ergebnis aus, dass es total unbrauch- bar wird. Warum liefert nun Python 1.5.2 das exakte Ergebnis ? Die naheliegende Vermutung, daß Python 1.5.2 einen Rechner mit unendlichem Speicher simmulieren kann, ist - auch wenn manche Python sowas zutrauen - falsch: Python 1.5.2 rundet vor der Ausgabe einfach das Ergebnis. Gruß, Uwe. _______________________________________________ Python-de maillist - Python-de@python.net http://python.net/mailman/listinfo/python-de
Axel Bringenberg <A.Bringenberg@srz-berlin.de> wrote:
Wieso ist bei Python 1.5.2 ...
4.0 - 0.1 3.9
aber bei 2.1.3 und später ...
4.0 - 0.1 3.8999999999999999
Es kommt bei der Subtraktion nicht wirklich was anderes heraus ;-) . Früher wurden Floats bei der Ausgabe standardmäßig gerundet, jetzt werden sie mit allen signifikanten Ziffern ausgegeben, damit man sieht, daß z.B. (2.0 ** 0.5) ** 2 nicht etwa 2 ist, sondern 2.0000000000000004 (oder was die Hardware so hergibt). Wer's nicht so genau wissen will, soll halt round((2.0 ** 0.5) ** 2, 6) schreiben; damit wird deutlich, daß keine "exakten" Werte verwendet werden. Es ist IMO ein Versuch, die Anwender mit der Nase auf die bekannten Floating-Point-Probleme zu stoßen. Ob er erfolgreich ist, weiß ich nicht ... Detlef _______________________________________________ Python-de maillist - Python-de@python.net http://python.net/mailman/listinfo/python-de
On Mo November 24 2003 17:39, Detlef Lannert wrote:
Es kommt bei der Subtraktion nicht wirklich was anderes heraus ;-) . Früher wurden Floats bei der Ausgabe standardmäßig gerundet, jetzt werden sie mit allen signifikanten Ziffern ausgegeben, damit man sieht, daß z.B. (2.0 ** 0.5) ** 2 nicht etwa 2 ist, sondern 2.0000000000000004 (oder was die Hardware so hergibt).
(2.0 ** 0.5) ** 2 2.0000000000000004 "%.51f" % ((2.0 ** 0.5) ** 2) '2.000000000000000444089209850062616169452667236328125' Die Hardware _scheint_ noch mehr herzugeben, als python ausgibt. :-> -Falk _______________________________________________ Python-de maillist - Python-de@python.net http://python.net/mailman/listinfo/python-de
Falk Friedrich <frodo@prima.de> wrote:
"%.51f" % ((2.0 ** 0.5) ** 2) '2.000000000000000444089209850062616169452667236328125'
Die Hardware _scheint_ noch mehr herzugeben, als python ausgibt. :->
Genau, _scheint_. Bei den meisten Zahlen dürfte es möglich sein, sich beliebig viele Stellen ausgeben zu lassen ... das ist aber keine von der Hardware gelieferte Präzision, sondern ein Artefakt der Konvertierung. Aber vielleicht läuft Dein Python auf einer 390-Maschine; dort gibt es m.W. REAL*16 mit 112 Bit Mantisse (28 Hexaziffern) ;-). Detlef _______________________________________________ Python-de maillist - Python-de@python.net http://python.net/mailman/listinfo/python-de
(float)
gefunden - bin also für jeden Hinweis dankbar.
Eigenwerbung, aber vielleicht hilft es Dir weiter ;-) http://www.kmkorn.de/artikel/fp/fp.htm -- Mit freundlichen Grüßen Klaus Meyer :-) _______________________________________________ Python-de maillist - Python-de@python.net http://python.net/mailman/listinfo/python-de
participants (8)
-
Andreas Jung
-
Axel Bringenberg
-
Detlef Lannert
-
Falk Friedrich
-
Georg Mischler
-
Klaus-G. Meyer
-
Uwe Schmitt
-
Walter Dörwald