Python3.8 带小数的四舍五入 带浮点数或字符串的构造函数

Python3.8 Round with decimal Constructor with Float or String

我在处理 python 十进制模块时遇到了一些奇怪的行为

示例如下:

print(round(Decimal('0.005'),2))
>>> Decimal('0.00')
print(round(Decimal(0.005),2))
>>> Decimal('0.01')


print(round(Decimal('0.006'),2))
>>> Decimal('0.01')
print(round(Decimal(0.006),2))
>>> Decimal('0.01')

谁能解释为什么会这样,我怎样才能将 Decimal('0.005') 转换为 Decimal(0.005)

您注意到十进制数字的浮点表示法

>>> Decimal(0.005) 
Decimal('0.005000000000000000104083408558608425664715468883514404296875')

等于 0.005 吗?

>>> 0.005 == 0.005000000000000000104083408558608425664715468883514404296875
True

在四舍五入阶段,由于值 > 0.005,因此四舍五入为 0.01

这是预期的行为。

how can I convert Decimal('0.005') to Decimal(0.005)

>>> round(Decimal(float('0.005')), 2)
Decimal('0.01')

但是,这可能不是您想要的。 在我看来,正确的做法是将您的输入忠实地转换为小数,然后明确应用舍入策略。

将浮点输入转换为十进制

有几个选项。

  1. 应用str您的输入

    >>> Decimal(str(0.005)) == Decimal(str('0.005'))
    True
    
  2. quantize 将浮点数转换为十进制后。 quantize 还允许您舍入并指定确切的舍入方法。请注意,在这里,我没有使用量化方法四舍五入(该示例在下面进一步介绍)。在这里,我指定与输入相同的位数。

    >>> Decimal(0.005).quantize(Decimal('1.000'))
    Decimal('0.005')
    

要四舍五入,您可以像您所做的那样在 Decimal 对象上调用 round。或者你可以使用Decimal.quantize方法

Decimal(0.005).quantize(Decimal('1.00'), rounding=<ROUNDING_METHOD>)

在哪里找到可用的 ROUNDING_METHOD in the documentation for the decimal module

如果您希望 Decimal(0.005) 始终向上舍入,请指定 ROUND_HALF_UP。但是,请注意 python 3 的默认舍入行为是 ROUND_HALF_EVEN(也称为银行家舍入),这就是为什么 round(Decimal('0.005'), 2) 输出 0.00