Python2数学.fsum不准确?

2024-05-03 05:58:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用python2数学模块来计算fsum的和。我知道0.1通常不能存储为二进制。据我所知数学.fsum该怎么解决这个问题。

import math
math.fsum([0.0, 0.1])
#0.1
math.fsum([0.1, 0.1])
#0.2
math.fsum([0.2, 0.1])
#0.30000000000000004
math.fsum([0.3, 0.1])
#0.4
math.fsum([0.4, 0.1])
#0.5

所以数学.fsum([0.2,0.1])==0.3将为False。这应该是这样吗?我做错什么了吗?

我怎样才能得到0.2+0.1==0.3是真的呢?


Tags: 模块importfalse二进制数学mathpython2fsum
2条回答

你误解了math.fsum的作用。它计算给定输入的最精确的可能和(即,与输入的精确数学和最接近的精确可表示值)。它不会神奇地用你最初想到的数字替换它的输入。在

在上面的第三行,math.fsum的输入是一个包含值0.1000000000000000055511151231257827021181583404541015625和{}的列表(请记住,对于二进制浮点,您看到的并不是您得到的结果;这里我展示的是Python使用的确切值)。这两个值的确切和是0.3000000000000000166533453693773481063544750213623046875,而与这个确切的和最接近的可表示的ieee754binary64 float是0.3000000000000000444089209850062616169452667236328125,这就是您得到的。在

您要求math.fsum的行为就像给了它精确的值0.1和{},但它无法知道这正是您想要的:它只能对您给它的输入进行操作。在

注意,在大多数机器上,两个浮点的加法已经被正确舍入,所以使用math.fsum没有任何好处。math.fsum旨在消除与两个浮点数相加时涉及的舍入误差累积。在

实际上,您应该避免对float使用equal运算符。因为计算机用二进制表示它们,而且只有浮点的近似值。在

如果确实需要检查两个浮点是否相等,则需要定义一个公差:

例如:

def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
    return abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)

请参考以下内容:

What is the best way to compare floats for almost-equality in Python?

我发现了一个有趣的网站:

http://0.30000000000000004.com/

在大多数语言中,0.1+0.2不等于0.3。在

相关问题 更多 >