source: trunk/essentials/dev-lang/python/Lib/decimal.py@ 3298

Last change on this file since 3298 was 3225, checked in by bird, 19 years ago

Python 2.5

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