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

eprice@users.sourceforge.net eprice@users.sourceforge.net
2003年7月02日 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 ----

AltStyle によって変換されたページ (->オリジナル) /