-3

我今天花了一个小时试图找出原因

return abs(val-desired) <= 0.1

偶尔会回来False,尽管valdesired有绝对差异<=0.1。经过一番调试,我发现-13.2 + 13.3 = 0.10000000000000142. 现在我明白 CPU 不能轻易地表示大多数实数,但这是一个例外,因为您可以减去0.00000000000000142和获取0.1,所以它可以用 Python 表示。

我在 Intel Core 架构 CPU 上运行 Python 2.7(这是我能够测试的全部)。0.1尽管无法将算术应用于特定的浮点值,但我很想知道如何存储 的值。val并且desiredfloat价值观。

4

3 回答 3

4

是的,这可能有点令人惊讶:

>>> +13.3
13.300000000000001
>>> -13.2
-13.199999999999999
>>> 0.1
0.10000000000000001

所有这些数字都可以用大约 16 位的精度表示。所以为什么:

>>> 13.3-13.2
0.10000000000000142

为什么在这种情况下只有 14 位的准确度?

嗯,那是因为 13.3 和 -13.2 有 16 位精度,这意味着 14位小数点,因为小数点前有两位数。所以结果也有 14位小数的精度。即使计算机可以用 16 位数字表示数字。

如果我们使数字更大,结果的准确性会进一步降低:

>>> 13000.3-13000.2
0.099999999998544808

>>> 1.33E10-13.2E10
-118700000000.0

简而言之,结果的准确性取决于输入的准确性。

于 2013-08-08T11:26:52.247 回答
1

“现在我明白 CPU 不能轻易地以高分辨率表示大多数浮点数”,你问这个问题的事实表明你不明白。实数值 13.2、13.3 和 0.1 都不能精确地表示为浮点数:

>>> "{:.20f}".format(13.2)
'13.19999999999999928946'
>>> "{:.20f}".format(13.3)
'13.30000000000000071054'
>>> "{:.20f}".format(0.1)
'0.10000000000000000555'
于 2013-08-08T11:26:04.937 回答
1

要直接解决您的“当我有不精确的浮点数时如何存储像 0.1 这样的值并与之进行精确比较”的问题,答案是使用不同的类型来表示您的数字。Python 有一个十进制模块,用于进行十进制定点和浮点数学运算,而不是二进制——显然,在十进制中,0.1、-13.2 和 13.3 都可以精确表示而不是近似表示;或者,您可以在使用小数进行计算时设置特定的精度级别,并丢弃低于该重要性级别的数字。

val = decimal.Decimal(some calculation)
desired = decimal.Decimal(some other calculation)
return abs(val-desired) <= decimal.Decimal('0.1')

另一种常见的替代方法是通过人为地乘以十的幂来使用整数而不是浮点数。

return not int(abs(val-desired)*10)
于 2013-08-08T13:53:41.253 回答