python中的近似比较

max*_*max 4 python comparison

我想让'=='运算符在我的程序中使用近似比较:浮点值x和y相等(==)if

abs(x-y)/(0.5(x+y)) < 0.001
Run Code Online (Sandbox Code Playgroud)

有什么好办法呢?鉴于float是一个内置类型,我不认为我可以重新定义==运算符,是吗?

请注意,我想使用float的其他功能,我唯一想改变的是等于运算符.

编辑:

感谢您的回答,我理解您关于可读性和其他问题的论点.

也就是说,如果可能的话,我真的更希望实际使用常规浮点类型,而不是使用新类或新的比较函数.是否有可能重新定义==运算符的常规浮点数?

我的理由是::

(a)每个使用我正在编写的程序的人都希望以这种方式比较浮点数

(b)世界上没有办法让任何人想要使用默认的==浮点数.为什么它甚至在语言中?

(c)我不喜欢代码中的额外词语; 显然使用现有的float会导致代码没有任何变化

编辑2.

既然我知道我不能重载浮动的==运算符,我必须改变我的问题.它将变得如此不同,我将在内置容器的自定义比较中创建一个新的

And*_*Dog 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
Run Code Online (Sandbox Code Playgroud)

您可能还想覆盖<=等运算符.

  • @Andidog:如果OP要以即时方式使用你的类,他需要为代码中的每个比较事件键入`Classname(a)== b`,这比两个键击更多`func_name (a,b)`如果一个人坚持PEP8,还有一个人.否则,对于保存可以在以后比较的浮点值的每个代码事件,OP需要找到该事件,并插入`classname(whatever)` - 你建议吗?你会很乐意维护这样的代码吗? (2认同)

Joh*_*hin 8

你的定义有两个问题:

  1. 想念一个 *

  2. 如果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)
Run Code Online (Sandbox Code Playgroud)

编辑:注意使用<=而不是<...需要使x == y == 0.0案例正常工作.

我不会试图覆盖 ==

编辑2:你写道:

世界上没有人会想要使用默认的==浮动..为什么它甚至在语言中???

没门?假设您有一个返回浮点数的函数,并且您有一个关于算法的脑波,可以更快和/或更优雅地生成相同的答案; 你是如何测试的?