【发布时间】: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 新手,我没有看到任何过于可疑的东西。
【问题讨论】:
-
我不是 numpy 或 python 正确源代码方面的专家,但我认为 numpy 实现在这里:github.com/numpy/numpy/blob/…,python 实现在这里:hg.python.org/cpython/file/1f1498fe50e5/Objects/…