在 Python 中比较数字的一般方法
General way of comparing numerics in Python
我一直在四处寻找比较 Python 中两个数字的通用方法。特别想弄清楚它们到底是不是一样的
Python中的数值类型为:
int, long, float & complex
例如,我可以通过简单地说来比较 2 个整数(一种数字):
a == b
对于浮点数,由于舍入精度,我们必须更加小心,但我可以在一定的公差范围内比较它们。
问题
我们得到 2 个通用数值 a
和 b
:我们如何比较它们?我正在考虑将两者都转换为复数(如果类型是 int
,那么虚部将是 0)并在该域中进行比较?
这个问题比直接比较浮点数更笼统。肯定和这个问题有关,但又不一样。
为什么不直接使用 ==
?
>>1 == (1+0j)
True
>>1.0 == 1
True
我很确定这适用于所有数字类型。
如果您要比较不同类型的数字,==
运算符没有任何问题: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
在 Python 3.5(和 Numpy)中你可以使用 isclose
阅读 PEP 485 that describes it, Python 3.5 math library listing and numpy.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)<=tolerance
的测试一样
Python 的所有数值类型都支持 Python 3.5 版本。 (使用复杂的 cmath
版本)
我认为从长远来看,这是您对数字的更好选择。对于较旧的 Python,只需导入源代码。 Github 上有一个版本。
或者,(放弃错误检查和 inf
和 NaN
支持)你可以只使用:
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 )
我一直在四处寻找比较 Python 中两个数字的通用方法。特别想弄清楚它们到底是不是一样的
Python中的数值类型为:
int, long, float & complex
例如,我可以通过简单地说来比较 2 个整数(一种数字):
a == b
对于浮点数,由于舍入精度,我们必须更加小心,但我可以在一定的公差范围内比较它们。
问题
我们得到 2 个通用数值 a
和 b
:我们如何比较它们?我正在考虑将两者都转换为复数(如果类型是 int
,那么虚部将是 0)并在该域中进行比较?
这个问题比直接比较浮点数更笼统。肯定和这个问题有关,但又不一样。
为什么不直接使用 ==
?
>>1 == (1+0j)
True
>>1.0 == 1
True
我很确定这适用于所有数字类型。
如果您要比较不同类型的数字,==
运算符没有任何问题: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
在 Python 3.5(和 Numpy)中你可以使用 isclose
阅读 PEP 485 that describes it, Python 3.5 math library listing and numpy.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)<=tolerance
Python 的所有数值类型都支持 Python 3.5 版本。 (使用复杂的 cmath
版本)
我认为从长远来看,这是您对数字的更好选择。对于较旧的 Python,只需导入源代码。 Github 上有一个版本。
或者,(放弃错误检查和 inf
和 NaN
支持)你可以只使用:
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 )