Gleitkommazahlen

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
Conker
User
Beiträge: 2
Registriert: Sonntag 27. August 2006, 18:08

Sonntag 27. August 2006, 18:16

Hi,
ich habe mit Python vor 2 Wochen angefangen. Im Vergleich zu C++ ist es auf jeden Fall einfacher zu lernen.
Jedoch ist mir folgendes aufgefallen, als ich es auf dem PDA ausprobiert habe:

Wenn ich 1.2**2 eingebe , also 1.2 zum Quadrat, dann müsste eigentlich genau 1.4 ausgegeben werden.
Aber ich erhalte folgende Ausgabe:
>>> 1.2**2
1.4399999999999999

Das selbe erhalte ich auf dem PC.
Deshalb wollte ich nachfragen, ob das nun ein Fehler in Python oder eine falsche Eingabe ist.
Habe auf beidem Python 2.4.3

Conker
Crush
User
Beiträge: 44
Registriert: Montag 1. Mai 2006, 11:32

Sonntag 27. August 2006, 18:28

irgendwo habe ich mal gelesen, wieso man hier solche Resultate erhält... aber leider weiss ich das nicht mehr :?

jedenfalls erhälst du das "richtige" Ergebnis wenn du für die Ausgabe print verwendest:

Code: Alles auswählen

>>> print 1.2**2
1.44
>>>
Mich würde es aber auch interessieren, wieso man hier "1.439999999 ..." als Resultat erhält, was ja eigentlich auch 1.44 ist, wenn man die Anzahl Stellen gegen Unendlich gehen lässt. Vielleicht hat ja jemand einen Link parat. :)

Crush
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

Sonntag 27. August 2006, 19:00

das hatten wir mal in einem Thread wo es darum ging das 0.3 - 0.1 eins nicht genau o.2 gab sondern 0.199999999999

das Problem ist... du kannst Binär 1.44 nicht abbilden und darum besteht immer eine gewisse ungenauikeit.

Wenn du mit print das ganze ausgibst, formt er das resultat in einen string um und roundet zusätzlich noch auf irgend wie 12 stellen. und dann gibt es logischerweise 1.44
Maho
User
Beiträge: 10
Registriert: Sonntag 27. August 2006, 11:14

Sonntag 27. August 2006, 19:35

Das problem mit dem rundungsfehler kommt daher, das Gleitpunktzahlen intern als Brüche behandelt werden. Das hat verschiedene Vorteile, aber eben auch Nachteile. Genaueres dazu erfährt man in der Wikipedia, die einen sehr ausführlichen Artikel zu dem Thema haben.
Benutzeravatar
Michael Schneider
User
Beiträge: 567
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Bremen
Kontaktdaten:

Sonntag 27. August 2006, 19:39

Hi,

Du kannst mit

Code: Alles auswählen

round(f,10)
den Floatwert auf 10 Stellen runden.

Wie Datenmetzger schon ansprach können manche Zahlen nicht angezeigt werden. Stell Dir vor, Du solltest mit einem Byte Zahlen zwischen 0 und 1 darstellen.
Du könntest sagen: "Gut, ich kann 256 unterschiedliche Werte darstellen. Dann nehme ich die Zustände von 0-200 dividiere durch 200."
Dann kannst Du alle Werte darstellen, die durch 0.005 teilbar sind, also 0, 0.005, 0.01, 0.015, 0.02, 0.025, [...], 0.995, 1.
Du könntest aber die Werte 0.003 oder 0.018 nicht darstellen, weil sie nicht in Deinem Wertebereich liegen.
Um noch tiefer zu gehen: Du würdest bei obiger Lösung 55 Zustände verschwenden, also teilst Du die Zahl durch 255. Dann ist jede Unterteilung 0,003921568.... Einheiten groß. Versuch damit mal eine 0.5 zu basteln. ;-)

Das gleiche Problem tritt aber auch bei C-Typen auf. Nur dass da auf eine genaue Stellenzahl gerundet wird.
EDIT Nachtrag: wenn ich mich recht erinnere können in C mit 4 Bytes 7 Stellen (8 mit der ganzen Stelle) genau dargestellt werden.

Michael
Zuletzt geändert von Michael Schneider am Sonntag 27. August 2006, 20:37, insgesamt 1-mal geändert.
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Conker
User
Beiträge: 2
Registriert: Sonntag 27. August 2006, 18:08

Sonntag 27. August 2006, 20:21

Ja, habe auch vermutet, dass es an der internen Verarbeitung liegt.
Danke, dass ihr es erklärt habt. :)
Ich wollte erst hier nachfragen, bevor ich Entwickler bei Python benachrichtige.

Conker
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Montag 28. August 2006, 08:09

Zum Thema hab ich gerade eine Wiki Seite gefunden:

[wiki]Das Problem mit den Dezimalzahlen[/wiki]

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Michael Schneider
User
Beiträge: 567
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Bremen
Kontaktdaten:

Montag 28. August 2006, 20:09

Hi,

das ist eine seltsame Frage, finde ich:
PythonWiki hat geschrieben:Warum ist 1 / 3.0 nicht 0.3, sondern 0.33333333333333331?
1/3.0 war noch nie 0.3, nicht mal annähernd. :) Jedenfalls für mich ist es weit von 0.33333333 Periode 3 entfernt.

Dabei ist gerade die Periode ein gutes Beispiel dafür, wie wir einen an sich eindeutigen Wert (im Beispiel den, der 1 ergibt, wenn man ihn mit 3 multipliziert) nicht als Dezimalzahl darstellen können. Faszinieren!

Grüße,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Montag 28. August 2006, 20:43

Michael Schneider hat geschrieben:
PythonWiki hat geschrieben:Warum ist 1 / 3.0 nicht 0.3, sondern 0.33333333333333331?
1/3.0 war noch nie 0.3, nicht mal annähernd. :) Jedenfalls für mich ist es weit von 0.33333333 Periode 3 entfernt.
Fehler meinerseits. Fixed
TUFKAB – the user formerly known as blackbird
Antworten