[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 ----