Python round()和numpy.round()之间的引擎盖下差异是什么?
让我们看一看不断令人震惊的回合声明:Python round()和numpy.round()之间的引擎盖下差异是什么?,python,numpy,rounding,Python,Numpy,Rounding,让我们看一看不断令人震惊的回合声明: >>> round(2.675, 2) 2.67 我知道为什么回合“失败”;这是因为2.675的二进制表示: >>> import decimal >>> decimal.Decimal(2.675) Decimal('2.67499999999999982236431605997495353221893310546875') 我不明白的是:为什么NumPy没有失败 >>> impo
>>> round(2.675, 2)
2.67
我知道为什么回合“失败”;这是因为2.675的二进制表示:
>>> import decimal
>>> decimal.Decimal(2.675)
Decimal('2.67499999999999982236431605997495353221893310546875')
我不明白的是:为什么NumPy没有失败
>>> import numpy
>>> numpy.round(2.675, 2)
2.6800000000000002
思考
不要介意额外的零;这是Python打印内部舍入的人工制品。如果我们看一下“精确”值,它们仍然是不同的:
>>> decimal.Decimal(round(2.675, 2))
Decimal('2.6699999999999999289457264239899814128875732421875')
>>> decimal.Decimal(numpy.round(2.675, 2))
Decimal('2.680000000000000159872115546022541821002960205078125')
为什么,为什么,为什么,努比的行为
起初我认为NumPy必须使用额外的位来处理浮动,但是:
>>> decimal.Decimal(numpy.float(2.675))
Decimal('2.67499999999999982236431605997495353221893310546875')
>>> decimal.Decimal(2.675)
Decimal('2.67499999999999982236431605997495353221893310546875')
# Twins!
窗帘后面发生了什么?我看了一下NumPy's,但我是Python新手,我没有看到任何过分可疑的东西。一个在引擎盖上的区别被记录下来: 在数字中间的情况下,舍入到最接近的“偶数”数字(乘以
10**n
后,n
是相应舍入
函数的第二个参数),而舍入到0
>>> np.round(2.685, 2)
2.6800000000000002
>>> round(2.685, 2)
2.69
在引擎盖下,使用缩放参数时可以获得差异。考虑<代码>圆(2.675×10 ** 2)< /代码>和<代码>圆(2.675,2)< /代码>之间的差异。这当然是浮点数学的结果,因为它总是有一些舍入误差。为了更进一步,我们需要看一下真正的实现。在这种情况下,n是什么?@HankDitton——round的第二个参数。对不起,应该更明确一些。为什么在你的例子中,
np.round
round是错误的-我认为是相反的,参见OP。OP的示例中,“最接近的偶数”和“远离零”是相同的。@user2357112——这是一个公平的点。当有疑问时。归咎于浮点数学:)。考虑<代码>圆(2.675×10 ** 2)< /代码>和<代码>圆(2.675,2)< /代码>之间的差异。显然,round
处理这一问题的可能性并不完全一致,因为乘以100后,该值不再正好介于这两个值之间。严格地说,2.67是更好的结果。2.68是一个舍入错误。我不是numpy或python适当源代码方面的专家,但我认为numpy实现在这里:python实现在这里: