[Python-checkins] python/nondist/sandbox/decimal Decimal.py,1.9,1.10

eprice@users.sourceforge.net eprice@users.sourceforge.net
Wed, 02 Jul 2003 16:48:24 -0700


Update of /cvsroot/python/python/nondist/sandbox/decimal
In directory sc8-pr-cvs1:/tmp/cvs-serv814

Modified Files:
	Decimal.py 
Log Message:
Bugfixes, removed context indirection.






Index: Decimal.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/decimal/Decimal.py,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** Decimal.py	13 Jun 2003 22:47:18 -0000	1.9
--- Decimal.py	2 Jul 2003 23:48:22 -0000	1.10
***************
*** 489,496 ****
--- 489,501 ----
          2 if sNaN
          """
+         #print repr(self), repr(self._exp)
+         #print 'here', self._exp
          if self._exp == 'n':
+             #print 'Gone'
              return 1
          elif self._exp == 'N':
+             #print 'Gone'
              return 2
+         #print 'Gone'
          return 0
  
***************
*** 557,560 ****
--- 562,618 ----
  
      def __cmp__(self, other, context=None):
+         if context is None:
+             context = getcontext()
+         if not isinstance(other, Decimal):
+             other = Decimal(other)
+ 
+         ans = self._check_nans(other, context)
+ 
+         if ans:
+             return 1
+ 
+         if not self and not other:
+             return 0 #If both 0, sign comparison isn't certain.
+ 
+         #If different signs, neg one is less
+         if other._sign < self._sign:
+             return -1
+         if self._sign < other._sign:
+             return 1
+ 
+         # INF = INF
+         if self._isinfinity() and other._isinfinity():
+             return 0
+         if self._isinfinity():
+             return (-1)**self._sign
+         if other._isinfinity():
+             return -((-1)**other._sign)
+ 
+         if self.adjusted() == other.adjusted() and \
+            self._int + (0,)*(self._exp - other._exp) == \
+            other._int + (0,)*(other._exp - self._exp):
+             return 0 #equal, except in precision. ([0]*(-x) = [])
+         elif self.adjusted() > other.adjusted() and self._int[0] != 0:
+             return (-1)**self._sign
+         elif self.adjusted < other.adjusted() and other._int[0] != 0:
+             return -((-1)**self._sign)
+ 
+         context = copy.copy(context)
+         rounding = context.set_rounding(ROUND_UP) #round away from 0
+ 
+         flags = context.ignore_all_flags()
+         res = self.__sub__(other, context=context)
+ 
+         context.regard_flags(*flags)
+ 
+         context.rounding = rounding
+ 
+         if not res:
+             return 0
+         elif res._sign:
+             return -1
+         return 1
+ 
+     def DecimalCmp(self, other, context=None):
          """Compares one to another.
  
***************
*** 562,577 ****
          0  => a = b
          1  => a > b
          Returns Decimal instances, though.
          """
          if context is None:
              context = getcontext()
- 
          if not isinstance(other, Decimal):
              other = Decimal(other)
  
          ans = self._check_nans(other, context)
          #compare(NaN, NaN) = NaN
          if ans:
              return ans
  
          if not self and not other:
--- 620,639 ----
          0  => a = b
          1  => a > b
+         NaN => one is NaN
          Returns Decimal instances, though.
          """
          if context is None:
              context = getcontext()
          if not isinstance(other, Decimal):
              other = Decimal(other)
+         #print repr(self), repr(other)
  
          ans = self._check_nans(other, context)
          #compare(NaN, NaN) = NaN
+         #print 'Here'
          if ans:
+             #print 'Yay', self, other, ans
              return ans
+         #print self, other
  
          if not self and not other:
***************
*** 605,609 ****
  
          flags = context.ignore_all_flags()
!         res = context.subtract(self, other)
  
          context.regard_flags(*flags)
--- 667,671 ----
  
          flags = context.ignore_all_flags()
!         res = self.__sub__(other, context=context)
  
          context.regard_flags(*flags)
***************
*** 768,774 ****
  
          if self._sign:
!             ans = context.minus(self)
          else:
!             ans = context.plus(self)
  
          return ans
--- 830,836 ----
  
          if self._sign:
!             ans = self.__neg__(context=context)
          else:
!             ans = self.__pos__(context=context)
  
          return ans
***************
*** 894,898 ****
          tmp._sign = 1-tmp._sign
  
!         return context.add(self, tmp)
  
      def __rsub__(self, other, context=None):
