comparación aproximada en python

Quiero hacer una comparación aproximada con el operador ‘==’ en mi progtwig: los valores flotantes x e y son iguales (==) si

abs(xy)/(0.5(x+y)) < 0.001 

¿Qué es una buena manera de hacer eso? Dado que float es un tipo integrado, no creo que pueda redefinir el operador ==, ¿puedo?

Tenga en cuenta que me gustaría usar otras funciones de float, lo único que me gustaría cambiar es el operador de igualdad.

EDITAR:

Gracias por las respuestas, y entiendo sus argumentos sobre la legibilidad y otros problemas.

Dicho esto, realmente preferiría, si es posible, seguir usando el tipo flotante normal, en lugar de tener una nueva clase o una nueva función de comparación. ¿Es incluso posible redefinir el operador == para flotadores regulares?

Mis razones son:

(a) todos los que usan el progtwig que estoy escribiendo quieren que las carrozas se comparen de esta manera

(b) no hay forma en el mundo de que alguien quiera usar el valor predeterminado == para flotadores … ¿Por qué está incluso en el idioma?

(c) No me gustan las palabras adicionales en el código; Obviamente, el uso de los resultados flotantes existentes no produce cambios en el código en absoluto

EDITAR 2.

Ahora que sé que no puedo sobrecargar el operador == para float, tengo que cambiar mi pregunta. Será tan diferente que haré una nueva en comparación personalizada para contenedores incorporados

Su definición tiene dos problemas:

  1. Falta un *

  2. Intentará dividir por cero si x + y == 0.0 (que cubre un caso posiblemente frecuente x == y == 0.0 )

Intenta esto en su lugar:

 define approx_Equal(x, y, tolerance=0.001): return abs(xy) <= 0.5 * tolerance * (x + y) 

Edición: tenga en cuenta que el uso de <= lugar de < ... es necesario para que el caso x == y == 0.0 funcione correctamente.

No trataría de anular ==

Edit 2: Usted escribió:

no hay forma en el mundo de que alguien quiera usar el valor predeterminado == para flotadores ... ¿Por qué incluso en el idioma?

¿De ninguna manera? Supongamos que tiene una función que devuelve un flotador y tiene una onda cerebral acerca de un algoritmo que produciría las mismas respuestas de forma más rápida y / o más elegante; ¿Cómo lo pruebas?

Puede crear una nueva clase derivada del tipo flotante incorporado, y luego sobrescribir los operadores necesarios:

 class InexactFloat(float): def __eq__(self, other): try: return abs(self.real - other) / (0.5 * (abs(self.real) + abs(other))) < 0.001 except ZeroDivisionError: # Could do another inexact comparison here, this is just an example: return self.real == other def __ne__(self, other): return not self.__eq__(other) print 5.2 == 5.20000000000001 # False print 5.2 != 5.20000000000001 # True print InexactFloat(5.2) == InexactFloat(5.20000000000001) # True print InexactFloat(5.2) != InexactFloat(5.20000000000001) # False print InexactFloat(-5) == -5 # True # Works for InexactFloat <-> float comparison print 5.0 == InexactFloat(5.0) # True print InexactFloat(5.0) == 5.0 # True # Zero division case (note how I implemented it above!) print InexactFloat(-0.00001) == InexactFloat(0.00001) # False print InexactFloat(-0.000000001) == InexactFloat(0.000000001) # False print InexactFloat(-5) == InexactFloat(5) # False # Unit test for fixed negative numbers problem print InexactFloat(-5) == InexactFloat(-10) # False 

También es posible que desee sobrescribir operadores como <= etc.

Si envuelve los números en una clase, puede sobrecargar “==” con:

 def __eq__(self, x): return abs(x - self.x) / (0.5 * (x + self.x)) < 0.001 

sin embargo debes reescribir la expresión a

abs(x - self.x) < 0.0005 * (x + self.x)

para evitar la división cero.