【问题标题】:General way of comparing numerics in Python [duplicate]在Python中比较数字的一般方法[重复]
【发布时间】:2017-02-22 18:44:22
【问题描述】:

我一直在寻找一种在 Python 中比较两个数字的通用方法。特别想弄清楚它们是否相同。

Python 中的数值类型有:

int, long, float & complex

例如,我可以通过简单地说来比较 2 个整数(一种数字):

a == b

对于浮点数,由于舍入精度,我们必须更加小心,但我可以在一定的公差范围内比较它们。

问题

我们得到 2 个通用数字 ab:我们如何比较它们?我正在考虑将两者都转换为复数(如果类型是 int,那么它的虚数部分将为 0)并在该域中进行比较?

这个问题比简单地直接比较浮点数更笼统。当然和这个问题有关,但又不一样。

【问题讨论】:

    标签: python floating-point int type-conversion numerics


    【解决方案1】:

    为什么不直接使用==

    >>1 == (1+0j)
    True
    >>1.0 == 1
    True
    

    我很确定这适用于所有数字类型。

    【讨论】:

    • 哈哈,相同的答案:)
    • 它甚至适用于布尔值 - True==1.0False==0.0 都返回 True
    【解决方案2】:

    如果您要比较不同类型的数字,== 运算符没有任何问题:Python 将处理类型转换。考虑以下几点:

    >>> 1 == 1 + 0j == 1.0
    True
    

    如果您正在执行可能导致精度损失的数学运算(尤其是浮点数),一种常见的技术是检查这些值是否在某个容差范围内。例如:

    >>> (10**.5)**2
    10.000000000000002
    >>> (10**.5)**2 == 10
    False
    

    在这种情况下,你可以找到差的绝对值,并确保它在某个阈值以下:

    >>> abs((10**.5)**2 - 10) < 1e-10
    True
    

    【讨论】:

    • 我想我担心的是宽容,这是怎么回事?
    • @denvar 我添加了一些容忍度
    • @denvar 检查stackoverflow.com/questions/5595425/… 与公差进行比较。我不认为这个答案适用于复数。
    【解决方案3】:

    在 Python 3.5(和 Numpy)中,您可以使用 isclose

    阅读描述它的PEP 485、Python 3.5 数学library listingnumpy.isclose 了解更多信息。 numpy 版本适用于所有支持 numpy 的 Python 版本。

    例子:

    >>> from math import isclose
    >>> isclose(1,1.00000000001)
    True
    >>> isclose(1,1.00001)
    False
    

    可以更改相对和绝对容差。

    相对容差可以认为是两个值之间的 +- 百分比:

    >>> isclose(100,98.9, rel_tol=0.02)
    True
    >>> isclose(100,97.1, rel_tol=0.02)
    False
    

    绝对容差是两个值之间的绝对值。和abs(a-b)&lt;=tolerance的测试一样

    Python 3.5 版本支持所有数字类型的 Python。 (复杂使用cmath版本)

    我认为从长远来看,这是您对数字的更好选择。对于较旧的 Python,只需导入源即可。 Github 上有一个版本。

    或者,(放弃错误检查和infNaN 支持)您可以使用:

    def myisclose(a, b, *, rel_tol=1e-09, abs_tol=0.0):
       return abs(a-b) <= max( rel_tol * max(abs(a), abs(b)), abs_tol )
    

    【讨论】:

    • +1 表示关闭 GitHub 库。正如他们所说:他们为完全平等而短路,但如果不是严格平等,他们会进行更仔细的检查。这就是我的想法(即使是处理复杂类型)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-16
    • 2018-07-17
    • 2021-12-05
    • 1970-01-01
    相关资源
    最近更新 更多