Python如何将'int'与'float'对象进行比较?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python如何将'int'与'float'对象进行比较?相关的知识,希望对你有一定的参考价值。

关于数字类型的The documentation指出:

Python完全支持混合算术:当二进制算术运算符具有不同数值类型的操作数时,具有“较窄”类型的操作数将扩展为另一个,即整数比浮点数窄,比浮点数窄。 混合类型的数字之间的比较使用相同的规则。

此行为受到以下支持:

>>> int.__eq__(1, 1.0)
NotImplemented
>>> float.__eq__(1.0, 1)
True

但是,对于大整数,似乎会发生其他事情,因为除非明确转换为float,否则它们将不会比较相等:

>>> n = 3**64
>>> float(n) == n
False
>>> float(n) == float(n)
True

另一方面,对于2的幂,这似乎不是问题:

>>> n = 2**512
>>> float(n) == n
True

由于文档暗示int被“加宽”(我假设转换/强制转换为float,所以我希望float(n) == nfloat(n) == float(n)相似,但上述带有n = 3**64的示例提出了不同的建议。那么,Python使用什么规则将intfloat(或通常为混合数字类型)进行比较?


使用Anaconda和PyPy 7.3.0(Python 3.6.9)的CPython 3.7.3测试。

答案

language specification on value comparisons包含以下段落:

内置数字类型(Numeric Types-int, float, complex)的数量以及标准库类型fractions.Fractiondecimal.Decimal的数量可以在其类型之内和之间进行比较,但有一个限制,即复数不支持顺序比较。在涉及的类型的范围内,它们在数学上(算法上)进行比较,但不损失精度

这意味着当比较两个数字类型时,将比较由这些对象表示的实际(数学)数字。例如,numeral 16677181699666569.0(即3**34)代表数字16677181699666569,即使在“浮动空间”中,该数字与16677181699666568.03**34 - 1)之间也没有区别,它们确实代表了不同的数字。由于有限的浮点精度,在64位体系结构上,值float(3**34)将存储为16677181699666568,因此它表示的数字与整数16677181699666569不同。因此,我们有float(3**34) != 3**34可以进行比较而不损失精度。

此属性对于保证数字类型transitivityequivalence relation很重要。如果intfloat的比较得出的结果类似于int对象将转换为float对象,则传递关系将无效:

>>> class Float(float):
...     def __eq__(self, other):
...         return super().__eq__(float(other))
... 
>>> a = 3**34 - 1
>>> b = Float(3**34)
>>> c = 3**34
>>> a == b
True
>>> b == c
True
>>> a == c  # transitivity demands that this holds true
False

另一方面,float.__eq__实现考虑了所表示的数学数字,没有违反该要求:

>>> a = 3**34 - 1
>>> b = float(3**34)
>>> c = 3**34
>>> a == b
True
>>> b == c
False
>>> a == c
False

由于缺少传递性,因此以下列表的顺序不会通过排序进行更改(因为所有连续的数字都相等):

>>> class Float(float):
...     def __lt__(self, other):
...         return super().__lt__(float(other))
...     def __eq__(self, other):
...         return super().__eq__(float(other))
... 
>>> numbers = [3**34, Float(3**34), 3**34 - 1]
>>> sorted(numbers) == numbers
True

另一方面,使用float,则顺序相反:

>>> numbers = [3**34, float(3**34), 3**34 - 1]
>>> sorted(numbers) == numbers[::-1]
True

以上是关于Python如何将'int'与'float'对象进行比较?的主要内容,如果未能解决你的问题,请参考以下文章

Python+int('35',8)为啥等于29?

python中如何把string 转换成int

Python中如何把str彻底转换为int

python 如何将列表转为字典,key值相同则合并value

【急,在线等】用python怎么将下面的列表处理一下???

python3.4.0 input Can't convert 'int' object to str implicitly 如何正确输出?