Python標準庫參考筆記-decimal

Python標準庫參考筆記-decimal

10.4 decimal

地址:http://docs.python.org/library/decimal.html

 

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])

 

使用Decimalint類型可以直接用來構造Decimal,但是float類型的變量要先轉換爲字符串。在進行運算之後結果會使用getcontext().prec來確定精度,例如prec5的時候,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='<', trailneg='>')

    '<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))

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章