python - 格式化数值与舍入值之间的差异

标签 python numpy rounding number-formatting

我使用 python 和 numpy 发现了这种奇怪的行为:

print('%10.3f' %0.4975)

返回 0.497,而

numpy.round(0.4975,3)

按预期返回 0.498。 对于其他类似的数字,我总是得到打印语句来提供正确舍入的值(例如:0.5975 --> 0.598)。 为什么是这样? 我在 Windows 7 上使用 python 3.4 和 numpy 1.9.2。

最佳答案

在 double 中,0.4975 是 8962163258467287/18014398509481984,比实数 0.4975 略小于。因此,Python 的 round 函数将其四舍五入为 0.497。

相比之下,0.5975 变为 5381801554707743/9007199254740992,比实数 0.5975 略更多。所以我们在四舍五入时得到了预期的 0.598。

为什么 NumPy 将 0.4975 舍入为 0.498?它的算法有点不同:要舍入到 N 位,它将给定数字乘以 10 的 N 次方,舍入到最接近的整数(最好是偶数),然后除以 10^N。在乘以10的幂的过程中,截断的方向发生变化;结果通常会得到一个半整数。 (示例:0.15*10 = 1.5 正好是 3/2,尽管 0.15 不正好是 3/20)。

简单来说,np.round(x, 3) 等同于round(x*1000)/1000。您可以检查当应用于 x = 0.4975 时两者都返回 0.498。实际上,在 double 中,0.4975*1000 恰好 497.5(即 995/2),然后正确选择舍入方向。

以下是 0.05、0.15、0.25 等四舍五入方式的比较:

python

>>> [round((2*i+1)/20, 1) for i in range(10)] 
[0.1, 0.1, 0.2, 0.3, 0.5, 0.6, 0.7, 0.8, 0.8, 0.9]  

NumPy

>>> import numpy as np
>>> np.around([(2*i+1)/20 for i in range(10)], 1)
array([ 0. ,  0.2,  0.2,  0.4,  0.4,  0.6,  0.6,  0.8,  0.8,  1. ])

这里的 NumPy 输出是人们在不考虑二进制表示的情况下所期望的。

然而,np.around([(2*i+1)/200 for i in range(100)], 2) 表明 NumPy 的算法并不总是符合预期,或者:有两个数字(0.55 和 0.57),末尾是奇数。问题是,例如,0.545*100 并不完全是 109/2;相反,它是 7670193115365377/140737488355328。

关于python - 格式化数值与舍入值之间的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38422170/

相关文章:

python - 文件夹名称带有\n

python - 平滑逼近 floor 函数以用于反向传播

python - 如何处理Python中Spearman测试中的nan_policy错误

python - 有没有办法知道在 python 中是向上舍入还是向下舍入?

Android:我可以创建一个不是矩形的 View / Canvas 吗?圆形的?

php - 当 PHP 精度设置为 18+ 时 round() 中断

Python 3.4 Tkinter : Frames and Command issues

python - 追加元组的元组

Python crypt 包 : Can type extra characters in password

numpy - SciPy: `scipy.special.fresnel(x[, out1, out2])` 中的参数是什么?