格式字符串舍入不一致

Format string rounding inconsistent

在 Python 中,我使用格式字符串来使用逗号分隔符并四舍五入。但四舍五入并不一致。例如

>>> '{:,.0f}'.format(1.5)
'2' # Here it is increasing to next integer
>>> '{:,.0f}'.format(2.5)
'2' # Here it is suppose to give 3 as per the earlier logic.

这取决于小数点前的数字。如果是偶数,则 Python 通过增加整数值进行四舍五入,对于奇数则相反。

谁能帮我对所有数字进行一致的四舍五入

浮点数可能会有所不同,无法预测,例如 1.5 可能是 1.4999999 或 1.5000001。所以你不能指望 .5 尖锐值会得到相同的结果。

在这种情况下,有很多方法可以解决,比如加一个小数,比如0.0001

实际上,.format() 一直在四舍五入——只是不是您所期望的那样。

IEEE floating point standard 定义了两种不同的四舍五入方式。您期望它 远离零 :

 2.5    rounds to   3.0
 1.5    rounds to   2.0
 0.5    rounds to   1.0
-0.5    rounds to  -1.0
-1.5    rounds to  -2.0

另一种方法是四舍五入为偶数:

 2.5    rounds to   2.0
 1.5    rounds to   2.0
 0.5    rounds to   0.0
-0.5    rounds to  -0.0     (yes, this is different from 0)
-1.5    rounds to  -2.0

这种方法是无偏的,因为四舍五入后的数字 sum/average 更可能与原始数字的 sum/average 匹配。这就是为什么 IEEE 推荐将此作为舍入的 默认规则

四舍五入的实现因函数、版本而异。下面是 table 不同表达式的轮换方式:

x                           2.5     1.5     0.5     -0.5    -1.5
round(x) in Py 2.x  away    3.0     2.0     1.0     -1.0    -2.0
round(x) in Py 3.x  even    2.0     2.0     0.0     -0.0    -2.0    Changed behaviour
'{:.0f}'.format(x)  even    2       2       0       -0      -2
'%.0f' % x          even    2       2       0       -0      -2
numpy.around(x)     even    2.0     2.0     0.0      0.0    -2.0

另见 dawg's answer on how you can choose your own rounding behaviour using the Decimal module. And John La Rooy has answered a similar question