--- 956,960 ----
          tmp._sign = 1-tmp._sign
  
!         return self.__add__(tmp, context=context)
  
      def __rsub__(self, other, context=None):
***************
*** 903,907 ****
          tmp = Decimal(self)
          tmp._sign = 1 - tmp._sign
!         return context.add(other, tmp)
  
      def increment(self, round=1, context=None):
--- 965,969 ----
          tmp = Decimal(self)
          tmp._sign = 1 - tmp._sign
!         return other.__add__(tmp, context=context)
  
      def increment(self, round=1, context=None):
***************
*** 1252,1256 ****
          flags = context.ignore_flags(Rounded, Inexact)
          #keep DivisionImpossible flags
!         (side, r) = context.divmod(self, other)
  
          if r._isnan():
--- 1314,1318 ----
          flags = context.ignore_flags(Rounded, Inexact)
          #keep DivisionImpossible flags
!         (side, r) = self.__divmod__(other, context=context)
  
          if r._isnan():
***************
*** 1262,1268 ****
  
          if other._sign:
!             comparison = context.divide(other, Decimal(-2))
          else:
!             comparison = context.divide(other, Decimal(2))
  
          context.set_rounding_decision(rounding)
--- 1324,1330 ----
  
          if other._sign:
!             comparison = other.__div__(Decimal(-2), context=context)
          else:
!             comparison = other.__div__(Decimal(2), context=context)
  
          context.set_rounding_decision(rounding)
***************
*** 1275,1279 ****
              r._sign, comparison._sign = s1, s2
              #Get flags now
!             context.divmod(self, other)
              return r.fix(context=context)
          r._sign, comparison._sign = s1, s2
--- 1337,1341 ----
              r._sign, comparison._sign = s1, s2
              #Get flags now
!             self.__divmod__(other, context=context)
              return r.fix(context=context)
          r._sign, comparison._sign = s1, s2
***************
*** 1281,1285 ****
          rounding = context.set_rounding_decision(NEVER_ROUND)
  
!         (side, r) = context.divmod(self, other)
          context.set_rounding_decision(rounding)
          if r._isnan():
--- 1343,1347 ----
          rounding = context.set_rounding_decision(NEVER_ROUND)
  
!         (side, r) = self.__divmod__(other, context=context)
          context.set_rounding_decision(rounding)
          if r._isnan():
***************
*** 1288,1292 ****
          decrease = not side._iseven()
          rounding = context.set_rounding_decision(NEVER_ROUND)
!         side = context.abs(side)
          context.set_rounding_decision(rounding)
  
--- 1350,1354 ----
          decrease = not side._iseven()
          rounding = context.set_rounding_decision(NEVER_ROUND)
!         side = side.__abs__(context=context)
          context.set_rounding_decision(rounding)
  
***************
*** 1296,1307 ****
              r._sign, comparison._sign = s1, s2
              context.prec += 1
!             if len((context.add(side,Decimal(1))._int)) >= context.prec:
                  context.prec -= 1
                  return context.raise_error(DivisionImpossible)[1]
              context.prec -= 1
              if self._sign == other._sign:
!                 r = context.subtract(r, other)
              else:
!                 r = context.add(r, other)
          else:
              r._sign, comparison._sign = s1, s2
--- 1358,1369 ----
              r._sign, comparison._sign = s1, s2
              context.prec += 1
!             if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
                  context.prec -= 1
                  return context.raise_error(DivisionImpossible)[1]
              context.prec -= 1
              if self._sign == other._sign:
!                 r = r.__sub__(other, context=context)
              else:
!                 r = r.__add__(other, context=context)
          else:
              r._sign, comparison._sign = s1, s2
***************
*** 1319,1322 ****
--- 1381,1393 ----
      def __long__(self):
          """Converts self to a long, truncating if necessary."""
+         if self._isnan():
+             
+             print "mmoo"
+             raise "ACK"
+             #raise "AIIII"
+             context = getcontext()
+             return context.raise_error(InvalidContext)
+         elif self._isinfinity():
+             raise OverflowError, "Cannot convert infinity to long"
          if not self:
              return 0L
