您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

在Python底数划分中舍入错误

在Python底数划分中舍入错误

正如您和海尔伍德已经注意到的那样,0.4不能完全表示为浮点数。为什么?它是五分之二(4/10 == 2/5),没有有限的二进制分数表示形式。

尝试这个:

from fractions import Fraction
Fraction('8.0') // Fraction('0.4')
    # or equivalently
    #     Fraction(8, 1) // Fraction(2, 5)
    # or
    #     Fraction('8/1') // Fraction('2/5')
# 20

然而

Fraction('8') // Fraction(0.4)
# 19

在这里0.4被解释为一个浮动文本(以及因此浮点二进制数)需要(二进制)舍入,并且只有 然后 转化为有理数Fraction(3602879701896397, 9007199254740992),这几乎是但不完全4/10。然后执行地板划分,而且因为

19 * Fraction(3602879701896397, 9007199254740992) < 8.0

20 * Fraction(3602879701896397, 9007199254740992) > 8.0

结果是19,而不是20。

同样的事情可能发生

8.0 // 0.4

即,似乎地板分割是原子确定的(但仅在解释的float文字的近似float值上)。

那为什么

floor(8.0 / 0.4)

给出“正确”的结果?因为在那里,两个舍入错误彼此抵消。 首先 1)进行除法,得到的东西略小于20.0,但不能表示为float。它四舍五入到最接近的浮点数,恰好是20.0。只有到 那时 ,该floor操作才被执行,但现在 恰好 作用于该操作20.0,因此不再更改该数字。

1)由于凯尔-斯特兰德指出,该确切的结果确定 圆 什么 实际 发生的低2) -电平(cpython中的C代码,甚至cpu指令)。但是,它对于确定预期的3)结果可能是有用的模型。

2)在 最低的 4)级别上,这可能相差不远。一些芯片组通过首先计算更精确的(但仍然不精确,只是具有更多的二进制数字)内部浮点结果,然后舍入为IEEE双精度来确定浮点结果。

3)由Python规范“预期”,不一定是我们的直觉。

4)那么,逻辑门 上方的 最低水平。我们不必考虑使半导体成为可能的量子力学。

python 2022/1/1 18:52:12 有296人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