python decimal函数_Python标准库参考笔记-decimal | 学步园

Python标准库参考笔记-decimal

10.4 decimal

Decimal支持大多数的数学操作。使用decimal的时候是在一个context背景下工作的。可以使用getcontext来获得当前背景:

from decimal import *

c = getcontext()

print c

结果:

Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, capitals=1, flags=[], traps=[Overflow, InvalidOperation, DivisionByZero])

使用Decimal,int类型可以直接用来构造Decimal,但是float类型的变量要先转换为字符串。在进行运算之后结果会使用getcontext().prec来确定精度,例如prec为5的时候,100.1234567890+0会等于100.12:

# -*- coding: cp936 -*-

from decimal import *

con = getcontext()

print '-----------------------context------------------------'

print con

a = Decimal(100)

print a

b = Decimal('100.001')

print b

print '--------------------------prec------------------------------'

c = Decimal('100.1234567890')

print c

con.prec = 5

print con

d = Decimal('100.1234567890')

print 'd:',d

print 'd+0:',d+0

结果:

>>>

-----------------------context------------------------

Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, capitals=1, flags=[], traps=[DivisionByZero, InvalidOperation, Overflow])

100

100.001

--------------------------prec------------------------------

100.1234567890

Context(prec=5, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, capitals=1, flags=[], traps=[DivisionByZero, InvalidOperation, Overflow])

d: 100.1234567890

d+0: 100.12

可以修改Context来改变Decimal运算的行为,例如精度、如何舍弃位数等等。例如下面的程序测试各种rounding设置对结果的影响:

# -*- coding: cp936 -*-

from decimal import *

con = getcontext()

con.prec = 5

print '-----------------------context------------------------'

print con

s = '100.005'

strs = [

'100.005',

'100.004',

'-100.005',

'-100.004',

]

round_methods = [

ROUND_CEILING,

ROUND_DOWN,

ROUND_FLOOR,

ROUND_HALF_DOWN,

ROUND_HALF_EVEN,

ROUND_HALF_UP,

ROUND_UP,

ROUND_05UP,

]

for method in round_methods:

con.rounding = method

print '----------------------------', con.rounding, '----------------------------'

for s in strs:

print ' %s+0:' % s, Decimal(s)+0

结果:

>>>

-----------------------context------------------------

Context(prec=5, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, capitals=1, flags=[], traps=[DivisionByZero, Overflow, InvalidOperation])

---------------------------- ROUND_CEILING ----------------------------

100.005+0: 100.01

100.004+0: 100.01

-100.005+0: -100.00

-100.004+0: -100.00

---------------------------- ROUND_DOWN ----------------------------

100.005+0: 100.00

100.004+0: 100.00

-100.005+0: -100.00

-100.004+0: -100.00

---------------------------- ROUND_FLOOR ----------------------------

100.005+0: 100.00

100.004+0: 100.00

-100.005+0: -100.01

-100.004+0: -100.01

---------------------------- ROUND_HALF_DOWN ----------------------------

100.005+0: 100.00

100.004+0: 100.00

-100.005+0: -100.00

-100.004+0: -100.00

---------------------------- ROUND_HALF_EVEN ----------------------------

100.005+0: 100.00

100.004+0: 100.00

-100.005+0: -100.00

-100.004+0: -100.00

---------------------------- ROUND_HALF_UP ----------------------------

100.005+0: 100.01

100.004+0: 100.00

-100.005+0: -100.01

-100.004+0: -100.00

---------------------------- ROUND_UP ----------------------------

100.005+0: 100.01

100.004+0: 100.01

-100.005+0: -100.01

-100.004+0: -100.01

---------------------------- ROUND_05UP ----------------------------

100.005+0: 100.01

100.004+0: 100.01

-100.005+0: -100.01

-100.004+0: -100.01

>>>

文档里有一个将Decimal转换为现金格式的函数:

def moneyfmt(value, places=2, curr='', sep=',', dp='.',

pos='', neg='-', trailneg=''):

"""Convert Decimal to a money formatted string.

places:required number of places after the decimal point

curr:optional currency symbol before the sign (may be blank)

sep:optional grouping separator (comma, period, space, or blank)

dp:decimal point indicator (comma or period)

only specify as blank when places is zero

pos:optional sign for positive numbers: '+', space or blank

neg:optional sign for negative numbers: '-', '(', space or blank

trailneg:optional trailing minus indicator:'-', ')', space or blank

>>> d = Decimal('-1234567.8901')

>>> moneyfmt(d, curr='$')

'-$1,234,567.89'

>>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-')

'1.234.568-'

>>> moneyfmt(d, curr='$', neg='(', trailneg=')')

'($1,234,567.89)'

>>> moneyfmt(Decimal(123456789), sep=' ')

'123 456 789.00'

>>> moneyfmt(Decimal('-0.02'), neg='')

'<0.02>'

"""

q = Decimal(10) ** -places# 2 places --> '0.01'

sign, digits, exp = value.quantize(q).as_tuple()

result = []

digits = map(str, digits)

build, next = result.append, digits.pop

if sign:

build(trailneg)

for i in range(places):

build(next() if digits else '0')

build(dp)

if not digits:

build('0')

i = 0

while digits:

build(next())

i += 1

if i == 3 and digits:

i = 0

build(sep)

build(curr)

build(neg if sign else pos)

return ''.join(reversed(result))

你可能感兴趣的:(python,decimal函数)