小数点后1位舍入不正确:
见下文:
round(11.35, 1)
11.3
round(1.35, 1)
1.4
如何在Python中解决此问题?
这个问题的解决方案是:
def round_decimal(value, rounding):
number = decimal.Decimal(str(value))
decimal_point = float("1e%d" % -rounding)
return float(number.quantize(decimal.Decimal(str(decimal_point))))
这是计算机中小数表示的一个问题(对于Python来说是不特定的)。
我认为解决这个问题的方法是使用标准库模块decimal
。在你的情况下,它看起来像这样:
num1 = decimal.Decimal("11.35")
print num1.quantize(decimal.Decimal("0.1")) # round to one decimal
# output: 11.4
num2 = decimal.Decimal("1.35")
print num2.quantize(decimal.Decimal("0.1"))
# output: 1.4
原因是11.35被保存为float
,使用二进制浮点表示进行存储。11.35不能精确地表示为二进制浮点值。
可表示的二进制浮点值的形式为s×2e,其中s和e是整数。请注意,11.35不能以这种形式编写。在Python中编写11.35
时,系统会使用最接近的可表示值。
最接近11.35的双精度值为:
11.35 = + 11.34999 99999 99999 64472 86321 19949 90706 44378 66210 9375
这就解释了为什么round(11.35, 1)
的行为如此。
有趣的是,round(11.35, 1)
甚至不完全等于11.3,因为11.3不能用二进制浮点精确表示。就这样,
如果您想精确地表示11.35,那么您需要将其存储在十进制数据类型中。decimal
标准库是在Python中实现这一点的明显方法。这个问题详细介绍了这个主题:如何设置小数点的格式以始终显示小数点后2位?
除了前面的答案之外,我认为了解四舍五入的规则很有帮助。您假设值11.35应该四舍五入到11.4,但实际上,当您在四舍五舍五入中达到中点值时,可以选择向下舍入。请参阅:http://en.wikipedia.org/wiki/Rounding
使用十进制库是解决您在python中遇到的问题的最佳方法。