[Python-checkins] r54973 - python/branches/decimal-branch/Lib/decimal.py

facundo.batista python-checkins at python.org
Wed Apr 25 23:09:03 CEST 2007


Author: facundo.batista
Date: Wed Apr 25 23:08:57 2007
New Revision: 54973
Modified:
 python/branches/decimal-branch/Lib/decimal.py
Log:
Fixed all the NaN and Inf cases, in all its variants. It does not passes
all the integer-rhs tests, though, there's one strange case with an
out-of-range exponent (?)
Modified: python/branches/decimal-branch/Lib/decimal.py
==============================================================================
--- python/branches/decimal-branch/Lib/decimal.py	(original)
+++ python/branches/decimal-branch/Lib/decimal.py	Wed Apr 25 23:08:57 2007
@@ -1790,7 +1790,7 @@
 else:
 return self._round_up(prec, expdiff, context)
 
- def __pow__(self, n, modulo = None, context=None):
+ def __pow__(self, n, modulo=None, context=None):
 """Return self ** n (mod modulo)
 
 If modulo is None (default), don't take it mod modulo.
@@ -1802,37 +1802,96 @@
 if context is None:
 context = getcontext()
 
- if self._is_special or n._is_special or n.adjusted() > 8:
- # Because the spot << doesn't work with really big exponents
- if n._isinfinity() or n.adjusted() > 8:
- return context._raise_error(InvalidOperation, 'x ** INF')
+# # FIXME: study if this finally disappears...
+# if self._is_special or n._is_special:# or n.adjusted() > 8:
+# # Because the spot << doesn't work with really big exponents
+# if n._isinfinity() or n.adjusted() > 8:
+# return context._raise_error(InvalidOperation, 'x ** INF')
 
- ans = self._check_nans(n, context)
- if ans:
- return ans
-
- if not n._isinteger():
- return context._raise_error(InvalidOperation, 'x ** (non-integer)')
+ ans = self._check_nans(n, context)
+ if ans:
+ return ans
 
- if not self and not n:
- return context._raise_error(InvalidOperation, '0 ** 0')
+ if not self:
+ if not n:
+ return context._raise_error(InvalidOperation, '0 ** 0')
+ if n._sign == 0:
+ zero = Decimal(0)
+ if n._iseven():
+ return zero
+ zero._sign = self._sign
+ return zero
+ # n is negative
+ if self._sign == 0:
+ return Inf
+ # also self is negative
+ if n._iseven():
+ return Inf
+ else:
+ return negInf
 
 if not n:
 return Decimal(1)
 
+ # FIXME: Reduce the following to something more readable
 if self == Decimal(1):
+ if n._isinfinity():
+ context._raise_error(Inexact)
+ context._raise_error(Rounded)
+ digits = (1,)+(0,)*(context.prec-1)
+ return Decimal((0, digits, -context.prec+1))
 return Decimal(1)
 
- sign = self._sign and not n._iseven()
- n = int(n)
-
- if self._isinfinity():
+ if self._isinfinity() == -1 and n._isinfinity():
+ return context._raise_error(InvalidOperation, '-Inf ** +-Inf')
+ if self._isinfinity() == 1:
+ if n._isinfinity() == 1:
+ return Inf
+ if n._isinfinity() == -1:
+ return Decimal(0)
+ 
+ if self._isinfinity() == 1:
 if modulo:
 return context._raise_error(InvalidOperation, 'INF % x')
- if n > 0:
- return Infsign[sign]
- return Decimal( (sign, (0,), 0) )
+ if not n:
+ return Decimal(1)
+ if n._sign == 1:
+ return Decimal(0)
+ return Inf
+ if self._isinfinity() == -1:
+ if modulo:
+ return context._raise_error(InvalidOperation, '-INF % x')
+ if not n:
+ return Decimal(1)
+ if abs(n) < 1:
+ return context._raise_error(InvalidOperation, '-INF ** -1<n<1')
+ if n._sign == 0:
+ if n._iseven():
+ return Inf
+ else:
+ return negInf
+ if n._iseven():
+ return Decimal(0)
+ else:
+ return Decimal((1, (0,), 0))
 
+ if n._isinfinity() == 1:
+ if self._sign == 1:
+ return context._raise_error(InvalidOperation, '-num ** Inf')
+ if self < 1:
+ return Decimal(0)
+ else:
+ return Inf
+ if n._isinfinity() == -1:
+ if self._sign == 1:
+ return context._raise_error(InvalidOperation, '-num ** -Inf')
+ if self > 1:
+ return Decimal(0)
+ else:
+ return Inf
+
+ sign = self._sign and not n._iseven()
+ n = int(n)
 # With ludicrously large exponent, just raise an overflow
 # and return inf.
 if not modulo and n > 0 and \


More information about the Python-checkins mailing list

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