将Python Decimal对象格式化为指定精度
我花了无数小时在研究、阅读和测试,最后感到困惑和失望,因为Python的Decimal对象在一个最基本的概念上缺乏支持:就是如何把Decimal的输出格式化成字符串。
假设我们有一些字符串或Decimal对象,它们的值如下:
0.0008
11.1111
222.2222
3333.3333
1234.5678
我们的目标是简单地把Decimal的精度设置到小数点后两位。比如,11.1111
应该格式化成11.11
,而1234.5678
则变成1234.57
。
我想要的代码大概是这样的:
import decimal
decimals = [
decimal.Decimal('0.0008'),
decimal.Decimal('11.1111'),
decimal.Decimal('222.2222'),
decimal.Decimal('3333.3333'),
decimal.Decimal('1234.5678'),
]
for dec in decimals:
print dec.as_string(precision=2, rounding=ROUND_HALF_UP)
最终的输出应该是:
0.00
11.11
222.22
3333.33
1234.57
显然,我们不能使用Decimal的上下文精度,因为它考虑的是数字的总位数,而不仅仅是小数的精度。
我也不想把Decimal转换成浮点数来输出它的值。使用Decimal的主要原因就是为了避免存储和计算浮点数。
还有其他解决方案吗?我知道在Stack Overflow上有很多类似的问题,但我没有找到能解决我所询问的根本问题的答案。
非常感谢!
2 个回答
2
def d(_in, decimal_places = 3):
''' Convert number to Decimal and do rounding, for doing calculations
Examples:
46.18271 to 46.183 rounded up
46.18749 to 46.187 rounded down
117.34999999999999 to 117.350
_rescale is a private function, bad practice yet works for now.
'''
return Decimal(_in)._rescale(-decimal_places, 'ROUND_HALF_EVEN')
补充说明:再次强调,_rescale() 这个东西不是给我们普通人用的,它在 Python 2.7 中可以用,但在 3.4 版本中是没有的。
29
你可以使用字符串格式化或者format()
函数来处理。
>>> for dec in decimals:
... print format(dec, '7.2f')
...
0.00
11.11
222.22
3333.33
1234.57
decimal.Decimal
支持和浮点数一样的格式规范,所以你可以根据需要使用科学计数法、固定小数点、通用格式、数字格式或百分比格式。
这是处理小数的官方且符合Python风格的方法;Decimal
类实现了.__format__()
方法,可以高效地处理这些格式化。