我在 python 中尝试过这个简单的数学运算
>>> math.floor(8.2-0.21)
7.0
>>> math.floor(8.21-0.2)
8.0
>>> math.floor(8.2-0.2)
7.0
第三个应该返回 8 但它是返回 7?!
更新
我已经在 PHP、ruby 和 JAVA 中尝试过,我得到了相同的结果。
更新 2 我不知道为什么这个问题会得到很多投票!
我在 python 中尝试过这个简单的数学运算
>>> math.floor(8.2-0.21)
7.0
>>> math.floor(8.21-0.2)
8.0
>>> math.floor(8.2-0.2)
7.0
第三个应该返回 8 但它是返回 7?!
更新
我已经在 PHP、ruby 和 JAVA 中尝试过,我得到了相同的结果。
更新 2 我不知道为什么这个问题会得到很多投票!
您引用的语言使用 IEEE-754 64 位二进制浮点或使用底层硬件的浮点,这可能是 IEEE-754 二进制浮点。
In IEEE-754 64-bit binary floating-point, the nearest representable value to 8.2 is 8.199999999999999289457264239899814128875732421875, and the nearest representable value to .2 is 0.200000000000000011102230246251565404236316680908203125.
所以,当你写的时候8.2 - 0.2
,实际发生的是从 8.199999999999999289457264239899814128875732421875 中减去 0.200000000000000011102230246251565404236316680908203125。结果是一个略低于 8 的值,而一个略低于 8 的值的下限是 7。
这里的教训是浮点运算通常是近似的,因此在评估具有不连续性(如地板)或陡坡的函数时必须小心。您必须设计代码以接受可能跨越间断的结果,或者必须设计计算以避免跨越间断的错误。
您的前两个示例是可以预期的:
8.2 - 0.21
是7.99
。的楼层7.99
是7
,这就是返回的内容。请记住,它floor(x)
是小于或等于 的最大整数x
。8
大于7.99
,因此不可能返回。7
,另一方面,满足这个要求。
8.21 - 0.2
是8.01
。楼层8.01
是8
——这里没有魔法。
>>> math.floor(8.2-0.2)
7.0
现在这更有趣了。它与不能用浮点数精确表示的事实有关8.2
,0.2
所以计算的结果可能不是你想象的那样:
>>> 8.2 - 0.2
7.999999999999999
再次,按记录floor()
工作。
您可以使用以下命令自己查看decimal
:
>> from decimal import Decimal
>>> Decimal(0.2)
Decimal('0.200000000000000011102230246251565404236316680908203125')
>>> Decimal(8.2)
Decimal('8.199999999999999289457264239899814128875732421875')
>>> a=0.2
>>> a
0.20000000000000001
>>> b = 8.2
>>> b
8.1999999999999993
>>> b-a
7.9999999999999991
>>> math.floor(b-a)
7.0
由于浮点数不准确
为什么应该是8?楼层函数返回最接近的向下舍入的整数,因此这两个示例是正确的。
8.2 - 0.21 = 7.99,向下取整为 7。
8.21 - 0.2 = 8.01,向下取整为 8。