python - Python如何处理浮点数的重复减法?
问题描述
我有一个非常简单的代码,它接受一个浮点数,并使用一个 while 循环来不断减 1,直到它达到零:
nr = 4.2
while nr > 0:
print(nr)
nr -= 1
我希望输出看起来像这样:
4.2
3.2
2.2
etc...
但相反,我得到了这个:
4.2
3.2
2.2
1.2000000000000002
0.20000000000000018
这些奇怪的浮点数从何而来?为什么它只发生在第三次执行循环之后?此外,非常有趣的是,当 nr 的最后一位小数为 5 时,不会发生这种情况。
发生了什么,我该如何预防?
解决方案
执行后nr = 4.2
,您的 Python 设置nr
为 4.20000000000000017763568394002504646778106689453125。这是将 4.2 转换为基于二进制的浮点格式所产生的值。
随后的减法显示的结果似乎仅由于格式决定而在低位数字上有所不同。浮点数的默认格式不显示所有数字。Python 对浮点行为并不严格,但我怀疑您的实现可能会显示与唯一区分二进制浮点数所需的一样多的十进制数字。
对于“4.2”、“3.2”和“2.2”,这只是两个有效数字,因为这些十进制数字接近实际的二进制浮点值。
接近 1.2 时,浮点格式具有更高的分辨率(因为值下降到 2 以下,意味着指数减小,因此将有效数字的有效位置移低,使其能够在绝对比例上包含另一位分辨率)。结果,恰好在 1.2 附近有另一个二进制浮点数,因此显示“1.2000000000000002”以区分当前输入的数字nr
和其他数字。
在 .2 附近,分辨率更高,因此附近的二进制浮点数更多,必须使用更多的数字来区分值。
推荐阅读
- macos - 如何使用 otool 打印库的完整路径?
- c# - 有没有办法仅使用 XAML 根据 It own Text 更改 Texblock 前景?
- php - WordPress | 在 termmeta 表中创建用于保存值的元框
- c - 为什么静态全局变量可以在其他文件中访问?
- .htaccess - WordPress 网站子目录中的 Yii2 应用程序:无法启用漂亮的网址
- python - AWS Glue 从 VPC 中的 RDS 数据库读取
- kubernetes - 终结器如何为 CustomResouce 对象工作?
- java - 为什么 Intellij 不允许我使用 VBox 类?
- php - PHP - 不同的值具有相同的结果
- javascript - 用户单击 Jquery 自动完成结果后如何隐藏输入中的代码?