【问题标题】:What are the under-the-hood differences between round() and numpy.round()?round() 和 numpy.round() 之间的底层区别是什么?
【发布时间】:2013-12-04 23:12:20
【问题描述】:

让我们来看看令人震惊的圆形声明:

>>> 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 为什么会这样?

一开始我以为 NumPy 必须使用额外的位来处理浮点数,但是:

>>> decimal.Decimal(numpy.float(2.675))
Decimal('2.67499999999999982236431605997495353221893310546875')
>>> decimal.Decimal(2.675)
Decimal('2.67499999999999982236431605997495353221893310546875')
# Twins!

窗帘后面发生了什么?我看了一下 NumPy 的 round implementation,但我是一个 Python 新手,我没有看到任何过于可疑的东西。

【问题讨论】:

标签: python numpy rounding


【解决方案1】:

记录了最重要的差异:

如果您在数字之间,np.round 会舍入到最接近的“偶数”数字(在乘以 10**n 后,n 是相应 round 函数的第二个参数)而 @ 987654322@ 从 0 舍入。

>>> np.round(2.685, 2)
2.6800000000000002
>>> round(2.685, 2)
2.69

在后台,您可以在使用缩放参数时获得差异。考虑round(2.675 * 10.**2)round(2.675, 2) 之间的区别。这当然是浮点数学的结果,它总是有一些与之相关的舍入误差。要想更进一步,我们真的需要看看真正的实现。

【讨论】:

  • 这里的 n 是什么?
  • @HankDitton -- round 的第二个参数。抱歉,应该更明确一点。
  • 为什么np.round 在你的情况下是错误的 - 我认为这是相反的,参见。 OP。
  • “最近的偶数”和“远离零”在 OP 的示例中是相同的。
  • @user2357112 -- 这是一个公平的观点。有疑问时。责备浮点数学:)。考虑round(2.675 * 10.**2)round(2.675, 2) 之间的区别。显然,round 并没有完全一致地处理这个问题,因为在乘以 100 之后,该值不再正好在两个值之间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-12
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多