【发布时间】:2021-12-26 16:22:30
【问题描述】:
我知道浮点运算中会发生舍入错误,但有人可以解释一下原因:
>>> 8.0 / 0.4 # as expected
20.0
>>> floor(8.0 / 0.4) # int works too
20
>>> 8.0 // 0.4 # expecting 20.0
19.0
这发生在 x64 上的 Python 2 和 3 上。
在我看来,这要么是一个错误,要么是 // 的一个非常愚蠢的规范,因为我看不出最后一个表达式应该评估为 19.0 的任何理由。
为什么a // b 不简单定义为floor(a / b)?
编辑:8.0 % 0.4 也计算为0.3999999999999996。至少这是随之而来的,因为那时8.0 // 0.4 * 0.4 + 8.0 % 0.4 评估为8.0
编辑:这不是 Is floating point math broken? 的重复,因为我在问为什么这个特定的操作会出现(也许可以避免的)舍入错误,以及为什么 a // b 没有被定义为 /等于floor(a / b)
REMARK:我想这不起作用的更深层原因是楼层划分是不连续的,因此有一个无限的condition number,使其成为一个不适定问题。楼层除法和浮点数根本不兼容,你永远不应该在浮点数上使用//。只需使用整数或分数即可。
【问题讨论】:
-
有趣的是,
'%.20f'%0.4给出了'0.40000000000000002220',所以0.4显然比0.4略高一点。 -
@khelwood
floor(8.0/0.4)如何产生正确的结果? -
首先,
float类型的浮点数通常是错误的。其次,//和%对于负数和float数字非常不可靠(意思是意外行为)。 documentation on Decimal objects 简要讨论了带有负整数的//以及Decimal库如何以不同的方式处理它。 -
@AlexanderVogt 不是吗?问题不在于为什么浮点结果不准确,而在于为什么 python 为
floor(8.0/0.4)和“floor-division”8.0//0.4做了两种不同的事情。
标签: python python-2.7 python-3.x floating-point rounding