Seite 1 von 1

Wie vergleiche ich Fließkommazahlen?

Verfasst: Donnerstag 7. August 2008, 23:13
von Mister L
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

Verfasst: Donnerstag 7. August 2008, 23:26
von audax

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.

Verfasst: Donnerstag 7. August 2008, 23:33
von Trundle
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.

Verfasst: Donnerstag 7. August 2008, 23:39
von audax
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)

Verfasst: Donnerstag 7. August 2008, 23:40
von BlackVivi
Wenn's genau sein soll sollte man decimal Modul verwenden, ansonsten sind solche Vergleiche doch eher selten.

edit: GRRRRR viel zu langsam....

Verfasst: Freitag 8. August 2008, 09:39
von CM
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

Verfasst: Samstag 9. August 2008, 16:52
von Mister L
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