1

我在做功课时发现了这个有趣的问题,我们知道,47.36/1.6**2 == 18.5

但是当我尝试运行以下代码时,它给了我一个 False(应该是真的)

打印47.36/1.6**2 == 18.5

有谁知道发生了什么?

4

6 回答 6

4

您可能会得到类似 18.49999999999 的答案,它并不完全等于 18.5。

与往常一样,相关参考资料是What Every Computer Scientist Should Know About Floating-Point Arithmetic

于 2012-10-16T00:03:57.523 回答
1

简短回答:IEEE 754 浮点不能准确表示分母不是 2 的幂的分数,例如 1/4、1/16、1/256 等。如果有足够的数字,您可以非常接近,但是从来没有完全在那里。

您可以通过将“等于”定义为“在某个增量内”来比较浮点数。你可以这样写:

def almost_equals(a, b, delta=0.0005):
    return abs(a - b) <= delta

然后用以下方法测试“可能相等”:

>>> almost_equals(47.36/1.6**2, 18.5)
True
于 2012-10-16T00:08:45.630 回答
1
>>> 47.36/1.6**2
18.499999999999996

请参阅此页面上的浮点算术:问题和限制

以下是如何通过使用小数模块18.5在不使用任何舍入或“足够接近”的行为的情况下精确计算:

>>> from decimal import Decimal
>>> Decimal('47.36') / Decimal('1.6')**2 == Decimal('18.5')
True
>>> float(Decimal('47.36') / Decimal('1.6')**2) == 18.5
True
于 2012-10-16T00:05:33.837 回答
1

在比较两个浮点数时,我会避免检查是否完全相等。取而代之的是,看看它是否小于您认为接近零的值。

(47.36/1.6**2 - 18.5) < 0.00000000001

将会

真的

于 2012-10-16T00:11:35.853 回答
1

正如其他人所说:

>>> 47.36/1.6**2
18.499999999999996

但是,据我所知,这不是由于浮点算术问题。即使您通过将操作数包装在Decimal()(之后from decimal import Decimal)中来使用十进制数学,您仍然会得到Decimal('18.49999999999999772404279952')答案。

我可能在Decimal()这里用错了,我的结果也有某种浮点错误;18.5但是,如果我是正确的,那么无论您使用哪种数学,该表达式都不等于。

编辑:正如格雷格在评论中指出的那样,我的方法的问题是 Decimal(1.6) 只会将 1.6 的浮点表示(不准确)转换为 Decimal。这给出了正确的答案:

>>> Decimal('47.36') / Decimal('1.6')**2
Decimal('18.5')

更好的是使用Kirk 建议的分数模块。

于 2012-10-16T00:12:39.737 回答
-3

47.36/1.6* 2 返回整数。所以 47.36/1.6 *2 将是 18,不等于 18.5。

编辑

很抱歉,实际上它被存储为 18.499999。
你应该做这个

import numpy as np
print np.around((47.36/1.6**2), decimals=1) == 18.5

这将返回 True。

于 2012-10-16T00:04:16.520 回答