(Un)Logik von Python: Gibt bei gleichen Werten False aus

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.
Mauli
User
Beiträge: 10
Registriert: Donnerstag 5. April 2007, 09:03

(Un)Logik von Python: Gibt bei gleichen Werten False aus

Beitragvon Mauli » Donnerstag 5. April 2007, 18:12

Sry, dass ich heute noch einen Thread öffne. Aber diesesmal habe ich kein Problem mit der Programmierung, sondern mit der internen Logik von Python.

Folgender Code führt mich zu der Annahme das Python spinnt oder aber ich die Logik eben nicht verstanden habe:


Code: Alles auswählen

import pylab as pl

x = pl.arange(1/360., 60, 1/360.)
y = pl.arange(1/200., 60, 1/200.)

# Zur Veranschaulichung ein Abschnitt aus jeder Sequenz:

x[60:64]
# out: array([ 0.16944444,  0.17222222,  0.175     ,  0.17777778])   
y[32:36]
# out: array([ 0.165,  0.17 ,  0.175,  0.18 ])

y[34]
# out: 0.175
x[62]
# out: 0.175

type(x[62])
# out: <type 'numpy.float64'>
type(y[34])
#out: <type 'numpy.float64'>

x[62]==y[34]
#out: FALSE   <-----------Wieso??

# Aber bei allen anderen, kleineren gemeinsammen Teilern, z.B. 0.15:

x[53]
# out: 0.15
y[29]
# out: 0.15

x[53]==y[29]
# out: TRUE  <------------ ???


Das ist doch total besch... und der Umstand dass 0,175 ungleich 0,175 ist, macht mir mein Programm zunichte :x .Wieso macht Python das???

Ich nehme nicht an dass es mit der Software und Umgebung zu tun hat, aber ich nutze matplotlib 0.90.0 mit Python 2.5 in der IDLE unter Win Xp.

Danke für jeden Hinweis schon mal im Voraus.

Ein verzweifelter Mauli :(
BlackJack

Beitragvon BlackJack » Donnerstag 5. April 2007, 18:21

Bist Du sicher das beide gleich sind? Bei Fliesskommazahlen muss man immer mit kleinen Ungenauigkeiten rechnen und sollte nie exakt auf Gleichheit oder Ungleichheit testen. Ich bekomme bei dem Vergleich der beiden Elemente zwar `True` aber dafür ein `False` wenn ich ``1.75`` direkt vergleiche. Was verständlicher wird, wenn man sich beide Zahlen mal genauer ansieht:

Code: Alles auswählen

In [34]: x = numpy.arange(1/360., 60, 1/360.)

In [35]: y = numpy.arange(1/200., 60, 1/200.)

In [36]: y[34] == x[62]
Out[36]: True

In [37]: x[62] == 0.175
Out[37]: False

In [38]: x[62]
Out[38]: 0.17500000000000002

In [39]: 0.175
Out[39]: 0.17499999999999999
Mauli
User
Beiträge: 10
Registriert: Donnerstag 5. April 2007, 09:03

Beitragvon Mauli » Donnerstag 5. April 2007, 18:46

Ich habe es nochmal probiert. Aber alleine die Tatsache, dass bei gleicher Eingabe bei Dir ein Vergleich "true" ausgibt und bei mir "false" scheint mir nicht grade eine Auszeichnung für diese Sprache zu sein. Was für eine Umgebung nutzt Du um dort "True" rauszubekommen? Mehr brauche ich ja nicht....

Bei mir werden beim Output auch gar nicht soviele Stellen angezeigt wie bei Dir.

Code: Alles auswählen

>>> import pylab as pl
>>> x = pl.arange(1/360., 60, 1/360.)
>>> y = pl.arange(1/200., 60, 1/200.)
>>> x[62]
0.175
>>> y[34]
0.175
>>> y[34] == x[62]
False
>>> x[62] == 0.175
True
>>> y[34] == 0.175
False
>>> print y[34]
0.175
>>> y[34]
0.175


Mir wird angezeigt das y[34] = 0,175 ist, aber dennoch scheint es das nicht zu sein. Innerhalb meines Programms teste ich nicht direkt auf Gleichheit, aber das Modul / Package scipy.interpolate.interp1d zur linearen Interpolation offensichtlich schon... Ob man numpy oder pylab importiert macht bei mir auch keinen Unterschied.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Donnerstag 5. April 2007, 19:01

Die Ausgabe von "print x" ist gerundet auf IIRC 11 Nachkommastellen, dabei werden beim Berechnen aufgetretene Fehler "versteckt", denn der float an sich hat eine größere Genauigkeit. repr(x) zeigt das auch.

Und ja, das hat absolut nichts mit Python zu tun, das findet sich in jeder Sprache, die Fließkommazahlen unterstützt.

Floats auf Gleichheit zu testen ist nie eine gute Idee, es sei denn man ist sich z.B. sicher, dass es sich um ganzzahlige Werte handelt. Ansonsten nimmt man so etwas:

Code: Alles auswählen

def float_eq(x, y, epsilon):
    return abs(x-y) < epsilon


mit einem geeigneten Wert für "epsilon".
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Donnerstag 5. April 2007, 19:20

Mauli hat geschrieben:Ich habe es nochmal probiert. Aber alleine die Tatsache, dass bei gleicher Eingabe bei Dir ein Vergleich "true" ausgibt und bei mir "false" scheint mir nicht grade eine Auszeichnung für diese Sprache zu sein.

Das ist bei allen Programmiersprachen so. Hier nachlesen. Aber Python bietet mit dem Decimal-Modul eine Möglichkeit, verlustfrei mit Float-Zahlen zu rechnen.
My god, it's full of CARs! | Leonidasvoice vs Modvoice

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot]