Wie vergleiche ich Fließkommazahlen?

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
Mister L
User
Beiträge: 2
Registriert: Donnerstag 7. August 2008, 21:36

Hallo Leute!

Ich bin seit etwa 3-4 Monaten ein "Pythoniser" und war bisher regelmäßiger Gast in diesem Forum.
Zur Zeit stehe ich vor einem Problem, welches ich trotz Forum und zwei Fachbücher noch nicht elegant lösen konnte. :?
Deshalb habe ich mich entschlossen, Mitglied der Familie zu werden! :D

Und nun zu meinem kleinen Ärgernis:

Ich muss errechete Koordinaten (float) untereinander vergleichen. Leider kommt mir da wohl die "automatische Echo-Ausgabe" in den Weg... :x
Hier ein Beispiel zu meinem Problem.... : obwohl "a" und "b" mathematisch gleich sein müssten, sind sie im Vergleich = False
(Der Folgende Auszug wurde aus Idle herauskopiert)

Code: Alles auswählen

>>> a = 2.4 + 0.2
>>> b = 2.8 - 0.2
>>> print a, b
2.6 2.6
>>> a,b
(2.6000000000000001, 2.5999999999999996)
>>> a == b
False
>>> c = 2.5
>>> c == 2. + 0.5
True
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Code: Alles auswählen

def float_eq(a, b, distance=0.01):
    return a - b < distance

assert float_eq(100.001, 100.01)
assert not float_eq(1.01, 1.0)
assert not float_eq(1.1, 1.08)
Indem man die Distanz zwischen ihnen misst.
Fließkommazahlen sind nur begrenzt genau, daher funktioniert der Vergleich auf Gleichzeit nicht.
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Dann aber vllt noch ein ``abs`` dazu, weil ``float_eq(1.0, 1e42) == True`` ist irgendwie verwirrend.

Ansonsten werfe ich noch [mod]decimal[/mod] in den Raum.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

auch wieder wahr...

Code: Alles auswählen

def float_eq(a, b, distance=0.01):
    return abs(a - b) < distance

assert float_eq(100.001, 100.01)
assert not float_eq(1.01, 1.0)
assert not float_eq(1.1, 1.08)
assert not float_eq(1.0, 5.123)
assert not float_eq(-5.2, 5.2)
assert float_eq(-5.2, -5.2)
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Wenn's genau sein soll sollte man decimal Modul verwenden, ansonsten sind solche Vergleiche doch eher selten.

edit: GRRRRR viel zu langsam....
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

BlackVivi hat geschrieben:Wenn's genau sein soll sollte man decimal Modul verwenden, ansonsten sind solche Vergleiche doch eher selten.
Überhaupt nicht ;-) - in wissenschaftlich / technischen Anwendungen ist das die Regel. Schon seit Jahrzehnten (ganz ohne decimal-Modul ;-) ).

Ich möchte noch numpy nachwerfen:

Code: Alles auswählen

In [1]: from numpy import *
In [2]: a = array([ 0.,  1.,  2.])
In [3]: b = a - 0.1
In [4]: allclose(a, b, atol=0.1)
Out[4]: True
In [5]: allclose(a, b, rtol=0.1)
Out[5]: False
Mit allclose kann man absolute Differenzen (Angabe der absoluten Toleranz: atol) und relative Differenzen (rtol) für ganze arrays abfragen. Sehr praktisch so etwas.

Gruß,
Christian
Mister L
User
Beiträge: 2
Registriert: Donnerstag 7. August 2008, 21:36

Ich danke Euch für die schnellen Antworten und Ideen. :D
Jetzt liegt es an mir, was ich daraus mache. Werde euch dann natürlich bescheid geben.

Gruß,
L
Antworten