Speedup and cleaning of __str__. Thanks Mark Dickinson.

This commit is contained in:
Facundo Batista 2007-12-03 16:29:52 +00:00
parent 0f6d4e6cd3
commit 62edb71556
1 changed files with 39 additions and 69 deletions

View File

@ -837,81 +837,51 @@ class Decimal(object):
Captures all of the information in the underlying representation.
"""
sign = ['', '-'][self._sign]
if self._is_special:
if self._isnan():
minus = '-'*self._sign
if self._int == '0':
info = ''
else:
info = self._int
if self._isnan() == 2:
return minus + 'sNaN' + info
return minus + 'NaN' + info
if self._isinfinity():
minus = '-'*self._sign
return minus + 'Infinity'
if self._exp == 'F':
return sign + 'Infinity'
elif self._exp == 'n':
return sign + 'NaN' + self._int
else: # self._exp == 'N'
return sign + 'sNaN' + self._int
if context is None:
context = getcontext()
# number of digits of self._int to left of decimal point
leftdigits = self._exp + len(self._int)
tmp = list(self._int)
numdigits = len(self._int)
leftdigits = self._exp + numdigits
if eng and not self: # self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
if self._exp < 0 and self._exp >= -6: # short, no need for e/E
s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
return s
# exp is closest mult. of 3 >= self._exp
exp = ((self._exp - 1)// 3 + 1) * 3
if exp != self._exp:
s = '0.'+'0'*(exp - self._exp)
else:
s = '0'
if exp != 0:
if context.capitals:
s += 'E'
else:
s += 'e'
if exp > 0:
s += '+' # 0.0e+3, not 0.0e3
s += str(exp)
s = '-'*self._sign + s
return s
if eng:
dotplace = (leftdigits-1)%3+1
adjexp = leftdigits -1 - (leftdigits-1)%3
else:
adjexp = leftdigits-1
# dotplace is number of digits of self._int to the left of the
# decimal point in the mantissa of the output string (that is,
# after adjusting the exponent)
if self._exp <= 0 and leftdigits > -6:
# no exponent required
dotplace = leftdigits
elif not eng:
# usual scientific notation: 1 digit on left of the point
dotplace = 1
if self._exp == 0:
pass
elif self._exp < 0 and adjexp >= 0:
tmp.insert(leftdigits, '.')
elif self._exp < 0 and adjexp >= -6:
tmp[0:0] = ['0'] * int(-leftdigits)
tmp.insert(0, '0.')
elif self._int == '0':
# engineering notation, zero
dotplace = (leftdigits + 1) % 3 - 1
else:
if numdigits > dotplace:
tmp.insert(dotplace, '.')
elif numdigits < dotplace:
tmp.extend(['0']*(dotplace-numdigits))
if adjexp:
if not context.capitals:
tmp.append('e')
else:
tmp.append('E')
if adjexp > 0:
tmp.append('+')
tmp.append(str(adjexp))
if eng:
while tmp[0:1] == ['0']:
tmp[0:1] = []
if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
tmp[0:0] = ['0']
if self._sign:
tmp.insert(0, '-')
# engineering notation, nonzero
dotplace = (leftdigits - 1) % 3 + 1
return ''.join(tmp)
if dotplace <= 0:
intpart = '0'
fracpart = '.' + '0'*(-dotplace) + self._int
elif dotplace >= len(self._int):
intpart = self._int+'0'*(dotplace-len(self._int))
fracpart = ''
else:
intpart = self._int[:dotplace]
fracpart = '.' + self._int[dotplace:]
if leftdigits == dotplace:
exp = ''
else:
if context is None:
context = getcontext()
exp = ['e', 'E'][context.capitals] + "%+d" % (leftdigits-dotplace)
return sign + intpart + fracpart + exp
def to_eng_string(self, context=None):
"""Convert to engineering-type string.