summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFacundo Batista <facundobatista@gmail.com>2007-12-03 16:29:52 (GMT)
committerFacundo Batista <facundobatista@gmail.com>2007-12-03 16:29:52 (GMT)
commit62edb71556d26f924a0e2e949af9cd3c211dea23 (patch)
treecfadb1701c57a8bfef97c8f50aced1483633fcd4
parent0f6d4e6cd35646a572dccce8c4a86ac3d1afb183 (diff)
downloadcpython-62edb71556d26f924a0e2e949af9cd3c211dea23.zip
cpython-62edb71556d26f924a0e2e949af9cd3c211dea23.tar.gz
cpython-62edb71556d26f924a0e2e949af9cd3c211dea23.tar.bz2
Speedup and cleaning of __str__. Thanks Mark Dickinson.
-rw-r--r--Lib/decimal.py112
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.