a_g*_*est 6 python floating-point types comparison-operators python-3.x
关于数字类型的文档指出:
Python 完全支持混合算术:当二元算术运算符具有不同数值类型的操作数时,具有“较窄”类型的操作数会被扩展为另一个类型的操作数,其中整数比浮点窄,浮点数比复数窄。混合类型数字之间的比较使用相同的规则。
以下行为支持这一点:
>>> int.__eq__(1, 1.0)
NotImplemented
>>> float.__eq__(1.0, 1)
True
Run Code Online (Sandbox Code Playgroud)
然而,对于大整数,似乎会发生其他事情,因为除非明确转换为,否则它们不会比较相等float:
>>> n = 3**64
>>> float(n) == n
False
>>> float(n) == float(n)
True
Run Code Online (Sandbox Code Playgroud)
另一方面,对于 2 的幂,这似乎不是问题:
>>> n = 2**512
>>> float(n) == n
True
Run Code Online (Sandbox Code Playgroud)
由于文档暗示这int是“扩大”(我假设转换/转换?)到float我期望的float(n) == n并且float(n) == float(n)是相似的,但上面的例子有n = 3**64不同的建议。那么什么样的规则不Python中使用比较int来float(一般或混合数字类型)?
使用 Anaconda 的 CPython 3.7.3 和 PyPy 7.3.0 (Python 3.6.9) 进行测试。
关于值比较的语言规范包含以下段落:
\n\n\n\n\n内置数字类型(数字类型 \xe2\x80\x94 )和
\nint, float, complex标准库类型的数量可以在其类型内和类型之间进行比较,但限制是复数不支持顺序比较。在所涉及类型的限制内,它们在数学上(算法上)进行比较是正确的,而不会损失精度。fractions.Fractiondecimal.Decimal
这意味着当比较两个数字类型时,将比较这些对象表示的实际(数学)数字。例如,数字 16677181699666569.0( )代表数字 16677181699666569 ,即使在“浮动空间”中,这个数字和( )3**34之间没有区别,但它们确实代表不同的数字。由于浮点精度有限,在 64 位架构上,该值将存储为 16677181699666568,因此它表示与整数 numeric 不同的数字。因此,我们可以在不损失精度的情况下进行比较。16677181699666568.03**34 - 1float(3**34)16677181699666569float(3**34) != 3**34
为了保证数值类型等价关系的传递性,这个属性很重要。如果比较会给出类似的结果,就好像对象将转换为对象一样,那么传递关系将无效:intfloatintfloat
>>> class Float(float):\n... def __eq__(self, other):\n... return super().__eq__(float(other))\n... \n>>> a = 3**34 - 1\n>>> b = Float(3**34)\n>>> c = 3**34\n>>> a == b\nTrue\n>>> b == c\nTrue\n>>> a == c # transitivity demands that this holds true\nFalse\nRun Code Online (Sandbox Code Playgroud)\n\n另一方面float.__eq__,考虑所表示的数学数字的实现并不违反该要求:
>>> a = 3**34 - 1\n>>> b = float(3**34)\n>>> c = 3**34\n>>> a == b\nTrue\n>>> b == c\nFalse\n>>> a == c\nFalse\nRun Code Online (Sandbox Code Playgroud)\n\n由于缺少传递性,以下列表的顺序不会因排序而改变(因为所有连续的数字看起来都相等):
\n\n>>> class Float(float):\n... def __lt__(self, other):\n... return super().__lt__(float(other))\n... def __eq__(self, other):\n... return super().__eq__(float(other))\n... \n>>> numbers = [3**34, Float(3**34), 3**34 - 1]\n>>> sorted(numbers) == numbers\nTrue\nRun Code Online (Sandbox Code Playgroud)\n\nfloat另一方面,顺序相反:
>>> numbers = [3**34, float(3**34), 3**34 - 1]\n>>> sorted(numbers) == numbers[::-1]\nTrue\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1047 次 |
| 最近记录: |