***************
*** 1340,1343 ****
--- 1411,1416 ----
          Equivalent to int(long(self))
          """
+         #print 'M', repr(self), repr(self._exp)
+         print self._exp == 'n'
          return int(self.__long__())
  
***************
*** 1680,1684 ****
              #n is a long now, not Decimal instance
              n = -n
!             mul = context.divide(Decimal(1), mul)
  
          shouldround = context.rounding_decision in (ALWAYS_ROUND,)
--- 1753,1757 ----
              #n is a long now, not Decimal instance
              n = -n
!             mul = Decimal(1).__div__(mul, context=context)
  
          shouldround = context.rounding_decision in (ALWAYS_ROUND,)
***************
*** 1691,1702 ****
          #Spot is the highest power of 2 less than n
          while spot:
!             val = context.multiply(val, val)
              if val._isinfinity():
                  val = Infsign[sign]
                  break
              if spot & n:
!                 val = context.multiply(val, mul)
              if modulo is not None:
!                 val = context.remainder(val, modulo)
              spot >>= 1
          context.prec = firstprec
--- 1764,1775 ----
          #Spot is the highest power of 2 less than n
          while spot:
!             val = val.__mul__(val, context=context)
              if val._isinfinity():
                  val = Infsign[sign]
                  break
              if spot & n:
!                 val = val.__mul__(mul, context=context)
              if modulo is not None:
!                 val = val.__mod__(modulo, context=context)
              spot >>= 1
          context.prec = firstprec
***************
*** 1730,1740 ****
  
      def quantize(self, exp, rounding = None, context=None, watchexp = 1):
          """
!         """
          ans = self._check_nans(exp, context)
          if ans:
              return ans
-         if exp._isinfinity():
-             return context.raise_error(InvalidOperation, 'quantize with an INF')
          return self.rescale(exp._exp, rounding, context, watchexp)
  
--- 1803,1817 ----
  
      def quantize(self, exp, rounding = None, context=None, watchexp = 1):
+         """Quantize self so its exponent is the same as that of exp.
+ 
+         Similar to self.rescale(exp._exp) but with error checking.
          """
!         if context is None:
!             context = getcontext()
!         if exp._isinfinity() or self._isinfinity():
!             return context.raise_error(InvalidOperation, 'quantize with an INF')
          ans = self._check_nans(exp, context)
          if ans:
              return ans
          return self.rescale(exp._exp, rounding, context, watchexp)
  
***************
*** 1803,1807 ****
  
      def sqrt(self, context=None):
!         """Return the sqrt of self.
  
          Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
--- 1880,1884 ----
  
      def sqrt(self, context=None):
