The code
import numpy as np
a = 5.92270987499999979065
print(round(a, 8))
print(round(np.float64(a), 8))
gives
5.92270987
5.92270988
知道为什么吗?
在 numpy 来源中找不到任何相关内容。
Update:
我知道处理这个问题的正确方法是以这种差异无关紧要的方式构建程序。我就是这么做的。我在回归测试中偶然发现了它。
Update2:
关于@VikasDamodar 评论。人们不应该相信repr()
功能:
>>> np.float64(5.92270987499999979065)
5.922709875
>>> '%.20f' % np.float64(5.92270987499999979065)
'5.92270987499999979065'
Update3:
在 python3.6.0 x32、numpy 1.14.0、win64 上测试。也在 python3.6.4 x64、numpy 1.14.0、debian 上。
Update4:
只是要确定:
import numpy as np
a = 5.92270987499999979065
print('%.20f' % round(a, 8))
print('%.20f' % round(np.float64(a), 8))
5.92270987000000026512
5.92270988000000020435
Update5:
下面的代码演示了差异发生在哪个阶段,而不使用str
:
>>> np.float64(a) - 5.922709874
1.000000082740371e-09
>>> a - 5.922709874
1.000000082740371e-09
>>> round(np.float64(a), 8) - 5.922709874
6.000000496442226e-09
>>> round(a, 8) - 5.922709874
-3.999999442783064e-09
显然,在应用“round”之前,它们是相同的数字。
Update6:
与@user2357112的答案相反,np.round
大约比圆形慢 4 倍:
%%timeit a = 5.92270987499999979065
round(a, 8)
1.18 µs ± 26.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%%timeit a = np.float64(5.92270987499999979065)
round(a, 8)
4.05 µs ± 43.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
也在我看来np.round
甚至比内置的四舍五入效果更好round
:最初我通过将 11.84541975 除以二得到这个 5.92270987499999979065 数字。