zhltom 发表于 2017-4-24 12:16:39

python 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=)
  使用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=)
  100
  100.001
  --------------------------prec------------------------------
  100.1234567890
  Context(prec=5, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, capitals=1, flags=[], traps=)
  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=)
  ---------------------------- 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))
  本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/runningtortoise/archive/2009/07/19/4361494.aspx
页: [1]
查看完整版本: python Decimal 使用