decimal.py revision 5aa478badfabb005e6f17c98fcf007a0bc54eecc
1# Copyright (c) 2004 Python Software Foundation. 2# All rights reserved. 3 4# Written by Eric Price <eprice at tjhsst.edu> 5# and Facundo Batista <facundo at taniquetil.com.ar> 6# and Raymond Hettinger <python at rcn.com> 7# and Aahz <aahz at pobox.com> 8# and Tim Peters 9 10 11""" 12This is a Py2.3 implementation of decimal floating point arithmetic based on 13the General Decimal Arithmetic Specification: 14 15 www2.hursley.ibm.com/decimal/decarith.html 16 17and IEEE standard 854-1987: 18 19 www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html 20 21Decimal floating point has finite precision with arbitrarily large bounds. 22 23The purpose of the module is to support arithmetic using familiar 24"schoolhouse" rules and to avoid the some of tricky representation 25issues associated with binary floating point. The package is especially 26useful for financial applications or for contexts where users have 27expectations that are at odds with binary floating point (for instance, 28in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead 29of the expected Decimal("0.00") returned by decimal floating point). 30 31Here are some examples of using the decimal module: 32 33>>> from decimal import * 34>>> setcontext(ExtendedContext) 35>>> Decimal(0) 36Decimal("0") 37>>> Decimal("1") 38Decimal("1") 39>>> Decimal("-.0123") 40Decimal("-0.0123") 41>>> Decimal(123456) 42Decimal("123456") 43>>> Decimal("123.45e12345678901234567890") 44Decimal("1.2345E+12345678901234567892") 45>>> Decimal("1.33") + Decimal("1.27") 46Decimal("2.60") 47>>> Decimal("12.34") + Decimal("3.87") - Decimal("18.41") 48Decimal("-2.20") 49>>> dig = Decimal(1) 50>>> print dig / Decimal(3) 510.333333333 52>>> getcontext().prec = 18 53>>> print dig / Decimal(3) 540.333333333333333333 55>>> print dig.sqrt() 561 57>>> print Decimal(3).sqrt() 581.73205080756887729 59>>> print Decimal(3) ** 123 604.85192780976896427E+58 61>>> inf = Decimal(1) / Decimal(0) 62>>> print inf 63Infinity 64>>> neginf = Decimal(-1) / Decimal(0) 65>>> print neginf 66-Infinity 67>>> print neginf + inf 68NaN 69>>> print neginf * inf 70-Infinity 71>>> print dig / 0 72Infinity 73>>> getcontext().trap_enablers[DivisionByZero] = 1 74>>> print dig / 0 75Traceback (most recent call last): 76 ... 77 ... 78 ... 79DivisionByZero: x / 0 80>>> c = Context() 81>>> c.trap_enablers[InvalidOperation] = 0 82>>> print c.flags[InvalidOperation] 830 84>>> c.divide(Decimal(0), Decimal(0)) 85Decimal("NaN") 86>>> c.trap_enablers[InvalidOperation] = 1 87>>> print c.flags[InvalidOperation] 881 89>>> c.flags[InvalidOperation] = 0 90>>> print c.flags[InvalidOperation] 910 92>>> print c.divide(Decimal(0), Decimal(0)) 93Traceback (most recent call last): 94 ... 95 ... 96 ... 97InvalidOperation: 0 / 0 98>>> print c.flags[InvalidOperation] 991 100>>> c.flags[InvalidOperation] = 0 101>>> c.trap_enablers[InvalidOperation] = 0 102>>> print c.divide(Decimal(0), Decimal(0)) 103NaN 104>>> print c.flags[InvalidOperation] 1051 106>>> 107""" 108 109__all__ = [ 110 # Two major classes 111 'Decimal', 'Context', 112 113 # Contexts 114 'DefaultContext', 'BasicContext', 'ExtendedContext', 115 116 # Exceptions 117 'DecimalException', 'Clamped', 'InvalidOperation', 'ConversionSyntax', 118 'DivisionByZero', 'DivisionImpossible', 'DivisionUndefined', 119 'Inexact', 'InvalidContext', 'Rounded', 'Subnormal', 'Overflow', 120 'Underflow', 121 122 # Constants for use in setting up contexts 123 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING', 124 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 125 'Signals', # <-- Used for building trap/flag dictionaries 126 127 # Functions for manipulating contexts 128 'setcontext', 'getcontext' 129] 130 131import threading 132import copy 133import operator 134 135#Exponent Range 136DEFAULT_MAX_EXPONENT = 999999999 137DEFAULT_MIN_EXPONENT = -999999999 138 139#Rounding 140ROUND_DOWN = 'ROUND_DOWN' 141ROUND_HALF_UP = 'ROUND_HALF_UP' 142ROUND_HALF_EVEN = 'ROUND_HALF_EVEN' 143ROUND_CEILING = 'ROUND_CEILING' 144ROUND_FLOOR = 'ROUND_FLOOR' 145ROUND_UP = 'ROUND_UP' 146ROUND_HALF_DOWN = 'ROUND_HALF_DOWN' 147 148#Rounding decision (not part of the public API) 149NEVER_ROUND = 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY 150ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end. 151 152#Errors 153 154class DecimalException(ArithmeticError): 155 """Base exception class. 156 157 Used exceptions derive from this. 158 If an exception derives from another exception besides this (such as 159 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only 160 called if the others are present. This isn't actually used for 161 anything, though. 162 163 handle -- Called when context._raise_error is called and the 164 trap_enabler is set. First argument is self, second is the 165 context. More arguments can be given, those being after 166 the explanation in _raise_error (For example, 167 context._raise_error(NewError, '(-x)!', self._sign) would 168 call NewError().handle(context, self._sign).) 169 170 To define a new exception, it should be sufficient to have it derive 171 from DecimalException. 172 """ 173 def handle(self, context, *args): 174 pass 175 176 177class Clamped(DecimalException): 178 """Exponent of a 0 changed to fit bounds. 179 180 This occurs and signals clamped if the exponent of a result has been 181 altered in order to fit the constraints of a specific concrete 182 representation. This may occur when the exponent of a zero result would 183 be outside the bounds of a representation, or when a large normal 184 number would have an encoded exponent that cannot be represented. In 185 this latter case, the exponent is reduced to fit and the corresponding 186 number of zero digits are appended to the coefficient ("fold-down"). 187 """ 188 189 190class InvalidOperation(DecimalException): 191 """An invalid operation was performed. 192 193 Various bad things cause this: 194 195 Something creates a signaling NaN 196 -INF + INF 197 0 * (+-)INF 198 (+-)INF / (+-)INF 199 x % 0 200 (+-)INF % x 201 x._rescale( non-integer ) 202 sqrt(-x) , x > 0 203 0 ** 0 204 x ** (non-integer) 205 x ** (+-)INF 206 An operand is invalid 207 """ 208 def handle(self, context, *args): 209 if args: 210 if args[0] == 1: #sNaN, must drop 's' but keep diagnostics 211 return Decimal( (args[1]._sign, args[1]._int, 'n') ) 212 return NaN 213 214# XXX Is there a logic error in subclassing InvalidOperation? 215# Setting the InvalidOperation trap to zero does not preclude ConversionSyntax. 216# Also, incrementing Conversion syntax flag will not increment InvalidOperation. 217# Both of these issues interfere with cross-language portability because 218# code following the spec would not know about the Python subclasses. 219 220class ConversionSyntax(InvalidOperation): 221 """Trying to convert badly formed string. 222 223 This occurs and signals invalid-operation if an string is being 224 converted to a number and it does not conform to the numeric string 225 syntax. The result is [0,qNaN]. 226 """ 227 228 def handle(self, context, *args): 229 return (0, (0,), 'n') #Passed to something which uses a tuple. 230 231class DivisionByZero(DecimalException, ZeroDivisionError): 232 """Division by 0. 233 234 This occurs and signals division-by-zero if division of a finite number 235 by zero was attempted (during a divide-integer or divide operation, or a 236 power operation with negative right-hand operand), and the dividend was 237 not zero. 238 239 The result of the operation is [sign,inf], where sign is the exclusive 240 or of the signs of the operands for divide, or is 1 for an odd power of 241 -0, for power. 242 """ 243 244 def handle(self, context, sign, double = None, *args): 245 if double is not None: 246 return (Infsign[sign],)*2 247 return Infsign[sign] 248 249class DivisionImpossible(InvalidOperation): 250 """Cannot perform the division adequately. 251 252 This occurs and signals invalid-operation if the integer result of a 253 divide-integer or remainder operation had too many digits (would be 254 longer than precision). The result is [0,qNaN]. 255 """ 256 257 def handle(self, context, *args): 258 return (NaN, NaN) 259 260class DivisionUndefined(InvalidOperation, ZeroDivisionError): 261 """Undefined result of division. 262 263 This occurs and signals invalid-operation if division by zero was 264 attempted (during a divide-integer, divide, or remainder operation), and 265 the dividend is also zero. The result is [0,qNaN]. 266 """ 267 268 def handle(self, context, tup=None, *args): 269 if tup is not None: 270 return (NaN, NaN) #for 0 %0, 0 // 0 271 return NaN 272 273class Inexact(DecimalException): 274 """Had to round, losing information. 275 276 This occurs and signals inexact whenever the result of an operation is 277 not exact (that is, it needed to be rounded and any discarded digits 278 were non-zero), or if an overflow or underflow condition occurs. The 279 result in all cases is unchanged. 280 281 The inexact signal may be tested (or trapped) to determine if a given 282 operation (or sequence of operations) was inexact. 283 """ 284 pass 285 286class InvalidContext(InvalidOperation): 287 """Invalid context. Unknown rounding, for example. 288 289 This occurs and signals invalid-operation if an invalid context was 290 detected during an operation. This can occur if contexts are not checked 291 on creation and either the precision exceeds the capability of the 292 underlying concrete representation or an unknown or unsupported rounding 293 was specified. These aspects of the context need only be checked when 294 the values are required to be used. The result is [0,qNaN]. 295 """ 296 297 def handle(self, context, *args): 298 return NaN 299 300class Rounded(DecimalException): 301 """Number got rounded (not necessarily changed during rounding). 302 303 This occurs and signals rounded whenever the result of an operation is 304 rounded (that is, some zero or non-zero digits were discarded from the 305 coefficient), or if an overflow or underflow condition occurs. The 306 result in all cases is unchanged. 307 308 The rounded signal may be tested (or trapped) to determine if a given 309 operation (or sequence of operations) caused a loss of precision. 310 """ 311 pass 312 313class Subnormal(DecimalException): 314 """Exponent < Emin before rounding. 315 316 This occurs and signals subnormal whenever the result of a conversion or 317 operation is subnormal (that is, its adjusted exponent is less than 318 Emin, before any rounding). The result in all cases is unchanged. 319 320 The subnormal signal may be tested (or trapped) to determine if a given 321 or operation (or sequence of operations) yielded a subnormal result. 322 """ 323 pass 324 325class Overflow(Inexact, Rounded): 326 """Numerical overflow. 327 328 This occurs and signals overflow if the adjusted exponent of a result 329 (from a conversion or from an operation that is not an attempt to divide 330 by zero), after rounding, would be greater than the largest value that 331 can be handled by the implementation (the value Emax). 332 333 The result depends on the rounding mode: 334 335 For round-half-up and round-half-even (and for round-half-down and 336 round-up, if implemented), the result of the operation is [sign,inf], 337 where sign is the sign of the intermediate result. For round-down, the 338 result is the largest finite number that can be represented in the 339 current precision, with the sign of the intermediate result. For 340 round-ceiling, the result is the same as for round-down if the sign of 341 the intermediate result is 1, or is [0,inf] otherwise. For round-floor, 342 the result is the same as for round-down if the sign of the intermediate 343 result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded 344 will also be raised. 345 """ 346 347 def handle(self, context, sign, *args): 348 if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN, 349 ROUND_HALF_DOWN, ROUND_UP): 350 return Infsign[sign] 351 if sign == 0: 352 if context.rounding == ROUND_CEILING: 353 return Infsign[sign] 354 return Decimal((sign, (9,)*context.prec, 355 context.Emax-context.prec+1)) 356 if sign == 1: 357 if context.rounding == ROUND_FLOOR: 358 return Infsign[sign] 359 return Decimal( (sign, (9,)*context.prec, 360 context.Emax-context.prec+1)) 361 362 363class Underflow(Inexact, Rounded, Subnormal): 364 """Numerical underflow with result rounded to 0. 365 366 This occurs and signals underflow if a result is inexact and the 367 adjusted exponent of the result would be smaller (more negative) than 368 the smallest value that can be handled by the implementation (the value 369 Emin). That is, the result is both inexact and subnormal. 370 371 The result after an underflow will be a subnormal number rounded, if 372 necessary, so that its exponent is not less than Etiny. This may result 373 in 0 with the sign of the intermediate result and an exponent of Etiny. 374 375 In all cases, Inexact, Rounded, and Subnormal will also be raised. 376 """ 377 378# List of public traps and flags 379Signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded, 380 Underflow, InvalidOperation, Subnormal] 381 382# Map conditions (per the spec) to signals 383_condition_map = {ConversionSyntax:InvalidOperation, 384 DivisionImpossible:InvalidOperation, 385 DivisionUndefined:InvalidOperation, 386 InvalidContext:InvalidOperation} 387 388##### Context Functions ####################################### 389 390#To fix reloading, force it to create a new context 391#Old contexts have different exceptions in their dicts, making problems. 392if hasattr(threading.currentThread(), '__decimal_context__'): 393 del threading.currentThread().__decimal_context__ 394 395def setcontext(context): 396 """Set this thread's context to context.""" 397 if context in (DefaultContext, BasicContext, ExtendedContext): 398 context = context.copy() 399 threading.currentThread().__decimal_context__ = context 400 401def getcontext(): 402 """Returns this thread's context. 403 404 If this thread does not yet have a context, returns 405 a new context and sets this thread's context. 406 New contexts are copies of DefaultContext. 407 """ 408 try: 409 return threading.currentThread().__decimal_context__ 410 except AttributeError: 411 context = Context() 412 threading.currentThread().__decimal_context__ = context 413 return context 414 415 416##### Decimal class ########################################### 417 418class Decimal(object): 419 """Floating point class for decimal arithmetic.""" 420 421 __slots__ = ('_exp','_int','_sign') 422 423 def __init__(self, value="0", context=None): 424 """Create a decimal point instance. 425 426 >>> Decimal('3.14') # string input 427 Decimal("3.14") 428 >>> Decimal((0, (3, 1, 4), -2)) # tuple input (sign, digit_tuple, exponent) 429 Decimal("3.14") 430 >>> Decimal(314) # int or long 431 Decimal("314") 432 >>> Decimal(Decimal(314)) # another decimal instance 433 Decimal("314") 434 """ 435 if context is None: 436 context = getcontext() 437 438 if isinstance(value, (int,long)): 439 value = str(value) 440 441 # String? 442 # REs insist on real strings, so we can too. 443 if isinstance(value, basestring): 444 if _isinfinity(value): 445 self._exp = 'F' 446 self._int = (0,) 447 sign = _isinfinity(value) 448 if sign == 1: 449 self._sign = 0 450 else: 451 self._sign = 1 452 return 453 if _isnan(value): 454 sig, sign, diag = _isnan(value) 455 if len(diag) > context.prec: #Diagnostic info too long 456 self._sign, self._int, self._exp = \ 457 context._raise_error(ConversionSyntax) 458 return 459 if sig == 1: 460 self._exp = 'n' #qNaN 461 else: #sig == 2 462 self._exp = 'N' #sNaN 463 self._sign = sign 464 self._int = tuple(map(int, diag)) #Diagnostic info 465 return 466 try: 467 self._sign, self._int, self._exp = _string2exact(value) 468 except ValueError: 469 self._sign, self._int, self._exp = context._raise_error(ConversionSyntax) 470 return 471 472 # tuple/list conversion (possibly from as_tuple()) 473 if isinstance(value, (list,tuple)): 474 if len(value) != 3: 475 raise ValueError, 'Invalid arguments' 476 if value[0] not in [0,1]: 477 raise ValueError, 'Invalid sign' 478 for digit in value[1]: 479 if not isinstance(digit, (int,long)) or digit < 0: 480 raise ValueError, "The second value in the tuple must be composed of non negative integer elements." 481 482 self._sign = value[0] 483 self._int = tuple(value[1]) 484 if value[2] in ('F','n','N'): 485 self._exp = value[2] 486 else: 487 self._exp = int(value[2]) 488 return 489 490 # Turn an intermediate value back to Decimal() 491 if isinstance(value, _WorkRep): 492 if value.sign == 1: 493 self._sign = 0 494 else: 495 self._sign = 1 496 self._int = tuple(value.int) 497 self._exp = int(value.exp) 498 return 499 500 if isinstance(value, Decimal): 501 self._exp = value._exp 502 self._sign = value._sign 503 self._int = value._int 504 return 505 506 raise TypeError("Can't convert %r" % value) 507 508 def _convert_other(self, other): 509 """Convert other to Decimal. 510 511 Verifies that it's ok to use in an implicit construction. 512 """ 513 if isinstance(other, Decimal): 514 return other 515 if isinstance(other, (int, long)): 516 other = Decimal(other) 517 return other 518 519 raise TypeError, "You can interact Decimal only with int, long or Decimal data types." 520 521 def _isnan(self): 522 """Returns whether the number is not actually one. 523 524 0 if a number 525 1 if NaN 526 2 if sNaN 527 """ 528 if self._exp == 'n': 529 return 1 530 elif self._exp == 'N': 531 return 2 532 return 0 533 534 def _isinfinity(self): 535 """Returns whether the number is infinite 536 537 0 if finite or not a number 538 1 if +INF 539 -1 if -INF 540 """ 541 if self._exp == 'F': 542 if self._sign: 543 return -1 544 return 1 545 return 0 546 547 def _check_nans(self, other = None, context=None): 548 """Returns whether the number is not actually one. 549 550 if self, other are sNaN, signal 551 if self, other are NaN return nan 552 return 0 553 554 Done before operations. 555 """ 556 if context is None: 557 context = getcontext() 558 559 if self._isnan() == 2: 560 return context._raise_error(InvalidOperation, 'sNaN', 561 1, self) 562 if other is not None and other._isnan() == 2: 563 return context._raise_error(InvalidOperation, 'sNaN', 564 1, other) 565 if self._isnan(): 566 return self 567 if other is not None and other._isnan(): 568 return other 569 return 0 570 571 def __nonzero__(self): 572 """Is the number non-zero? 573 574 0 if self == 0 575 1 if self != 0 576 """ 577 if isinstance(self._exp, str): 578 return 1 579 return self._int != (0,)*len(self._int) 580 581 def __cmp__(self, other, context=None): 582 if context is None: 583 context = getcontext() 584 other = self._convert_other(other) 585 586 ans = self._check_nans(other, context) 587 if ans: 588 return 1 589 590 if not self and not other: 591 return 0 #If both 0, sign comparison isn't certain. 592 593 #If different signs, neg one is less 594 if other._sign < self._sign: 595 return -1 596 if self._sign < other._sign: 597 return 1 598 599 # INF = INF 600 if self._isinfinity() and other._isinfinity(): 601 return 0 602 if self._isinfinity(): 603 return (-1)**self._sign 604 if other._isinfinity(): 605 return -((-1)**other._sign) 606 607 if self.adjusted() == other.adjusted() and \ 608 self._int + (0,)*(self._exp - other._exp) == \ 609 other._int + (0,)*(other._exp - self._exp): 610 return 0 #equal, except in precision. ([0]*(-x) = []) 611 elif self.adjusted() > other.adjusted() and self._int[0] != 0: 612 return (-1)**self._sign 613 elif self.adjusted < other.adjusted() and other._int[0] != 0: 614 return -((-1)**self._sign) 615 616 context = context.copy() 617 rounding = context._set_rounding(ROUND_UP) #round away from 0 618 619 flags = context._ignore_all_flags() 620 res = self.__sub__(other, context=context) 621 622 context._regard_flags(*flags) 623 624 context.rounding = rounding 625 626 if not res: 627 return 0 628 elif res._sign: 629 return -1 630 return 1 631 632 def __eq__(self, other): 633 if not isinstance(other, (Decimal, int, long)): 634 return False 635 return self.__cmp__(other) == 0 636 637 def __ne__(self, other): 638 if not isinstance(other, (Decimal, int, long)): 639 return True 640 return self.__cmp__(other) != 0 641 642 def compare(self, other, context=None): 643 """Compares one to another. 644 645 -1 => a < b 646 0 => a = b 647 1 => a > b 648 NaN => one is NaN 649 Like __cmp__, but returns Decimal instances. 650 """ 651 if context is None: 652 context = getcontext() 653 other = self._convert_other(other) 654 655 #compare(NaN, NaN) = NaN 656 ans = self._check_nans(other, context) 657 if ans: 658 return ans 659 660 return Decimal(self.__cmp__(other, context)) 661 662 def __hash__(self): 663 """x.__hash__() <==> hash(x)""" 664 # Decimal integers must hash the same as the ints 665 # Non-integer decimals are normalized and hashed as strings 666 # Normalization assures that hast(100E-1) == hash(10) 667 i = int(self) 668 if self == Decimal(i): 669 return hash(i) 670 assert self.__nonzero__() # '-0' handled by integer case 671 return hash(str(self.normalize())) 672 673 def as_tuple(self): 674 """Represents the number as a triple tuple. 675 676 To show the internals exactly as they are. 677 """ 678 return (self._sign, self._int, self._exp) 679 680 def __repr__(self): 681 """Represents the number as an instance of Decimal.""" 682 # Invariant: eval(repr(d)) == d 683 return 'Decimal("%s")' % str(self) 684 685 def __str__(self, eng = 0, context=None): 686 """Return string representation of the number in scientific notation. 687 688 Captures all of the information in the underlying representation. 689 """ 690 691 if self._isnan(): 692 minus = '-'*self._sign 693 if self._int == (0,): 694 info = '' 695 else: 696 info = ''.join(map(str, self._int)) 697 if self._isnan() == 2: 698 return minus + 'sNaN' + info 699 return minus + 'NaN' + info 700 if self._isinfinity(): 701 minus = '-'*self._sign 702 return minus + 'Infinity' 703 704 if context is None: 705 context = getcontext() 706 707 tmp = map(str, self._int) 708 numdigits = len(self._int) 709 leftdigits = self._exp + numdigits 710 if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY 711 if self._exp < 0 and self._exp >= -6: #short, no need for e/E 712 s = '-'*self._sign + '0.' + '0'*(abs(self._exp)) 713 return s 714 #exp is closest mult. of 3 >= self._exp 715 exp = ((self._exp - 1)// 3 + 1) * 3 716 if exp != self._exp: 717 s = '0.'+'0'*(exp - self._exp) 718 else: 719 s = '0' 720 if exp != 0: 721 if context.capitals: 722 s += 'E' 723 else: 724 s += 'e' 725 if exp > 0: 726 s += '+' #0.0e+3, not 0.0e3 727 s += str(exp) 728 s = '-'*self._sign + s 729 return s 730 if eng: 731 dotplace = (leftdigits-1)%3+1 732 adjexp = leftdigits -1 - (leftdigits-1)%3 733 else: 734 adjexp = leftdigits-1 735 dotplace = 1 736 if self._exp == 0: 737 pass 738 elif self._exp < 0 and adjexp >= 0: 739 tmp.insert(leftdigits, '.') 740 elif self._exp < 0 and adjexp >= -6: 741 tmp[0:0] = ['0'] * int(-leftdigits) 742 tmp.insert(0, '0.') 743 else: 744 if numdigits > dotplace: 745 tmp.insert(dotplace, '.') 746 elif numdigits < dotplace: 747 tmp.extend(['0']*(dotplace-numdigits)) 748 if adjexp: 749 if not context.capitals: 750 tmp.append('e') 751 else: 752 tmp.append('E') 753 if adjexp > 0: 754 tmp.append('+') 755 tmp.append(str(adjexp)) 756 if eng: 757 while tmp[0:1] == ['0']: 758 tmp[0:1] = [] 759 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e': 760 tmp[0:0] = ['0'] 761 if self._sign: 762 tmp.insert(0, '-') 763 764 return ''.join(tmp) 765 766 def to_eng_string(self, context=None): 767 """Convert to engineering-type string. 768 769 Engineering notation has an exponent which is a multiple of 3, so there 770 are up to 3 digits left of the decimal place. 771 772 Same rules for when in exponential and when as a value as in __str__. 773 """ 774 if context is None: 775 context = getcontext() 776 return self.__str__(eng=1, context=context) 777 778 def __neg__(self, context=None): 779 """Returns a copy with the sign switched. 780 781 Rounds, if it has reason. 782 """ 783 if context is None: 784 context = getcontext() 785 ans = self._check_nans(context=context) 786 if ans: 787 return ans 788 789 if not self: 790 # -Decimal('0') is Decimal('0'), not Decimal('-0') 791 sign = 0 792 elif self._sign: 793 sign = 0 794 else: 795 sign = 1 796 if context._rounding_decision == ALWAYS_ROUND: 797 return Decimal((sign, self._int, self._exp))._fix(context=context) 798 return Decimal( (sign, self._int, self._exp)) 799 800 def __pos__(self, context=None): 801 """Returns a copy, unless it is a sNaN. 802 803 Rounds the number (if more then precision digits) 804 """ 805 if context is None: 806 context = getcontext() 807 ans = self._check_nans(context=context) 808 if ans: 809 return ans 810 811 sign = self._sign 812 if not self: 813 # + (-0) = 0 814 sign = 0 815 816 if context._rounding_decision == ALWAYS_ROUND: 817 ans = self._fix(context=context) 818 else: 819 ans = Decimal(self) 820 ans._sign = sign 821 return ans 822 823 def __abs__(self, round=1, context=None): 824 """Returns the absolute value of self. 825 826 If the second argument is 0, do not round. 827 """ 828 if context is None: 829 context = getcontext() 830 ans = self._check_nans(context=context) 831 if ans: 832 return ans 833 834 if not round: 835 context = context.copy() 836 context._set_rounding_decision(NEVER_ROUND) 837 838 if self._sign: 839 ans = self.__neg__(context=context) 840 else: 841 ans = self.__pos__(context=context) 842 843 return ans 844 845 def __add__(self, other, context=None): 846 """Returns self + other. 847 848 -INF + INF (or the reverse) cause InvalidOperation errors. 849 """ 850 if context is None: 851 context = getcontext() 852 other = self._convert_other(other) 853 854 ans = self._check_nans(other, context) 855 if ans: 856 return ans 857 858 if self._isinfinity(): 859 #If both INF, same sign => same as both, opposite => error. 860 if self._sign != other._sign and other._isinfinity(): 861 return context._raise_error(InvalidOperation, '-INF + INF') 862 return Decimal(self) 863 if other._isinfinity(): 864 return Decimal(other) #Can't both be infinity here 865 866 shouldround = context._rounding_decision == ALWAYS_ROUND 867 868 exp = min(self._exp, other._exp) 869 negativezero = 0 870 if context.rounding == ROUND_FLOOR and self._sign != other._sign: 871 #If the answer is 0, the sign should be negative, in this case. 872 negativezero = 1 873 874 if not self and not other: 875 sign = min(self._sign, other._sign) 876 if negativezero: 877 sign = 1 878 return Decimal( (sign, (0,), exp)) 879 if not self: 880 if exp < other._exp - context.prec-1: 881 exp = other._exp - context.prec-1 882 ans = other._rescale(exp, watchexp=0, context=context) 883 if shouldround: 884 ans = ans._fix(context=context) 885 return ans 886 if not other: 887 if exp < self._exp - context.prec-1: 888 exp = self._exp - context.prec-1 889 ans = self._rescale(exp, watchexp=0, context=context) 890 if shouldround: 891 ans = ans._fix(context=context) 892 return ans 893 894 op1 = _WorkRep(self) 895 op2 = _WorkRep(other) 896 op1, op2 = _normalize(op1, op2, shouldround, context.prec) 897 898 result = _WorkRep() 899 900 if op1.sign != op2.sign: 901 diff = cmp(abs(op1), abs(op2)) 902 # Equal and opposite 903 if diff == 0: 904 if exp < context.Etiny(): 905 exp = context.Etiny() 906 context._raise_error(Clamped) 907 return Decimal((negativezero, (0,), exp)) 908 if diff < 0: 909 op1, op2 = op2, op1 910 #OK, now abs(op1) > abs(op2) 911 if op1.sign == -1: 912 result.sign = -1 913 op1.sign, op2.sign = op2.sign, op1.sign 914 else: 915 result.sign = 1 916 #So we know the sign, and op1 > 0. 917 elif op1.sign == -1: 918 result.sign = -1 919 op1.sign, op2.sign = (1, 1) 920 else: 921 result.sign = 1 922 #Now, op1 > abs(op2) > 0 923 924 op1.int.reverse() 925 op2.int.reverse() 926 927 if op2.sign == 1: 928 result.int = resultint = map(operator.add, op1.int, op2.int) 929 carry = 0 930 for i in xrange(len(op1.int)): 931 tmp = resultint[i] + carry 932 carry = 0 933 if tmp > 9: 934 carry = 1 935 tmp -= 10 936 resultint[i] = tmp 937 if carry: 938 resultint.append(1) 939 else: 940 result.int = resultint = map(operator.sub, op1.int, op2.int) 941 loan = 0 942 for i in xrange(len(op1.int)): 943 tmp = resultint[i] - loan 944 loan = 0 945 if tmp < 0: 946 loan = 1 947 tmp += 10 948 resultint[i] = tmp 949 assert not loan 950 951 while resultint[-1] == 0: 952 resultint.pop() 953 resultint.reverse() 954 955 result.exp = op1.exp 956 ans = Decimal(result) 957 if shouldround: 958 ans = ans._fix(context=context) 959 return ans 960 961 __radd__ = __add__ 962 963 def __sub__(self, other, context=None): 964 """Return self + (-other)""" 965 if context is None: 966 context = getcontext() 967 other = self._convert_other(other) 968 969 ans = self._check_nans(other, context=context) 970 if ans: 971 return ans 972 973 # -Decimal(0) = Decimal(0), which we don't want since 974 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.) 975 # so we change the sign directly to a copy 976 tmp = Decimal(other) 977 tmp._sign = 1-tmp._sign 978 979 return self.__add__(tmp, context=context) 980 981 def __rsub__(self, other, context=None): 982 """Return other + (-self)""" 983 if context is None: 984 context = getcontext() 985 other = self._convert_other(other) 986 987 tmp = Decimal(self) 988 tmp._sign = 1 - tmp._sign 989 return other.__add__(tmp, context=context) 990 991 def _increment(self, round=1, context=None): 992 """Special case of add, adding 1eExponent 993 994 Since it is common, (rounding, for example) this adds 995 (sign)*one E self._exp to the number more efficiently than add. 996 997 For example: 998 Decimal('5.624e10')._increment() == Decimal('5.625e10') 999 """ 1000 if context is None: 1001 context = getcontext() 1002 ans = self._check_nans(context=context) 1003 if ans: 1004 return ans 1005 1006 L = list(self._int) 1007 L[-1] += 1 1008 spot = len(L)-1 1009 while L[spot] == 10: 1010 L[spot] = 0 1011 if spot == 0: 1012 L[0:0] = [1] 1013 break 1014 L[spot-1] += 1 1015 spot -= 1 1016 ans = Decimal((self._sign, L, self._exp)) 1017 1018 if round and context._rounding_decision == ALWAYS_ROUND: 1019 ans = ans._fix(context=context) 1020 return ans 1021 1022 def __mul__(self, other, context=None): 1023 """Return self * other. 1024 1025 (+-) INF * 0 (or its reverse) raise InvalidOperation. 1026 """ 1027 if context is None: 1028 context = getcontext() 1029 other = self._convert_other(other) 1030 1031 ans = self._check_nans(other, context) 1032 if ans: 1033 return ans 1034 1035 resultsign = operator.xor(self._sign, other._sign) 1036 if self._isinfinity(): 1037 if not other: 1038 return context._raise_error(InvalidOperation, '(+-)INF * 0') 1039 return Infsign[resultsign] 1040 1041 if other._isinfinity(): 1042 if not self: 1043 return context._raise_error(InvalidOperation, '0 * (+-)INF') 1044 return Infsign[resultsign] 1045 1046 resultexp = self._exp + other._exp 1047 shouldround = context._rounding_decision == ALWAYS_ROUND 1048 1049 # Special case for multiplying by zero 1050 if not self or not other: 1051 ans = Decimal((resultsign, (0,), resultexp)) 1052 if shouldround: 1053 #Fixing in case the exponent is out of bounds 1054 ans = ans._fix(context=context) 1055 return ans 1056 1057 # Special case for multiplying by power of 10 1058 if self._int == (1,): 1059 ans = Decimal((resultsign, other._int, resultexp)) 1060 if shouldround: 1061 ans = ans._fix(context=context) 1062 return ans 1063 if other._int == (1,): 1064 ans = Decimal((resultsign, self._int, resultexp)) 1065 if shouldround: 1066 ans = ans._fix(context=context) 1067 return ans 1068 1069 op1 = list(self._int) 1070 op2 = list(other._int) 1071 op1.reverse() 1072 op2.reverse() 1073 # Minimize Decimal additions 1074 if len(op2) > len(op1): 1075 op1, op2 = op2, op1 1076 1077 _divmod = divmod 1078 accumulator = [0]*(len(self._int) + len(other._int)) 1079 for i in xrange(len(op2)): 1080 if op2[i] == 0: 1081 continue 1082 mult = op2[i] 1083 carry = 0 1084 for j in xrange(len(op1)): 1085 carry, accumulator[i+j] = _divmod( mult * op1[j] + carry 1086 + accumulator[i+j], 10) 1087 1088 if carry: 1089 accumulator[i + j + 1] += carry 1090 while not accumulator[-1]: 1091 accumulator.pop() 1092 accumulator.reverse() 1093 1094 ans = Decimal( (resultsign, accumulator, resultexp)) 1095 if shouldround: 1096 ans = ans._fix(context=context) 1097 1098 return ans 1099 __rmul__ = __mul__ 1100 1101 def __div__(self, other, context=None): 1102 """Return self / other.""" 1103 return self._divide(other, context=context) 1104 __truediv__ = __div__ 1105 1106 def _divide(self, other, divmod = 0, context=None): 1107 """Return a / b, to context.prec precision. 1108 1109 divmod: 1110 0 => true division 1111 1 => (a //b, a%b) 1112 2 => a //b 1113 3 => a%b 1114 1115 Actually, if divmod is 2 or 3 a tuple is returned, but errors for 1116 computing the other value are not raised. 1117 """ 1118 if context is None: 1119 context = getcontext() 1120 other = self._convert_other(other) 1121 1122 ans = self._check_nans(other, context) 1123 if ans: 1124 if divmod: 1125 return (ans, ans) 1126 else: 1127 return ans 1128 1129 sign = operator.xor(self._sign, other._sign) 1130 if not self and not other: 1131 if divmod: 1132 return context._raise_error(DivisionUndefined, '0 / 0', 1) 1133 return context._raise_error(DivisionUndefined, '0 / 0') 1134 if self._isinfinity() and other._isinfinity(): 1135 if not divmod: 1136 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF') 1137 else: 1138 return (context._raise_error(InvalidOperation, 1139 '(+-)INF // (+-)INF'), 1140 context._raise_error(InvalidOperation, 1141 '(+-)INF % (+-)INF')) 1142 1143 if not divmod: 1144 if other._isinfinity(): 1145 context._raise_error(Clamped, 'Division by infinity') 1146 return Decimal((sign, (0,), context.Etiny())) 1147 if self._isinfinity(): 1148 return Infsign[sign] 1149 #These two have different precision. 1150 if not self: 1151 exp = self._exp - other._exp 1152 if exp < context.Etiny(): 1153 exp = context.Etiny() 1154 context._raise_error(Clamped, '0e-x / y') 1155 if exp > context.Emax: 1156 exp = context.Emax 1157 context._raise_error(Clamped, '0e+x / y') 1158 return Decimal( (sign, (0,), exp) ) 1159 1160 if not other: 1161 return context._raise_error(DivisionByZero, 'x / 0', sign) 1162 if divmod: 1163 if other._isinfinity(): 1164 return (Decimal((sign, (0,), 0)), Decimal(self)) 1165 if self._isinfinity(): 1166 if divmod == 1: 1167 return (Infsign[sign], 1168 context._raise_error(InvalidOperation, 'INF % x')) 1169 elif divmod == 2: 1170 return (Infsign[sign], NaN) 1171 elif divmod == 3: 1172 return (Infsign[sign], 1173 context._raise_error(InvalidOperation, 'INF % x')) 1174 if not self: 1175 otherside = Decimal(self) 1176 otherside._exp = min(self._exp, other._exp) 1177 return (Decimal((sign, (0,), 0)), otherside) 1178 1179 if not other: 1180 return context._raise_error(DivisionByZero, 'divmod(x,0)', 1181 sign, 1) 1182 1183 #OK, so neither = 0, INF 1184 1185 shouldround = context._rounding_decision == ALWAYS_ROUND 1186 1187 #If we're dividing into ints, and self < other, stop. 1188 #self.__abs__(0) does not round. 1189 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)): 1190 1191 if divmod == 1 or divmod == 3: 1192 exp = min(self._exp, other._exp) 1193 ans2 = self._rescale(exp, context=context, watchexp=0) 1194 if shouldround: 1195 ans2 = ans2._fix(context=context) 1196 return (Decimal( (sign, (0,), 0) ), 1197 ans2) 1198 1199 elif divmod == 2: 1200 #Don't round the mod part, if we don't need it. 1201 return (Decimal( (sign, (0,), 0) ), Decimal(self)) 1202 1203 if sign: 1204 sign = -1 1205 else: 1206 sign = 1 1207 adjust = 0 1208 op1 = _WorkRep(self) 1209 op2 = _WorkRep(other) 1210 op1, op2, adjust = _adjust_coefficients(op1, op2) 1211 res = _WorkRep( (sign, [0], (op1.exp - op2.exp)) ) 1212 if divmod and res.exp > context.prec + 1: 1213 return context._raise_error(DivisionImpossible) 1214 1215 ans = None 1216 while 1: 1217 while( (len(op2.int) < len(op1.int) and op1.int[0]) or 1218 (len(op2.int) == len(op1.int) and op2.int <= op1.int)): 1219 #Meaning, while op2.int < op1.int, when normalized. 1220 res._increment() 1221 op1.subtract(op2.int) 1222 if res.exp == 0 and divmod: 1223 if len(res.int) > context.prec and shouldround: 1224 return context._raise_error(DivisionImpossible) 1225 otherside = Decimal(op1) 1226 frozen = context._ignore_all_flags() 1227 1228 exp = min(self._exp, other._exp) 1229 otherside = otherside._rescale(exp, context=context, 1230 watchexp=0) 1231 context._regard_flags(*frozen) 1232 if shouldround: 1233 otherside = otherside._fix(context=context) 1234 return (Decimal(res), otherside) 1235 1236 if op1.int == [0]*len(op1.int) and adjust >= 0 and not divmod: 1237 break 1238 if (len(res.int) > context.prec) and shouldround: 1239 if divmod: 1240 return context._raise_error(DivisionImpossible) 1241 shouldround=1 1242 # Really, the answer is a bit higher, so adding a one to 1243 # the end will make sure the rounding is right. 1244 if op1.int != [0]*len(op1.int): 1245 res.int.append(1) 1246 res.exp -= 1 1247 1248 break 1249 res.exp -= 1 1250 adjust += 1 1251 res.int.append(0) 1252 op1.int.append(0) 1253 op1.exp -= 1 1254 1255 if res.exp == 0 and divmod and (len(op2.int) > len(op1.int) or 1256 (len(op2.int) == len(op1.int) and 1257 op2.int > op1.int)): 1258 #Solves an error in precision. Same as a previous block. 1259 1260 if len(res.int) > context.prec 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=context) 1275 return ans 1276 1277 def __rdiv__(self, other, context=None): 1278 """Swaps self/other and returns __div__.""" 1279 other = self._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 = self._convert_other(other) 1292 return other.__divmod__(self, context=context) 1293 1294 def __mod__(self, other, context=None): 1295 """ 1296 self % other 1297 """ 1298 if context is None: 1299 context = getcontext() 1300 other = self._convert_other(other) 1301 1302 ans = self._check_nans(other, context) 1303 if ans: 1304 return ans 1305 1306 if self and not other: 1307 return context._raise_error(InvalidOperation, 'x % 0') 1308 1309 return self._divide(other, 3, context)[1] 1310 1311 def __rmod__(self, other, context=None): 1312 """Swaps self/other and returns __mod__.""" 1313 other = self._convert_other(other) 1314 return other.__mod__(self, context=context) 1315 1316 def remainder_near(self, other, context=None): 1317 """ 1318 Remainder nearest to 0- abs(remainder-near) <= other/2 1319 """ 1320 if context is None: 1321 context = getcontext() 1322 other = self._convert_other(other) 1323 1324 ans = self._check_nans(other, context) 1325 if ans: 1326 return ans 1327 if self and not other: 1328 return context._raise_error(InvalidOperation, 'x % 0') 1329 1330 # If DivisionImpossible causes an error, do not leave Rounded/Inexact 1331 # ignored in the calling function. 1332 context = context.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.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=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=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 = self._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._isnan(): 1408 context = getcontext() 1409 return context._raise_error(InvalidContext) 1410 elif self._isinfinity(): 1411 raise OverflowError, "Cannot convert infinity to long" 1412 if not self: 1413 return 0 1414 sign = '-'*self._sign 1415 if self._exp >= 0: 1416 s = sign + ''.join(map(str, self._int)) + '0'*self._exp 1417 return int(s) 1418 s = sign + ''.join(map(str, self._int))[:self._exp] 1419 return int(s) 1420 tmp = list(self._int) 1421 tmp.reverse() 1422 val = 0 1423 while tmp: 1424 val *= 10 1425 val += tmp.pop() 1426 return int(((-1) ** self._sign) * val * 10.**int(self._exp)) 1427 1428 def __long__(self): 1429 """Converts to a long. 1430 1431 Equivalent to long(int(self)) 1432 """ 1433 return long(self.__int__()) 1434 1435 def _fix(self, prec=None, rounding=None, folddown=None, context=None): 1436 """Round if it is necessary to keep self within prec precision. 1437 1438 Rounds and fixes the exponent. Does not raise on a sNaN. 1439 1440 Arguments: 1441 self - Decimal instance 1442 prec - precision to which to round. By default, the context decides. 1443 rounding - Rounding method. By default, the context decides. 1444 folddown - Fold down high elements, by default context._clamp 1445 context - context used. 1446 """ 1447 if self._isinfinity() or self._isnan(): 1448 return self 1449 if context is None: 1450 context = getcontext() 1451 if prec is None: 1452 prec = context.prec 1453 ans = Decimal(self) 1454 ans = ans._fixexponents(prec, rounding, folddown=folddown, 1455 context=context) 1456 if len(ans._int) > prec: 1457 ans = ans._round(prec, rounding, context=context) 1458 ans = ans._fixexponents(prec, rounding, folddown=folddown, 1459 context=context) 1460 return ans 1461 1462 def _fixexponents(self, prec=None, rounding=None, folddown=None, 1463 context=None): 1464 """Fix the exponents and return a copy with the exponent in bounds.""" 1465 if self._isinfinity(): 1466 return self 1467 if context is None: 1468 context = getcontext() 1469 if prec is None: 1470 prec = context.prec 1471 if folddown is None: 1472 folddown = context._clamp 1473 Emin, Emax = context.Emin, context.Emax 1474 Etop = context.Etop() 1475 ans = Decimal(self) 1476 if ans.adjusted() < Emin: 1477 Etiny = context.Etiny() 1478 if ans._exp < Etiny: 1479 if not ans: 1480 ans._exp = Etiny 1481 context._raise_error(Clamped) 1482 return ans 1483 ans = ans._rescale(Etiny, context=context) 1484 #It isn't zero, and exp < Emin => subnormal 1485 context._raise_error(Subnormal) 1486 if context.flags[Inexact]: 1487 context._raise_error(Underflow) 1488 else: 1489 if ans: 1490 #Only raise subnormal if non-zero. 1491 context._raise_error(Subnormal) 1492 elif folddown and ans._exp > Etop: 1493 context._raise_error(Clamped) 1494 ans = ans._rescale(Etop, context=context) 1495 elif ans.adjusted() > Emax: 1496 if not ans: 1497 ans._exp = Emax 1498 context._raise_error(Clamped) 1499 return ans 1500 context._raise_error(Inexact) 1501 context._raise_error(Rounded) 1502 return context._raise_error(Overflow, 'above Emax', ans._sign) 1503 return ans 1504 1505 def _round(self, prec=None, rounding=None, context=None): 1506 """Returns a rounded version of self. 1507 1508 You can specify the precision or rounding method. Otherwise, the 1509 context determines it. 1510 """ 1511 1512 if context is None: 1513 context = getcontext() 1514 ans = self._check_nans(context=context) 1515 if ans: 1516 return ans 1517 1518 if self._isinfinity(): 1519 return Decimal(self) 1520 1521 if rounding is None: 1522 rounding = context.rounding 1523 if prec is None: 1524 prec = context.prec 1525 1526 if not self: 1527 if prec <= 0: 1528 dig = (0,) 1529 exp = len(self._int) - prec + self._exp 1530 else: 1531 dig = (0,) * prec 1532 exp = len(self._int) + self._exp - prec 1533 ans = Decimal((self._sign, dig, exp)) 1534 context._raise_error(Rounded) 1535 return ans 1536 1537 if prec == 0: 1538 temp = Decimal(self) 1539 temp._int = (0,)+temp._int 1540 prec = 1 1541 elif prec < 0: 1542 exp = self._exp + len(self._int) - prec - 1 1543 temp = Decimal( (self._sign, (0, 1), exp)) 1544 prec = 1 1545 else: 1546 temp = Decimal(self) 1547 1548 numdigits = len(temp._int) 1549 if prec == numdigits: 1550 return temp 1551 1552 # See if we need to extend precision 1553 expdiff = prec - numdigits 1554 if expdiff > 0: 1555 tmp = list(temp._int) 1556 tmp.extend([0] * expdiff) 1557 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff)) 1558 return ans 1559 1560 #OK, but maybe all the lost digits are 0. 1561 lostdigits = self._int[expdiff:] 1562 if lostdigits == (0,) * len(lostdigits): 1563 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff)) 1564 #Rounded, but not Inexact 1565 context._raise_error(Rounded) 1566 return ans 1567 1568 # Okay, let's round and lose data 1569 1570 this_function = getattr(temp, self._pick_rounding_function[rounding]) 1571 #Now we've got the rounding function 1572 1573 if prec != context.prec: 1574 context = context.copy() 1575 context.prec = prec 1576 ans = this_function(prec, expdiff, context) 1577 context._raise_error(Rounded) 1578 context._raise_error(Inexact, 'Changed in rounding') 1579 1580 return ans 1581 1582 _pick_rounding_function = {} 1583 1584 def _round_down(self, prec, expdiff, context): 1585 """Also known as round-towards-0, truncate.""" 1586 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) ) 1587 1588 def _round_half_up(self, prec, expdiff, context, tmp = None): 1589 """Rounds 5 up (away from 0)""" 1590 1591 if tmp is None: 1592 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff)) 1593 if self._int[prec] >= 5: 1594 tmp = tmp._increment(round=0, context=context) 1595 if len(tmp._int) > prec: 1596 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1)) 1597 return tmp 1598 1599 def _round_half_even(self, prec, expdiff, context): 1600 """Round 5 to even, rest to nearest.""" 1601 1602 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff)) 1603 half = (self._int[prec] == 5) 1604 if half: 1605 for digit in self._int[prec+1:]: 1606 if digit != 0: 1607 half = 0 1608 break 1609 if half: 1610 if self._int[prec-1] %2 == 0: 1611 return tmp 1612 return self._round_half_up(prec, expdiff, context, tmp) 1613 1614 def _round_half_down(self, prec, expdiff, context): 1615 """Round 5 down""" 1616 1617 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff)) 1618 half = (self._int[prec] == 5) 1619 if half: 1620 for digit in self._int[prec+1:]: 1621 if digit != 0: 1622 half = 0 1623 break 1624 if half: 1625 return tmp 1626 return self._round_half_up(prec, expdiff, context, tmp) 1627 1628 def _round_up(self, prec, expdiff, context): 1629 """Rounds away from 0.""" 1630 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) ) 1631 for digit in self._int[prec:]: 1632 if digit != 0: 1633 tmp = tmp._increment(round=1, context=context) 1634 if len(tmp._int) > prec: 1635 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1)) 1636 else: 1637 return tmp 1638 return tmp 1639 1640 def _round_ceiling(self, prec, expdiff, context): 1641 """Rounds up (not away from 0 if negative.)""" 1642 if self._sign: 1643 return self._round_down(prec, expdiff, context) 1644 else: 1645 return self._round_up(prec, expdiff, context) 1646 1647 def _round_floor(self, prec, expdiff, context): 1648 """Rounds down (not towards 0 if negative)""" 1649 if not self._sign: 1650 return self._round_down(prec, expdiff, context) 1651 else: 1652 return self._round_up(prec, expdiff, context) 1653 1654 def __pow__(self, n, modulo = None, context=None): 1655 """Return self ** n (mod modulo) 1656 1657 If modulo is None (default), don't take it mod modulo. 1658 """ 1659 if context is None: 1660 context = getcontext() 1661 n = self._convert_other(n) 1662 1663 #Because the spot << doesn't work with really big exponents 1664 if n._isinfinity() or n.adjusted() > 8: 1665 return context._raise_error(InvalidOperation, 'x ** INF') 1666 1667 ans = self._check_nans(n, context) 1668 if ans: 1669 return ans 1670 1671 if not n._isinfinity() and not n._isinteger(): 1672 return context._raise_error(InvalidOperation, 'x ** (non-integer)') 1673 1674 if not self and not n: 1675 return context._raise_error(InvalidOperation, '0 ** 0') 1676 1677 if not n: 1678 return Decimal(1) 1679 1680 if self == Decimal(1): 1681 return Decimal(1) 1682 1683 sign = self._sign and not n._iseven() 1684 n = int(n) 1685 1686 if self._isinfinity(): 1687 if modulo: 1688 return context._raise_error(InvalidOperation, 'INF % x') 1689 if n > 0: 1690 return Infsign[sign] 1691 return Decimal( (sign, (0,), 0) ) 1692 1693 #with ludicrously large exponent, just raise an overflow and return inf. 1694 if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \ 1695 and self: 1696 1697 tmp = Decimal('inf') 1698 tmp._sign = sign 1699 context._raise_error(Rounded) 1700 context._raise_error(Inexact) 1701 context._raise_error(Overflow, 'Big power', sign) 1702 return tmp 1703 1704 elength = len(str(abs(n))) 1705 firstprec = context.prec 1706 1707 if not modulo and firstprec + elength + 1 > DEFAULT_MAX_EXPONENT: 1708 return context._raise_error(Overflow, 'Too much precision.', sign) 1709 1710 mul = Decimal(self) 1711 val = Decimal(1) 1712 context = context.copy() 1713 context.prec = firstprec + elength + 1 1714 rounding = context.rounding 1715 if n < 0: 1716 #n is a long now, not Decimal instance 1717 n = -n 1718 mul = Decimal(1).__div__(mul, context=context) 1719 1720 shouldround = context._rounding_decision == ALWAYS_ROUND 1721 1722 spot = 1 1723 while spot <= n: 1724 spot <<= 1 1725 1726 spot >>= 1 1727 #Spot is the highest power of 2 less than n 1728 while spot: 1729 val = val.__mul__(val, context=context) 1730 if val._isinfinity(): 1731 val = Infsign[sign] 1732 break 1733 if spot & n: 1734 val = val.__mul__(mul, context=context) 1735 if modulo is not None: 1736 val = val.__mod__(modulo, context=context) 1737 spot >>= 1 1738 context.prec = firstprec 1739 1740 if shouldround: 1741 return val._fix(context=context) 1742 return val 1743 1744 def __rpow__(self, other, context=None): 1745 """Swaps self/other and returns __pow__.""" 1746 other = self._convert_other(other) 1747 return other.__pow__(self, context=context) 1748 1749 def normalize(self, context=None): 1750 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0""" 1751 if context is None: 1752 context = getcontext() 1753 1754 ans = self._check_nans(context=context) 1755 if ans: 1756 return ans 1757 1758 dup = self._fix(context=context) 1759 if dup._isinfinity(): 1760 return dup 1761 1762 if not dup: 1763 return Decimal( (dup._sign, (0,), 0) ) 1764 end = len(dup._int) 1765 exp = dup._exp 1766 while dup._int[end-1] == 0: 1767 exp += 1 1768 end -= 1 1769 return Decimal( (dup._sign, dup._int[:end], exp) ) 1770 1771 1772 def quantize(self, exp, rounding = None, context=None, watchexp = 1): 1773 """Quantize self so its exponent is the same as that of exp. 1774 1775 Similar to self._rescale(exp._exp) but with error checking. 1776 """ 1777 if context is None: 1778 context = getcontext() 1779 1780 ans = self._check_nans(exp, context) 1781 if ans: 1782 return ans 1783 1784 if exp._isinfinity() or self._isinfinity(): 1785 if exp._isinfinity() and self._isinfinity(): 1786 return self #if both are inf, it is OK 1787 return context._raise_error(InvalidOperation, 1788 'quantize with one INF') 1789 return self._rescale(exp._exp, rounding, context, watchexp) 1790 1791 def same_quantum(self, other): 1792 """Test whether self and other have the same exponent. 1793 1794 same as self._exp == other._exp, except NaN == sNaN 1795 """ 1796 if self._isnan() or other._isnan(): 1797 return self._isnan() and other._isnan() and True 1798 if self._isinfinity() or other._isinfinity(): 1799 return self._isinfinity() and other._isinfinity() and True 1800 return self._exp == other._exp 1801 1802 def _rescale(self, exp, rounding = None, context=None, watchexp = 1): 1803 """Rescales so that the exponent is exp. 1804 1805 exp = exp to scale to (an integer) 1806 rounding = rounding version 1807 watchexp: if set (default) an error is returned if exp is greater 1808 than Emax or less than Etiny. 1809 """ 1810 if context is None: 1811 context = getcontext() 1812 1813 if self._isinfinity(): 1814 return context._raise_error(InvalidOperation, 'rescale with an INF') 1815 1816 ans = self._check_nans(context=context) 1817 if ans: 1818 return ans 1819 1820 out = 0 1821 1822 if watchexp and (context.Emax < exp or context.Etiny() > exp): 1823 return context._raise_error(InvalidOperation, 'rescale(a, INF)') 1824 1825 if not self: 1826 ans = Decimal(self) 1827 ans._int = (0,) 1828 ans._exp = exp 1829 return ans 1830 1831 diff = self._exp - exp 1832 digits = len(self._int)+diff 1833 1834 if watchexp and digits > context.prec: 1835 return context._raise_error(InvalidOperation, 'Rescale > prec') 1836 1837 tmp = Decimal(self) 1838 tmp._int = (0,)+tmp._int 1839 digits += 1 1840 1841 prevexact = context.flags[Inexact] 1842 if digits < 0: 1843 tmp._exp = -digits + tmp._exp 1844 tmp._int = (0,1) 1845 digits = 1 1846 tmp = tmp._round(digits, rounding, context=context) 1847 1848 if tmp._int[0] == 0 and len(tmp._int) > 1: 1849 tmp._int = tmp._int[1:] 1850 tmp._exp = exp 1851 1852 if tmp and tmp.adjusted() < context.Emin: 1853 context._raise_error(Subnormal) 1854 elif tmp and tmp.adjusted() > context.Emax: 1855 return context._raise_error(InvalidOperation, 'rescale(a, INF)') 1856 return tmp 1857 1858 def to_integral(self, rounding = None, context=None): 1859 """Rounds to the nearest integer, without raising inexact, rounded.""" 1860 if context is None: 1861 context = getcontext() 1862 ans = self._check_nans(context=context) 1863 if ans: 1864 return ans 1865 if self._exp >= 0: 1866 return self 1867 flags = context._ignore_flags(Rounded, Inexact) 1868 ans = self._rescale(0, rounding, context=context) 1869 context._regard_flags(flags) 1870 return ans 1871 1872 def sqrt(self, context=None): 1873 """Return the square root of self. 1874 1875 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn)) 1876 Should quadratically approach the right answer. 1877 """ 1878 if context is None: 1879 context = getcontext() 1880 1881 ans = self._check_nans(context=context) 1882 if ans: 1883 return ans 1884 1885 if not self: 1886 #exponent = self._exp / 2, using round_down. 1887 #if self._exp < 0: 1888 # exp = (self._exp+1) // 2 1889 #else: 1890 exp = (self._exp) // 2 1891 if self._sign == 1: 1892 #sqrt(-0) = -0 1893 return Decimal( (1, (0,), exp)) 1894 else: 1895 return Decimal( (0, (0,), exp)) 1896 1897 if self._sign == 1: 1898 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0') 1899 1900 if self._isinfinity(): 1901 return Decimal(self) 1902 1903 tmp = Decimal(self) 1904 1905 expadd = tmp._exp / 2 1906 if tmp._exp % 2 == 1: 1907 tmp._int += (0,) 1908 tmp._exp = 0 1909 else: 1910 tmp._exp = 0 1911 1912 context = context.copy() 1913 flags = context._ignore_all_flags() 1914 firstprec = context.prec 1915 context.prec = 3 1916 if tmp.adjusted() % 2 == 0: 1917 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) ) 1918 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)), 1919 context=context), context=context) 1920 ans._exp -= 1 + tmp.adjusted()/2 1921 else: 1922 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) ) 1923 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)), 1924 context=context), context=context) 1925 ans._exp -= 1 + tmp.adjusted()/2 1926 1927 #ans is now a linear approximation. 1928 1929 Emax, Emin = context.Emax, context.Emin 1930 context.Emax, context.Emin = DEFAULT_MAX_EXPONENT, DEFAULT_MIN_EXPONENT 1931 1932 1933 half = Decimal('0.5') 1934 1935 count = 1 1936 maxp = firstprec + 2 1937 rounding = context._set_rounding(ROUND_HALF_EVEN) 1938 while 1: 1939 context.prec = min(2*context.prec - 2, maxp) 1940 ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context), 1941 context=context), context=context) 1942 if context.prec == maxp: 1943 break 1944 1945 #round to the answer's precision-- the only error can be 1 ulp. 1946 context.prec = firstprec 1947 prevexp = ans.adjusted() 1948 ans = ans._round(context=context) 1949 1950 #Now, check if the other last digits are better. 1951 context.prec = firstprec + 1 1952 # In case we rounded up another digit and we should actually go lower. 1953 if prevexp != ans.adjusted(): 1954 ans._int += (0,) 1955 ans._exp -= 1 1956 1957 1958 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context) 1959 context._set_rounding(ROUND_UP) 1960 if lower.__mul__(lower, context=context) > (tmp): 1961 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context) 1962 1963 else: 1964 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context) 1965 context._set_rounding(ROUND_DOWN) 1966 if upper.__mul__(upper, context=context) < tmp: 1967 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context) 1968 1969 ans._exp += expadd 1970 1971 context.prec = firstprec 1972 context.rounding = rounding 1973 ans = ans._fix(context=context) 1974 1975 rounding = context._set_rounding_decision(NEVER_ROUND) 1976 if not ans.__mul__(ans, context=context) == self: 1977 # Only rounded/inexact if here. 1978 context._regard_flags(flags) 1979 context._raise_error(Rounded) 1980 context._raise_error(Inexact) 1981 else: 1982 #Exact answer, so let's set the exponent right. 1983 #if self._exp < 0: 1984 # exp = (self._exp +1)// 2 1985 #else: 1986 exp = self._exp // 2 1987 context.prec += ans._exp - exp 1988 ans = ans._rescale(exp, context=context) 1989 context.prec = firstprec 1990 context._regard_flags(flags) 1991 context.Emax, context.Emin = Emax, Emin 1992 1993 return ans._fix(context=context) 1994 1995 def max(self, other, context=None): 1996 """Returns the larger value. 1997 1998 like max(self, other) except if one is not a number, returns 1999 NaN (and signals if one is sNaN). Also rounds. 2000 """ 2001 if context is None: 2002 context = getcontext() 2003 other = self._convert_other(other) 2004 2005 ans = self._check_nans(other, context) 2006 if ans: 2007 return ans 2008 2009 ans = self 2010 if self < other: 2011 ans = other 2012 shouldround = context._rounding_decision == ALWAYS_ROUND 2013 if shouldround: 2014 ans = ans._fix(context=context) 2015 return ans 2016 2017 def min(self, other, context=None): 2018 """Returns the smaller value. 2019 2020 like min(self, other) except if one is not a number, returns 2021 NaN (and signals if one is sNaN). Also rounds. 2022 """ 2023 if context is None: 2024 context = getcontext() 2025 other = self._convert_other(other) 2026 2027 ans = self._check_nans(other, context) 2028 if ans: 2029 return ans 2030 2031 ans = self 2032 2033 if self > other: 2034 ans = other 2035 2036 if context._rounding_decision == ALWAYS_ROUND: 2037 ans = ans._fix(context=context) 2038 2039 return ans 2040 2041 def _isinteger(self): 2042 """Returns whether self is an integer""" 2043 if self._exp >= 0: 2044 return True 2045 rest = self._int[self._exp:] 2046 return rest == (0,)*len(rest) 2047 2048 def _iseven(self): 2049 """Returns 1 if self is even. Assumes self is an integer.""" 2050 if self._exp > 0: 2051 return 1 2052 return self._int[-1+self._exp] % 2 == 0 2053 2054 def adjusted(self): 2055 """Return the adjusted exponent of self""" 2056 try: 2057 return self._exp + len(self._int) - 1 2058 #If NaN or Infinity, self._exp is string 2059 except TypeError: 2060 return 0 2061 2062 #properties to immutability-near feature 2063 def _get_sign(self): 2064 return self._sign 2065 def _get_int(self): 2066 return self._int 2067 def _get_exp(self): 2068 return self._exp 2069 sign = property(_get_sign) 2070 int = property(_get_int) 2071 exp = property(_get_exp) 2072 2073 # support for pickling, copy, and deepcopy 2074 def __reduce__(self): 2075 return (self.__class__, (str(self),)) 2076 2077 def __copy__(self): 2078 if type(self) == Decimal: 2079 return self # I'm immutable; therefore I am my own clone 2080 return self.__class__(str(self)) 2081 2082 def __deepcopy__(self, memo): 2083 if type(self) == Decimal: 2084 return self # My components are also immutable 2085 return self.__class__(str(self)) 2086 2087##### Context class ########################################### 2088 2089 2090# get rounding method function: 2091rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')] 2092for name in rounding_functions: 2093 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value. 2094 globalname = name[1:].upper() 2095 val = globals()[globalname] 2096 Decimal._pick_rounding_function[val] = name 2097 2098del name, val, globalname, rounding_functions 2099 2100class Context(object): 2101 """Contains the context for a Decimal instance. 2102 2103 Contains: 2104 prec - precision (for use in rounding, division, square roots..) 2105 rounding - rounding type. (how you round) 2106 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round? 2107 trap_enablers - If trap_enablers[exception] = 1, then the exception is 2108 raised when it is caused. Otherwise, a value is 2109 substituted in. 2110 flags - When an exception is caused, flags[exception] is incremented. 2111 (Whether or not the trap_enabler is set) 2112 Should be reset by user of Decimal instance. 2113 Emin - Minimum exponent 2114 Emax - Maximum exponent 2115 capitals - If 1, 1*10^1 is printed as 1E+1. 2116 If 0, printed as 1e1 2117 _clamp - If 1, change exponents if too high (Default 0) 2118 """ 2119 2120 DefaultLock = threading.Lock() 2121 2122 def __init__(self, prec=None, rounding=None, 2123 trap_enablers=None, flags=None, 2124 _rounding_decision=None, 2125 Emin=None, Emax=None, 2126 capitals=None, _clamp=0, 2127 _ignored_flags=[]): 2128 if flags is None: 2129 flags = dict.fromkeys(Signals, 0) 2130 self.DefaultLock.acquire() 2131 for name, val in locals().items(): 2132 if val is None: 2133 setattr(self, name, copy.copy(getattr(DefaultContext, name))) 2134 else: 2135 setattr(self, name, val) 2136 self.DefaultLock.release() 2137 del self.self 2138 2139 def __repr__(self): 2140 """Show the current context in readable form, not in a form for eval().""" 2141 s = [] 2142 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d' % vars(self)) 2143 s.append('setflags=%r' % [f.__name__ for f, v in self.flags.items() if v]) 2144 s.append('settraps=%r' % [t.__name__ for t, v in self.trap_enablers.items() if v]) 2145 return ', '.join(s) + ')' 2146 2147 def clear_flags(self): 2148 """Reset all flags to zero""" 2149 for flag in self.flags: 2150 self.flags[flag] = 0 2151 2152 def copy(self): 2153 """Returns a copy from self.""" 2154 nc = Context(self.prec, self.rounding, self.trap_enablers, self.flags, 2155 self._rounding_decision, self.Emin, self.Emax, 2156 self.capitals, self._clamp, self._ignored_flags) 2157 return nc 2158 __copy__ = copy 2159 2160 def _raise_error(self, condition, explanation = None, *args): 2161 """Handles an error 2162 2163 If the flag is in _ignored_flags, returns the default response. 2164 Otherwise, it increments the flag, then, if the corresponding 2165 trap_enabler is set, it reaises the exception. Otherwise, it returns 2166 the default value after incrementing the flag. 2167 """ 2168 error = _condition_map.get(condition, condition) 2169 if error in self._ignored_flags: 2170 #Don't touch the flag 2171 return error().handle(self, *args) 2172 2173 self.flags[error] += 1 2174 if not self.trap_enablers[error]: 2175 #The errors define how to handle themselves. 2176 return condition().handle(self, *args) 2177 2178 # Errors should only be risked on copies of the context 2179 #self._ignored_flags = [] 2180 raise error, explanation 2181 2182 def _ignore_all_flags(self): 2183 """Ignore all flags, if they are raised""" 2184 return self._ignore_flags(*Signals) 2185 2186 def _ignore_flags(self, *flags): 2187 """Ignore the flags, if they are raised""" 2188 # Do not mutate-- This way, copies of a context leave the original 2189 # alone. 2190 self._ignored_flags = (self._ignored_flags + list(flags)) 2191 return list(flags) 2192 2193 def _regard_flags(self, *flags): 2194 """Stop ignoring the flags, if they are raised""" 2195 if flags and isinstance(flags[0], (tuple,list)): 2196 flags = flags[0] 2197 for flag in flags: 2198 self._ignored_flags.remove(flag) 2199 2200 def __hash__(self): 2201 """A Context cannot be hashed.""" 2202 # We inherit object.__hash__, so we must deny this explicitly 2203 raise TypeError, "Cannot hash a Context." 2204 2205 def Etiny(self): 2206 """Returns Etiny (= Emin - prec + 1)""" 2207 return int(self.Emin - self.prec + 1) 2208 2209 def Etop(self): 2210 """Returns maximum exponent (= Emax - prec + 1)""" 2211 return int(self.Emax - self.prec + 1) 2212 2213 def _set_rounding_decision(self, type): 2214 """Sets the rounding decision. 2215 2216 Sets the rounding decision, and returns the current (previous) 2217 rounding decision. Often used like: 2218 2219 context = context.copy() 2220 # That so you don't change the calling context 2221 # if an error occurs in the middle (say DivisionImpossible is raised). 2222 2223 rounding = context._set_rounding_decision(NEVER_ROUND) 2224 instance = instance / Decimal(2) 2225 context._set_rounding_decision(rounding) 2226 2227 This will make it not round for that operation. 2228 """ 2229 2230 rounding = self._rounding_decision 2231 self._rounding_decision = type 2232 return rounding 2233 2234 def _set_rounding(self, type): 2235 """Sets the rounding type. 2236 2237 Sets the rounding type, and returns the current (previous) 2238 rounding type. Often used like: 2239 2240 context = context.copy() 2241 # so you don't change the calling context 2242 # if an error occurs in the middle. 2243 rounding = context._set_rounding(ROUND_UP) 2244 val = self.__sub__(other, context=context) 2245 context._set_rounding(rounding) 2246 2247 This will make it round up for that operation. 2248 """ 2249 rounding = self.rounding 2250 self.rounding= type 2251 return rounding 2252 2253 def create_decimal(self, num): 2254 """Creates a new Decimal instance but using self as context.""" 2255 d = Decimal(num, context=self) 2256 return d._fix(context=self) 2257 2258 #Methods 2259 def abs(self, a): 2260 """Returns the absolute value of the operand. 2261 2262 If the operand is negative, the result is the same as using the minus 2263 operation on the operand. Otherwise, the result is the same as using 2264 the plus operation on the operand. 2265 2266 >>> ExtendedContext.abs(Decimal('2.1')) 2267 Decimal("2.1") 2268 >>> ExtendedContext.abs(Decimal('-100')) 2269 Decimal("100") 2270 >>> ExtendedContext.abs(Decimal('101.5')) 2271 Decimal("101.5") 2272 >>> ExtendedContext.abs(Decimal('-101.5')) 2273 Decimal("101.5") 2274 """ 2275 return a.__abs__(context=self) 2276 2277 def add(self, a, b): 2278 """Return the sum of the two operands. 2279 2280 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00')) 2281 Decimal("19.00") 2282 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4')) 2283 Decimal("1.02E+4") 2284 """ 2285 return a.__add__(b, context=self) 2286 2287 def _apply(self, a): 2288 return str(a._fix(context=self)) 2289 2290 def compare(self, a, b): 2291 """Compares values numerically. 2292 2293 If the signs of the operands differ, a value representing each operand 2294 ('-1' if the operand is less than zero, '0' if the operand is zero or 2295 negative zero, or '1' if the operand is greater than zero) is used in 2296 place of that operand for the comparison instead of the actual 2297 operand. 2298 2299 The comparison is then effected by subtracting the second operand from 2300 the first and then returning a value according to the result of the 2301 subtraction: '-1' if the result is less than zero, '0' if the result is 2302 zero or negative zero, or '1' if the result is greater than zero. 2303 2304 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3')) 2305 Decimal("-1") 2306 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1')) 2307 Decimal("0") 2308 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10')) 2309 Decimal("0") 2310 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1')) 2311 Decimal("1") 2312 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3')) 2313 Decimal("1") 2314 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1')) 2315 Decimal("-1") 2316 """ 2317 return a.compare(b, context=self) 2318 2319 def divide(self, a, b): 2320 """Decimal division in a specified context. 2321 2322 >>> ExtendedContext.divide(Decimal('1'), Decimal('3')) 2323 Decimal("0.333333333") 2324 >>> ExtendedContext.divide(Decimal('2'), Decimal('3')) 2325 Decimal("0.666666667") 2326 >>> ExtendedContext.divide(Decimal('5'), Decimal('2')) 2327 Decimal("2.5") 2328 >>> ExtendedContext.divide(Decimal('1'), Decimal('10')) 2329 Decimal("0.1") 2330 >>> ExtendedContext.divide(Decimal('12'), Decimal('12')) 2331 Decimal("1") 2332 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2')) 2333 Decimal("4.00") 2334 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0')) 2335 Decimal("1.20") 2336 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100')) 2337 Decimal("10") 2338 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1')) 2339 Decimal("1000") 2340 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2')) 2341 Decimal("1.20E+6") 2342 """ 2343 return a.__div__(b, context=self) 2344 2345 def divide_int(self, a, b): 2346 """Divides two numbers and returns the integer part of the result. 2347 2348 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3')) 2349 Decimal("0") 2350 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3')) 2351 Decimal("3") 2352 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3')) 2353 Decimal("3") 2354 """ 2355 return a.__floordiv__(b, context=self) 2356 2357 def divmod(self, a, b): 2358 return a.__divmod__(b, context=self) 2359 2360 def max(self, a,b): 2361 """max compares two values numerically and returns the maximum. 2362 2363 If either operand is a NaN then the general rules apply. 2364 Otherwise, the operands are compared as as though by the compare 2365 operation. If they are numerically equal then the left-hand operand 2366 is chosen as the result. Otherwise the maximum (closer to positive 2367 infinity) of the two operands is chosen as the result. 2368 2369 >>> ExtendedContext.max(Decimal('3'), Decimal('2')) 2370 Decimal("3") 2371 >>> ExtendedContext.max(Decimal('-10'), Decimal('3')) 2372 Decimal("3") 2373 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1')) 2374 Decimal("1.0") 2375 """ 2376 return a.max(b, context=self) 2377 2378 def min(self, a,b): 2379 """min compares two values numerically and returns the minimum. 2380 2381 If either operand is a NaN then the general rules apply. 2382 Otherwise, the operands are compared as as though by the compare 2383 operation. If they are numerically equal then the left-hand operand 2384 is chosen as the result. Otherwise the minimum (closer to negative 2385 infinity) of the two operands is chosen as the result. 2386 2387 >>> ExtendedContext.min(Decimal('3'), Decimal('2')) 2388 Decimal("2") 2389 >>> ExtendedContext.min(Decimal('-10'), Decimal('3')) 2390 Decimal("-10") 2391 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1')) 2392 Decimal("1.0") 2393 """ 2394 return a.min(b, context=self) 2395 2396 def minus(self, a): 2397 """Minus corresponds to unary prefix minus in Python. 2398 2399 The operation is evaluated using the same rules as subtract; the 2400 operation minus(a) is calculated as subtract('0', a) where the '0' 2401 has the same exponent as the operand. 2402 2403 >>> ExtendedContext.minus(Decimal('1.3')) 2404 Decimal("-1.3") 2405 >>> ExtendedContext.minus(Decimal('-1.3')) 2406 Decimal("1.3") 2407 """ 2408 return a.__neg__(context=self) 2409 2410 def multiply(self, a, b): 2411 """multiply multiplies two operands. 2412 2413 If either operand is a special value then the general rules apply. 2414 Otherwise, the operands are multiplied together ('long multiplication'), 2415 resulting in a number which may be as long as the sum of the lengths 2416 of the two operands. 2417 2418 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3')) 2419 Decimal("3.60") 2420 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3')) 2421 Decimal("21") 2422 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8')) 2423 Decimal("0.72") 2424 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0')) 2425 Decimal("-0.0") 2426 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321')) 2427 Decimal("4.28135971E+11") 2428 """ 2429 return a.__mul__(b, context=self) 2430 2431 def normalize(self, a): 2432 """normalize reduces an operand to its simplest form. 2433 2434 Essentially a plus operation with all trailing zeros removed from the 2435 result. 2436 2437 >>> ExtendedContext.normalize(Decimal('2.1')) 2438 Decimal("2.1") 2439 >>> ExtendedContext.normalize(Decimal('-2.0')) 2440 Decimal("-2") 2441 >>> ExtendedContext.normalize(Decimal('1.200')) 2442 Decimal("1.2") 2443 >>> ExtendedContext.normalize(Decimal('-120')) 2444 Decimal("-1.2E+2") 2445 >>> ExtendedContext.normalize(Decimal('120.00')) 2446 Decimal("1.2E+2") 2447 >>> ExtendedContext.normalize(Decimal('0.00')) 2448 Decimal("0") 2449 """ 2450 return a.normalize(context=self) 2451 2452 def plus(self, a): 2453 """Plus corresponds to unary prefix plus in Python. 2454 2455 The operation is evaluated using the same rules as add; the 2456 operation plus(a) is calculated as add('0', a) where the '0' 2457 has the same exponent as the operand. 2458 2459 >>> ExtendedContext.plus(Decimal('1.3')) 2460 Decimal("1.3") 2461 >>> ExtendedContext.plus(Decimal('-1.3')) 2462 Decimal("-1.3") 2463 """ 2464 return a.__pos__(context=self) 2465 2466 def power(self, a, b, modulo=None): 2467 """Raises a to the power of b, to modulo if given. 2468 2469 The right-hand operand must be a whole number whose integer part (after 2470 any exponent has been applied) has no more than 9 digits and whose 2471 fractional part (if any) is all zeros before any rounding. The operand 2472 may be positive, negative, or zero; if negative, the absolute value of 2473 the power is used, and the left-hand operand is inverted (divided into 2474 1) before use. 2475 2476 If the increased precision needed for the intermediate calculations 2477 exceeds the capabilities of the implementation then an Invalid operation 2478 condition is raised. 2479 2480 If, when raising to a negative power, an underflow occurs during the 2481 division into 1, the operation is not halted at that point but 2482 continues. 2483 2484 >>> ExtendedContext.power(Decimal('2'), Decimal('3')) 2485 Decimal("8") 2486 >>> ExtendedContext.power(Decimal('2'), Decimal('-3')) 2487 Decimal("0.125") 2488 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8')) 2489 Decimal("69.7575744") 2490 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2')) 2491 Decimal("0") 2492 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1')) 2493 Decimal("0") 2494 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0')) 2495 Decimal("1") 2496 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1')) 2497 Decimal("Infinity") 2498 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2')) 2499 Decimal("Infinity") 2500 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2')) 2501 Decimal("0") 2502 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1')) 2503 Decimal("-0") 2504 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0')) 2505 Decimal("1") 2506 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1')) 2507 Decimal("-Infinity") 2508 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2')) 2509 Decimal("Infinity") 2510 >>> ExtendedContext.power(Decimal('0'), Decimal('0')) 2511 Decimal("NaN") 2512 """ 2513 return a.__pow__(b, modulo, context=self) 2514 2515 def quantize(self, a, b): 2516 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'. 2517 2518 The coefficient of the result is derived from that of the left-hand 2519 operand. It may be rounded using the current rounding setting (if the 2520 exponent is being increased), multiplied by a positive power of ten (if 2521 the exponent is being decreased), or is unchanged (if the exponent is 2522 already equal to that of the right-hand operand). 2523 2524 Unlike other operations, if the length of the coefficient after the 2525 quantize operation would be greater than precision then an Invalid 2526 operation condition is raised. This guarantees that, unless there is an 2527 error condition, the exponent of the result of a quantize is always 2528 equal to that of the right-hand operand. 2529 2530 Also unlike other operations, quantize will never raise Underflow, even 2531 if the result is subnormal and inexact. 2532 2533 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001')) 2534 Decimal("2.170") 2535 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01')) 2536 Decimal("2.17") 2537 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1')) 2538 Decimal("2.2") 2539 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0')) 2540 Decimal("2") 2541 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1')) 2542 Decimal("0E+1") 2543 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity')) 2544 Decimal("-Infinity") 2545 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity')) 2546 Decimal("NaN") 2547 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1')) 2548 Decimal("-0") 2549 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5')) 2550 Decimal("-0E+5") 2551 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2')) 2552 Decimal("NaN") 2553 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2')) 2554 Decimal("NaN") 2555 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1')) 2556 Decimal("217.0") 2557 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0')) 2558 Decimal("217") 2559 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1')) 2560 Decimal("2.2E+2") 2561 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2')) 2562 Decimal("2E+2") 2563 """ 2564 return a.quantize(b, context=self) 2565 2566 def remainder(self, a, b): 2567 """Returns the remainder from integer division. 2568 2569 The result is the residue of the dividend after the operation of 2570 calculating integer division as described for divide-integer, rounded to 2571 precision digits if necessary. The sign of the result, if non-zero, is 2572 the same as that of the original dividend. 2573 2574 This operation will fail under the same conditions as integer division 2575 (that is, if integer division on the same two operands would fail, the 2576 remainder cannot be calculated). 2577 2578 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3')) 2579 Decimal("2.1") 2580 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3')) 2581 Decimal("1") 2582 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3')) 2583 Decimal("-1") 2584 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1')) 2585 Decimal("0.2") 2586 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3')) 2587 Decimal("0.1") 2588 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3')) 2589 Decimal("1.0") 2590 """ 2591 return a.__mod__(b, context=self) 2592 2593 def remainder_near(self, a, b): 2594 """Returns to be "a - b * n", where n is the integer nearest the exact 2595 value of "x / b" (if two integers are equally near then the even one 2596 is chosen). If the result is equal to 0 then its sign will be the 2597 sign of a. 2598 2599 This operation will fail under the same conditions as integer division 2600 (that is, if integer division on the same two operands would fail, the 2601 remainder cannot be calculated). 2602 2603 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3')) 2604 Decimal("-0.9") 2605 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6')) 2606 Decimal("-2") 2607 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3')) 2608 Decimal("1") 2609 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3')) 2610 Decimal("-1") 2611 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1')) 2612 Decimal("0.2") 2613 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3')) 2614 Decimal("0.1") 2615 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3')) 2616 Decimal("-0.3") 2617 """ 2618 return a.remainder_near(b, context=self) 2619 2620 def same_quantum(self, a, b): 2621 """Returns True if the two operands have the same exponent. 2622 2623 The result is never affected by either the sign or the coefficient of 2624 either operand. 2625 2626 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001')) 2627 False 2628 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01')) 2629 True 2630 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1')) 2631 False 2632 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf')) 2633 True 2634 """ 2635 return a.same_quantum(b) 2636 2637 def sqrt(self, a): 2638 """Returns the square root of a non-negative number to context precision. 2639 2640 If the result must be inexact, it is rounded using the round-half-even 2641 algorithm. 2642 2643 >>> ExtendedContext.sqrt(Decimal('0')) 2644 Decimal("0") 2645 >>> ExtendedContext.sqrt(Decimal('-0')) 2646 Decimal("-0") 2647 >>> ExtendedContext.sqrt(Decimal('0.39')) 2648 Decimal("0.624499800") 2649 >>> ExtendedContext.sqrt(Decimal('100')) 2650 Decimal("10") 2651 >>> ExtendedContext.sqrt(Decimal('1')) 2652 Decimal("1") 2653 >>> ExtendedContext.sqrt(Decimal('1.0')) 2654 Decimal("1.0") 2655 >>> ExtendedContext.sqrt(Decimal('1.00')) 2656 Decimal("1.0") 2657 >>> ExtendedContext.sqrt(Decimal('7')) 2658 Decimal("2.64575131") 2659 >>> ExtendedContext.sqrt(Decimal('10')) 2660 Decimal("3.16227766") 2661 >>> ExtendedContext.prec 2662 9 2663 """ 2664 return a.sqrt(context=self) 2665 2666 def subtract(self, a, b): 2667 """Return the sum of the two operands. 2668 2669 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07')) 2670 Decimal("0.23") 2671 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30')) 2672 Decimal("0.00") 2673 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07')) 2674 Decimal("-0.77") 2675 """ 2676 return a.__sub__(b, context=self) 2677 2678 def to_eng_string(self, a): 2679 """Converts a number to a string, using scientific notation. 2680 2681 The operation is not affected by the context. 2682 """ 2683 return a.to_eng_string(context=self) 2684 2685 def to_sci_string(self, a): 2686 """Converts a number to a string, using scientific notation. 2687 2688 The operation is not affected by the context. 2689 """ 2690 return a.__str__(context=self) 2691 2692 def to_integral(self, a): 2693 """Rounds to an integer. 2694 2695 When the operand has a negative exponent, the result is the same 2696 as using the quantize() operation using the given operand as the 2697 left-hand-operand, 1E+0 as the right-hand-operand, and the precision 2698 of the operand as the precision setting, except that no flags will 2699 be set. The rounding mode is taken from the context. 2700 2701 >>> ExtendedContext.to_integral(Decimal('2.1')) 2702 Decimal("2") 2703 >>> ExtendedContext.to_integral(Decimal('100')) 2704 Decimal("100") 2705 >>> ExtendedContext.to_integral(Decimal('100.0')) 2706 Decimal("100") 2707 >>> ExtendedContext.to_integral(Decimal('101.5')) 2708 Decimal("102") 2709 >>> ExtendedContext.to_integral(Decimal('-101.5')) 2710 Decimal("-102") 2711 >>> ExtendedContext.to_integral(Decimal('10E+5')) 2712 Decimal("1.0E+6") 2713 >>> ExtendedContext.to_integral(Decimal('7.89E+77')) 2714 Decimal("7.89E+77") 2715 >>> ExtendedContext.to_integral(Decimal('-Inf')) 2716 Decimal("-Infinity") 2717 """ 2718 return a.to_integral(context=self) 2719 2720class _WorkRep(object): 2721 __slots__ = ('sign','int','exp') 2722 # sign: -1 None 1 2723 # int: list 2724 # exp: None, int, or string 2725 2726 def __init__(self, value=None): 2727 if value is None: 2728 self.sign = None 2729 self.int = [] 2730 self.exp = None 2731 if isinstance(value, Decimal): 2732 if value._sign: 2733 self.sign = -1 2734 else: 2735 self.sign = 1 2736 self.int = list(value._int) 2737 self.exp = value._exp 2738 if isinstance(value, tuple): 2739 self.sign = value[0] 2740 self.int = value[1] 2741 self.exp = value[2] 2742 2743 def __repr__(self): 2744 return "(%r, %r, %r)" % (self.sign, self.int, self.exp) 2745 2746 __str__ = __repr__ 2747 2748 def __neg__(self): 2749 if self.sign == 1: 2750 return _WorkRep( (-1, self.int, self.exp) ) 2751 else: 2752 return _WorkRep( (1, self.int, self.exp) ) 2753 2754 def __abs__(self): 2755 if self.sign == -1: 2756 return -self 2757 else: 2758 return self 2759 2760 def __cmp__(self, other): 2761 if self.exp != other.exp: 2762 raise ValueError("Operands not normalized: %r, %r" % (self, other)) 2763 if self.sign != other.sign: 2764 if self.sign == -1: 2765 return -1 2766 else: 2767 return 1 2768 if self.sign == -1: 2769 direction = -1 2770 else: 2771 direction = 1 2772 int1 = self.int 2773 int2 = other.int 2774 if len(int1) > len(int2): 2775 return direction * 1 2776 if len(int1) < len(int2): 2777 return direction * -1 2778 for i in xrange(len(int1)): 2779 if int1[i] > int2[i]: 2780 return direction * 1 2781 if int1[i] < int2[i]: 2782 return direction * -1 2783 return 0 2784 2785 def _increment(self): 2786 curspot = len(self.int) - 1 2787 self.int[curspot]+= 1 2788 while (self.int[curspot] >= 10): 2789 self.int[curspot] -= 10 2790 if curspot == 0: 2791 self.int[0:0] = [1] 2792 break 2793 self.int[curspot-1] += 1 2794 curspot -= 1 2795 2796 def subtract(self, alist): 2797 """Subtract a list from the current int (in place). 2798 2799 It is assured that (len(list) = len(self.int) and list < self.int) or 2800 len(list) = len(self.int)-1 2801 (i.e. that int(join(list)) < int(join(self.int))) 2802 """ 2803 2804 selfint = self.int 2805 selfint.reverse() 2806 alist.reverse() 2807 2808 carry = 0 2809 for x in xrange(len(alist)): 2810 selfint[x] -= alist[x] + carry 2811 if selfint[x] < 0: 2812 carry = 1 2813 selfint[x] += 10 2814 else: 2815 carry = 0 2816 if carry: 2817 selfint[x+1] -= 1 2818 last = len(selfint)-1 2819 while len(selfint) > 1 and selfint[last] == 0: 2820 last -= 1 2821 if last == 0: 2822 break 2823 selfint[last+1:]=[] 2824 selfint.reverse() 2825 alist.reverse() 2826 return 2827 2828 2829def _normalize(op1, op2, shouldround = 0, prec = 0): 2830 """Normalizes op1, op2 to have the same exp and length of coefficient. 2831 2832 Done during addition. 2833 """ 2834 # Yes, the exponent is a long, but the difference between exponents 2835 # must be an int-- otherwise you'd get a big memory problem. 2836 numdigits = int(op1.exp - op2.exp) 2837 if numdigits < 0: 2838 numdigits = -numdigits 2839 tmp = op2 2840 other = op1 2841 else: 2842 tmp = op1 2843 other = op2 2844 2845 if shouldround and numdigits > len(other.int) + prec + 1 -len(tmp.int): 2846 # If the difference in adjusted exps is > prec+1, we know 2847 # other is insignificant, so might as well put a 1 after the precision. 2848 # (since this is only for addition.) Also stops MemoryErrors. 2849 2850 extend = prec + 2 -len(tmp.int) 2851 if extend <= 0: 2852 extend = 1 2853 tmp.int.extend([0]*extend) 2854 tmp.exp -= extend 2855 other.int[:] = [0]*(len(tmp.int)-1)+[1] 2856 other.exp = tmp.exp 2857 return op1, op2 2858 2859 tmp.int.extend([0] * numdigits) 2860 tmp.exp = tmp.exp - numdigits 2861 numdigits = len(op1.int) - len(op2.int) 2862 # numdigits != 0 => They have the same exponent, but not the same length 2863 # of the coefficient. 2864 if numdigits < 0: 2865 numdigits = -numdigits 2866 tmp = op1 2867 else: 2868 tmp = op2 2869 tmp.int[0:0] = [0] * numdigits 2870 return op1, op2 2871 2872def _adjust_coefficients(op1, op2): 2873 """Adjust op1, op2 so that op2.int+[0] > op1.int >= op2.int. 2874 2875 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp. 2876 2877 Used on _WorkRep instances during division. 2878 """ 2879 adjust = 0 2880 #If op1 is smaller, get it to same size 2881 if len(op2.int) > len(op1.int): 2882 diff = len(op2.int) - len(op1.int) 2883 op1.int.extend([0]*diff) 2884 op1.exp -= diff 2885 adjust = diff 2886 2887 #Same length, wrong order 2888 if len(op1.int) == len(op2.int) and op1.int < op2.int: 2889 op1.int.append(0) 2890 op1.exp -= 1 2891 adjust+= 1 2892 return op1, op2, adjust 2893 2894 if len(op1.int) > len(op2.int) + 1: 2895 diff = len(op1.int) - len(op2.int) - 1 2896 op2.int.extend([0]*diff) 2897 op2.exp -= diff 2898 adjust -= diff 2899 2900 if len(op1.int) == len(op2.int)+1 and op1.int > op2.int: 2901 2902 op2.int.append(0) 2903 op2.exp -= 1 2904 adjust -= 1 2905 return op1, op2, adjust 2906 2907##### Helper Functions ######################################## 2908 2909_infinity_map = { 2910 'inf' : 1, 2911 'infinity' : 1, 2912 '+inf' : 1, 2913 '+infinity' : 1, 2914 '-inf' : -1, 2915 '-infinity' : -1 2916} 2917 2918def _isinfinity(num): 2919 """Determines whether a string or float is infinity. 2920 2921 +1 for negative infinity; 0 for finite ; +1 for positive infinity 2922 """ 2923 num = str(num).lower() 2924 return _infinity_map.get(num, 0) 2925 2926def _isnan(num): 2927 """Determines whether a string or float is NaN 2928 2929 (1, sign, diagnostic info as string) => NaN 2930 (2, sign, diagnostic info as string) => sNaN 2931 0 => not a NaN 2932 """ 2933 num = str(num).lower() 2934 if not num: 2935 return 0 2936 2937 #get the sign, get rid of trailing [+-] 2938 sign = 0 2939 if num[0] == '+': 2940 num = num[1:] 2941 elif num[0] == '-': #elif avoids '+-nan' 2942 num = num[1:] 2943 sign = 1 2944 2945 if num.startswith('nan'): 2946 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info 2947 return 0 2948 return (1, sign, num[3:].lstrip('0')) 2949 if num.startswith('snan'): 2950 if len(num) > 4 and not num[4:].isdigit(): 2951 return 0 2952 return (2, sign, num[4:].lstrip('0')) 2953 return 0 2954 2955 2956##### Setup Specific Contexts ################################ 2957 2958# The default context prototype used by Context() 2959# Is mutable, so than new contexts can have different default values 2960 2961_default_traps = dict.fromkeys(Signals, 0) 2962_default_traps.update({DivisionByZero:1, Overflow:1, InvalidOperation:1}) 2963 2964DefaultContext = Context( 2965 prec=28, rounding=ROUND_HALF_EVEN, 2966 trap_enablers=_default_traps, 2967 flags=None, 2968 _rounding_decision=ALWAYS_ROUND, 2969 Emax=DEFAULT_MAX_EXPONENT, 2970 Emin=DEFAULT_MIN_EXPONENT, 2971 capitals=1 2972) 2973 2974# Pre-made alternate contexts offered by the specification 2975# Don't change these; the user should be able to select these 2976# contexts and be able to reproduce results from other implementations 2977# of the spec. 2978 2979_basic_traps = dict.fromkeys(Signals, 1) 2980_basic_traps.update({Inexact:0, Rounded:0, Subnormal:0}) 2981 2982BasicContext = Context( 2983 prec=9, rounding=ROUND_HALF_UP, 2984 trap_enablers=_basic_traps, 2985 flags=None, 2986 _rounding_decision=ALWAYS_ROUND, 2987) 2988 2989ExtendedContext = Context( 2990 prec=9, rounding=ROUND_HALF_EVEN, 2991 trap_enablers=dict.fromkeys(Signals, 0), 2992 flags=None, 2993 _rounding_decision=ALWAYS_ROUND, 2994) 2995 2996 2997##### Useful Constants (internal use only) #################### 2998 2999#Reusable defaults 3000Inf = Decimal('Inf') 3001negInf = Decimal('-Inf') 3002 3003#Infsign[sign] is infinity w/ that sign 3004Infsign = (Inf, negInf) 3005 3006NaN = Decimal('NaN') 3007 3008 3009##### crud for parsing strings ################################# 3010import re 3011 3012# There's an optional sign at the start, and an optional exponent 3013# at the end. The exponent has an optional sign and at least one 3014# digit. In between, must have either at least one digit followed 3015# by an optional fraction, or a decimal point followed by at least 3016# one digit. Yuck. 3017 3018_parser = re.compile(r""" 3019# \s* 3020 (?P<sign>[-+])? 3021 ( 3022 (?P<int>\d+) (\. (?P<frac>\d*))? 3023 | 3024 \. (?P<onlyfrac>\d+) 3025 ) 3026 ([eE](?P<exp>[-+]? \d+))? 3027# \s* 3028 $ 3029""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces. 3030 3031del re 3032 3033# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly 3034 3035def _string2exact(s): 3036 m = _parser(s) 3037 if m is None: 3038 raise ValueError("invalid literal for Decimal: %r" % s) 3039 3040 if m.group('sign') == "-": 3041 sign = 1 3042 else: 3043 sign = 0 3044 3045 exp = m.group('exp') 3046 if exp is None: 3047 exp = 0 3048 else: 3049 exp = int(exp) 3050 3051 intpart = m.group('int') 3052 if intpart is None: 3053 intpart = "" 3054 fracpart = m.group('onlyfrac') 3055 else: 3056 fracpart = m.group('frac') 3057 if fracpart is None: 3058 fracpart = "" 3059 3060 exp -= len(fracpart) 3061 3062 mantissa = intpart + fracpart 3063 tmp = map(int, mantissa) 3064 backup = tmp 3065 while tmp and tmp[0] == 0: 3066 del tmp[0] 3067 3068 # It's a zero 3069 if not tmp: 3070 if backup: 3071 return (sign, tuple(backup), exp) 3072 return (sign, (0,), exp) 3073 mantissa = tuple(tmp) 3074 3075 return (sign, mantissa, exp) 3076 3077 3078if __name__ == '__main__': 3079 import doctest, sys 3080 doctest.testmod(sys.modules[__name__]) 3081