[Python-checkins] r57339 - in python/branches/decimal-branch/Lib: decimal.py test/decimaltestdata/extra.decTest

facundo.batista python-checkins at python.org
Thu Aug 23 20:42:10 CEST 2007


Author: facundo.batista
Date: Thu Aug 23 20:42:09 2007
New Revision: 57339

Modified:
   python/branches/decimal-branch/Lib/decimal.py
   python/branches/decimal-branch/Lib/test/decimaltestdata/extra.decTest
Log:

Fixed some bugs in extreme cases in addition. Added some
tests for them in the extra file. Thanks Mark Dickinson.


Modified: python/branches/decimal-branch/Lib/decimal.py
==============================================================================
--- python/branches/decimal-branch/Lib/decimal.py	(original)
+++ python/branches/decimal-branch/Lib/decimal.py	Thu Aug 23 20:42:09 2007
@@ -1029,10 +1029,10 @@
         if op1.sign != op2.sign:
             # Equal and opposite
             if op1.int == op2.int:
-                if exp < context.Etiny():
-                    exp = context.Etiny()
-                    context._raise_error(Clamped)
-                return Decimal((negativezero, (0,), exp))
+                ans = Decimal((negativezero, (0,), exp))
+                if shouldround:
+                    ans = ans._fix(context)
+                return ans
             if op1.int < op2.int:
                 op1, op2 = op2, op1
                 # OK, now abs(op1) > abs(op2)
@@ -4927,39 +4927,28 @@
 
     Done during addition.
     """
-    # Yes, the exponent is a long, but the difference between exponents
-    # must be an int-- otherwise you'd get a big memory problem.
-    numdigits = int(op1.exp - op2.exp)
-    if numdigits < 0:
-        numdigits = -numdigits
+    if op1.exp < op2.exp:
         tmp = op2
         other = op1
     else:
         tmp = op1
         other = op2
 
-
-    if shouldround and numdigits > prec + 1:
-        # Big difference in exponents - check the adjusted exponents
+    # Let exp = min(tmp.exp - 1, tmp.adjusted() - precision - 1).
+    # Then adding 10**exp to tmp has the same effect (after rounding)
+    # as adding any positive quantity smaller than 10**exp; similarly
+    # for subtraction.  So if other is smaller than 10**exp we replace
+    # it with 10**exp.  This avoids tmp.exp - other.exp getting too large.
+    if shouldround:
         tmp_len = len(str(tmp.int))
         other_len = len(str(other.int))
-        if numdigits > (other_len + prec + 1 - tmp_len):
-            # If the difference in adjusted exps is > prec+1, we know
-            # other is insignificant, so might as well put a 1 after the
-            # precision (since this is only for addition).  Also stops
-            # use of massive longs.
-
-            extend = prec + 2 - tmp_len
-            if extend <= 0:
-                extend = 1
-            tmp.int *= 10 ** extend
-            tmp.exp -= extend
+        exp = tmp.exp + min(-1, tmp_len - prec - 2)
+        if other_len + other.exp - 1 < exp:
             other.int = 1
-            other.exp = tmp.exp
-            return op1, op2
+            other.exp = exp
 
-    tmp.int *= 10 ** numdigits
-    tmp.exp -= numdigits
+    tmp.int *= 10 ** (tmp.exp - other.exp)
+    tmp.exp = other.exp
     return op1, op2
 
 def _adjust_coefficients(op1, op2):

Modified: python/branches/decimal-branch/Lib/test/decimaltestdata/extra.decTest
==============================================================================
--- python/branches/decimal-branch/Lib/test/decimaltestdata/extra.decTest	(original)
+++ python/branches/decimal-branch/Lib/test/decimaltestdata/extra.decTest	Thu Aug 23 20:42:09 2007
@@ -103,6 +103,30 @@
 clamp: 0
 extr1003 add 0E+1000 0E-1005 -> 0E-1004 Clamped
 extr1004 add 0E-1006 0 -> 0E-1004 Clamped
+extr1005 add 1E+1000 -1E+1000 -> 0E+999 Clamped
+extr1006 add -3.1E+1004 3.1E+1004 -> 0E+999 Clamped
+clamp: 1
+extr1007 add 1E+998 -1E+998 -> 0E+994 Clamped
+clamp: 0
+extr1008 add 2E-1005 -2E-1005 -> 0E-1004 Clamped
+extr1009 add -3.1E-1005 3.1E-1005 -> 0E-1004 Clamped
+
+precision: 3
+extr1010 add 99949.9 0.200000 -> 1.00E+5 Inexact Rounded
+extr1011 add 99949.9 0.100000 -> 1.00E+5 Inexact Rounded
+extr1012 add 99849.9 0.200000 -> 9.99E+4 Inexact Rounded
+extr1013 add 99849.9 0.100000 -> 9.98E+4 Inexact Rounded
+extr1014 add 1.0149 0.00011 -> 1.02 Inexact Rounded
+extr1015 add 1.0149 0.00010 -> 1.02 Inexact Rounded
+extr1016 add 1.0149 0.00009 -> 1.01 Inexact Rounded
+extr1017 add 1.0049 0.00011 -> 1.01 Inexact Rounded
+extr1018 add 1.0049 0.00010 -> 1.00 Inexact Rounded
+extr1019 add 1.0049 0.00009 -> 1.00 Inexact Rounded
+rounding: down
+extr1020 add 99999.9 0.200000 -> 1.00E+5 Inexact Rounded
+extr1021 add 99999.8 0.200000 -> 1.00E+5 Rounded
+extr1022 add 99999.7 0.200000 -> 9.99E+4 Inexact Rounded
+rounding: half_even
 
 -- a bug in _rescale caused the following to fail in Python 2.5.1
 maxexponent: 999


More information about the Python-checkins mailing list