Python - 如何定义 Decimal.quantize 的舍入范围

sam*_*mba 6 python floating-point decimal rounding python-3.x

我编写了一个函数,用于将数字四舍五入到点右侧的特定位数。但我仍然不明白如何正确定义与量化一起使用的比例。

在下面的例子中,res1返回res2预期的结果。我发现了不同的示例来定义比例以在浮点之后有 2 个数字。使用“1.00”和“0.01”有什么区别?两者的工作方式似乎相同。

至于res3当我将浮点数传递给 Decimal 构造函数以获取 number_3 时 -ROUND_HALF_UP似乎在那里不起作用。为什么会出现这种情况?我应该如何定义从浮点数创建的小数的比例?

如果我将浮点数作为输入是获得量化工作的唯一方法 - 首先将浮点数转换为字符串?

from decimal import Decimal, ROUND_HALF_UP


def custom_round(dec: Decimal, scale, rounding_mode):
    return dec.quantize(Decimal(scale), rounding_mode)


number_1 = Decimal("10.026")
res1 = custom_round(number_1, "1.00", ROUND_HALF_UP)
print(res1) # 10.03

number_2 = Decimal("28.525")
res2 = custom_round(number_2, "0.01", ROUND_HALF_UP)
print(res2) # 28.53

number_3 = Decimal(28.525)
res3 = custom_round(number_3, "0.01", ROUND_HALF_UP)
print(res3) # 28.52 
Run Code Online (Sandbox Code Playgroud)

Tim*_*ers 4

在这种情况下,“1.00”和“0.01”之间没有区别。与二进制浮点不同,十进制实例具有有效尾随零的概念,并且仅quantize()用于内部指数。的确,

>>> custom_round(Decimal("28.525"), "1234.56", ROUND_HALF_UP)
Decimal('28.53')
>>> custom_round(Decimal("28.525"), "000000.00", ROUND_HALF_UP)
Decimal('28.53')
Run Code Online (Sandbox Code Playgroud)

也以同样的方式工作。

对于您的其他问题,请查看number_3转换为的内容:

>>> number_3
Decimal('28.52499999999999857891452847979962825775146484375')
Run Code Online (Sandbox Code Playgroud)

float->decimal 转换是精确的,并且浮点文字 28.525 在内部由仅近似十进制 28.525 的二进制浮点表示(它不能精确地表示为二进制浮点 - 您会得到最接近的可能的二进制近似值)。如图所示,该二进制近似值的精确十进制值比十进制 28.525 小一点点。这就是为什么它向下舍入。