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.