我想让'=='运算符在我的程序中使用近似比较:浮点值x和y相等(==)if
abs(x-y)/(0.5(x+y)) < 0.001
这样做的好方法是什么?鉴于float是一个内置类型,我认为我不能重新定义==运算符,可以吗?
请注意,我想使用float的其他功能,我唯一想改变的是等于运算符。
编辑:
感谢您的回答,我理解您关于可读性和其他问题的论点。
那就是说,如果可能的话,我真的更愿意继续使用常规浮点类型,而不是使用新类或新的比较函数。甚至可以重新定义常规浮点数的==运算符吗?
我的理由是::
(a)每个使用我正在编写的程序的人都希望以这种方式比较浮点数
(b)世界上没有办法让任何人想要使用默认的==浮点数。为什么它甚至用语言?
(c)我不喜欢代码中的额外单词;显然使用现有的float会导致代码无论如何都没有变化
编辑2。
现在我知道我不能重载浮动的==运算符,我必须改变我的问题。它将变得如此不同,我将在custom comparison for built-in containers
创建一个新的答案 0 :(得分:18)
您可以创建一个从内置float类型派生的新类,然后覆盖必要的运算符:
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
您可能还想覆盖像&lt; = etc。
这样的运算符答案 1 :(得分:7)
您的定义有两个问题:
缺少*
如果x + y == 0.0
(涵盖可能经常发生的情况x == y == 0.0
)
请改为尝试:
define approx_Equal(x, y, tolerance=0.001):
return abs(x-y) <= 0.5 * tolerance * (x + y)
修改:请注意使用<=
代替<
...,以使x == y == 0.0
案例正常运作。
我不会尝试覆盖==
编辑2:你写道:
世界上没有人会想要使用默认设置 == for floats ..为什么它甚至用语言???
没办法?假设您有一个返回浮点数的函数,并且您有一个关于算法的脑波,可以更快和/或更优雅地生成相同的答案;你是如何测试它的?
答案 2 :(得分:3)
如果你将数字包装在一个类中,你可以使用:
重载“==”def __eq__(self, x):
return abs(x - self.x) / (0.5 * (x + self.x)) < 0.001
但是你应该将表达式重写为
abs(x - self.x) < 0.0005 * (x + self.x)
避免零分割。