-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 我不知道为什么这个问题会得到很多投票!

4

4 回答 4

8

您引用的语言使用 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。

这里的教训是浮点运算通常是近似的,因此在评估具有不连续性(如地板)或陡坡的函数时必须小心。您必须设计代码以接受可能跨越间断的结果,或者必须设计计算以避免跨越间断的错误。

于 2013-10-21T21:42:56.603 回答
4

您的前两个示例是可以预期的:

  • 8.2 - 0.217.99。的楼层7.997,这就是返回的内容。请记住,它floor(x)是小于或等于 的最大整数x8大于7.99,因此不可能返回。7,另一方面,满足这个要求。

  • 8.21 - 0.28.01。楼层8.018——这里没有魔法。


>>> math.floor(8.2-0.2)
7.0

现在这更有趣了。它与不能用浮点数精确表示的事实有关8.20.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')

相关:每个计算机科学家都应该知道的关于浮点运算的知识

于 2013-10-21T21:07:57.233 回答
0
>>> a=0.2
>>> a
0.20000000000000001
>>> b = 8.2
>>> b
8.1999999999999993
>>> b-a
7.9999999999999991
>>> math.floor(b-a)
7.0

由于浮点数不准确

于 2013-10-21T21:40:08.640 回答
0

为什么应该是8?楼层函数返回最接近的向下舍入的整数,因此这两个示例是正确的。

8.2 - 0.21 = 7.99,向下取整为 7。

8.21 - 0.2 = 8.01,向下取整为 8。

于 2013-10-21T21:09:57.117 回答