Rechnen mit "float(str(Zahl)" ?

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.
Leto
User
Beiträge: 6
Registriert: Donnerstag 27. Juli 2006, 15:23

Donnerstag 27. Juli 2006, 15:42

Hallo,
ich habe eine seltsame "Entdeckung" gemacht, die erfahrenen Programmieren in Python wahrscheinlich bekannt sein dürfte.

Da ich mich gerade mit der Ungenauigkeit von Python float's herumschlagen muss - Stichwort:

Code: Alles auswählen

>>>0.3-0.1 == 0.2 
False
- bin ich ganz zufällig auf folgende Lösung dieses Problems gestoßen:

Code: Alles auswählen

>>>float(str(0.3-0.1))==0.2
True
Wie kommt das? Warum geht das eine, das andere aber nicht. Rechenfehler bleibt doch Rechenfehler.
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Donnerstag 27. Juli 2006, 16:05

Hi,

also bei mir sieht die Rechnung so aus

Code: Alles auswählen

>>> float (0.3-0.1) == 0.19999999999999998
True

#float 0.2 ist in python

>>> float(0.2)
0.20000000000000001
vlt hilft dir das ein bisschen.
helmut
User
Beiträge: 57
Registriert: Mittwoch 2. November 2005, 07:45
Wohnort: Dormagen

Donnerstag 27. Juli 2006, 16:07

Gestrichen, da hatte ich Addition und Subtraktion vertauscht.

Gruss, Helmut
Leto
User
Beiträge: 6
Registriert: Donnerstag 27. Juli 2006, 15:23

Donnerstag 27. Juli 2006, 17:32

Also mir ist schon klar, dass (0.3-0.1) und 0.2 in Python nicht gleich sind.
ich verstehe nur nicht, warum str(0.3-0.1) auf einmal '0.2' ist.
Wird da gerundet? Und wenn ja, an welcher Stelle bzw. nach welchem System?
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

Donnerstag 27. Juli 2006, 17:45

Code: Alles auswählen

>>> round(0.3-0.1, 1)
0.20000000000000001
>>> round(0.3-0.1, 1) == 0.2
True

So geht es ;)
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Donnerstag 27. Juli 2006, 18:01

Leto hat geschrieben:Also mir ist schon klar, dass (0.3-0.1) und 0.2 in Python nicht gleich sind.
ich verstehe nur nicht, warum str(0.3-0.1) auf einmal '0.2' ist.
Wird da gerundet? Und wenn ja, an welcher Stelle bzw. nach welchem System?
vielleicht ist es so besser .

Code: Alles auswählen

>>> a=str(0.3-0.1)
>>> b=0.2
>>> a == b
False
>>> print float(a)
0.2
>>> float(a) == b
True
weisst du jetzt was da passiert ist ?
Im übrigen es wird nirgends wo gerundet ( nur mal als hilfe )!Den Rest musst du selber rausfinden :D
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Donnerstag 27. Juli 2006, 19:26

Um hier mal Klarheit zu schaffen:
Floats sind nicht nur in Python ungenau. Sie sind überall ungenau, weil das nicht anders geht, wenn man dezimale Zahlen in einem Binärsystem mit einer begrenzten Anzahl von Stellen repräsentiert. (Deswegen gibts ja auch das decimal-Modul).

Bei Anwendung von str() auf einen float wird auf 12 Stellen, bei repr() auf 17 Stellen "gerundet". Eventuelle Nullen am Ende werden dann entfernt. Das führt dazu, dass die Ausgabe von

>>> 0.3-0.1
0.1999...

anders aussieht als von

>>> print 0.3-0.1
0.2

da print str() verwendet, das Prompt an sich aber repr().
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Donnerstag 27. Juli 2006, 20:11

Hi birkenfeld
birkenfeld hat geschrieben: Bei Anwendung von str() auf einen float wird auf 12 Stellen, bei repr() auf 17 Stellen "gerundet". Eventuelle Nullen am Ende werden dann entfernt. Das führt dazu, dass die Ausgabe von
weiss nicht so genau was du damit meinst !

Code: Alles auswählen

>>> x=float(0.2)
>>> y=str(0.2)
>>> x
0.20000000000000001
>>> y
'0.2'
>>> float(y)
0.20000000000000001
>>> 
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

Donnerstag 27. Juli 2006, 20:19

Code: Alles auswählen

>>> str(0.3)
'0.3'
>>> repr(0.3)
'0.29999999999999999'
str() entfernt die überflüssigen 0s und rundet zuerst noch
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Donnerstag 27. Juli 2006, 20:44

DatenMetzgerX hat geschrieben:

Code: Alles auswählen

>>> str(0.3)
'0.3'
>>> repr(0.3)
'0.29999999999999999'
str() entfernt die überflüssigen 0s und rundet zuerst noch
sorry aber das ist so nicht ganz richtig.

Code: Alles auswählen

>>> x=str(0.3)
>>> type(x)
<type 'str'>
>>> y=float(x)
>>> type(y)
<type 'float'>
>>> 
>>> x
'0.3'
>>> y
0.29999999999999999
>>> 
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Donnerstag 27. Juli 2006, 20:57

pyStyler hat geschrieben:
DatenMetzgerX hat geschrieben:

Code: Alles auswählen

>>> str(0.3)
'0.3'
>>> repr(0.3)
'0.29999999999999999'
str() entfernt die überflüssigen 0s und rundet zuerst noch
sorry aber das ist so nicht ganz richtig.
Doch, man kann es so sagen.
pyStyler hat geschrieben:

Code: Alles auswählen

>>> x=str(0.3)
>>> type(x)
<type 'str'>
>>> y=float(x)
>>> type(y)
<type 'float'>
>>> 
>>> x
'0.3'
>>> y
0.29999999999999999
>>> 
Was soll das jetzt beweisen? Indem du float("0.3") ausführst, hast du wieder einen Float. Keinen String. Wenn du diesen am Interpreterprompt direkt anzeigen lässt (also via repr()), wird die Ungenauigkeit deutlich. Nochmal: Es gibt keine Möglichkeit für den Computer, die 0.3 als Float exakt zu speichern.
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Donnerstag 27. Juli 2006, 21:16

hmm ich will hier nichts beweisen! Nur bitte ich den Unterschied zwischen einen String und einer Dezimalzahl zumachen.

Code: Alles auswählen

>>> zahl=str(0.3)
>>> repr(zahl)
"'0.3'"
>>>
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Donnerstag 27. Juli 2006, 21:17

pyStyler hat geschrieben:hmm ich will hier nichts beweisen! Nur bitte ich den Unterschied zwischen einen String und eine Dezimalzahl zumachen.
Das ist ja auch löblich. Nur war das doch gar nicht das Thema.
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Donnerstag 27. Juli 2006, 21:19

birkenfeld hat geschrieben:
pyStyler hat geschrieben:hmm ich will hier nichts beweisen! Nur bitte ich den Unterschied zwischen einen String und eine Dezimalzahl zumachen.
Das ist ja auch löblich. Nur war das doch gar nicht das Thema.
naja wie auch immer ... Fakt ist das hier ein paar infos nicht ganz richtig waren.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Donnerstag 27. Juli 2006, 21:20

pyStyler hat geschrieben:naja wie auch immer ... Fakt ist das hier ein paar infos nicht ganz richtig waren.
Solange jetzt nicht die meinst, auf die du mit "weiss nicht so genau was du damit meinst !" geantwortet hast... ;-)
Antworten