floating point equality in Python und allgemein

Ich habe einen Code, der sich unterschiedlich verhält, je nachdem, ob ich ein Wörterbuch durchforste, um Umrechnungsfaktoren abzurufen, oder ob ich sie direkt verwende.

Der folgende Code wird gedruckt1.0 == 1.0 -> False

Aber wenn Sie @ ersetzfactors[units_from] mit10.0 undfactors[units_to ] mit1.0 / 2.54 es wird gedruckt1.0 == 1.0 -> True

#!/usr/bin/env python

base = 'cm'
factors = {
    'cm'        : 1.0,
    'mm'        : 10.0,
    'm'         : 0.01,
    'km'        : 1.0e-5,
    'in'        : 1.0 / 2.54,
    'ft'        : 1.0 / 2.54 / 12.0,
    'yd'        : 1.0 / 2.54 / 12.0 / 3.0,
    'mile'      : 1.0 / 2.54 / 12.0 / 5280,
    'lightyear' : 1.0 / 2.54 / 12.0 / 5280 / 5.87849981e12,
}

# convert 25.4 mm to inches
val = 25.4
units_from = 'mm'
units_to = 'in'

base_value = val / factors[units_from]
ret = base_value * factors[units_to  ]
print ret, '==', 1.0, '->', ret == 1.0

Lassen Sie mich zuerst sagen, dass ich ziemlich sicher bin, was hier los ist. Ich habe es vorher in C gesehen, nur nie in Python, aber seitdem Python in C implementiert ist, sehen wir es.

Ich weiß, dass Gleitkommazahlen die Werte von einem CPU-Register zum Cache und zurück ändern. Ich weiß, dass der Vergleich zweier gleicher Variablen falsch ist, wenn eine davon ausgelagert wurde, während die andere in einem Register residierte.

Frage

Was ist der beste Weg, um solche Probleme zu vermeiden? ... In Python oder allgemein. Mache ich etwas völlig falsch?

Randnoti

Dies ist offensichtlich Teil eines abgespeckten Beispiels, aber ich versuche es mit Klassen von Länge, Volumen usw. zu tun, die mit anderen Objekten derselben Klasse, aber mit unterschiedlichen Einheiten verglichen werden können.

Rhetorische Frage

Wenn dies ein potenziell gefährliches Problem ist, da sich Programme dadurch undetermanistisch verhalten, sollten Compiler gewarnt oder fehlerhaft sein, wenn sie feststellen, dass Sie die Gleichheit von Floats überprüfen.Sollten Compiler eine Option unterstützen, mit der alle Float-Gleichheitsprüfungen durch eine 'close enough'-Funktion ersetzt werden können? Tun Compiler dies bereits und ich kann die Informationen einfach nicht finden.

Antworten auf die Frage(16)

Ihre Antwort auf die Frage