python - 为什么 python 对这些比较感到困惑?
问题描述
如果我在 Python 3.8.6 中运行此代码,我会得到输出False
:
(((3980 - 91 + 1)/(3980)) * ((1 / 3980)**(91 - 1))) > (((3981 - 91 + 1)/(3981)) * ((1 / 3981)**(91 - 1)))
但是,如果我在 WolframAlpha 中运行它,它会返回True
.
我猜这是由于浮动不精确而发生的。但是为什么它会发生在这里呢?在我为以下功能测试过的 1200 万个组合中s
,z
这只发生了两次。z = 91
和s = 3980
和。z = 92
_s = 3457
(((s - z + 1)/(s)) * ((1 / s)**(z - 1))) > ((((s+1) - z + 1)/(s+1)) * ((1 / (s+1))**(z - 1)))
另外,在您的口译员中尝试这些:
(((3458 - 92 + 1)/(3458)) * ((1 / 3458)**(92 - 1))) > (((3459 - 92 + 1)/(3459)) * ((1 / 3459)**(92 - 1)))
(((3457 - 92 + 1)/(3457)) * ((1 / 3457)**(92 - 1))) > (((3458 - 92 + 1)/(3458)) * ((1 / 3458)**(92 - 1)))
(((3456 - 92 + 1)/(3456)) * ((1 / 3456)**(92 - 1))) > (((3457 - 92 + 1)/(3457)) * ((1 / 3457)**(92 - 1)))
他们给出了这些结果:
True
False
True
为什么模式True False True
只发生在这些输入上?保持z
不变,没有其他s
返回值False
。
解决方案
舍入误差。如果您想准确了解,请阅读 IEEE 754 规范。您的数字非常小,它们在正常范围内,并且在您的示例中具有 5-10 位的精度。正常范围内的浮点数具有 53 位精度。
如果您使用它查看两个值,float.hex()
则会显示它们的确切二进制表示:
>>> (((3980 - 91 + 1)/(3980)) * ((1 / 3980)**(91 - 1))).hex()
'0x0.0p+0'
>>> (((3981 - 91 + 1)/(3981)) * ((1 / 3981)**(91 - 1))).hex()
'0x0.0p+0'
它们在 IEEE 754float64
精度下都非常小,它们都四舍五入为零。如果事实上最后一项真的很小:
>>> ((1/3981)**89).hex()
'0x0.0000000000327p-1022'
推荐阅读
- python - 无法通过套接字发送字节:消息太长
- azure - 您如何使用代码验证逻辑应用程序 microsoft.web/connections 连接
- python - 从多索引问题中去除空格 - 我的代码还删除了索引名称
- python - If the user inputs a position over 5. It is supposed to print `The account number not found`
- kubernetes - Kubernetes 无法访问从节点的 pod
- node.js - 如何在 gulp 任务上创建一个空文件?
- mysql - 当我尝试查询数据数组时,节点中的 MariaDB SQL 抛出 ER_PARSE_ERROR
- c - 使用 printf 在 yacc 中打印字符串文字标记会导致分段错误
- excel - VBA查找方法不返回实际上存在于工作表中的值
- javascript - 使用来自 aysnc Javascript http 请求的数据?(AWS 无服务器)