Python 2.7第1位小数不正确



小数点后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中遇到的问题的最佳方法。

最新更新