!         """Return the square root of self.
  
          Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
***************
*** 1848,1858 ****
          if tmp.adjusted() % 2 == 0:
              ans = Decimal( (0, (8,1,9), tmp.adjusted()  - 2) )
!             ans = context.add(ans, context.multiply(Decimal((0, (2,5,9), -2)),
!                                                     tmp))
              ans._exp -= 1 + tmp.adjusted()/2
          else:
              ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
!             ans = context.add(ans, context.multiply(Decimal((0, (8,1,9), -3)),
!                                                     tmp))
              ans._exp -= 1 + tmp.adjusted()/2
  
--- 1925,1935 ----
          if tmp.adjusted() % 2 == 0:
              ans = Decimal( (0, (8,1,9), tmp.adjusted()  - 2) )
!             ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
!                                           context=context), context=context)
              ans._exp -= 1 + tmp.adjusted()/2
          else:
              ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
!             ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
!                                           context=context), context=context)
              ans._exp -= 1 + tmp.adjusted()/2
  
***************
*** 1869,1874 ****
          while 1:
              context.prec = min(2*context.prec - 2, maxp)
!             ans = context.multiply(half, context.add(ans, \
!                                                 context.divide(tmp, ans)))
              if context.prec == maxp:
                  break
--- 1946,1951 ----
          while 1:
              context.prec = min(2*context.prec - 2, maxp)
!             ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
!                                            context=context), context=context)
              if context.prec == maxp:
                  break
***************
*** 1877,1881 ****
          context.prec = firstprec
          prevexp = ans.adjusted()
!         ans = context.round(ans)
  
          #Now, check if the other last digits are better.
--- 1954,1958 ----
          context.prec = firstprec
          prevexp = ans.adjusted()
!         ans = ans.round(context=context)
  
          #Now, check if the other last digits are better.
***************
*** 1886,1898 ****
              ans._exp -= 1
  
!         lower = context.subtract(ans, Decimal((0, (5,), ans._exp-1) ))
          context.set_rounding(ROUND_UP)
!         if (context.multiply(lower, lower))> (tmp):
!             ans = context.subtract(ans, Decimal( (0, (1,), ans._exp) ))
          else:
!             upper = context.add(ans, Decimal((0, (5,), ans._exp-1) ))
              context.set_rounding(ROUND_DOWN)
!             if context.multiply(upper, upper) < tmp:
!                 ans = context.add(ans, Decimal( (0, (1,), ans._exp) ))
  
          ans._exp += expadd
--- 1963,1977 ----
              ans._exp -= 1
  
! 
!         lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
          context.set_rounding(ROUND_UP)
!         if lower.__mul__(lower, context=context) > (tmp):
!             ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
! 
          else:
!             upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
              context.set_rounding(ROUND_DOWN)
!             if upper.__mul__(upper, context=context) < tmp:
!                 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
  
          ans._exp += expadd
***************
*** 1903,1907 ****
  
          rounding = context.set_rounding_decision(NEVER_ROUND)
!         if not context.multiply(ans, ans) == self:
              # Only rounded/inexact if here.
              context.regard_flags(flags)
--- 1982,1986 ----
  
          rounding = context.set_rounding_decision(NEVER_ROUND)
!         if not ans.__mul__(ans, context=context) == self:
              # Only rounded/inexact if here.
              context.regard_flags(flags)
***************
*** 2140,2144 ****
          # if an error occurs in the middle.
          rounding = context.set_rounding(ROUND_UP)
!         val = context.subtract(self, other)
          context.set_rounding(rounding)
  
--- 2219,2223 ----
          # if an error occurs in the middle.
          rounding = context.set_rounding(ROUND_UP)
!         val = self.__sub__(other, context=context)
          context.set_rounding(rounding)
  
***************
*** 2157,2161 ****
          return str(a.fix(context=self))
      def compare(self, a, b):
!         return a.__cmp__(b, context=self)
      def lt(self, a, b):
          return Decimal(int(self.compare(a, b)) == -1)
--- 2236,2240 ----
          return str(a.fix(context=self))
      def compare(self, a, b):
!         return a.DecimalCmp(b, context=self)
      def lt(self, a, b):
          return Decimal(int(self.compare(a, b)) == -1)
***************
*** 2197,2201 ****
          return a.remainder_near(b, context=self)
      def quantize(self, a, b):
!         return a.rescale(b, context=self)
      def rescale(self, a, b):
          return a.rescale(b, context=self)
--- 2276,2280 ----
          return a.remainder_near(b, context=self)
      def quantize(self, a, b):
!         return a.quantize(b, context=self)
      def rescale(self, a, b):
          return a.rescale(b, context=self)
***************
*** 2647,2694 ****
      return "%s%se%d" % (sign, str(top), e)
  
- #Map the test cases' error names to the actual errors
- ErrorNames = {'clamped' : Clamped,
-               'conversion_syntax' : ConversionSyntax,
-               'division_by_zero' : DivisionByZero,
-               'division_impossible' : DivisionImpossible,
-               'division_undefined' : DivisionUndefined,
-               'inexact' : Inexact,
-               'insufficient_storage' : InsufficientStorage,
-               'invalid_context' : InvalidContext,
-               'invalid_operation' : InvalidOperation,
-               'lost_digits' : LostDigits,
-               'overflow' : Overflow,
-               'rounded' : Rounded,
-               'subnormal' : Subnormal,
-               'underflow' : Underflow}
- 
  
- def change_precision(precision):
-     """Changes the precision of DefaultContext (used by new threads)."""
-     global DEFAULT_PRECISION
-     DEFAULT_PRECISION = precision
-     SetDefaultContext()
- 
- def change_max_exponent(exp):
-     """changes Emax used by new threads."""
-     global DEFAULT_MAX_EXPONENT
-     DEFAULT_MAX_EXPONENT = exp
-     SetDefaultContext()
- 
- def change_min_exponent(exp):
-     """changes Emin used by new threads"""
-     global DEFAULT_MIN_EXPONENT
-     DEFAULT_MIN_EXPONENT = exp
-     SetDefaultContext()
- 
- def change_rounding_method(rounding):
-     """changes the rounding method used by new threads."""
-     global DEFAULT_ROUNDING
-     DEFAULT_ROUNDING = rounding
-     SetDefaultContext()
- 
- def change_rounding_decision(decision):
-     """changes the decision of when to round used by new threads."""
-     global DEFAULT_ROUNDING_DECISION
-     DEFAULT_ROUNDING_DECISION = decision
-     SetDefaultContext()
--- 2726,2728 ----