python - print('%.70f' % (0.2 + 0.1)) 输出中的 36 位补丁
问题描述
我理解为什么0.1 + 0.2
在 Python 3 中产生这个:
>>> 0.1 + 0.2
0.30000000000000004
...但我不明白为什么在如下所示的输出中间有一段 36 位(大部分)非零数字:
>>> print('%.70f' % (0.2 + 0.1))
0.3000000000000000444089209850062616169452667236328125000000000000000000
我确实希望 0.1 + 0.2 和最接近 0.1 + 0.2 的二进制 IEEE 754 浮点数之间存在差异,但我不明白为什么这种差异会导致 36 位表示(对应于大约 ~120 位的精度)。
我可以理解错误是否具有更小(< 53 位)的精度,或者具有(明显的)无限精度,可能是由于评估算法的伪影所致'%.70f' % (0.2 + 0.1)
。但我无法理解会导致上面显示的 36 位补丁的错误。
解决方案
您正在使用的 Python 实现显然将 IEEE-754 binary64 用于浮点。(这很常见,但 Python 没有强制要求。)
在这种格式中,数字表示为 2 的幂的倍数,其中使用的 2 的特定幂取决于数字的大小。(浮点格式也以其他数学上等效的方式描述,例如使用具有固定小数位数的有效位而不是我在此处使用的整数倍数。这种描述更容易解释手。)
对于 0.3 左右的数字,使用的 2 的幂是 2 −54。在舍入以适应浮点格式后添加.1
and的结果是 5404319552844596 乘以 2 −54或 5404319552844596 / 2 54。.2
这个数字 5404319552844596 / 2 54正好是 0.3000000000000000444089209850062616169452667236328125。
推荐阅读
- oracle - 从 Oracle DB 创建的 SAS 表无法加载到 CAS VIYA
- c# - 列出不同用户给定目录的内容,Linux
- c# - 使用c#通过蓝牙读取数据
- smartsheet-api - 未检索 Smartsheet 注释 C#
- dynamics-crm - 在为 Dynamics 365 创建 IServiceManagement 时,为什么身份验证终结点会使用 HTML 登录页面进行响应?
- rest - 当我们使用 REST API 时,6.5 和 6.0 vcenter 之间是否存在差异
- reactjs - Typescript,在 Redux 操作中测试 Api 调用,在 Enzyme 中模拟类,Jest
- c# - Swagger 显示不正确的查询参数
- content-security-policy - CSP“自我”在各种指令中都失败了
- html5-canvas - 如何将SVG文本节点的“字母间距”值映射到FabricJS中fabric.TextBox的“charSpacing”属性?