0001 # Copyright (c) 2004 Python Software Foundation. 0002 # All rights reserved. 0003 0004 # Written by Eric Price <eprice at tjhsst.edu> 0005 # and Facundo Batista <facundo at taniquetil.com.ar> 0006 # and Raymond Hettinger <python at rcn.com> 0007 # and Aahz <aahz at pobox.com> 0008 # and Tim Peters 0009 0010 # This module is currently Py2.3 compatible and should be kept that way 0011 # unless a major compelling advantage arises. IOW, 2.3 compatibility is 0012 # strongly preferred, but not guaranteed. 0013 0014 # Also, this module should be kept in sync with the latest updates of 0015 # the IBM specification as it evolves. Those updates will be treated 0016 # as bug fixes (deviation from the spec is a compatibility, usability 0017 # bug) and will be backported. At this point the spec is stabilizing 0018 # and the updates are becoming fewer, smaller, and less significant. 0019 0020 """ 0021 This is a Py2.3 implementation of decimal floating point arithmetic based on 0022 the General Decimal Arithmetic Specification: 0023 0024 www2.hursley.ibm.com/decimal/decarith.html 0025 0026 and IEEE standard 854-1987: 0027 0028 www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html 0029 0030 Decimal floating point has finite precision with arbitrarily large bounds. 0031 0032 The purpose of the module is to support arithmetic using familiar 0033 "schoolhouse" rules and to avoid the some of tricky representation 0034 issues associated with binary floating point. The package is especially 0035 useful for financial applications or for contexts where users have 0036 expectations that are at odds with binary floating point (for instance, 0037 in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead 0038 of the expected Decimal("0.00") returned by decimal floating point). 0039 0040 Here are some examples of using the decimal module: 0041 0042 >>> from decimal import * 0043 >>> setcontext(ExtendedContext) 0044 >>> Decimal(0) 0045 Decimal("0") 0046 >>> Decimal("1") 0047 Decimal("1") 0048 >>> Decimal("-.0123") 0049 Decimal("-0.0123") 0050 >>> Decimal(123456) 0051 Decimal("123456") 0052 >>> Decimal("123.45e12345678901234567890") 0053 Decimal("1.2345E+12345678901234567892") 0054 >>> Decimal("1.33") + Decimal("1.27") 0055 Decimal("2.60") 0056 >>> Decimal("12.34") + Decimal("3.87") - Decimal("18.41") 0057 Decimal("-2.20") 0058 >>> dig = Decimal(1) 0059 >>> print dig / Decimal(3) 0060 0.333333333 0061 >>> getcontext().prec = 18 0062 >>> print dig / Decimal(3) 0063 0.333333333333333333 0064 >>> print dig.sqrt() 0065 1 0066 >>> print Decimal(3).sqrt() 0067 1.73205080756887729 0068 >>> print Decimal(3) ** 123 0069 4.85192780976896427E+58 0070 >>> inf = Decimal(1) / Decimal(0) 0071 >>> print inf 0072 Infinity 0073 >>> neginf = Decimal(-1) / Decimal(0) 0074 >>> print neginf 0075 -Infinity 0076 >>> print neginf + inf 0077 NaN 0078 >>> print neginf * inf 0079 -Infinity 0080 >>> print dig / 0 0081 Infinity 0082 >>> getcontext().traps[DivisionByZero] = 1 0083 >>> print dig / 0 0084 Traceback (most recent call last): 0085 ... 0086 ... 0087 ... 0088 DivisionByZero: x / 0 0089 >>> c = Context() 0090 >>> c.traps[InvalidOperation] = 0 0091 >>> print c.flags[InvalidOperation] 0092 0 0093 >>> c.divide(Decimal(0), Decimal(0)) 0094 Decimal("NaN") 0095 >>> c.traps[InvalidOperation] = 1 0096 >>> print c.flags[InvalidOperation] 0097 1 0098 >>> c.flags[InvalidOperation] = 0 0099 >>> print c.flags[InvalidOperation] 0100 0 0101 >>> print c.divide(Decimal(0), Decimal(0)) 0102 Traceback (most recent call last): 0103 ... 0104 ... 0105 ... 0106 InvalidOperation: 0 / 0 0107 >>> print c.flags[InvalidOperation] 0108 1 0109 >>> c.flags[InvalidOperation] = 0 0110 >>> c.traps[InvalidOperation] = 0 0111 >>> print c.divide(Decimal(0), Decimal(0)) 0112 NaN 0113 >>> print c.flags[InvalidOperation] 0114 1 0115 >>> 0116 """ 0117 0118 __all__ = [ 0119 # Two major classes 0120 'Decimal', 'Context', 0121 0122 # Contexts 0123 'DefaultContext', 'BasicContext', 'ExtendedContext', 0124 0125 # Exceptions 0126 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero', 0127 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow', 0128 0129 # Constants for use in setting up contexts 0130 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING', 0131 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 0132 0133 # Functions for manipulating contexts 0134 'setcontext', 'getcontext' 0135 ] 0136 0137 import threading 0138 import copy 0139 0140 #Rounding 0141 ROUND_DOWN = 'ROUND_DOWN' 0142 ROUND_HALF_UP = 'ROUND_HALF_UP' 0143 ROUND_HALF_EVEN = 'ROUND_HALF_EVEN' 0144 ROUND_CEILING = 'ROUND_CEILING' 0145 ROUND_FLOOR = 'ROUND_FLOOR' 0146 ROUND_UP = 'ROUND_UP' 0147 ROUND_HALF_DOWN = 'ROUND_HALF_DOWN' 0148 0149 #Rounding decision (not part of the public API) 0150 NEVER_ROUND = 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY 0151 ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end. 0152 0153 #Errors 0154 0155 class DecimalException(ArithmeticError): 0156 """Base exception class. 0157 0158 Used exceptions derive from this. 0159 If an exception derives from another exception besides this (such as 0160 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only 0161 called if the others are present. This isn't actually used for 0162 anything, though. 0163 0164 handle -- Called when context._raise_error is called and the 0165 trap_enabler is set. First argument is self, second is the 0166 context. More arguments can be given, those being after 0167 the explanation in _raise_error (For example, 0168 context._raise_error(NewError, '(-x)!', self._sign) would 0169 call NewError().handle(context, self._sign).) 0170 0171 To define a new exception, it should be sufficient to have it derive 0172 from DecimalException. 0173 """ 0174 def handle(self, context, *args): 0175 pass 0176 0177 0178 class Clamped(DecimalException): 0179 """Exponent of a 0 changed to fit bounds. 0180 0181 This occurs and signals clamped if the exponent of a result has been 0182 altered in order to fit the constraints of a specific concrete 0183 representation. This may occur when the exponent of a zero result would 0184 be outside the bounds of a representation, or when a large normal 0185 number would have an encoded exponent that cannot be represented. In 0186 this latter case, the exponent is reduced to fit and the corresponding 0187 number of zero digits are appended to the coefficient ("fold-down"). 0188 """ 0189 0190 0191 class InvalidOperation(DecimalException): 0192 """An invalid operation was performed. 0193 0194 Various bad things cause this: 0195 0196 Something creates a signaling NaN 0197 -INF + INF 0198 0 * (+-)INF 0199 (+-)INF / (+-)INF 0200 x % 0 0201 (+-)INF % x 0202 x._rescale( non-integer ) 0203 sqrt(-x) , x > 0 0204 0 ** 0 0205 x ** (non-integer) 0206 x ** (+-)INF 0207 An operand is invalid 0208 """ 0209 def handle(self, context, *args): 0210 if args: 0211 if args[0] == 1: #sNaN, must drop 's' but keep diagnostics 0212 return Decimal( (args[1]._sign, args[1]._int, 'n') ) 0213 return NaN 0214 0215 class ConversionSyntax(InvalidOperation): 0216 """Trying to convert badly formed string. 0217 0218 This occurs and signals invalid-operation if an string is being 0219 converted to a number and it does not conform to the numeric string 0220 syntax. The result is [0,qNaN]. 0221 """ 0222 0223 def handle(self, context, *args): 0224 return (0, (0,), 'n') #Passed to something which uses a tuple. 0225 0226 class DivisionByZero(DecimalException, ZeroDivisionError): 0227 """Division by 0. 0228 0229 This occurs and signals division-by-zero if division of a finite number 0230 by zero was attempted (during a divide-integer or divide operation, or a 0231 power operation with negative right-hand operand), and the dividend was 0232 not zero. 0233 0234 The result of the operation is [sign,inf], where sign is the exclusive 0235 or of the signs of the operands for divide, or is 1 for an odd power of 0236 -0, for power. 0237 """ 0238 0239 def handle(self, context, sign, double = None, *args): 0240 if double is not None: 0241 return (Infsign[sign],)*2 0242 return Infsign[sign] 0243 0244 class DivisionImpossible(InvalidOperation): 0245 """Cannot perform the division adequately. 0246 0247 This occurs and signals invalid-operation if the integer result of a 0248 divide-integer or remainder operation had too many digits (would be 0249 longer than precision). The result is [0,qNaN]. 0250 """ 0251 0252 def handle(self, context, *args): 0253 return (NaN, NaN) 0254 0255 class DivisionUndefined(InvalidOperation, ZeroDivisionError): 0256 """Undefined result of division. 0257 0258 This occurs and signals invalid-operation if division by zero was 0259 attempted (during a divide-integer, divide, or remainder operation), and 0260 the dividend is also zero. The result is [0,qNaN]. 0261 """ 0262 0263 def handle(self, context, tup=None, *args): 0264 if tup is not None: 0265 return (NaN, NaN) #for 0 %0, 0 // 0 0266 return NaN 0267 0268 class Inexact(DecimalException): 0269 """Had to round, losing information. 0270 0271 This occurs and signals inexact whenever the result of an operation is 0272 not exact (that is, it needed to be rounded and any discarded digits 0273 were non-zero), or if an overflow or underflow condition occurs. The 0274 result in all cases is unchanged. 0275 0276 The inexact signal may be tested (or trapped) to determine if a given 0277 operation (or sequence of operations) was inexact. 0278 """ 0279 pass 0280 0281 class InvalidContext(InvalidOperation): 0282 """Invalid context. Unknown rounding, for example. 0283 0284 This occurs and signals invalid-operation if an invalid context was 0285 detected during an operation. This can occur if contexts are not checked 0286 on creation and either the precision exceeds the capability of the 0287 underlying concrete representation or an unknown or unsupported rounding 0288 was specified. These aspects of the context need only be checked when 0289 the values are required to be used. The result is [0,qNaN]. 0290 """ 0291 0292 def handle(self, context, *args): 0293 return NaN 0294 0295 class Rounded(DecimalException): 0296 """Number got rounded (not necessarily changed during rounding). 0297 0298 This occurs and signals rounded whenever the result of an operation is 0299 rounded (that is, some zero or non-zero digits were discarded from the 0300 coefficient), or if an overflow or underflow condition occurs. The 0301 result in all cases is unchanged. 0302 0303 The rounded signal may be tested (or trapped) to determine if a given 0304 operation (or sequence of operations) caused a loss of precision. 0305 """ 0306 pass 0307 0308 class Subnormal(DecimalException): 0309 """Exponent < Emin before rounding. 0310 0311 This occurs and signals subnormal whenever the result of a conversion or 0312 operation is subnormal (that is, its adjusted exponent is less than 0313 Emin, before any rounding). The result in all cases is unchanged. 0314 0315 The subnormal signal may be tested (or trapped) to determine if a given 0316 or operation (or sequence of operations) yielded a subnormal result. 0317 """ 0318 pass 0319 0320 class Overflow(Inexact, Rounded): 0321 """Numerical overflow. 0322 0323 This occurs and signals overflow if the adjusted exponent of a result 0324 (from a conversion or from an operation that is not an attempt to divide 0325 by zero), after rounding, would be greater than the largest value that 0326 can be handled by the implementation (the value Emax). 0327 0328 The result depends on the rounding mode: 0329 0330 For round-half-up and round-half-even (and for round-half-down and 0331 round-up, if implemented), the result of the operation is [sign,inf], 0332 where sign is the sign of the intermediate result. For round-down, the 0333 result is the largest finite number that can be represented in the 0334 current precision, with the sign of the intermediate result. For 0335 round-ceiling, the result is the same as for round-down if the sign of 0336 the intermediate result is 1, or is [0,inf] otherwise. For round-floor, 0337 the result is the same as for round-down if the sign of the intermediate 0338 result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded 0339 will also be raised. 0340 """ 0341 0342 def handle(self, context, sign, *args): 0343 if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN, 0344 ROUND_HALF_DOWN, ROUND_UP): 0345 return Infsign[sign] 0346 if sign == 0: 0347 if context.rounding == ROUND_CEILING: 0348 return Infsign[sign] 0349 return Decimal((sign, (9,)*context.prec, 0350 context.Emax-context.prec+1)) 0351 if sign == 1: 0352 if context.rounding == ROUND_FLOOR: 0353 return Infsign[sign] 0354 return Decimal( (sign, (9,)*context.prec, 0355 context.Emax-context.prec+1)) 0356 0357 0358 class Underflow(Inexact, Rounded, Subnormal): 0359 """Numerical underflow with result rounded to 0. 0360 0361 This occurs and signals underflow if a result is inexact and the 0362 adjusted exponent of the result would be smaller (more negative) than 0363 the smallest value that can be handled by the implementation (the value 0364 Emin). That is, the result is both inexact and subnormal. 0365 0366 The result after an underflow will be a subnormal number rounded, if 0367 necessary, so that its exponent is not less than Etiny. This may result 0368 in 0 with the sign of the intermediate result and an exponent of Etiny. 0369 0370 In all cases, Inexact, Rounded, and Subnormal will also be raised. 0371 """ 0372 0373 # List of public traps and flags 0374 _signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded, 0375 Underflow, InvalidOperation, Subnormal] 0376 0377 # Map conditions (per the spec) to signals 0378 _condition_map = {ConversionSyntax:InvalidOperation, 0379 DivisionImpossible:InvalidOperation, 0380 DivisionUndefined:InvalidOperation, 0381 InvalidContext:InvalidOperation} 0382 0383 ##### Context Functions ####################################### 0384 0385 # The getcontext() and setcontext() function manage access to a thread-local 0386 # current context. Py2.4 offers direct support for thread locals. If that 0387 # is not available, use threading.currentThread() which is slower but will 0388 # work for older Pythons. 0389 0390 try: 0391 threading.local 0392 0393 except AttributeError: 0394 0395 #To fix reloading, force it to create a new context 0396 #Old contexts have different exceptions in their dicts, making problems. 0397 if hasattr(threading.currentThread(), '__decimal_context__'): 0398 del threading.currentThread().__decimal_context__ 0399 0400 def setcontext(context): 0401 """Set this thread's context to context.""" 0402 if context in (DefaultContext, BasicContext, ExtendedContext): 0403 context = context.copy() 0404 context.clear_flags() 0405 threading.currentThread().__decimal_context__ = context 0406 0407 def getcontext(): 0408 """Returns this thread's context. 0409 0410 If this thread does not yet have a context, returns 0411 a new context and sets this thread's context. 0412 New contexts are copies of DefaultContext. 0413 """ 0414 try: 0415 return threading.currentThread().__decimal_context__ 0416 except AttributeError: 0417 context = Context() 0418 threading.currentThread().__decimal_context__ = context 0419 return context 0420 0421 else: 0422 0423 local = threading.local() 0424 if hasattr(local, '__decimal_context__'): 0425 del local.__decimal_context__ 0426 0427 def getcontext(_local=local): 0428 """Returns this thread's context. 0429 0430 If this thread does not yet have a context, returns 0431 a new context and sets this thread's context. 0432 New contexts are copies of DefaultContext. 0433 """ 0434 try: 0435 return _local.__decimal_context__ 0436 except AttributeError: 0437 context = Context() 0438 _local.__decimal_context__ = context 0439 return context 0440 0441 def setcontext(context, _local=local): 0442 """Set this thread's context to context.""" 0443 if context in (DefaultContext, BasicContext, ExtendedContext): 0444 context = context.copy() 0445 context.clear_flags() 0446 _local.__decimal_context__ = context 0447 0448 del threading, local # Don't contaminate the namespace 0449 0450 0451 ##### Decimal class ########################################### 0452 0453 class Decimal(object): 0454 """Floating point class for decimal arithmetic.""" 0455 0456 __slots__ = ('_exp','_int','_sign', '_is_special') 0457 # Generally, the value of the Decimal instance is given by 0458 # (-1)**_sign * _int * 10**_exp 0459 # Special values are signified by _is_special == True 0460 0461 # We're immutable, so use __new__ not __init__ 0462 def __new__(cls, value="0", context=None): 0463 """Create a decimal point instance. 0464 0465 >>> Decimal('3.14') # string input 0466 Decimal("3.14") 0467 >>> Decimal((0, (3, 1, 4), -2)) # tuple input (sign, digit_tuple, exponent) 0468 Decimal("3.14") 0469 >>> Decimal(314) # int or long 0470 Decimal("314") 0471 >>> Decimal(Decimal(314)) # another decimal instance 0472 Decimal("314") 0473 """ 0474 0475 self = object.__new__(cls) 0476 self._is_special = False 0477 0478 # From an internal working value 0479 if isinstance(value, _WorkRep): 0480 self._sign = value.sign 0481 self._int = tuple(map(int, str(value.int))) 0482 self._exp = int(value.exp) 0483 return self 0484 0485 # From another decimal 0486 if isinstance(value, Decimal): 0487 self._exp = value._exp 0488 self._sign = value._sign 0489 self._int = value._int 0490 self._is_special = value._is_special 0491 return self 0492 0493 # From an integer 0494 if isinstance(value, (int,long)): 0495 if value >= 0: 0496 self._sign = 0 0497 else: 0498 self._sign = 1 0499 self._exp = 0 0500 self._int = tuple(map(int, str(abs(value)))) 0501 return self 0502 0503 # tuple/list conversion (possibly from as_tuple()) 0504 if isinstance(value, (list,tuple)): 0505 if len(value) != 3: 0506 raise ValueError, 'Invalid arguments' 0507 if value[0] not in [0,1]: 0508 raise ValueError, 'Invalid sign' 0509 for digit in value[1]: 0510 if not isinstance(digit, (int,long)) or digit < 0: 0511 raise ValueError, "The second value in the tuple must be composed of non negative integer elements." 0512 0513 self._sign = value[0] 0514 self._int = tuple(value[1]) 0515 if value[2] in ('F','n','N'): 0516 self._exp = value[2] 0517 self._is_special = True 0518 else: 0519 self._exp = int(value[2]) 0520 return self 0521 0522 if isinstance(value, float): 0523 raise TypeError("Cannot convert float to Decimal. " + 0524 "First convert the float to a string") 0525 0526 # Other argument types may require the context during interpretation 0527 if context is None: 0528 context = getcontext() 0529 0530 # From a string 0531 # REs insist on real strings, so we can too. 0532 if isinstance(value, basestring): 0533 if _isinfinity(value): 0534 self._exp = 'F' 0535 self._int = (0,) 0536 self._is_special = True 0537 if _isinfinity(value) == 1: 0538 self._sign = 0 0539 else: 0540 self._sign = 1 0541 return self 0542 if _isnan(value): 0543 sig, sign, diag = _isnan(value) 0544 self._is_special = True 0545 if len(diag) > context.prec: #Diagnostic info too long 0546 self._sign, self._int, self._exp = \ 0547 context._raise_error(ConversionSyntax) 0548 return self 0549 if sig == 1: 0550 self._exp = 'n' #qNaN 0551 else: #sig == 2 0552 self._exp = 'N' #sNaN 0553 self._sign = sign 0554 self._int = tuple(map(int, diag)) #Diagnostic info 0555 return self 0556 try: 0557 self._sign, self._int, self._exp = _string2exact(value) 0558 except ValueError: 0559 self._is_special = True 0560 self._sign, self._int, self._exp = context._raise_error(ConversionSyntax) 0561 return self 0562 0563 raise TypeError("Cannot convert %r to Decimal" % value) 0564 0565 def _isnan(self): 0566 """Returns whether the number is not actually one. 0567 0568 0 if a number 0569 1 if NaN 0570 2 if sNaN 0571 """ 0572 if self._is_special: 0573 exp = self._exp 0574 if exp == 'n': 0575 return 1 0576 elif exp == 'N': 0577 return 2 0578 return 0 0579 0580 def _isinfinity(self): 0581 """Returns whether the number is infinite 0582 0583 0 if finite or not a number 0584 1 if +INF 0585 -1 if -INF 0586 """ 0587 if self._exp == 'F': 0588 if self._sign: 0589 return -1 0590 return 1 0591 return 0 0592 0593 def _check_nans(self, other = None, context=None): 0594 """Returns whether the number is not actually one. 0595 0596 if self, other are sNaN, signal 0597 if self, other are NaN return nan 0598 return 0 0599 0600 Done before operations. 0601 """ 0602 0603 self_is_nan = self._isnan() 0604 if other is None: 0605 other_is_nan = False 0606 else: 0607 other_is_nan = other._isnan() 0608 0609 if self_is_nan or other_is_nan: 0610 if context is None: 0611 context = getcontext() 0612 0613 if self_is_nan == 2: 0614 return context._raise_error(InvalidOperation, 'sNaN', 0615 1, self) 0616 if other_is_nan == 2: 0617 return context._raise_error(InvalidOperation, 'sNaN', 0618 1, other) 0619 if self_is_nan: 0620 return self 0621 0622 return other 0623 return 0 0624 0625 def __nonzero__(self): 0626 """Is the number non-zero? 0627 0628 0 if self == 0 0629 1 if self != 0 0630 """ 0631 if self._is_special: 0632 return 1 0633 return sum(self._int) != 0 0634 0635 def __cmp__(self, other, context=None): 0636 other = _convert_other(other) 0637 0638 if self._is_special or other._is_special: 0639 ans = self._check_nans(other, context) 0640 if ans: 0641 return 1 # Comparison involving NaN's always reports self > other 0642 0643 # INF = INF 0644 return cmp(self._isinfinity(), other._isinfinity()) 0645 0646 if not self and not other: 0647 return 0 #If both 0, sign comparison isn't certain. 0648 0649 #If different signs, neg one is less 0650 if other._sign < self._sign: 0651 return -1 0652 if self._sign < other._sign: 0653 return 1 0654 0655 self_adjusted = self.adjusted() 0656 other_adjusted = other.adjusted() 0657 if self_adjusted == other_adjusted and \ 0658 self._int + (0,)*(self._exp - other._exp) == \ 0659 other._int + (0,)*(other._exp - self._exp): 0660 return 0 #equal, except in precision. ([0]*(-x) = []) 0661 elif self_adjusted > other_adjusted and self._int[0] != 0: 0662 return (-1)**self._sign 0663 elif self_adjusted < other_adjusted and other._int[0] != 0: 0664 return -((-1)**self._sign) 0665 0666 # Need to round, so make sure we have a valid context 0667 if context is None: 0668 context = getcontext() 0669 0670 context = context._shallow_copy() 0671 rounding = context._set_rounding(ROUND_UP) #round away from 0 0672 0673 flags = context._ignore_all_flags() 0674 res = self.__sub__(other, context=context) 0675 0676 context._regard_flags(*flags) 0677 0678 context.rounding = rounding 0679 0680 if not res: 0681 return 0 0682 elif res._sign: 0683 return -1 0684 return 1 0685 0686 def __eq__(self, other): 0687 if not isinstance(other, (Decimal, int, long)): 0688 return False 0689 return self.__cmp__(other) == 0 0690 0691 def __ne__(self, other): 0692 if not isinstance(other, (Decimal, int, long)): 0693 return True 0694 return self.__cmp__(other) != 0 0695 0696 def compare(self, other, context=None): 0697 """Compares one to another. 0698 0699 -1 => a < b 0700 0 => a = b 0701 1 => a > b 0702 NaN => one is NaN 0703 Like __cmp__, but returns Decimal instances. 0704 """ 0705 other = _convert_other(other) 0706 0707 #compare(NaN, NaN) = NaN 0708 if (self._is_special or other and other._is_special): 0709 ans = self._check_nans(other, context) 0710 if ans: 0711 return ans 0712 0713 return Decimal(self.__cmp__(other, context)) 0714 0715 def __hash__(self): 0716 """x.__hash__() <==> hash(x)""" 0717 # Decimal integers must hash the same as the ints 0718 # Non-integer decimals are normalized and hashed as strings 0719 # Normalization assures that hast(100E-1) == hash(10) 0720 i = int(self) 0721 if self == Decimal(i): 0722 return hash(i) 0723 assert self.__nonzero__() # '-0' handled by integer case 0724 return hash(str(self.normalize())) 0725 0726 def as_tuple(self): 0727 """Represents the number as a triple tuple. 0728 0729 To show the internals exactly as they are. 0730 """ 0731 return (self._sign, self._int, self._exp) 0732 0733 def __repr__(self): 0734 """Represents the number as an instance of Decimal.""" 0735 # Invariant: eval(repr(d)) == d 0736 return 'Decimal("%s")' % str(self) 0737 0738 def __str__(self, eng = 0, context=None): 0739 """Return string representation of the number in scientific notation. 0740 0741 Captures all of the information in the underlying representation. 0742 """ 0743 0744 if self._isnan(): 0745 minus = '-'*self._sign 0746 if self._int == (0,): 0747 info = '' 0748 else: 0749 info = ''.join(map(str, self._int)) 0750 if self._isnan() == 2: 0751 return minus + 'sNaN' + info 0752 return minus + 'NaN' + info 0753 if self._isinfinity(): 0754 minus = '-'*self._sign 0755 return minus + 'Infinity' 0756 0757 if context is None: 0758 context = getcontext() 0759 0760 tmp = map(str, self._int) 0761 numdigits = len(self._int) 0762 leftdigits = self._exp + numdigits 0763 if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY 0764 if self._exp < 0 and self._exp >= -6: #short, no need for e/E 0765 s = '-'*self._sign + '0.' + '0'*(abs(self._exp)) 0766 return s 0767 #exp is closest mult. of 3 >= self._exp 0768 exp = ((self._exp - 1)// 3 + 1) * 3 0769 if exp != self._exp: 0770 s = '0.'+'0'*(exp - self._exp) 0771 else: 0772 s = '0' 0773 if exp != 0: 0774 if context.capitals: 0775 s += 'E' 0776 else: 0777 s += 'e' 0778 if exp > 0: 0779 s += '+' #0.0e+3, not 0.0e3 0780 s += str(exp) 0781 s = '-'*self._sign + s 0782 return s 0783 if eng: 0784 dotplace = (leftdigits-1)%3+1 0785 adjexp = leftdigits -1 - (leftdigits-1)%3 0786 else: 0787 adjexp = leftdigits-1 0788 dotplace = 1 0789 if self._exp == 0: 0790 pass 0791 elif self._exp < 0 and adjexp >= 0: 0792 tmp.insert(leftdigits, '.') 0793 elif self._exp < 0 and adjexp >= -6: 0794 tmp[0:0] = ['0'] * int(-leftdigits) 0795 tmp.insert(0, '0.') 0796 else: 0797 if numdigits > dotplace: 0798 tmp.insert(dotplace, '.') 0799 elif numdigits < dotplace: 0800 tmp.extend(['0']*(dotplace-numdigits)) 0801 if adjexp: 0802 if not context.capitals: 0803 tmp.append('e') 0804 else: 0805 tmp.append('E') 0806 if adjexp > 0: 0807 tmp.append('+') 0808 tmp.append(str(adjexp)) 0809 if eng: 0810 while tmp[0:1] == ['0']: 0811 tmp[0:1] = [] 0812 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e': 0813 tmp[0:0] = ['0'] 0814 if self._sign: 0815 tmp.insert(0, '-') 0816 0817 return ''.join(tmp) 0818 0819 def to_eng_string(self, context=None): 0820 """Convert to engineering-type string. 0821 0822 Engineering notation has an exponent which is a multiple of 3, so there 0823 are up to 3 digits left of the decimal place. 0824 0825 Same rules for when in exponential and when as a value as in __str__. 0826 """ 0827 return self.__str__(eng=1, context=context) 0828 0829 def __neg__(self, context=None): 0830 """Returns a copy with the sign switched. 0831 0832 Rounds, if it has reason. 0833 """ 0834 if self._is_special: 0835 ans = self._check_nans(context=context) 0836 if ans: 0837 return ans 0838 0839 if not self: 0840 # -Decimal('0') is Decimal('0'), not Decimal('-0') 0841 sign = 0 0842 elif self._sign: 0843 sign = 0 0844 else: 0845 sign = 1 0846 0847 if context is None: 0848 context = getcontext() 0849 if context._rounding_decision == ALWAYS_ROUND: 0850 return Decimal((sign, self._int, self._exp))._fix(context) 0851 return Decimal( (sign, self._int, self._exp)) 0852 0853 def __pos__(self, context=None): 0854 """Returns a copy, unless it is a sNaN. 0855 0856 Rounds the number (if more then precision digits) 0857 """ 0858 if self._is_special: 0859 ans = self._check_nans(context=context) 0860 if ans: 0861 return ans 0862 0863 sign = self._sign 0864 if not self: 0865 # + (-0) = 0 0866 sign = 0 0867 0868 if context is None: 0869 context = getcontext() 0870 0871 if context._rounding_decision == ALWAYS_ROUND: 0872 ans = self._fix(context) 0873 else: 0874 ans = Decimal(self) 0875 ans._sign = sign 0876 return ans 0877 0878 def __abs__(self, round=1, context=None): 0879 """Returns the absolute value of self. 0880 0881 If the second argument is 0, do not round. 0882 """ 0883 if self._is_special: 0884 ans = self._check_nans(context=context) 0885 if ans: 0886 return ans 0887 0888 if not round: 0889 if context is None: 0890 context = getcontext() 0891 context = context._shallow_copy() 0892 context._set_rounding_decision(NEVER_ROUND) 0893 0894 if self._sign: 0895 ans = self.__neg__(context=context) 0896 else: 0897 ans = self.__pos__(context=context) 0898 0899 return ans 0900 0901 def __add__(self, other, context=None): 0902 """Returns self + other. 0903 0904 -INF + INF (or the reverse) cause InvalidOperation errors. 0905 """ 0906 other = _convert_other(other) 0907 0908 if context is None: 0909 context = getcontext() 0910 0911 if self._is_special or other._is_special: 0912 ans = self._check_nans(other, context) 0913 if ans: 0914 return ans 0915 0916 if self._isinfinity(): 0917 #If both INF, same sign => same as both, opposite => error. 0918 if self._sign != other._sign and other._isinfinity(): 0919 return context._raise_error(InvalidOperation, '-INF + INF') 0920 return Decimal(self) 0921 if other._isinfinity(): 0922 return Decimal(other) #Can't both be infinity here 0923 0924 shouldround = context._rounding_decision == ALWAYS_ROUND 0925 0926 exp = min(self._exp, other._exp) 0927 negativezero = 0 0928 if context.rounding == ROUND_FLOOR and self._sign != other._sign: 0929 #If the answer is 0, the sign should be negative, in this case. 0930 negativezero = 1 0931 0932 if not self and not other: 0933 sign = min(self._sign, other._sign) 0934 if negativezero: 0935 sign = 1 0936 return Decimal( (sign, (0,), exp)) 0937 if not self: 0938 exp = max(exp, other._exp - context.prec-1) 0939 ans = other._rescale(exp, watchexp=0, context=context) 0940 if shouldround: 0941 ans = ans._fix(context) 0942 return ans 0943 if not other: 0944 exp = max(exp, self._exp - context.prec-1) 0945 ans = self._rescale(exp, watchexp=0, context=context) 0946 if shouldround: 0947 ans = ans._fix(context) 0948 return ans 0949 0950 op1 = _WorkRep(self) 0951 op2 = _WorkRep(other) 0952 op1, op2 = _normalize(op1, op2, shouldround, context.prec) 0953 0954 result = _WorkRep() 0955 if op1.sign != op2.sign: 0956 # Equal and opposite 0957 if op1.int == op2.int: 0958 if exp < context.Etiny(): 0959 exp = context.Etiny() 0960 context._raise_error(Clamped) 0961 return Decimal((negativezero, (0,), exp)) 0962 if op1.int < op2.int: 0963 op1, op2 = op2, op1 0964 #OK, now abs(op1) > abs(op2) 0965 if op1.sign == 1: 0966 result.sign = 1 0967 op1.sign, op2.sign = op2.sign, op1.sign 0968 else: 0969 result.sign = 0 0970 #So we know the sign, and op1 > 0. 0971 elif op1.sign == 1: 0972 result.sign = 1 0973 op1.sign, op2.sign = (0, 0) 0974 else: 0975 result.sign = 0 0976 #Now, op1 > abs(op2) > 0 0977 0978 if op2.sign == 0: 0979 result.int = op1.int + op2.int 0980 else: 0981 result.int = op1.int - op2.int 0982 0983 result.exp = op1.exp 0984 ans = Decimal(result) 0985 if shouldround: 0986 ans = ans._fix(context) 0987 return ans 0988 0989 __radd__ = __add__ 0990 0991 def __sub__(self, other, context=None): 0992 """Return self + (-other)""" 0993 other = _convert_other(other) 0994 0995 if self._is_special or other._is_special: 0996 ans = self._check_nans(other, context=context) 0997 if ans: 0998 return ans 0999 1000 # -Decimal(0) = Decimal(0), which we don't want since 1001 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.) 1002 # so we change the sign directly to a copy 1003 tmp = Decimal(other) 1004 tmp._sign = 1-tmp._sign 1005 1006 return self.__add__(tmp, context=context) 1007 1008 def __rsub__(self, other, context=None): 1009 """Return other + (-self)""" 1010 other = _convert_other(other) 1011 1012 tmp = Decimal(self) 1013 tmp._sign = 1 - tmp._sign 1014 return other.__add__(tmp, context=context) 1015 1016 def _increment(self, round=1, context=None): 1017 """Special case of add, adding 1eExponent 1018 1019 Since it is common, (rounding, for example) this adds 1020 (sign)*one E self._exp to the number more efficiently than add. 1021 1022 For example: 1023 Decimal('5.624e10')._increment() == Decimal('5.625e10') 1024 """ 1025 if self._is_special: 1026 ans = self._check_nans(context=context) 1027 if ans: 1028 return ans 1029 1030 return Decimal(self) # Must be infinite, and incrementing makes no difference 1031 1032 L = list(self._int) 1033 L[-1] += 1 1034 spot = len(L)-1 1035 while L[spot] == 10: 1036 L[spot] = 0 1037 if spot == 0: 1038 L[0:0] = [1] 1039 break 1040 L[spot-1] += 1 1041 spot -= 1 1042 ans = Decimal((self._sign, L, self._exp)) 1043 1044 if context is None: 1045 context = getcontext() 1046 if round and context._rounding_decision == ALWAYS_ROUND: 1047 ans = ans._fix(context) 1048 return ans 1049 1050 def __mul__(self, other, context=None): 1051 """Return self * other. 1052 1053 (+-) INF * 0 (or its reverse) raise InvalidOperation. 1054 """ 1055 other = _convert_other(other) 1056 1057 if context is None: 1058 context = getcontext() 1059 1060 resultsign = self._sign ^ other._sign 1061 1062 if self._is_special or other._is_special: 1063 ans = self._check_nans(other, context) 1064 if ans: 1065 return ans 1066 1067 if self._isinfinity(): 1068 if not other: 1069 return context._raise_error(InvalidOperation, '(+-)INF * 0') 1070 return Infsign[resultsign] 1071 1072 if other._isinfinity(): 1073 if not self: 1074 return context._raise_error(InvalidOperation, '0 * (+-)INF') 1075 return Infsign[resultsign] 1076 1077 resultexp = self._exp + other._exp 1078 shouldround = context._rounding_decision == ALWAYS_ROUND 1079 1080 # Special case for multiplying by zero 1081 if not self or not other: 1082 ans = Decimal((resultsign, (0,), resultexp)) 1083 if shouldround: 1084 #Fixing in case the exponent is out of bounds 1085 ans = ans._fix(context) 1086 return ans 1087 1088 # Special case for multiplying by power of 10 1089 if self._int == (1,): 1090 ans = Decimal((resultsign, other._int, resultexp)) 1091 if shouldround: 1092 ans = ans._fix(context) 1093 return ans 1094 if other._int == (1,): 1095 ans = Decimal((resultsign, self._int, resultexp)) 1096 if shouldround: 1097 ans = ans._fix(context) 1098 return ans 1099 1100 op1 = _WorkRep(self) 1101 op2 = _WorkRep(other) 1102 1103 ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp)) 1104 if shouldround: 1105 ans = ans._fix(context) 1106 1107 return ans 1108 __rmul__ = __mul__ 1109 1110 def __div__(self, other, context=None): 1111 """Return self / other.""" 1112 return self._divide(other, context=context) 1113 __truediv__ = __div__ 1114 1115 def _divide(self, other, divmod = 0, context=None): 1116 """Return a / b, to context.prec precision. 1117 1118 divmod: 1119 0 => true division 1120 1 => (a //b, a%b) 1121 2 => a //b 1122 3 => a%b 1123 1124 Actually, if divmod is 2 or 3 a tuple is returned, but errors for 1125 computing the other value are not raised. 1126 """ 1127 other = _convert_other(other) 1128 1129 if context is None: 1130 context = getcontext() 1131 1132 sign = self._sign ^ other._sign 1133 1134 if self._is_special or other._is_special: 1135 ans = self._check_nans(other, context) 1136 if ans: 1137 if divmod: 1138 return (ans, ans) 1139 return ans 1140 1141 if self._isinfinity() and other._isinfinity(): 1142 if divmod: 1143 return (context._raise_error(InvalidOperation, 1144 '(+-)INF // (+-)INF'), 1145 context._raise_error(InvalidOperation, 1146 '(+-)INF % (+-)INF')) 1147 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF') 1148 1149 if self._isinfinity(): 1150 if divmod == 1: 1151 return (Infsign[sign], 1152 context._raise_error(InvalidOperation, 'INF % x')) 1153 elif divmod == 2: 1154 return (Infsign[sign], NaN) 1155 elif divmod == 3: 1156 return (Infsign[sign], 1157 context._raise_error(InvalidOperation, 'INF % x')) 1158 return Infsign[sign] 1159 1160 if other._isinfinity(): 1161 if divmod: 1162 return (Decimal((sign, (0,), 0)), Decimal(self)) 1163 context._raise_error(Clamped, 'Division by infinity') 1164 return Decimal((sign, (0,), context.Etiny())) 1165 1166 # Special cases for zeroes 1167 if not self and not other: 1168 if divmod: 1169 return context._raise_error(DivisionUndefined, '0 / 0', 1) 1170 return context._raise_error(DivisionUndefined, '0 / 0') 1171 1172 if not self: 1173 if divmod: 1174 otherside = Decimal(self) 1175 otherside._exp = min(self._exp, other._exp) 1176 return (Decimal((sign, (0,), 0)), otherside) 1177 exp = self._exp - other._exp 1178 if exp < context.Etiny(): 1179 exp = context.Etiny() 1180 context._raise_error(Clamped, '0e-x / y') 1181 if exp > context.Emax: 1182 exp = context.Emax 1183 context._raise_error(Clamped, '0e+x / y') 1184 return Decimal( (sign, (0,), exp) ) 1185 1186 if not other: 1187 if divmod: 1188 return context._raise_error(DivisionByZero, 'divmod(x,0)', 1189 sign, 1) 1190 return context._raise_error(DivisionByZero, 'x / 0', sign) 1191 1192 #OK, so neither = 0, INF or NaN 1193 1194 shouldround = context._rounding_decision == ALWAYS_ROUND 1195 1196 #If we're dividing into ints, and self < other, stop. 1197 #self.__abs__(0) does not round. 1198 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)): 1199 1200 if divmod == 1 or divmod == 3: 1201 exp = min(self._exp, other._exp) 1202 ans2 = self._rescale(exp, context=context, watchexp=0) 1203 if shouldround: 1204 ans2 = ans2._fix(context) 1205 return (Decimal( (sign, (0,), 0) ), 1206 ans2) 1207 1208 elif divmod == 2: 1209 #Don't round the mod part, if we don't need it. 1210 return (Decimal( (sign, (0,), 0) ), Decimal(self)) 1211 1212 op1 = _WorkRep(self) 1213 op2 = _WorkRep(other) 1214 op1, op2, adjust = _adjust_coefficients(op1, op2) 1215 res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) ) 1216 if divmod and res.exp > context.prec + 1: 1217 return context._raise_error(DivisionImpossible) 1218 1219 prec_limit = 10 ** context.prec 1220 while 1: 1221 while op2.int <= op1.int: 1222 res.int += 1 1223 op1.int -= op2.int 1224 if res.exp == 0 and divmod: 1225 if res.int >= prec_limit and shouldround: 1226 return context._raise_error(DivisionImpossible) 1227 otherside = Decimal(op1) 1228 frozen = context._ignore_all_flags() 1229 1230 exp = min(self._exp, other._exp) 1231 otherside = otherside._rescale(exp, context=context, watchexp=0) 1232 context._regard_flags(*frozen) 1233 if shouldround: 1234 otherside = otherside._fix(context) 1235 return (Decimal(res), otherside) 1236 1237 if op1.int == 0 and adjust >= 0 and not divmod: 1238 break 1239 if res.int >= prec_limit and shouldround: 1240 if divmod: 1241 return context._raise_error(DivisionImpossible) 1242 shouldround=1 1243 # Really, the answer is a bit higher, so adding a one to 1244 # the end will make sure the rounding is right. 1245 if op1.int != 0: 1246 res.int *= 10 1247 res.int += 1 1248 res.exp -= 1 1249 1250 break 1251 res.int *= 10 1252 res.exp -= 1 1253 adjust += 1 1254 op1.int *= 10 1255 op1.exp -= 1 1256 1257 if res.exp == 0 and divmod and op2.int > op1.int: 1258 #Solves an error in precision. Same as a previous block. 1259 1260 if res.int >= prec_limit and shouldround: 1261 return context._raise_error(DivisionImpossible) 1262 otherside = Decimal(op1) 1263 frozen = context._ignore_all_flags() 1264 1265 exp = min(self._exp, other._exp) 1266 otherside = otherside._rescale(exp, context=context) 1267 1268 context._regard_flags(*frozen) 1269 1270 return (Decimal(res), otherside) 1271 1272 ans = Decimal(res) 1273 if shouldround: 1274 ans = ans._fix(context) 1275 return ans 1276 1277 def __rdiv__(self, other, context=None): 1278 """Swaps self/other and returns __div__.""" 1279 other = _convert_other(other) 1280 return other.__div__(self, context=context) 1281 __rtruediv__ = __rdiv__ 1282 1283 def __divmod__(self, other, context=None): 1284 """ 1285 (self // other, self % other) 1286 """ 1287 return self._divide(other, 1, context) 1288 1289 def __rdivmod__(self, other, context=None): 1290 """Swaps self/other and returns __divmod__.""" 1291 other = _convert_other(other) 1292 return other.__divmod__(self, context=context) 1293 1294 def __mod__(self, other, context=None): 1295 """ 1296 self % other 1297 """ 1298 other = _convert_other(other) 1299 1300 if self._is_special or other._is_special: 1301 ans = self._check_nans(other, context) 1302 if ans: 1303 return ans 1304 1305 if self and not other: 1306 return context._raise_error(InvalidOperation, 'x % 0') 1307 1308 return self._divide(other, 3, context)[1] 1309 1310 def __rmod__(self, other, context=None): 1311 """Swaps self/other and returns __mod__.""" 1312 other = _convert_other(other) 1313 return other.__mod__(self, context=context) 1314 1315 def remainder_near(self, other, context=None): 1316 """ 1317 Remainder nearest to 0- abs(remainder-near) <= other/2 1318 """ 1319 other = _convert_other(other) 1320 1321 if self._is_special or other._is_special: 1322 ans = self._check_nans(other, context) 1323 if ans: 1324 return ans 1325 if self and not other: 1326 return context._raise_error(InvalidOperation, 'x % 0') 1327 1328 if context is None: 1329 context = getcontext() 1330 # If DivisionImpossible causes an error, do not leave Rounded/Inexact 1331 # ignored in the calling function. 1332 context = context._shallow_copy() 1333 flags = context._ignore_flags(Rounded, Inexact) 1334 #keep DivisionImpossible flags 1335 (side, r) = self.__divmod__(other, context=context) 1336 1337 if r._isnan(): 1338 context._regard_flags(*flags) 1339 return r 1340 1341 context = context._shallow_copy() 1342 rounding = context._set_rounding_decision(NEVER_ROUND) 1343 1344 if other._sign: 1345 comparison = other.__div__(Decimal(-2), context=context) 1346 else: 1347 comparison = other.__div__(Decimal(2), context=context) 1348 1349 context._set_rounding_decision(rounding) 1350 context._regard_flags(*flags) 1351 1352 s1, s2 = r._sign, comparison._sign 1353 r._sign, comparison._sign = 0, 0 1354 1355 if r < comparison: 1356 r._sign, comparison._sign = s1, s2 1357 #Get flags now 1358 self.__divmod__(other, context=context) 1359 return r._fix(context) 1360 r._sign, comparison._sign = s1, s2 1361 1362 rounding = context._set_rounding_decision(NEVER_ROUND) 1363 1364 (side, r) = self.__divmod__(other, context=context) 1365 context._set_rounding_decision(rounding) 1366 if r._isnan(): 1367 return r 1368 1369 decrease = not side._iseven() 1370 rounding = context._set_rounding_decision(NEVER_ROUND) 1371 side = side.__abs__(context=context) 1372 context._set_rounding_decision(rounding) 1373 1374 s1, s2 = r._sign, comparison._sign 1375 r._sign, comparison._sign = 0, 0 1376 if r > comparison or decrease and r == comparison: 1377 r._sign, comparison._sign = s1, s2 1378 context.prec += 1 1379 if len(side.__add__(Decimal(1), context=context)._int) >= context.prec: 1380 context.prec -= 1 1381 return context._raise_error(DivisionImpossible)[1] 1382 context.prec -= 1 1383 if self._sign == other._sign: 1384 r = r.__sub__(other, context=context) 1385 else: 1386 r = r.__add__(other, context=context) 1387 else: 1388 r._sign, comparison._sign = s1, s2 1389 1390 return r._fix(context) 1391 1392 def __floordiv__(self, other, context=None): 1393 """self // other""" 1394 return self._divide(other, 2, context)[0] 1395 1396 def __rfloordiv__(self, other, context=None): 1397 """Swaps self/other and returns __floordiv__.""" 1398 other = _convert_other(other) 1399 return other.__floordiv__(self, context=context) 1400 1401 def __float__(self): 1402 """Float representation.""" 1403 return float(str(self)) 1404 1405 def __int__(self): 1406 """Converts self to a int, truncating if necessary.""" 1407 if self._is_special: 1408 if self._isnan(): 1409 context = getcontext() 1410 return context._raise_error(InvalidContext) 1411 elif self._isinfinity(): 1412 raise OverflowError, "Cannot convert infinity to long" 1413 if not self: 1414 return 0 1415 sign = '-'*self._sign 1416 if self._exp >= 0: 1417 s = sign + ''.join(map(str, self._int)) + '0'*self._exp 1418 return int(s) 1419 s = sign + ''.join(map(str, self._int))[:self._exp] 1420 return int(s) 1421 1422 def __long__(self): 1423 """Converts to a long. 1424 1425 Equivalent to long(int(self)) 1426 """ 1427 return long(self.__int__()) 1428 1429 def _fix(self, context): 1430 """Round if it is necessary to keep self within prec precision. 1431 1432 Rounds and fixes the exponent. Does not raise on a sNaN. 1433 1434 Arguments: 1435 self - Decimal instance 1436 context - context used. 1437 """ 1438 if self._is_special: 1439 return self 1440 if context is None: 1441 context = getcontext() 1442 prec = context.prec 1443 ans = self._fixexponents(context) 1444 if len(ans._int) > prec: 1445 ans = ans._round(prec, context=context) 1446 ans = ans._fixexponents(context) 1447 return ans 1448 1449 def _fixexponents(self, context): 1450 """Fix the exponents and return a copy with the exponent in bounds. 1451 Only call if known to not be a special value. 1452 """ 1453 folddown = context._clamp 1454 Emin = context.Emin 1455 ans = self 1456 ans_adjusted = ans.adjusted() 1457 if ans_adjusted < Emin: 1458 Etiny = context.Etiny() 1459 if ans._exp < Etiny: 1460 if not ans: 1461 ans = Decimal(self) 1462 ans._exp = Etiny 1463 context._raise_error(Clamped) 1464 return ans 1465 ans = ans._rescale(Etiny, context=context) 1466 #It isn't zero, and exp < Emin => subnormal 1467 context._raise_error(Subnormal) 1468 if context.flags[Inexact]: 1469 context._raise_error(Underflow) 1470 else: 1471 if ans: 1472 #Only raise subnormal if non-zero. 1473 context._raise_error(Subnormal) 1474 else: 1475 Etop = context.Etop() 1476 if folddown and ans._exp > Etop: 1477 context._raise_error(Clamped) 1478 ans = ans._rescale(Etop, context=context) 1479 else: 1480 Emax = context.Emax 1481 if ans_adjusted > Emax: 1482 if not ans: 1483 ans = Decimal(self) 1484 ans._exp = Emax 1485 context._raise_error(Clamped) 1486 return ans 1487 context._raise_error(Inexact) 1488 context._raise_error(Rounded) 1489 return context._raise_error(Overflow, 'above Emax', ans._sign) 1490 return ans 1491 1492 def _round(self, prec=None, rounding=None, context=None): 1493 """Returns a rounded version of self. 1494 1495 You can specify the precision or rounding method. Otherwise, the 1496 context determines it. 1497 """ 1498 1499 if self._is_special: 1500 ans = self._check_nans(context=context) 1501 if ans: 1502 return ans 1503 1504 if self._isinfinity(): 1505 return Decimal(self) 1506 1507 if context is None: 1508 context = getcontext() 1509 1510 if rounding is None: 1511 rounding = context.rounding 1512 if prec is None: 1513 prec = context.prec 1514 1515 if not self: 1516 if prec <= 0: 1517 dig = (0,) 1518 exp = len(self._int) - prec + self._exp 1519 else: 1520 dig = (0,) * prec 1521 exp = len(self._int) + self._exp - prec 1522 ans = Decimal((self._sign, dig, exp)) 1523 context._raise_error(Rounded) 1524 return ans 1525 1526 if prec == 0: 1527 temp = Decimal(self) 1528 temp._int = (0,)+temp._int 1529 prec = 1 1530 elif prec < 0: 1531 exp = self._exp + len(self._int) - prec - 1 1532 temp = Decimal( (self._sign, (0, 1), exp)) 1533 prec = 1 1534 else: 1535 temp = Decimal(self) 1536 1537 numdigits = len(temp._int) 1538 if prec == numdigits: 1539 return temp 1540 1541 # See if we need to extend precision 1542 expdiff = prec - numdigits 1543 if expdiff > 0: 1544 tmp = list(temp._int) 1545 tmp.extend([0] * expdiff) 1546 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff)) 1547 return ans 1548 1549 #OK, but maybe all the lost digits are 0. 1550 lostdigits = self._int[expdiff:] 1551 if lostdigits == (0,) * len(lostdigits): 1552 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff)) 1553 #Rounded, but not Inexact 1554 context._raise_error(Rounded) 1555 return ans 1556 1557 # Okay, let's round and lose data 1558 1559 this_function = getattr(temp, self._pick_rounding_function[rounding]) 1560 #Now we've got the rounding function 1561 1562 if prec != context.prec: 1563 context = context._shallow_copy() 1564 context.prec = prec 1565 ans = this_function(prec, expdiff, context) 1566 context._raise_error(Rounded) 1567 context._raise_error(Inexact, 'Changed in rounding') 1568 1569 return ans 1570 1571 _pick_rounding_function = {} 1572 1573 def _round_down(self, prec, expdiff, context): 1574 """Also known as round-towards-0, truncate.""" 1575 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) ) 1576 1577 def _round_half_up(self, prec, expdiff, context, tmp = None): 1578 """Rounds 5 up (away from 0)""" 1579 1580 if tmp is None: 1581 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff)) 1582 if self._int[prec] >= 5: 1583 tmp = tmp._increment(round=0, context=context) 1584 if len(tmp._int) > prec: 1585 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1)) 1586 return tmp 1587 1588 def _round_half_even(self, prec, expdiff, context): 1589 """Round 5 to even, rest to nearest.""" 1590 1591 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff)) 1592 half = (self._int[prec] == 5) 1593 if half: 1594 for digit in self._int[prec+1:]: 1595 if digit != 0: 1596 half = 0 1597 break 1598 if half: 1599 if self._int[prec-1] & 1 == 0: 1600 return tmp 1601 return self._round_half_up(prec, expdiff, context, tmp) 1602 1603 def _round_half_down(self, prec, expdiff, context): 1604 """Round 5 down""" 1605 1606 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff)) 1607 half = (self._int[prec] == 5) 1608 if half: 1609 for digit in self._int[prec+1:]: 1610 if digit != 0: 1611 half = 0 1612 break 1613 if half: 1614 return tmp 1615 return self._round_half_up(prec, expdiff, context, tmp) 1616 1617 def _round_up(self, prec, expdiff, context): 1618 """Rounds away from 0.""" 1619 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) ) 1620 for digit in self._int[prec:]: 1621 if digit != 0: 1622 tmp = tmp._increment(round=1, context=context) 1623 if len(tmp._int) > prec: 1624 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1)) 1625 else: 1626 return tmp 1627 return tmp 1628 1629 def _round_ceiling(self, prec, expdiff, context): 1630 """Rounds up (not away from 0 if negative.)""" 1631 if self._sign: 1632 return self._round_down(prec, expdiff, context) 1633 else: 1634 return self._round_up(prec, expdiff, context) 1635 1636 def _round_floor(self, prec, expdiff, context): 1637 """Rounds down (not towards 0 if negative)""" 1638 if not self._sign: 1639 return self._round_down(prec, expdiff, context) 1640 else: 1641 return self._round_up(prec, expdiff, context) 1642 1643 def __pow__(self, n, modulo = None, context=None): 1644 """Return self ** n (mod modulo) 1645 1646 If modulo is None (default), don't take it mod modulo. 1647 """ 1648 n = _convert_other(n) 1649 1650 if context is None: 1651 context = getcontext() 1652 1653 if self._is_special or n._is_special or n.adjusted() > 8: 1654 #Because the spot << doesn't work with really big exponents 1655 if n._isinfinity() or n.adjusted() > 8: 1656 return context._raise_error(InvalidOperation, 'x ** INF') 1657 1658 ans = self._check_nans(n, context) 1659 if ans: 1660 return ans 1661 1662 if not n._isinteger(): 1663 return context._raise_error(InvalidOperation, 'x ** (non-integer)') 1664 1665 if not self and not n: 1666 return context._raise_error(InvalidOperation, '0 ** 0') 1667 1668 if not n: 1669 return Decimal(1) 1670 1671 if self == Decimal(1): 1672 return Decimal(1) 1673 1674 sign = self._sign and not n._iseven() 1675 n = int(n) 1676 1677 if self._isinfinity(): 1678 if modulo: 1679 return context._raise_error(InvalidOperation, 'INF % x') 1680 if n > 0: 1681 return Infsign[sign] 1682 return Decimal( (sign, (0,), 0) ) 1683 1684 #with ludicrously large exponent, just raise an overflow and return inf. 1685 if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \ 1686 and self: 1687 1688 tmp = Decimal('inf') 1689 tmp._sign = sign 1690 context._raise_error(Rounded) 1691 context._raise_error(Inexact) 1692 context._raise_error(Overflow, 'Big power', sign) 1693 return tmp 1694 1695 elength = len(str(abs(n))) 1696 firstprec = context.prec 1697 1698 if not modulo and firstprec + elength + 1 > DefaultContext.Emax: 1699 return context._raise_error(Overflow, 'Too much precision.', sign) 1700 1701 mul = Decimal(self) 1702 val = Decimal(1) 1703 context = context._shallow_copy() 1704 context.prec = firstprec + elength + 1 1705 if n < 0: 1706 #n is a long now, not Decimal instance 1707 n = -n 1708 mul = Decimal(1).__div__(mul, context=context) 1709 1710 spot = 1 1711 while spot <= n: 1712 spot <<= 1 1713 1714 spot >>= 1 1715 #Spot is the highest power of 2 less than n 1716 while spot: 1717 val = val.__mul__(val, context=context) 1718 if val._isinfinity(): 1719 val = Infsign[sign] 1720 break 1721 if spot & n: 1722 val = val.__mul__(mul, context=context) 1723 if modulo is not None: 1724 val = val.__mod__(modulo, context=context) 1725 spot >>= 1 1726 context.prec = firstprec 1727 1728 if context._rounding_decision == ALWAYS_ROUND: 1729 return val._fix(context) 1730 return val 1731 1732 def __rpow__(self, other, context=None): 1733 """Swaps self/other and returns __pow__.""" 1734 other = _convert_other(other) 1735 return other.__pow__(self, context=context) 1736 1737 def normalize(self, context=None): 1738 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0""" 1739 1740 if self._is_special: 1741 ans = self._check_nans(context=context) 1742 if ans: 1743 return ans 1744 1745 dup = self._fix(context) 1746 if dup._isinfinity(): 1747 return dup 1748 1749 if not dup: 1750 return Decimal( (dup._sign, (0,), 0) ) 1751 end = len(dup._int) 1752 exp = dup._exp 1753 while dup._int[end-1] == 0: 1754 exp += 1 1755 end -= 1 1756 return Decimal( (dup._sign, dup._int[:end], exp) ) 1757 1758 1759 def quantize(self, exp, rounding=None, context=None, watchexp=1): 1760 """Quantize self so its exponent is the same as that of exp. 1761 1762 Similar to self._rescale(exp._exp) but with error checking. 1763 """ 1764 if self._is_special or exp._is_special: 1765 ans = self._check_nans(exp, context) 1766 if ans: 1767 return ans 1768 1769 if exp._isinfinity() or self._isinfinity(): 1770 if exp._isinfinity() and self._isinfinity(): 1771 return self #if both are inf, it is OK 1772 if context is None: 1773 context = getcontext() 1774 return context._raise_error(InvalidOperation, 1775 'quantize with one INF') 1776 return self._rescale(exp._exp, rounding, context, watchexp) 1777 1778 def same_quantum(self, other): 1779 """Test whether self and other have the same exponent. 1780 1781 same as self._exp == other._exp, except NaN == sNaN 1782 """ 1783 if self._is_special or other._is_special: 1784 if self._isnan() or other._isnan(): 1785 return self._isnan() and other._isnan() and True 1786 if self._isinfinity() or other._isinfinity(): 1787 return self._isinfinity() and other._isinfinity() and True 1788 return self._exp == other._exp 1789 1790 def _rescale(self, exp, rounding=None, context=None, watchexp=1): 1791 """Rescales so that the exponent is exp. 1792 1793 exp = exp to scale to (an integer) 1794 rounding = rounding version 1795 watchexp: if set (default) an error is returned if exp is greater 1796 than Emax or less than Etiny. 1797 """ 1798 if context is None: 1799 context = getcontext() 1800 1801 if self._is_special: 1802 if self._isinfinity(): 1803 return context._raise_error(InvalidOperation, 'rescale with an INF') 1804 1805 ans = self._check_nans(context=context) 1806 if ans: 1807 return ans 1808 1809 if watchexp and (context.Emax < exp or context.Etiny() > exp): 1810 return context._raise_error(InvalidOperation, 'rescale(a, INF)') 1811 1812 if not self: 1813 ans = Decimal(self) 1814 ans._int = (0,) 1815 ans._exp = exp 1816 return ans 1817 1818 diff = self._exp - exp 1819 digits = len(self._int) + diff 1820 1821 if watchexp and digits > context.prec: 1822 return context._raise_error(InvalidOperation, 'Rescale > prec') 1823 1824 tmp = Decimal(self) 1825 tmp._int = (0,) + tmp._int 1826 digits += 1 1827 1828 if digits < 0: 1829 tmp._exp = -digits + tmp._exp 1830 tmp._int = (0,1) 1831 digits = 1 1832 tmp = tmp._round(digits, rounding, context=context) 1833 1834 if tmp._int[0] == 0 and len(tmp._int) > 1: 1835 tmp._int = tmp._int[1:] 1836 tmp._exp = exp 1837 1838 tmp_adjusted = tmp.adjusted() 1839 if tmp and tmp_adjusted < context.Emin: 1840 context._raise_error(Subnormal) 1841 elif tmp and tmp_adjusted > context.Emax: 1842 return context._raise_error(InvalidOperation, 'rescale(a, INF)') 1843 return tmp 1844 1845 def to_integral(self, rounding=None, context=None): 1846 """Rounds to the nearest integer, without raising inexact, rounded.""" 1847 if self._is_special: 1848 ans = self._check_nans(context=context) 1849 if ans: 1850 return ans 1851 if self._exp >= 0: 1852 return self 1853 if context is None: 1854 context = getcontext() 1855 flags = context._ignore_flags(Rounded, Inexact) 1856 ans = self._rescale(0, rounding, context=context) 1857 context._regard_flags(flags) 1858 return ans 1859 1860 def sqrt(self, context=None): 1861 """Return the square root of self. 1862 1863 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn)) 1864 Should quadratically approach the right answer. 1865 """ 1866 if self._is_special: 1867 ans = self._check_nans(context=context) 1868 if ans: 1869 return ans 1870 1871 if self._isinfinity() and self._sign == 0: 1872 return Decimal(self) 1873 1874 if not self: 1875 #exponent = self._exp / 2, using round_down. 1876 #if self._exp < 0: 1877 # exp = (self._exp+1) // 2 1878 #else: 1879 exp = (self._exp) // 2 1880 if self._sign == 1: 1881 #sqrt(-0) = -0 1882 return Decimal( (1, (0,), exp)) 1883 else: 1884 return Decimal( (0, (0,), exp)) 1885 1886 if context is None: 1887 context = getcontext() 1888 1889 if self._sign == 1: 1890 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0') 1891 1892 tmp = Decimal(self) 1893 1894 expadd = tmp._exp // 2 1895 if tmp._exp & 1: 1896 tmp._int += (0,) 1897 tmp._exp = 0 1898 else: 1899 tmp._exp = 0 1900 1901 context = context._shallow_copy() 1902 flags = context._ignore_all_flags() 1903 firstprec = context.prec 1904 context.prec = 3 1905 if tmp.adjusted() & 1 == 0: 1906 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) ) 1907 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)), 1908 context=context), context=context) 1909 ans._exp -= 1 + tmp.adjusted() // 2 1910 else: 1911 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) ) 1912 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)), 1913 context=context), context=context) 1914 ans._exp -= 1 + tmp.adjusted() // 2 1915 1916 #ans is now a linear approximation. 1917 1918 Emax, Emin = context.Emax, context.Emin 1919 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin 1920 1921 half = Decimal('0.5') 1922 1923 maxp = firstprec + 2 1924 rounding = context._set_rounding(ROUND_HALF_EVEN) 1925 while 1: 1926 context.prec = min(2*context.prec - 2, maxp) 1927 ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context), 1928 context=context), context=context) 1929 if context.prec == maxp: 1930 break 1931 1932 #round to the answer's precision-- the only error can be 1 ulp. 1933 context.prec = firstprec 1934 prevexp = ans.adjusted() 1935 ans = ans._round(context=context) 1936 1937 #Now, check if the other last digits are better. 1938 context.prec = firstprec + 1 1939 # In case we rounded up another digit and we should actually go lower. 1940 if prevexp != ans.adjusted(): 1941 ans._int += (0,) 1942 ans._exp -= 1 1943 1944 1945 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context) 1946 context._set_rounding(ROUND_UP) 1947 if lower.__mul__(lower, context=context) > (tmp): 1948 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context) 1949 1950 else: 1951 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context) 1952 context._set_rounding(ROUND_DOWN) 1953 if upper.__mul__(upper, context=context) < tmp: 1954 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context) 1955 1956 ans._exp += expadd 1957 1958 context.prec = firstprec 1959 context.rounding = rounding 1960 ans = ans._fix(context) 1961 1962 rounding = context._set_rounding_decision(NEVER_ROUND) 1963 if not ans.__mul__(ans, context=context) == self: 1964 # Only rounded/inexact if here. 1965 context._regard_flags(flags) 1966 context._raise_error(Rounded) 1967 context._raise_error(Inexact) 1968 else: 1969 #Exact answer, so let's set the exponent right. 1970 #if self._exp < 0: 1971 # exp = (self._exp +1)// 2 1972 #else: 1973 exp = self._exp // 2 1974 context.prec += ans._exp - exp 1975 ans = ans._rescale(exp, context=context) 1976 context.prec = firstprec 1977 context._regard_flags(flags) 1978 context.Emax, context.Emin = Emax, Emin 1979 1980 return ans._fix(context) 1981 1982 def max(self, other, context=None): 1983 """Returns the larger value. 1984 1985 like max(self, other) except if one is not a number, returns 1986 NaN (and signals if one is sNaN). Also rounds. 1987 """ 1988 other = _convert_other(other) 1989 1990 if self._is_special or other._is_special: 1991 # if one operand is a quiet NaN and the other is number, then the 1992 # number is always returned 1993 sn = self._isnan() 1994 on = other._isnan() 1995 if sn or on: 1996 if on == 1 and sn != 2: 1997 return self 1998 if sn == 1 and on != 2: 1999 return other 2000 return self._check_nans(other, context) 2001 2002 ans = self 2003 c = self.__cmp__(other) 2004 if c == 0: 2005 # if both operands are finite and equal in numerical value 2006 # then an ordering is applied: 2007 # 2008 # if the signs differ then max returns the operand with the 2009 # positive sign and min returns the operand with the negative sign 2010 # 2011 # if the signs are the same then the exponent is used to select 2012 # the result. 2013 if self._sign != other._sign: 2014 if self._sign: 2015 ans = other 2016 elif self._exp < other._exp and not self._sign: 2017 ans = other 2018 elif self._exp > other._exp and self._sign: 2019 ans = other 2020 elif c == -1: 2021 ans = other 2022 2023 if context is None: 2024 context = getcontext() 2025 if context._rounding_decision == ALWAYS_ROUND: 2026 return ans._fix(context) 2027 return ans 2028 2029 def min(self, other, context=None): 2030 """Returns the smaller value. 2031 2032 like min(self, other) except if one is not a number, returns 2033 NaN (and signals if one is sNaN). Also rounds. 2034 """ 2035 other = _convert_other(other) 2036 2037 if self._is_special or other._is_special: 2038 # if one operand is a quiet NaN and the other is number, then the 2039 # number is always returned 2040 sn = self._isnan() 2041 on = other._isnan() 2042 if sn or on: 2043 if on == 1 and sn != 2: 2044 return self 2045 if sn == 1 and on != 2: 2046 return other 2047 return self._check_nans(other, context) 2048 2049 ans = self 2050 c = self.__cmp__(other) 2051 if c == 0: 2052 # if both operands are finite and equal in numerical value 2053 # then an ordering is applied: 2054 # 2055 # if the signs differ then max returns the operand with the 2056 # positive sign and min returns the operand with the negative sign 2057 # 2058 # if the signs are the same then the exponent is used to select 2059 # the result. 2060 if self._sign != other._sign: 2061 if other._sign: 2062 ans = other 2063 elif self._exp > other._exp and not self._sign: 2064 ans = other 2065 elif self._exp < other._exp and self._sign: 2066 ans = other 2067 elif c == 1: 2068 ans = other 2069 2070 if context is None: 2071 context = getcontext() 2072 if context._rounding_decision == ALWAYS_ROUND: 2073 return ans._fix(context) 2074 return ans 2075 2076 def _isinteger(self): 2077 """Returns whether self is an integer""" 2078 if self._exp >= 0: 2079 return True 2080 rest = self._int[self._exp:] 2081 return rest == (0,)*len(rest) 2082 2083 def _iseven(self): 2084 """Returns 1 if self is even. Assumes self is an integer.""" 2085 if self._exp > 0: 2086 return 1 2087 return self._int[-1+self._exp] & 1 == 0 2088 2089 def adjusted(self): 2090 """Return the adjusted exponent of self""" 2091 try: 2092 return self._exp + len(self._int) - 1 2093 #If NaN or Infinity, self._exp is string 2094 except TypeError: 2095 return 0 2096 2097 # support for pickling, copy, and deepcopy 2098 def __reduce__(self): 2099 return (self.__class__, (str(self),)) 2100 2101 def __copy__(self): 2102 if type(self) == Decimal: 2103 return self # I'm immutable; therefore I am my own clone 2104 return self.__class__(str(self)) 2105 2106 def __deepcopy__(self, memo): 2107 if type(self) == Decimal: 2108 return self # My components are also immutable 2109 return self.__class__(str(self)) 2110 2111 ##### Context class ########################################### 2112 2113 2114 # get rounding method function: 2115 rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')] 2116 for name in rounding_functions: 2117 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value. 2118 globalname = name[1:].upper() 2119 val = globals()[globalname] 2120 Decimal._pick_rounding_function[val] = name 2121 2122 del name, val, globalname, rounding_functions 2123 2124 class Context(object): 2125 """Contains the context for a Decimal instance. 2126 2127 Contains: 2128 prec - precision (for use in rounding, division, square roots..) 2129 rounding - rounding type. (how you round) 2130 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round? 2131 traps - If traps[exception] = 1, then the exception is 2132 raised when it is caused. Otherwise, a value is 2133 substituted in. 2134 flags - When an exception is caused, flags[exception] is incremented. 2135 (Whether or not the trap_enabler is set) 2136 Should be reset by user of Decimal instance. 2137 Emin - Minimum exponent 2138 Emax - Maximum exponent 2139 capitals - If 1, 1*10^1 is printed as 1E+1. 2140 If 0, printed as 1e1 2141 _clamp - If 1, change exponents if too high (Default 0) 2142 """ 2143 2144 def __init__(self, prec=None, rounding=None, 2145 traps=None, flags=None, 2146 _rounding_decision=None, 2147 Emin=None, Emax=None, 2148 capitals=None, _clamp=0, 2149 _ignored_flags=None): 2150 if flags is None: 2151 flags = [] 2152 if _ignored_flags is None: 2153 _ignored_flags = [] 2154 if not isinstance(flags, dict): 2155 flags = dict([(s,s in flags) for s in _signals]) 2156 del s 2157 if traps is not None and not isinstance(traps, dict): 2158 traps = dict([(s,s in traps) for s in _signals]) 2159 del s 2160 for name, val in locals().items(): 2161 if val is None: 2162 setattr(self, name, copy.copy(getattr(DefaultContext, name))) 2163 else: 2164 setattr(self, name, val) 2165 del self.self 2166 2167 def __repr__(self): 2168 """Show the current context.""" 2169 s = [] 2170 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self)) 2171 s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']') 2172 s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']') 2173 return ', '.join(s) + ')' 2174 2175 def clear_flags(self): 2176 """Reset all flags to zero""" 2177 for flag in self.flags: 2178 self.flags[flag] = 0 2179 2180 def _shallow_copy(self): 2181 """Returns a shallow copy from self.""" 2182 nc = Context(self.prec, self.rounding, self.traps, self.flags, 2183 self._rounding_decision, self.Emin, self.Emax, 2184 self.capitals, self._clamp, self._ignored_flags) 2185 return nc 2186 2187 def copy(self): 2188 """Returns a deep copy from self.""" 2189 nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(), 2190 self._rounding_decision, self.Emin, self.Emax, 2191 self.capitals, self._clamp, self._ignored_flags) 2192 return nc 2193 __copy__ = copy 2194 2195 def _raise_error(self, condition, explanation = None, *args): 2196 """Handles an error 2197 2198 If the flag is in _ignored_flags, returns the default response. 2199 Otherwise, it increments the flag, then, if the corresponding 2200 trap_enabler is set, it reaises the exception. Otherwise, it returns 2201 the default value after incrementing the flag. 2202 """ 2203 error = _condition_map.get(condition, condition) 2204 if error in self._ignored_flags: 2205 #Don't touch the flag 2206 return error().handle(self, *args) 2207 2208 self.flags[error] += 1 2209 if not self.traps[error]: 2210 #The errors define how to handle themselves. 2211 return condition().handle(self, *args) 2212 2213 # Errors should only be risked on copies of the context 2214 #self._ignored_flags = [] 2215 raise error, explanation 2216 2217 def _ignore_all_flags(self): 2218 """Ignore all flags, if they are raised""" 2219 return self._ignore_flags(*_signals) 2220 2221 def _ignore_flags(self, *flags): 2222 """Ignore the flags, if they are raised""" 2223 # Do not mutate-- This way, copies of a context leave the original 2224 # alone. 2225 self._ignored_flags = (self._ignored_flags + list(flags)) 2226 return list(flags) 2227 2228 def _regard_flags(self, *flags): 2229 """Stop ignoring the flags, if they are raised""" 2230 if flags and isinstance(flags[0], (tuple,list)): 2231 flags = flags[0] 2232 for flag in flags: 2233 self._ignored_flags.remove(flag) 2234 2235 def __hash__(self): 2236 """A Context cannot be hashed.""" 2237 # We inherit object.__hash__, so we must deny this explicitly 2238 raise TypeError, "Cannot hash a Context." 2239 2240 def Etiny(self): 2241 """Returns Etiny (= Emin - prec + 1)""" 2242 return int(self.Emin - self.prec + 1) 2243 2244 def Etop(self): 2245 """Returns maximum exponent (= Emax - prec + 1)""" 2246 return int(self.Emax - self.prec + 1) 2247 2248 def _set_rounding_decision(self, type): 2249 """Sets the rounding decision. 2250 2251 Sets the rounding decision, and returns the current (previous) 2252 rounding decision. Often used like: 2253 2254 context = context._shallow_copy() 2255 # That so you don't change the calling context 2256 # if an error occurs in the middle (say DivisionImpossible is raised). 2257 2258 rounding = context._set_rounding_decision(NEVER_ROUND) 2259 instance = instance / Decimal(2) 2260 context._set_rounding_decision(rounding) 2261 2262 This will make it not round for that operation. 2263 """ 2264 2265 rounding = self._rounding_decision 2266 self._rounding_decision = type 2267 return rounding 2268 2269 def _set_rounding(self, type): 2270 """Sets the rounding type. 2271 2272 Sets the rounding type, and returns the current (previous) 2273 rounding type. Often used like: 2274 2275 context = context.copy() 2276 # so you don't change the calling context 2277 # if an error occurs in the middle. 2278 rounding = context._set_rounding(ROUND_UP) 2279 val = self.__sub__(other, context=context) 2280 context._set_rounding(rounding) 2281 2282 This will make it round up for that operation. 2283 """ 2284 rounding = self.rounding 2285 self.rounding= type 2286 return rounding 2287 2288 def create_decimal(self, num='0'): 2289 """Creates a new Decimal instance but using self as context.""" 2290 d = Decimal(num, context=self) 2291 return d._fix(self) 2292 2293 #Methods 2294 def abs(self, a): 2295 """Returns the absolute value of the operand. 2296 2297 If the operand is negative, the result is the same as using the minus 2298 operation on the operand. Otherwise, the result is the same as using 2299 the plus operation on the operand. 2300 2301 >>> ExtendedContext.abs(Decimal('2.1')) 2302 Decimal("2.1") 2303 >>> ExtendedContext.abs(Decimal('-100')) 2304 Decimal("100") 2305 >>> ExtendedContext.abs(Decimal('101.5')) 2306 Decimal("101.5") 2307 >>> ExtendedContext.abs(Decimal('-101.5')) 2308 Decimal("101.5") 2309 """ 2310 return a.__abs__(context=self) 2311 2312 def add(self, a, b): 2313 """Return the sum of the two operands. 2314 2315 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00')) 2316 Decimal("19.00") 2317 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4')) 2318 Decimal("1.02E+4") 2319 """ 2320 return a.__add__(b, context=self) 2321 2322 def _apply(self, a): 2323 return str(a._fix(self)) 2324 2325 def compare(self, a, b): 2326 """Compares values numerically. 2327 2328 If the signs of the operands differ, a value representing each operand 2329 ('-1' if the operand is less than zero, '0' if the operand is zero or 2330 negative zero, or '1' if the operand is greater than zero) is used in 2331 place of that operand for the comparison instead of the actual 2332 operand. 2333 2334 The comparison is then effected by subtracting the second operand from 2335 the first and then returning a value according to the result of the 2336 subtraction: '-1' if the result is less than zero, '0' if the result is 2337 zero or negative zero, or '1' if the result is greater than zero. 2338 2339 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3')) 2340 Decimal("-1") 2341 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1')) 2342 Decimal("0") 2343 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10')) 2344 Decimal("0") 2345 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1')) 2346 Decimal("1") 2347 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3')) 2348 Decimal("1") 2349 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1')) 2350 Decimal("-1") 2351 """ 2352 return a.compare(b, context=self) 2353 2354 def divide(self, a, b): 2355 """Decimal division in a specified context. 2356 2357 >>> ExtendedContext.divide(Decimal('1'), Decimal('3')) 2358 Decimal("0.333333333") 2359 >>> ExtendedContext.divide(Decimal('2'), Decimal('3')) 2360 Decimal("0.666666667") 2361 >>> ExtendedContext.divide(Decimal('5'), Decimal('2')) 2362 Decimal("2.5") 2363 >>> ExtendedContext.divide(Decimal('1'), Decimal('10')) 2364 Decimal("0.1") 2365 >>> ExtendedContext.divide(Decimal('12'), Decimal('12')) 2366 Decimal("1") 2367 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2')) 2368 Decimal("4.00") 2369 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0')) 2370 Decimal("1.20") 2371 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100')) 2372 Decimal("10") 2373 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1')) 2374 Decimal("1000") 2375 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2')) 2376 Decimal("1.20E+6") 2377 """ 2378 return a.__div__(b, context=self) 2379 2380 def divide_int(self, a, b): 2381 """Divides two numbers and returns the integer part of the result. 2382 2383 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3')) 2384 Decimal("0") 2385 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3')) 2386 Decimal("3") 2387 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3')) 2388 Decimal("3") 2389 """ 2390 return a.__floordiv__(b, context=self) 2391 2392 def divmod(self, a, b): 2393 return a.__divmod__(b, context=self) 2394 2395 def max(self, a,b): 2396 """max compares two values numerically and returns the maximum. 2397 2398 If either operand is a NaN then the general rules apply. 2399 Otherwise, the operands are compared as as though by the compare 2400 operation. If they are numerically equal then the left-hand operand 2401 is chosen as the result. Otherwise the maximum (closer to positive 2402 infinity) of the two operands is chosen as the result. 2403 2404 >>> ExtendedContext.max(Decimal('3'), Decimal('2')) 2405 Decimal("3") 2406 >>> ExtendedContext.max(Decimal('-10'), Decimal('3')) 2407 Decimal("3") 2408 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1')) 2409 Decimal("1") 2410 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN')) 2411 Decimal("7") 2412 """ 2413 return a.max(b, context=self) 2414 2415 def min(self, a,b): 2416 """min compares two values numerically and returns the minimum. 2417 2418 If either operand is a NaN then the general rules apply. 2419 Otherwise, the operands are compared as as though by the compare 2420 operation. If they are numerically equal then the left-hand operand 2421 is chosen as the result. Otherwise the minimum (closer to negative 2422 infinity) of the two operands is chosen as the result. 2423 2424 >>> ExtendedContext.min(Decimal('3'), Decimal('2')) 2425 Decimal("2") 2426 >>> ExtendedContext.min(Decimal('-10'), Decimal('3')) 2427 Decimal("-10") 2428 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1')) 2429 Decimal("1.0") 2430 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN')) 2431 Decimal("7") 2432 """ 2433 return a.min(b, context=self) 2434 2435 def minus(self, a): 2436 """Minus corresponds to unary prefix minus in Python. 2437 2438 The operation is evaluated using the same rules as subtract; the 2439 operation minus(a) is calculated as subtract('0', a) where the '0' 2440 has the same exponent as the operand. 2441 2442 >>> ExtendedContext.minus(Decimal('1.3')) 2443 Decimal("-1.3") 2444 >>> ExtendedContext.minus(Decimal('-1.3')) 2445 Decimal("1.3") 2446 """ 2447 return a.__neg__(context=self) 2448 2449 def multiply(self, a, b): 2450 """multiply multiplies two operands. 2451 2452 If either operand is a special value then the general rules apply. 2453 Otherwise, the operands are multiplied together ('long multiplication'), 2454 resulting in a number which may be as long as the sum of the lengths 2455 of the two operands. 2456 2457 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3')) 2458 Decimal("3.60") 2459 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3')) 2460 Decimal("21") 2461 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8')) 2462 Decimal("0.72") 2463 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0')) 2464 Decimal("-0.0") 2465 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321')) 2466 Decimal("4.28135971E+11") 2467 """ 2468 return a.__mul__(b, context=self) 2469 2470 def normalize(self, a): 2471 """normalize reduces an operand to its simplest form. 2472 2473 Essentially a plus operation with all trailing zeros removed from the 2474 result. 2475 2476 >>> ExtendedContext.normalize(Decimal('2.1')) 2477 Decimal("2.1") 2478 >>> ExtendedContext.normalize(Decimal('-2.0')) 2479 Decimal("-2") 2480 >>> ExtendedContext.normalize(Decimal('1.200')) 2481 Decimal("1.2") 2482 >>> ExtendedContext.normalize(Decimal('-120')) 2483 Decimal("-1.2E+2") 2484 >>> ExtendedContext.normalize(Decimal('120.00')) 2485 Decimal("1.2E+2") 2486 >>> ExtendedContext.normalize(Decimal('0.00')) 2487 Decimal("0") 2488 """ 2489 return a.normalize(context=self) 2490 2491 def plus(self, a): 2492 """Plus corresponds to unary prefix plus in Python. 2493 2494 The operation is evaluated using the same rules as add; the 2495 operation plus(a) is calculated as add('0', a) where the '0' 2496 has the same exponent as the operand. 2497 2498 >>> ExtendedContext.plus(Decimal('1.3')) 2499 Decimal("1.3") 2500 >>> ExtendedContext.plus(Decimal('-1.3')) 2501 Decimal("-1.3") 2502 """ 2503 return a.__pos__(context=self) 2504 2505 def power(self, a, b, modulo=None): 2506 """Raises a to the power of b, to modulo if given. 2507 2508 The right-hand operand must be a whole number whose integer part (after 2509 any exponent has been applied) has no more than 9 digits and whose 2510 fractional part (if any) is all zeros before any rounding. The operand 2511 may be positive, negative, or zero; if negative, the absolute value of 2512 the power is used, and the left-hand operand is inverted (divided into 2513 1) before use. 2514 2515 If the increased precision needed for the intermediate calculations 2516 exceeds the capabilities of the implementation then an Invalid operation 2517 condition is raised. 2518 2519 If, when raising to a negative power, an underflow occurs during the 2520 division into 1, the operation is not halted at that point but 2521 continues. 2522 2523 >>> ExtendedContext.power(Decimal('2'), Decimal('3')) 2524 Decimal("8") 2525 >>> ExtendedContext.power(Decimal('2'), Decimal('-3')) 2526 Decimal("0.125") 2527 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8')) 2528 Decimal("69.7575744") 2529 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2')) 2530 Decimal("0") 2531 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1')) 2532 Decimal("0") 2533 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0')) 2534 Decimal("1") 2535 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1')) 2536 Decimal("Infinity") 2537 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2')) 2538 Decimal("Infinity") 2539 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2')) 2540 Decimal("0") 2541 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1')) 2542 Decimal("-0") 2543 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0')) 2544 Decimal("1") 2545 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1')) 2546 Decimal("-Infinity") 2547 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2')) 2548 Decimal("Infinity") 2549 >>> ExtendedContext.power(Decimal('0'), Decimal('0')) 2550 Decimal("NaN") 2551 """ 2552 return a.__pow__(b, modulo, context=self) 2553 2554 def quantize(self, a, b): 2555 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'. 2556 2557 The coefficient of the result is derived from that of the left-hand 2558 operand. It may be rounded using the current rounding setting (if the 2559 exponent is being increased), multiplied by a positive power of ten (if 2560 the exponent is being decreased), or is unchanged (if the exponent is 2561 already equal to that of the right-hand operand). 2562 2563 Unlike other operations, if the length of the coefficient after the 2564 quantize operation would be greater than precision then an Invalid 2565 operation condition is raised. This guarantees that, unless there is an 2566 error condition, the exponent of the result of a quantize is always 2567 equal to that of the right-hand operand. 2568 2569 Also unlike other operations, quantize will never raise Underflow, even 2570 if the result is subnormal and inexact. 2571 2572 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001')) 2573 Decimal("2.170") 2574 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01')) 2575 Decimal("2.17") 2576 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1')) 2577 Decimal("2.2") 2578 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0')) 2579 Decimal("2") 2580 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1')) 2581 Decimal("0E+1") 2582 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity')) 2583 Decimal("-Infinity") 2584 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity')) 2585 Decimal("NaN") 2586 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1')) 2587 Decimal("-0") 2588 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5')) 2589 Decimal("-0E+5") 2590 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2')) 2591 Decimal("NaN") 2592 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2')) 2593 Decimal("NaN") 2594 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1')) 2595 Decimal("217.0") 2596 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0')) 2597 Decimal("217") 2598 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1')) 2599 Decimal("2.2E+2") 2600 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2')) 2601 Decimal("2E+2") 2602 """ 2603 return a.quantize(b, context=self) 2604 2605 def remainder(self, a, b): 2606 """Returns the remainder from integer division. 2607 2608 The result is the residue of the dividend after the operation of 2609 calculating integer division as described for divide-integer, rounded to 2610 precision digits if necessary. The sign of the result, if non-zero, is 2611 the same as that of the original dividend. 2612 2613 This operation will fail under the same conditions as integer division 2614 (that is, if integer division on the same two operands would fail, the 2615 remainder cannot be calculated). 2616 2617 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3')) 2618 Decimal("2.1") 2619 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3')) 2620 Decimal("1") 2621 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3')) 2622 Decimal("-1") 2623 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1')) 2624 Decimal("0.2") 2625 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3')) 2626 Decimal("0.1") 2627 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3')) 2628 Decimal("1.0") 2629 """ 2630 return a.__mod__(b, context=self) 2631 2632 def remainder_near(self, a, b): 2633 """Returns to be "a - b * n", where n is the integer nearest the exact 2634 value of "x / b" (if two integers are equally near then the even one 2635 is chosen). If the result is equal to 0 then its sign will be the 2636 sign of a. 2637 2638 This operation will fail under the same conditions as integer division 2639 (that is, if integer division on the same two operands would fail, the 2640 remainder cannot be calculated). 2641 2642 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3')) 2643 Decimal("-0.9") 2644 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6')) 2645 Decimal("-2") 2646 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3')) 2647 Decimal("1") 2648 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3')) 2649 Decimal("-1") 2650 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1')) 2651 Decimal("0.2") 2652 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3')) 2653 Decimal("0.1") 2654 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3')) 2655 Decimal("-0.3") 2656 """ 2657 return a.remainder_near(b, context=self) 2658 2659 def same_quantum(self, a, b): 2660 """Returns True if the two operands have the same exponent. 2661 2662 The result is never affected by either the sign or the coefficient of 2663 either operand. 2664 2665 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001')) 2666 False 2667 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01')) 2668 True 2669 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1')) 2670 False 2671 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf')) 2672 True 2673 """ 2674 return a.same_quantum(b) 2675 2676 def sqrt(self, a): 2677 """Returns the square root of a non-negative number to context precision. 2678 2679 If the result must be inexact, it is rounded using the round-half-even 2680 algorithm. 2681 2682 >>> ExtendedContext.sqrt(Decimal('0')) 2683 Decimal("0") 2684 >>> ExtendedContext.sqrt(Decimal('-0')) 2685 Decimal("-0") 2686 >>> ExtendedContext.sqrt(Decimal('0.39')) 2687 Decimal("0.624499800") 2688 >>> ExtendedContext.sqrt(Decimal('100')) 2689 Decimal("10") 2690 >>> ExtendedContext.sqrt(Decimal('1')) 2691 Decimal("1") 2692 >>> ExtendedContext.sqrt(Decimal('1.0')) 2693 Decimal("1.0") 2694 >>> ExtendedContext.sqrt(Decimal('1.00')) 2695 Decimal("1.0") 2696 >>> ExtendedContext.sqrt(Decimal('7')) 2697 Decimal("2.64575131") 2698 >>> ExtendedContext.sqrt(Decimal('10')) 2699 Decimal("3.16227766") 2700 >>> ExtendedContext.prec 2701 9 2702 """ 2703 return a.sqrt(context=self) 2704 2705 def subtract(self, a, b): 2706 """Return the sum of the two operands. 2707 2708 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07')) 2709 Decimal("0.23") 2710 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30')) 2711 Decimal("0.00") 2712 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07')) 2713 Decimal("-0.77") 2714 """ 2715 return a.__sub__(b, context=self) 2716 2717 def to_eng_string(self, a): 2718 """Converts a number to a string, using scientific notation. 2719 2720 The operation is not affected by the context. 2721 """ 2722 return a.to_eng_string(context=self) 2723 2724 def to_sci_string(self, a): 2725 """Converts a number to a string, using scientific notation. 2726 2727 The operation is not affected by the context. 2728 """ 2729 return a.__str__(context=self) 2730 2731 def to_integral(self, a): 2732 """Rounds to an integer. 2733 2734 When the operand has a negative exponent, the result is the same 2735 as using the quantize() operation using the given operand as the 2736 left-hand-operand, 1E+0 as the right-hand-operand, and the precision 2737 of the operand as the precision setting, except that no flags will 2738 be set. The rounding mode is taken from the context. 2739 2740 >>> ExtendedContext.to_integral(Decimal('2.1')) 2741 Decimal("2") 2742 >>> ExtendedContext.to_integral(Decimal('100')) 2743 Decimal("100") 2744 >>> ExtendedContext.to_integral(Decimal('100.0')) 2745 Decimal("100") 2746 >>> ExtendedContext.to_integral(Decimal('101.5')) 2747 Decimal("102") 2748 >>> ExtendedContext.to_integral(Decimal('-101.5')) 2749 Decimal("-102") 2750 >>> ExtendedContext.to_integral(Decimal('10E+5')) 2751 Decimal("1.0E+6") 2752 >>> ExtendedContext.to_integral(Decimal('7.89E+77')) 2753 Decimal("7.89E+77") 2754 >>> ExtendedContext.to_integral(Decimal('-Inf')) 2755 Decimal("-Infinity") 2756 """ 2757 return a.to_integral(context=self) 2758 2759 class _WorkRep(object): 2760 __slots__ = ('sign','int','exp') 2761 # sign: 0 or 1 2762 # int: int or long 2763 # exp: None, int, or string 2764 2765 def __init__(self, value=None): 2766 if value is None: 2767 self.sign = None 2768 self.int = 0 2769 self.exp = None 2770 elif isinstance(value, Decimal): 2771 self.sign = value._sign 2772 cum = 0 2773 for digit in value._int: 2774 cum = cum * 10 + digit 2775 self.int = cum 2776 self.exp = value._exp 2777 else: 2778 # assert isinstance(value, tuple) 2779 self.sign = value[0] 2780 self.int = value[1] 2781 self.exp = value[2] 2782 2783 def __repr__(self): 2784 return "(%r, %r, %r)" % (self.sign, self.int, self.exp) 2785 2786 __str__ = __repr__ 2787 2788 2789 2790 def _normalize(op1, op2, shouldround = 0, prec = 0): 2791 """Normalizes op1, op2 to have the same exp and length of coefficient. 2792 2793 Done during addition. 2794 """ 2795 # Yes, the exponent is a long, but the difference between exponents 2796 # must be an int-- otherwise you'd get a big memory problem. 2797 numdigits = int(op1.exp - op2.exp) 2798 if numdigits < 0: 2799 numdigits = -numdigits 2800 tmp = op2 2801 other = op1 2802 else: 2803 tmp = op1 2804 other = op2 2805 2806 2807 if shouldround and numdigits > prec + 1: 2808 # Big difference in exponents - check the adjusted exponents 2809 tmp_len = len(str(tmp.int)) 2810 other_len = len(str(other.int)) 2811 if numdigits > (other_len + prec + 1 - tmp_len): 2812 # If the difference in adjusted exps is > prec+1, we know 2813 # other is insignificant, so might as well put a 1 after the precision. 2814 # (since this is only for addition.) Also stops use of massive longs. 2815 2816 extend = prec + 2 - tmp_len 2817 if extend <= 0: 2818 extend = 1 2819 tmp.int *= 10 ** extend 2820 tmp.exp -= extend 2821 other.int = 1 2822 other.exp = tmp.exp 2823 return op1, op2 2824 2825 tmp.int *= 10 ** numdigits 2826 tmp.exp -= numdigits 2827 return op1, op2 2828 2829 def _adjust_coefficients(op1, op2): 2830 """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int. 2831 2832 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp. 2833 2834 Used on _WorkRep instances during division. 2835 """ 2836 adjust = 0 2837 #If op1 is smaller, make it larger 2838 while op2.int > op1.int: 2839 op1.int *= 10 2840 op1.exp -= 1 2841 adjust += 1 2842 2843 #If op2 is too small, make it larger 2844 while op1.int >= (10 * op2.int): 2845 op2.int *= 10 2846 op2.exp -= 1 2847 adjust -= 1 2848 2849 return op1, op2, adjust 2850 2851 ##### Helper Functions ######################################## 2852 2853 def _convert_other(other): 2854 """Convert other to Decimal. 2855 2856 Verifies that it's ok to use in an implicit construction. 2857 """ 2858 if isinstance(other, Decimal): 2859 return other 2860 if isinstance(other, (int, long)): 2861 return Decimal(other) 2862 2863 raise TypeError, "You can interact Decimal only with int, long or Decimal data types." 2864 2865 _infinity_map = { 2866 'inf' : 1, 2867 'infinity' : 1, 2868 '+inf' : 1, 2869 '+infinity' : 1, 2870 '-inf' : -1, 2871 '-infinity' : -1 2872 } 2873 2874 def _isinfinity(num): 2875 """Determines whether a string or float is infinity. 2876 2877 +1 for negative infinity; 0 for finite ; +1 for positive infinity 2878 """ 2879 num = str(num).lower() 2880 return _infinity_map.get(num, 0) 2881 2882 def _isnan(num): 2883 """Determines whether a string or float is NaN 2884 2885 (1, sign, diagnostic info as string) => NaN 2886 (2, sign, diagnostic info as string) => sNaN 2887 0 => not a NaN 2888 """ 2889 num = str(num).lower() 2890 if not num: 2891 return 0 2892 2893 #get the sign, get rid of trailing [+-] 2894 sign = 0 2895 if num[0] == '+': 2896 num = num[1:] 2897 elif num[0] == '-': #elif avoids '+-nan' 2898 num = num[1:] 2899 sign = 1 2900 2901 if num.startswith('nan'): 2902 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info 2903 return 0 2904 return (1, sign, num[3:].lstrip('0')) 2905 if num.startswith('snan'): 2906 if len(num) > 4 and not num[4:].isdigit(): 2907 return 0 2908 return (2, sign, num[4:].lstrip('0')) 2909 return 0 2910 2911 2912 ##### Setup Specific Contexts ################################ 2913 2914 # The default context prototype used by Context() 2915 # Is mutable, so that new contexts can have different default values 2916 2917 DefaultContext = Context( 2918 prec=28, rounding=ROUND_HALF_EVEN, 2919 traps=[DivisionByZero, Overflow, InvalidOperation], 2920 flags=[], 2921 _rounding_decision=ALWAYS_ROUND, 2922 Emax=999999999, 2923 Emin=-999999999, 2924 capitals=1 2925 ) 2926 2927 # Pre-made alternate contexts offered by the specification 2928 # Don't change these; the user should be able to select these 2929 # contexts and be able to reproduce results from other implementations 2930 # of the spec. 2931 2932 BasicContext = Context( 2933 prec=9, rounding=ROUND_HALF_UP, 2934 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow], 2935 flags=[], 2936 ) 2937 2938 ExtendedContext = Context( 2939 prec=9, rounding=ROUND_HALF_EVEN, 2940 traps=[], 2941 flags=[], 2942 ) 2943 2944 2945 ##### Useful Constants (internal use only) #################### 2946 2947 #Reusable defaults 2948 Inf = Decimal('Inf') 2949 negInf = Decimal('-Inf') 2950 2951 #Infsign[sign] is infinity w/ that sign 2952 Infsign = (Inf, negInf) 2953 2954 NaN = Decimal('NaN') 2955 2956 2957 ##### crud for parsing strings ################################# 2958 import re 2959 2960 # There's an optional sign at the start, and an optional exponent 2961 # at the end. The exponent has an optional sign and at least one 2962 # digit. In between, must have either at least one digit followed 2963 # by an optional fraction, or a decimal point followed by at least 2964 # one digit. Yuck. 2965 2966 _parser = re.compile(r""" 2967 # \s* 2968 (?P<sign>[-+])? 2969 ( 2970 (?P<int>\d+) (\. (?P<frac>\d*))? 2971 | 2972 \. (?P<onlyfrac>\d+) 2973 ) 2974 ([eE](?P<exp>[-+]? \d+))? 2975 # \s* 2976 $ 2977 """, re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces. 2978 2979 del re 2980 2981 # return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly 2982 2983 def _string2exact(s): 2984 m = _parser(s) 2985 if m is None: 2986 raise ValueError("invalid literal for Decimal: %r" % s) 2987 2988 if m.group('sign') == "-": 2989 sign = 1 2990 else: 2991 sign = 0 2992 2993 exp = m.group('exp') 2994 if exp is None: 2995 exp = 0 2996 else: 2997 exp = int(exp) 2998 2999 intpart = m.group('int') 3000 if intpart is None: 3001 intpart = "" 3002 fracpart = m.group('onlyfrac') 3003 else: 3004 fracpart = m.group('frac') 3005 if fracpart is None: 3006 fracpart = "" 3007 3008 exp -= len(fracpart) 3009 3010 mantissa = intpart + fracpart 3011 tmp = map(int, mantissa) 3012 backup = tmp 3013 while tmp and tmp[0] == 0: 3014 del tmp[0] 3015 3016 # It's a zero 3017 if not tmp: 3018 if backup: 3019 return (sign, tuple(backup), exp) 3020 return (sign, (0,), exp) 3021 mantissa = tuple(tmp) 3022 3023 return (sign, mantissa, exp) 3024 3025 3026 if __name__ == '__main__': 3027 import doctest, sys 3028 doctest.testmod(sys.modules[__name__]) 3029
Generated by PyXR 0.9.4