[Python-checkins] r59293 - python/trunk/Lib/decimal.py

facundo.batista python-checkins at python.org
Mon Dec 3 17:29:53 CET 2007


Author: facundo.batista
Date: Mon Dec  3 17:29:52 2007
New Revision: 59293

Modified:
   python/trunk/Lib/decimal.py
Log:

Speedup and cleaning of __str__.  Thanks Mark Dickinson.


Modified: python/trunk/Lib/decimal.py
==============================================================================
--- python/trunk/Lib/decimal.py	(original)
+++ python/trunk/Lib/decimal.py	Mon Dec  3 17:29:52 2007
@@ -837,81 +837,51 @@
         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()
+            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
+        elif self._int == '0':
+            # engineering notation, zero
+            dotplace = (leftdigits + 1) % 3 - 1
+        else:
+            # engineering notation, nonzero
+            dotplace = (leftdigits - 1) % 3 + 1
 
-        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
+        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:
-            adjexp = leftdigits-1
-            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.')
+            intpart = self._int[:dotplace]
+            fracpart = '.' + self._int[dotplace:]
+        if leftdigits == dotplace:
+            exp = ''
         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, '-')
+            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.


More information about the Python-checkins mailing list