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

facundo.batista python-checkins at python.org
Thu Aug 23 20:29:12 CEST 2007


Author: facundo.batista
Date: Thu Aug 23 20:29:12 2007
New Revision: 57335
Modified:
 python/branches/decimal-branch/Lib/decimal.py
Log:
Removed the 'phantom nan' artifact, now the problem for
what it was needed is resolved in a more elegant (and
correct) way. 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:29:12 2007
@@ -213,9 +213,10 @@
 def handle(self, context, *args):
 if args:
 if args[0] == 1: # sNaN, must drop 's' but keep diagnostics
- return Decimal( (args[1]._sign, args[1]._int, 'n') )
+ ans = Decimal((args[1]._sign, args[1]._int, 'n'))
+ return ans._fix_nan(context)
 elif args[0] == 2:
- return Decimal( (args[1], args[2], 'P') )
+ return Decimal( (args[1], args[2], 'n') )
 return NaN
 
 
@@ -573,7 +574,7 @@
 "composed of non negative integer elements.")
 self._sign = value[0]
 self._int = tuple(value[1])
- if value[2] in ('F','n','N', 'P'):
+ if value[2] in ('F','n','N'):
 self._exp = value[2]
 self._is_special = True
 else:
@@ -603,19 +604,6 @@
 if _isnan(value):
 sig, sign, diag = _isnan(value)
 self._is_special = True
- if len(diag) > context.prec: # Diagnostic info too long
- # sig=1, qNaN -> ConversionSyntax
- # sig=2, sNaN -> InvalidOperation
- digits = tuple(int(x) for x in diag[-context.prec:])
- if sig == 1:
- self._exp = 'P' # qNaN
- self._sign = sign
- self._int = digits
- return self
-
- return context._raise_error(InvalidOperation,
- 'diagnostic info too long',
- 2, sign, digits)
 if sig == 1:
 self._exp = 'n' # qNaN
 else: # sig == 2
@@ -642,7 +630,7 @@
 """
 if self._is_special:
 exp = self._exp
- if exp == 'n' or exp == 'P':
+ if exp == 'n':
 return 1
 elif exp == 'N':
 return 2
@@ -688,9 +676,9 @@
 return context._raise_error(InvalidOperation, 'sNaN',
 1, other)
 if self_is_nan:
- return self
+ return self._fix_nan(context)
 
- return other
+ return other._fix_nan(context)
 return 0
 
 def __nonzero__(self):
@@ -1536,6 +1524,17 @@
 """
 return long(self.__int__())
 
+ def _fix_nan(self, context):
+ """Decapitate the payload of a NaN to fit the context"""
+ payload = self._int
+ if len(payload) > context.prec:
+ pos = -context.prec
+ while payload[pos] == 0 and pos < -1:
+ pos += 1
+ payload = payload[pos:]
+ return Decimal((self._sign, payload, self._exp))
+ return self
+
 def _fix(self, context):
 """Round if it is necessary to keep self within prec precision.
 
@@ -1546,7 +1545,10 @@
 context - context used.
 """
 if self._is_special:
- return self
+ if self._isnan():
+ return self._fix_nan(context)
+ else:
+ return self
 if context is None:
 context = getcontext()
 prec = context.prec
@@ -2601,8 +2603,6 @@
 if self._is_special or other._is_special:
 # If one operand is a quiet NaN and the other is number, then the
 # number is always returned
- if other._exp == 'P':
- return other
 sn = self._isnan()
 on = other._isnan()
 if sn or on:
@@ -3781,6 +3781,9 @@
 def create_decimal(self, num='0'):
 """Creates a new Decimal instance but using self as context."""
 d = Decimal(num, context=self)
+ if d._isnan() and len(d._int) > self.prec:
+ return self._raise_error(ConversionSyntax,
+ "diagnostic info too long in NaN")
 return d._fix(self)
 
 # Methods
@@ -4826,8 +4829,6 @@
 
 The operation is not affected by the context.
 """
- if a._exp == 'P':
- a = self._raise_error(ConversionSyntax)
 return a.__str__(context=self)
 
 def to_integral_exact(self, a):


More information about the Python-checkins mailing list

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