Python2 math.fsum不准确吗?

时间:2016-01-07 08:35:50

标签: python math sum

我使用python2数学模块用fsum计算总和。我知道0.1通常不能存储二进制。就我所知,math.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

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

我怎样才能得到0.2 + 0.1 == 0.3为真?

2 个答案:

答案 0 :(得分:6)

你误解了math.fsum的作用。它计算给定输入的最准确可能总和 (即,与输入的精确数学和最接近的可精确表示的值)。它并没有用你原先想到的数字神奇地取代它的输入。

在上面的第三行中,math.fsum的输入是一个包含值0.10000000000000000555111512312578270211815834045410156250.200000000000000011102230246251565404236316680908203125的列表(请记住,使用二进制浮点数,所见即所得不是你获取;这里我显示了Python使用的确切值。这两个值的精确总和是0.3000000000000000166533453693773481063544750213623046875,最接近的可表示的IEEE 754 binary64浮动到那个精确的总和是0.3000000000000000444089209850062616169452667236328125,这正是你得到的。

您要求math.fsum的行为就像给出了确切的值0.10.2一样,但它无法知道这些是什么你想要什么:它只能对你提供的输入进行操作。

请注意,在大多数机器上,添加两个浮点数已经正确舍入,因此使用math.fsum没有任何优势。 math.fsum旨在消除累加 more 所涉及的舍入错误的累积,而不是两个浮点数。

答案 1 :(得分:1)

实际上,你应该避免使用等于运算符的浮点数。因为计算机以二进制形式呈现它们,并且只是浮点数的近似值。

如果你真的需要检查两个浮点数是否相等,你需要定义一个容差:

例如:

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)

请参考:

enter image description here

我发现这个有趣的网站:

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

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