diff options
author | Facundo Batista <facundobatista@gmail.com> | 2007-12-03 16:29:52 (GMT) |
---|---|---|
committer | Facundo Batista <facundobatista@gmail.com> | 2007-12-03 16:29:52 (GMT) |
commit | 62edb71556d26f924a0e2e949af9cd3c211dea23 (patch) | |
tree | cfadb1701c57a8bfef97c8f50aced1483633fcd4 | |
parent | 0f6d4e6cd35646a572dccce8c4a86ac3d1afb183 (diff) | |
download | cpython-62edb71556d26f924a0e2e949af9cd3c211dea23.zip cpython-62edb71556d26f924a0e2e949af9cd3c211dea23.tar.gz cpython-62edb71556d26f924a0e2e949af9cd3c211dea23.tar.bz2 |
Speedup and cleaning of __str__. Thanks Mark Dickinson.
-rw-r--r-- | Lib/decimal.py | 112 |
1 files changed, 41 insertions, 71 deletions
diff --git a/Lib/decimal.py b/Lib/decimal.py index 6baa838..c503d2f 100644 --- a/Lib/decimal.py +++ b/Lib/decimal.py @@ -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 context is None: - context = getcontext() - - 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 + 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 + + # number of digits of self._int to left of decimal point + leftdigits = self._exp + len(self._int) + + # 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 + + 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 ''.join(tmp) + return sign + intpart + fracpart + exp def to_eng_string(self, context=None): """Convert to engineering-type string. |