我想在货币计算中使用小数,因此我想对逗号后面的两个数字进行精确运算。最初,我认为十进制上下文中的prec
是指该属性,但是经过几次实验,我感到有些困惑。
实验1:
In [1]: import decimal
In [2]: decimal.getcontext().prec = 2
In [3]: a = decimal.Decimal('159.9')
In [4]: a
Out[4]: Decimal('159.9')
In [5]: b = decimal.Decimal('200')
In [6]: b
Out[6]: Decimal('200')
In [7]: b - a
Out[7]: Decimal('40')
实验2:
In [8]: decimal.getcontext().prec = 4
In [9]: a = decimal.Decimal('159.9')
In [10]: a
Out[10]: Decimal('159.9')
In [11]: b = decimal.Decimal('200')
In [12]: b
Out[12]: Decimal('200')
In [13]: b - a
Out[13]: Decimal('40.1')
实验3:(prec
仍设置为4)
In [14]: a = decimal.Decimal('159999.9')
In [15]: a
Out[15]: Decimal('159999.9')
In [16]: b = decimal.Decimal('200000')
In [17]: b
Out[17]: Decimal('200000')
In [18]: b - a
Out[18]: Decimal('4.000E+4')
为什么它在我的示例中起作用?在(货币计算)情况下,应该如何使用小数?
答案 0 :(得分:1)
精度设置的有效位数,不等于小数点后的位数。
因此,如果精度为2,则将有两个有效数字,因此具有3个有效数字的数字(如40.1
将被减少为前两个有效数字,得到40
。 / p>
没有简单的方法用Decimal
设置小数点后的位数。但是,您可以使用高精度,并且始终将结果round
保留为两位小数:
>>> from decimal import Decimal, getcontext
>>> getcontext().prec = 60 # use a higher/lower one if needed
>>> Decimal('200') - Decimal('159.9')
Decimal('40.1')
>>> r = Decimal('200') - Decimal('159.9')
>>> round(r, 2)
Decimal('40.10')
decimal FAQ还包含类似的问答(使用quantize
):
问:在具有两位小数位的定点应用程序中,某些输入有很多位,需要四舍五入。其他人不应有多余的数字,需要进行验证。应该使用什么方法?A。 Quantize()方法将舍入到固定数量的小数位数。如果设置了不精确陷阱,则它对于验证也很有用:
问:输入有效的两个位置后,如何在整个应用程序中保持不变?>>> TWOPLACES = Decimal(10) ** -2 # same as Decimal('0.01') >>> # Round to two places >>> Decimal('3.214').quantize(TWOPLACES) Decimal('3.21') >>> # Validate that a number does not exceed two places >>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact])) Decimal('3.21') >>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact])) Traceback (most recent call last): ... Inexact: None
A。某些操作(例如加,减和乘整数)将自动保留定点。除法运算和非整数乘法之类的其他运算将更改小数位数,并且需要在其后执行quantize()步骤:
>>> a = Decimal('102.72') # Initial fixed-point values >>> b = Decimal('3.17') >>> a + b # Addition preserves fixed-point Decimal('105.89') >>> a - b Decimal('99.55') >>> a * 42 # So does integer multiplication Decimal('4314.24') >>> (a * b).quantize(TWOPLACES) # Must quantize non-integer multiplication Decimal('325.62') >>> (b / a).quantize(TWOPLACES) # And quantize division Decimal('0.03')
在开发定点应用程序时,可以方便地定义函数来处理quantize()步骤:
>>> def mul(x, y, fp=TWOPLACES): ... return (x * y).quantize(fp) >>> def div(x, y, fp=TWOPLACES): ... return (x / y).quantize(fp) >>> mul(a, b) # Automatically preserve fixed-point Decimal('325.62') >>> div(b, a) Decimal('0.03')
答案 1 :(得分:1)
我发现最好的方法是设置较高的prec
并使用Decimal.quantize
来取整结果:
decimal.getcontext().prec=100
a = Decimal('400000.123456789')
b = Decimal('200000.0')
a-b
>>> Decimal('2.0000E+5')
(a-b).quantize(Decimal('0.01'))
>>> Decimal('200000.12')