【发布时间】:2018-11-12 18:02:07
【问题描述】:
我偶然发现了一个由浮点精度引起的测试失败,并试图理解它。
简而言之:Python3 round 根据类型是 float 还是 numpy.float64 返回不同的值,尽管我认为 float==double==float64 和 Python3 并且 NumPy 应该四舍五入最接近偶数。
这里是例子:
npVal = np.float64(435)/100
pyVal = 435/100
print(round(npVal,1)) // 4.4
print(round(pyVal,1)) // 4.3
print(round(np.float64(pyVal),1)) // 4.4
print(round(float(npVal),1)) // 4.3
我知道 4.35 和 4.4 可能不能完全用 double 表示,但是为什么 numpy round 与 Python 不同,尽管它们都使用相同的数据类型并指定相似的函数?我使用了显式除法来避免输入舍入错误。
我不确定 4.35 的双精度值是多还是少,所以我不能说这些实现中的哪个是(可能是?)错误的。
有一个类似的问题:Strange behavior of numpy.round
有人指出,NumPy“四舍五入到最接近的偶数值”和“Python 2 和 Python 3 之间的行为发生了变化;Python 3 在此处的行为与 NumPy 相同”。
所以两者都应该做同样的事情并四舍五入到最接近的偶数值。所以如果 4.35 是一个精确的浮点数,4.4 是正确的答案,需要两者都返回。
【问题讨论】:
-
他们都是对的,
4.35在数轴上与4.4的距离与与4.3的距离相同。您可以尝试允许更多的小数位数将罐子踢得更远一点。 -
round的两个实现都应该按照对链接问题的评论中的解释进行舍入:“值得注意的是,这种行为在 Python 2 和 Python 3 之间发生了变化;Python 3 的行为与 NumPy 相同这里。”我在问为什么不是这样? -
@coldspeed 这不是重复的:另一个问题是关于 Python 2,这个问题使用
print函数,使用 Python 3 也是如此,它们应该具有相同的行为。跨度> -
Python 的
round是正确舍入的(但速度很慢)。 NumPy 不是(但更快)。不同的权衡。 (同意这不是重复的。) -
@coldspeed:这个问题不是重复的。它说
numpy.round舍入甚至是舍入十进制值之间的值。但是这个问题中的npVal不能正好在 4.3 和 4.4 之间,因为 4.35 不能用 64 位二进制浮点表示。最接近的可表示值是 4.3499999999999996447286321199499070644378662109375,应该向下取整。
标签: python numpy floating-point rounding