我正在使用一个使用int
表示金额的库。例如,如下所示:
599
->5.99500
->5.005
->0.050
->0.00-599
->-5.99
我写了下面的函数,它可以在不引起浮点错误的情况下进行精确的浮点转换,但我想知道的是,我是否以错误的方式处理了这一问题,或者是否有一个更干净的解决方案。
def money_int_to_float(value: int) -> float:
neg: str = '-' if value < 0 else ''
value = abs(value)
cents: int = value % 100
remaining: int = value - cents
dollars: int = int(str(remaining).removesuffix('00'))
return float(f'{neg}{dollars}.{str(cents).zfill(2)}')
我想要精确浮动转换的原因是,在处理金钱时,你永远不要对浮动过于小心。
divmod
听起来像是你应该了解的东西:
def money_int_to_str(value: int) -> str:
sign = '-' if value < 0 else ''
dollars, cents = divmod(abs(value), 100)
return f'${sign}{dollars}.{cents:02}'
远离浮点的原因是,例如,money_int_to_float(123456789123456789)
不会从任何实现中给你89美分——浮点中没有足够的精度来存储它。
感谢@Samwise的评论,我找到了这个问题的干净解决方案。使用Decimal类,我们可以如下重写函数:
from decimal import Decimal
def money_int_to_float(value: int) -> float:
return float(Decimal(value).quantize(Decimal('0.00')).shift(-2))