1 # Copyright (c) 2004 Python Software Foundation.
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>
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.
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.
21 This is a Py2.3 implementation of decimal floating point arithmetic based on
22 the General Decimal Arithmetic Specification:
24 www2.hursley.ibm.com/decimal/decarith.html
26 and IEEE standard 854-1987:
28 www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html
30 Decimal floating point has finite precision with arbitrarily large bounds.
32 The purpose of the module is to support arithmetic using familiar
33 "schoolhouse" rules and to avoid the some of tricky representation
34 issues associated with binary floating point. The package is especially
35 useful for financial applications or for contexts where users have
36 expectations that are at odds with binary floating point (for instance,
37 in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead
38 of the expected Decimal("0.00") returned by decimal floating point).
40 Here are some examples of using the decimal module:
42 >>> from decimal import *
43 >>> setcontext(ExtendedContext)
52 >>> Decimal("123.45e12345678901234567890")
53 Decimal("1.2345E+12345678901234567892")
54 >>> Decimal("1.33") + Decimal("1.27")
56 >>> Decimal("12.34") + Decimal("3.87") - Decimal("18.41")
59 >>> print dig / Decimal(3)
61 >>> getcontext().prec = 18
62 >>> print dig / Decimal(3)
66 >>> print Decimal(3).sqrt()
68 >>> print Decimal(3) ** 123
69 4.85192780976896427E+58
70 >>> inf = Decimal(1) / Decimal(0)
73 >>> neginf = Decimal(-1) / Decimal(0)
76 >>> print neginf + inf
78 >>> print neginf * inf
82 >>> getcontext().traps[DivisionByZero] = 1
84 Traceback (most recent call last):
90 >>> c.traps[InvalidOperation] = 0
91 >>> print c.flags[InvalidOperation]
93 >>> c.divide(Decimal(0), Decimal(0))
95 >>> c.traps[InvalidOperation] = 1
96 >>> print c.flags[InvalidOperation]
98 >>> c.flags[InvalidOperation] = 0
99 >>> print c.flags[InvalidOperation]
101 >>> print c.divide(Decimal(0), Decimal(0))
102 Traceback (most recent call last):
106 InvalidOperation: 0 / 0
107 >>> print c.flags[InvalidOperation]
109 >>> c.flags[InvalidOperation] = 0
110 >>> c.traps[InvalidOperation] = 0
111 >>> print c.divide(Decimal(0), Decimal(0))
113 >>> print c.flags[InvalidOperation]
120 'Decimal', 'Context',
123 'DefaultContext', 'BasicContext', 'ExtendedContext',
126 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
127 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
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',
133 # Functions for manipulating contexts
134 'setcontext', 'getcontext'
140 ROUND_DOWN
= 'ROUND_DOWN'
141 ROUND_HALF_UP
= 'ROUND_HALF_UP'
142 ROUND_HALF_EVEN
= 'ROUND_HALF_EVEN'
143 ROUND_CEILING
= 'ROUND_CEILING'
144 ROUND_FLOOR
= 'ROUND_FLOOR'
145 ROUND_UP
= 'ROUND_UP'
146 ROUND_HALF_DOWN
= 'ROUND_HALF_DOWN'
148 #Rounding decision (not part of the public API)
149 NEVER_ROUND
= 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY
150 ALWAYS_ROUND
= 'ALWAYS_ROUND' # Every operation rounds at end.
154 class DecimalException(ArithmeticError):
155 """Base exception class.
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
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).)
170 To define a new exception, it should be sufficient to have it derive
171 from DecimalException.
173 def handle(self
, context
, *args
):
177 class Clamped(DecimalException
):
178 """Exponent of a 0 changed to fit bounds.
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").
190 class InvalidOperation(DecimalException
):
191 """An invalid operation was performed.
193 Various bad things cause this:
195 Something creates a signaling NaN
201 x._rescale( non-integer )
206 An operand is invalid
208 def handle(self
, context
, *args
):
210 if args
[0] == 1: #sNaN, must drop 's' but keep diagnostics
211 return Decimal( (args
[1]._sign
, args
[1]._int
, 'n') )
214 class ConversionSyntax(InvalidOperation
):
215 """Trying to convert badly formed string.
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].
222 def handle(self
, context
, *args
):
223 return (0, (0,), 'n') #Passed to something which uses a tuple.
225 class DivisionByZero(DecimalException
, ZeroDivisionError):
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
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
238 def handle(self
, context
, sign
, double
= None, *args
):
239 if double
is not None:
240 return (Infsign
[sign
],)*2
243 class DivisionImpossible(InvalidOperation
):
244 """Cannot perform the division adequately.
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].
251 def handle(self
, context
, *args
):
254 class DivisionUndefined(InvalidOperation
, ZeroDivisionError):
255 """Undefined result of division.
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].
262 def handle(self
, context
, tup
=None, *args
):
264 return (NaN
, NaN
) #for 0 %0, 0 // 0
267 class Inexact(DecimalException
):
268 """Had to round, losing information.
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.
275 The inexact signal may be tested (or trapped) to determine if a given
276 operation (or sequence of operations) was inexact.
280 class InvalidContext(InvalidOperation
):
281 """Invalid context. Unknown rounding, for example.
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].
291 def handle(self
, context
, *args
):
294 class Rounded(DecimalException
):
295 """Number got rounded (not necessarily changed during rounding).
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.
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.
307 class Subnormal(DecimalException
):
308 """Exponent < Emin before rounding.
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.
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.
319 class Overflow(Inexact
, Rounded
):
320 """Numerical overflow.
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).
327 The result depends on the rounding mode:
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
341 def handle(self
, context
, sign
, *args
):
342 if context
.rounding
in (ROUND_HALF_UP
, ROUND_HALF_EVEN
,
343 ROUND_HALF_DOWN
, ROUND_UP
):
346 if context
.rounding
== ROUND_CEILING
:
348 return Decimal((sign
, (9,)*context
.prec
,
349 context
.Emax
-context
.prec
+1))
351 if context
.rounding
== ROUND_FLOOR
:
353 return Decimal( (sign
, (9,)*context
.prec
,
354 context
.Emax
-context
.prec
+1))
357 class Underflow(Inexact
, Rounded
, Subnormal
):
358 """Numerical underflow with result rounded to 0.
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.
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.
369 In all cases, Inexact, Rounded, and Subnormal will also be raised.
372 # List of public traps and flags
373 _signals
= [Clamped
, DivisionByZero
, Inexact
, Overflow
, Rounded
,
374 Underflow
, InvalidOperation
, Subnormal
]
376 # Map conditions (per the spec) to signals
377 _condition_map
= {ConversionSyntax
:InvalidOperation
,
378 DivisionImpossible
:InvalidOperation
,
379 DivisionUndefined
:InvalidOperation
,
380 InvalidContext
:InvalidOperation
}
382 ##### Context Functions #######################################
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.
393 # Python was compiled without threads; create a mock object instead
396 def local(self
, sys
=sys
):
397 return sys
.modules
[__name__
]
398 threading
= MockThreading()
399 del sys
, MockThreading
404 except AttributeError:
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
__
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
419 """Returns this thread's context.
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.
426 return threading
.currentThread().__decimal
_context
__
427 except AttributeError:
429 threading
.currentThread().__decimal
_context
__ = context
434 local
= threading
.local()
435 if hasattr(local
, '__decimal_context__'):
436 del local
.__decimal
_context
__
438 def getcontext(_local
=local
):
439 """Returns this thread's context.
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.
446 return _local
.__decimal
_context
__
447 except AttributeError:
449 _local
.__decimal
_context
__ = context
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
459 del threading
, local
# Don't contaminate the namespace
462 ##### Decimal class ###########################################
464 class Decimal(object):
465 """Floating point class for decimal arithmetic."""
467 __slots__
= ('_exp','_int','_sign', '_is_special')
468 # Generally, the value of the Decimal instance is given by
469 # (-1)**_sign * _int * 10**_exp
470 # Special values are signified by _is_special == True
472 # We're immutable, so use __new__ not __init__
473 def __new__(cls
, value
="0", context
=None):
474 """Create a decimal point instance.
476 >>> Decimal('3.14') # string input
478 >>> Decimal((0, (3, 1, 4), -2)) # tuple input (sign, digit_tuple, exponent)
480 >>> Decimal(314) # int or long
482 >>> Decimal(Decimal(314)) # another decimal instance
486 self
= object.__new
__(cls
)
487 self
._is
_special
= False
489 # From an internal working value
490 if isinstance(value
, _WorkRep
):
491 self
._sign
= value
.sign
492 self
._int
= tuple(map(int, str(value
.int)))
493 self
._exp
= int(value
.exp
)
496 # From another decimal
497 if isinstance(value
, Decimal
):
498 self
._exp
= value
._exp
499 self
._sign
= value
._sign
500 self
._int
= value
._int
501 self
._is
_special
= value
._is
_special
505 if isinstance(value
, (int,long)):
511 self
._int
= tuple(map(int, str(abs(value
))))
514 # tuple/list conversion (possibly from as_tuple())
515 if isinstance(value
, (list,tuple)):
517 raise ValueError, 'Invalid arguments'
518 if value
[0] not in [0,1]:
519 raise ValueError, 'Invalid sign'
520 for digit
in value
[1]:
521 if not isinstance(digit
, (int,long)) or digit
< 0:
522 raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
524 self
._sign
= value
[0]
525 self
._int
= tuple(value
[1])
526 if value
[2] in ('F','n','N'):
528 self
._is
_special
= True
530 self
._exp
= int(value
[2])
533 if isinstance(value
, float):
534 raise TypeError("Cannot convert float to Decimal. " +
535 "First convert the float to a string")
537 # Other argument types may require the context during interpretation
539 context
= getcontext()
542 # REs insist on real strings, so we can too.
543 if isinstance(value
, basestring
):
544 if _isinfinity(value
):
547 self
._is
_special
= True
548 if _isinfinity(value
) == 1:
554 sig
, sign
, diag
= _isnan(value
)
555 self
._is
_special
= True
556 if len(diag
) > context
.prec
: #Diagnostic info too long
557 self
._sign
, self
._int
, self
._exp
= \
558 context
._raise
_error
(ConversionSyntax
)
561 self
._exp
= 'n' #qNaN
563 self
._exp
= 'N' #sNaN
565 self
._int
= tuple(map(int, diag
)) #Diagnostic info
568 self
._sign
, self
._int
, self
._exp
= _string2exact(value
)
570 self
._is
_special
= True
571 self
._sign
, self
._int
, self
._exp
= context
._raise
_error
(ConversionSyntax
)
574 raise TypeError("Cannot convert %r to Decimal" % value
)
577 """Returns whether the number is not actually one.
591 def _isinfinity(self
):
592 """Returns whether the number is infinite
594 0 if finite or not a number
604 def _check_nans(self
, other
= None, context
=None):
605 """Returns whether the number is not actually one.
607 if self, other are sNaN, signal
608 if self, other are NaN return nan
611 Done before operations.
614 self_is_nan
= self
._isnan
()
618 other_is_nan
= other
._isnan
()
620 if self_is_nan
or other_is_nan
:
622 context
= getcontext()
625 return context
._raise
_error
(InvalidOperation
, 'sNaN',
627 if other_is_nan
== 2:
628 return context
._raise
_error
(InvalidOperation
, 'sNaN',
636 def __nonzero__(self
):
637 """Is the number non-zero?
644 return sum(self
._int
) != 0
646 def __cmp__(self
, other
, context
=None):
647 other
= _convert_other(other
)
649 if self
._is
_special
or other
._is
_special
:
650 ans
= self
._check
_nans
(other
, context
)
652 return 1 # Comparison involving NaN's always reports self > other
655 return cmp(self
._isinfinity
(), other
._isinfinity
())
657 if not self
and not other
:
658 return 0 #If both 0, sign comparison isn't certain.
660 #If different signs, neg one is less
661 if other
._sign
< self
._sign
:
663 if self
._sign
< other
._sign
:
666 self_adjusted
= self
.adjusted()
667 other_adjusted
= other
.adjusted()
668 if self_adjusted
== other_adjusted
and \
669 self
._int
+ (0,)*(self
._exp
- other
._exp
) == \
670 other
._int
+ (0,)*(other
._exp
- self
._exp
):
671 return 0 #equal, except in precision. ([0]*(-x) = [])
672 elif self_adjusted
> other_adjusted
and self
._int
[0] != 0:
673 return (-1)**self
._sign
674 elif self_adjusted
< other_adjusted
and other
._int
[0] != 0:
675 return -((-1)**self
._sign
)
677 # Need to round, so make sure we have a valid context
679 context
= getcontext()
681 context
= context
._shallow
_copy
()
682 rounding
= context
._set
_rounding
(ROUND_UP
) #round away from 0
684 flags
= context
._ignore
_all
_flags
()
685 res
= self
.__sub
__(other
, context
=context
)
687 context
._regard
_flags
(*flags
)
689 context
.rounding
= rounding
697 def __eq__(self
, other
):
698 if not isinstance(other
, (Decimal
, int, long)):
700 return self
.__cmp
__(other
) == 0
702 def __ne__(self
, other
):
703 if not isinstance(other
, (Decimal
, int, long)):
705 return self
.__cmp
__(other
) != 0
707 def compare(self
, other
, context
=None):
708 """Compares one to another.
714 Like __cmp__, but returns Decimal instances.
716 other
= _convert_other(other
)
718 #compare(NaN, NaN) = NaN
719 if (self
._is
_special
or other
and other
._is
_special
):
720 ans
= self
._check
_nans
(other
, context
)
724 return Decimal(self
.__cmp
__(other
, context
))
727 """x.__hash__() <==> hash(x)"""
728 # Decimal integers must hash the same as the ints
729 # Non-integer decimals are normalized and hashed as strings
730 # Normalization assures that hast(100E-1) == hash(10)
732 if self
== Decimal(i
):
734 assert self
.__nonzero
__() # '-0' handled by integer case
735 return hash(str(self
.normalize()))
738 """Represents the number as a triple tuple.
740 To show the internals exactly as they are.
742 return (self
._sign
, self
._int
, self
._exp
)
745 """Represents the number as an instance of Decimal."""
746 # Invariant: eval(repr(d)) == d
747 return 'Decimal("%s")' % str(self
)
749 def __str__(self
, eng
= 0, context
=None):
750 """Return string representation of the number in scientific notation.
752 Captures all of the information in the underlying representation.
756 minus
= '-'*self
._sign
757 if self
._int
== (0,):
760 info
= ''.join(map(str, self
._int
))
761 if self
._isnan
() == 2:
762 return minus
+ 'sNaN' + info
763 return minus
+ 'NaN' + info
764 if self
._isinfinity
():
765 minus
= '-'*self
._sign
766 return minus
+ 'Infinity'
769 context
= getcontext()
771 tmp
= map(str, self
._int
)
772 numdigits
= len(self
._int
)
773 leftdigits
= self
._exp
+ numdigits
774 if eng
and not self
: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
775 if self
._exp
< 0 and self
._exp
>= -6: #short, no need for e/E
776 s
= '-'*self
._sign
+ '0.' + '0'*(abs(self
._exp
))
778 #exp is closest mult. of 3 >= self._exp
779 exp
= ((self
._exp
- 1)// 3 + 1) * 3
781 s
= '0.'+'0'*(exp
- self
._exp
)
790 s
+= '+' #0.0e+3, not 0.0e3
792 s
= '-'*self
._sign
+ s
795 dotplace
= (leftdigits
-1)%3+1
796 adjexp
= leftdigits
-1 - (leftdigits
-1)%3
798 adjexp
= leftdigits
-1
802 elif self
._exp
< 0 and adjexp
>= 0:
803 tmp
.insert(leftdigits
, '.')
804 elif self
._exp
< 0 and adjexp
>= -6:
805 tmp
[0:0] = ['0'] * int(-leftdigits
)
808 if numdigits
> dotplace
:
809 tmp
.insert(dotplace
, '.')
810 elif numdigits
< dotplace
:
811 tmp
.extend(['0']*(dotplace
-numdigits
))
813 if not context
.capitals
:
819 tmp
.append(str(adjexp
))
821 while tmp
[0:1] == ['0']:
823 if len(tmp
) == 0 or tmp
[0] == '.' or tmp
[0].lower() == 'e':
830 def to_eng_string(self
, context
=None):
831 """Convert to engineering-type string.
833 Engineering notation has an exponent which is a multiple of 3, so there
834 are up to 3 digits left of the decimal place.
836 Same rules for when in exponential and when as a value as in __str__.
838 return self
.__str
__(eng
=1, context
=context
)
840 def __neg__(self
, context
=None):
841 """Returns a copy with the sign switched.
843 Rounds, if it has reason.
846 ans
= self
._check
_nans
(context
=context
)
851 # -Decimal('0') is Decimal('0'), not Decimal('-0')
859 context
= getcontext()
860 if context
._rounding
_decision
== ALWAYS_ROUND
:
861 return Decimal((sign
, self
._int
, self
._exp
))._fix
(context
)
862 return Decimal( (sign
, self
._int
, self
._exp
))
864 def __pos__(self
, context
=None):
865 """Returns a copy, unless it is a sNaN.
867 Rounds the number (if more then precision digits)
870 ans
= self
._check
_nans
(context
=context
)
880 context
= getcontext()
882 if context
._rounding
_decision
== ALWAYS_ROUND
:
883 ans
= self
._fix
(context
)
889 def __abs__(self
, round=1, context
=None):
890 """Returns the absolute value of self.
892 If the second argument is 0, do not round.
895 ans
= self
._check
_nans
(context
=context
)
901 context
= getcontext()
902 context
= context
._shallow
_copy
()
903 context
._set
_rounding
_decision
(NEVER_ROUND
)
906 ans
= self
.__neg
__(context
=context
)
908 ans
= self
.__pos
__(context
=context
)
912 def __add__(self
, other
, context
=None):
913 """Returns self + other.
915 -INF + INF (or the reverse) cause InvalidOperation errors.
917 other
= _convert_other(other
)
920 context
= getcontext()
922 if self
._is
_special
or other
._is
_special
:
923 ans
= self
._check
_nans
(other
, context
)
927 if self
._isinfinity
():
928 #If both INF, same sign => same as both, opposite => error.
929 if self
._sign
!= other
._sign
and other
._isinfinity
():
930 return context
._raise
_error
(InvalidOperation
, '-INF + INF')
932 if other
._isinfinity
():
933 return Decimal(other
) #Can't both be infinity here
935 shouldround
= context
._rounding
_decision
== ALWAYS_ROUND
937 exp
= min(self
._exp
, other
._exp
)
939 if context
.rounding
== ROUND_FLOOR
and self
._sign
!= other
._sign
:
940 #If the answer is 0, the sign should be negative, in this case.
943 if not self
and not other
:
944 sign
= min(self
._sign
, other
._sign
)
947 return Decimal( (sign
, (0,), exp
))
949 exp
= max(exp
, other
._exp
- context
.prec
-1)
950 ans
= other
._rescale
(exp
, watchexp
=0, context
=context
)
952 ans
= ans
._fix
(context
)
955 exp
= max(exp
, self
._exp
- context
.prec
-1)
956 ans
= self
._rescale
(exp
, watchexp
=0, context
=context
)
958 ans
= ans
._fix
(context
)
962 op2
= _WorkRep(other
)
963 op1
, op2
= _normalize(op1
, op2
, shouldround
, context
.prec
)
966 if op1
.sign
!= op2
.sign
:
968 if op1
.int == op2
.int:
969 if exp
< context
.Etiny():
970 exp
= context
.Etiny()
971 context
._raise
_error
(Clamped
)
972 return Decimal((negativezero
, (0,), exp
))
973 if op1
.int < op2
.int:
975 #OK, now abs(op1) > abs(op2)
978 op1
.sign
, op2
.sign
= op2
.sign
, op1
.sign
981 #So we know the sign, and op1 > 0.
984 op1
.sign
, op2
.sign
= (0, 0)
987 #Now, op1 > abs(op2) > 0
990 result
.int = op1
.int + op2
.int
992 result
.int = op1
.int - op2
.int
995 ans
= Decimal(result
)
997 ans
= ans
._fix
(context
)
1002 def __sub__(self
, other
, context
=None):
1003 """Return self + (-other)"""
1004 other
= _convert_other(other
)
1006 if self
._is
_special
or other
._is
_special
:
1007 ans
= self
._check
_nans
(other
, context
=context
)
1011 # -Decimal(0) = Decimal(0), which we don't want since
1012 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
1013 # so we change the sign directly to a copy
1014 tmp
= Decimal(other
)
1015 tmp
._sign
= 1-tmp
._sign
1017 return self
.__add
__(tmp
, context
=context
)
1019 def __rsub__(self
, other
, context
=None):
1020 """Return other + (-self)"""
1021 other
= _convert_other(other
)
1024 tmp
._sign
= 1 - tmp
._sign
1025 return other
.__add
__(tmp
, context
=context
)
1027 def _increment(self
, round=1, context
=None):
1028 """Special case of add, adding 1eExponent
1030 Since it is common, (rounding, for example) this adds
1031 (sign)*one E self._exp to the number more efficiently than add.
1034 Decimal('5.624e10')._increment() == Decimal('5.625e10')
1036 if self
._is
_special
:
1037 ans
= self
._check
_nans
(context
=context
)
1041 return Decimal(self
) # Must be infinite, and incrementing makes no difference
1046 while L
[spot
] == 10:
1053 ans
= Decimal((self
._sign
, L
, self
._exp
))
1056 context
= getcontext()
1057 if round and context
._rounding
_decision
== ALWAYS_ROUND
:
1058 ans
= ans
._fix
(context
)
1061 def __mul__(self
, other
, context
=None):
1062 """Return self * other.
1064 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1066 other
= _convert_other(other
)
1069 context
= getcontext()
1071 resultsign
= self
._sign ^ other
._sign
1073 if self
._is
_special
or other
._is
_special
:
1074 ans
= self
._check
_nans
(other
, context
)
1078 if self
._isinfinity
():
1080 return context
._raise
_error
(InvalidOperation
, '(+-)INF * 0')
1081 return Infsign
[resultsign
]
1083 if other
._isinfinity
():
1085 return context
._raise
_error
(InvalidOperation
, '0 * (+-)INF')
1086 return Infsign
[resultsign
]
1088 resultexp
= self
._exp
+ other
._exp
1089 shouldround
= context
._rounding
_decision
== ALWAYS_ROUND
1091 # Special case for multiplying by zero
1092 if not self
or not other
:
1093 ans
= Decimal((resultsign
, (0,), resultexp
))
1095 #Fixing in case the exponent is out of bounds
1096 ans
= ans
._fix
(context
)
1099 # Special case for multiplying by power of 10
1100 if self
._int
== (1,):
1101 ans
= Decimal((resultsign
, other
._int
, resultexp
))
1103 ans
= ans
._fix
(context
)
1105 if other
._int
== (1,):
1106 ans
= Decimal((resultsign
, self
._int
, resultexp
))
1108 ans
= ans
._fix
(context
)
1111 op1
= _WorkRep(self
)
1112 op2
= _WorkRep(other
)
1114 ans
= Decimal( (resultsign
, map(int, str(op1
.int * op2
.int)), resultexp
))
1116 ans
= ans
._fix
(context
)
1121 def __div__(self
, other
, context
=None):
1122 """Return self / other."""
1123 return self
._divide
(other
, context
=context
)
1124 __truediv__
= __div__
1126 def _divide(self
, other
, divmod = 0, context
=None):
1127 """Return a / b, to context.prec precision.
1135 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1136 computing the other value are not raised.
1138 other
= _convert_other(other
)
1141 context
= getcontext()
1143 sign
= self
._sign ^ other
._sign
1145 if self
._is
_special
or other
._is
_special
:
1146 ans
= self
._check
_nans
(other
, context
)
1152 if self
._isinfinity
() and other
._isinfinity
():
1154 return (context
._raise
_error
(InvalidOperation
,
1155 '(+-)INF // (+-)INF'),
1156 context
._raise
_error
(InvalidOperation
,
1157 '(+-)INF % (+-)INF'))
1158 return context
._raise
_error
(InvalidOperation
, '(+-)INF/(+-)INF')
1160 if self
._isinfinity
():
1162 return (Infsign
[sign
],
1163 context
._raise
_error
(InvalidOperation
, 'INF % x'))
1165 return (Infsign
[sign
], NaN
)
1167 return (Infsign
[sign
],
1168 context
._raise
_error
(InvalidOperation
, 'INF % x'))
1169 return Infsign
[sign
]
1171 if other
._isinfinity
():
1173 return (Decimal((sign
, (0,), 0)), Decimal(self
))
1174 context
._raise
_error
(Clamped
, 'Division by infinity')
1175 return Decimal((sign
, (0,), context
.Etiny()))
1177 # Special cases for zeroes
1178 if not self
and not other
:
1180 return context
._raise
_error
(DivisionUndefined
, '0 / 0', 1)
1181 return context
._raise
_error
(DivisionUndefined
, '0 / 0')
1185 otherside
= Decimal(self
)
1186 otherside
._exp
= min(self
._exp
, other
._exp
)
1187 return (Decimal((sign
, (0,), 0)), otherside
)
1188 exp
= self
._exp
- other
._exp
1189 if exp
< context
.Etiny():
1190 exp
= context
.Etiny()
1191 context
._raise
_error
(Clamped
, '0e-x / y')
1192 if exp
> context
.Emax
:
1194 context
._raise
_error
(Clamped
, '0e+x / y')
1195 return Decimal( (sign
, (0,), exp
) )
1199 return context
._raise
_error
(DivisionByZero
, 'divmod(x,0)',
1201 return context
._raise
_error
(DivisionByZero
, 'x / 0', sign
)
1203 #OK, so neither = 0, INF or NaN
1205 shouldround
= context
._rounding
_decision
== ALWAYS_ROUND
1207 #If we're dividing into ints, and self < other, stop.
1208 #self.__abs__(0) does not round.
1209 if divmod and (self
.__abs
__(0, context
) < other
.__abs
__(0, context
)):
1211 if divmod == 1 or divmod == 3:
1212 exp
= min(self
._exp
, other
._exp
)
1213 ans2
= self
._rescale
(exp
, context
=context
, watchexp
=0)
1215 ans2
= ans2
._fix(context
)
1216 return (Decimal( (sign
, (0,), 0) ),
1220 #Don't round the mod part, if we don't need it.
1221 return (Decimal( (sign
, (0,), 0) ), Decimal(self
))
1223 op1
= _WorkRep(self
)
1224 op2
= _WorkRep(other
)
1225 op1
, op2
, adjust
= _adjust_coefficients(op1
, op2
)
1226 res
= _WorkRep( (sign
, 0, (op1
.exp
- op2
.exp
)) )
1227 if divmod and res
.exp
> context
.prec
+ 1:
1228 return context
._raise
_error
(DivisionImpossible
)
1230 prec_limit
= 10 ** context
.prec
1232 while op2
.int <= op1
.int:
1235 if res
.exp
== 0 and divmod:
1236 if res
.int >= prec_limit
and shouldround
:
1237 return context
._raise
_error
(DivisionImpossible
)
1238 otherside
= Decimal(op1
)
1239 frozen
= context
._ignore
_all
_flags
()
1241 exp
= min(self
._exp
, other
._exp
)
1242 otherside
= otherside
._rescale
(exp
, context
=context
, watchexp
=0)
1243 context
._regard
_flags
(*frozen
)
1245 otherside
= otherside
._fix
(context
)
1246 return (Decimal(res
), otherside
)
1248 if op1
.int == 0 and adjust
>= 0 and not divmod:
1250 if res
.int >= prec_limit
and shouldround
:
1252 return context
._raise
_error
(DivisionImpossible
)
1254 # Really, the answer is a bit higher, so adding a one to
1255 # the end will make sure the rounding is right.
1268 if res
.exp
== 0 and divmod and op2
.int > op1
.int:
1269 #Solves an error in precision. Same as a previous block.
1271 if res
.int >= prec_limit
and shouldround
:
1272 return context
._raise
_error
(DivisionImpossible
)
1273 otherside
= Decimal(op1
)
1274 frozen
= context
._ignore
_all
_flags
()
1276 exp
= min(self
._exp
, other
._exp
)
1277 otherside
= otherside
._rescale
(exp
, context
=context
)
1279 context
._regard
_flags
(*frozen
)
1281 return (Decimal(res
), otherside
)
1285 ans
= ans
._fix
(context
)
1288 def __rdiv__(self
, other
, context
=None):
1289 """Swaps self/other and returns __div__."""
1290 other
= _convert_other(other
)
1291 return other
.__div
__(self
, context
=context
)
1292 __rtruediv__
= __rdiv__
1294 def __divmod__(self
, other
, context
=None):
1296 (self // other, self % other)
1298 return self
._divide
(other
, 1, context
)
1300 def __rdivmod__(self
, other
, context
=None):
1301 """Swaps self/other and returns __divmod__."""
1302 other
= _convert_other(other
)
1303 return other
.__divmod
__(self
, context
=context
)
1305 def __mod__(self
, other
, context
=None):
1309 other
= _convert_other(other
)
1311 if self
._is
_special
or other
._is
_special
:
1312 ans
= self
._check
_nans
(other
, context
)
1316 if self
and not other
:
1317 return context
._raise
_error
(InvalidOperation
, 'x % 0')
1319 return self
._divide
(other
, 3, context
)[1]
1321 def __rmod__(self
, other
, context
=None):
1322 """Swaps self/other and returns __mod__."""
1323 other
= _convert_other(other
)
1324 return other
.__mod
__(self
, context
=context
)
1326 def remainder_near(self
, other
, context
=None):
1328 Remainder nearest to 0- abs(remainder-near) <= other/2
1330 other
= _convert_other(other
)
1332 if self
._is
_special
or other
._is
_special
:
1333 ans
= self
._check
_nans
(other
, context
)
1336 if self
and not other
:
1337 return context
._raise
_error
(InvalidOperation
, 'x % 0')
1340 context
= getcontext()
1341 # If DivisionImpossible causes an error, do not leave Rounded/Inexact
1342 # ignored in the calling function.
1343 context
= context
._shallow
_copy
()
1344 flags
= context
._ignore
_flags
(Rounded
, Inexact
)
1345 #keep DivisionImpossible flags
1346 (side
, r
) = self
.__divmod
__(other
, context
=context
)
1349 context
._regard
_flags
(*flags
)
1352 context
= context
._shallow
_copy
()
1353 rounding
= context
._set
_rounding
_decision
(NEVER_ROUND
)
1356 comparison
= other
.__div
__(Decimal(-2), context
=context
)
1358 comparison
= other
.__div
__(Decimal(2), context
=context
)
1360 context
._set
_rounding
_decision
(rounding
)
1361 context
._regard
_flags
(*flags
)
1363 s1
, s2
= r
._sign
, comparison
._sign
1364 r
._sign
, comparison
._sign
= 0, 0
1367 r
._sign
, comparison
._sign
= s1
, s2
1369 self
.__divmod
__(other
, context
=context
)
1370 return r
._fix
(context
)
1371 r
._sign
, comparison
._sign
= s1
, s2
1373 rounding
= context
._set
_rounding
_decision
(NEVER_ROUND
)
1375 (side
, r
) = self
.__divmod
__(other
, context
=context
)
1376 context
._set
_rounding
_decision
(rounding
)
1380 decrease
= not side
._iseven
()
1381 rounding
= context
._set
_rounding
_decision
(NEVER_ROUND
)
1382 side
= side
.__abs
__(context
=context
)
1383 context
._set
_rounding
_decision
(rounding
)
1385 s1
, s2
= r
._sign
, comparison
._sign
1386 r
._sign
, comparison
._sign
= 0, 0
1387 if r
> comparison
or decrease
and r
== comparison
:
1388 r
._sign
, comparison
._sign
= s1
, s2
1390 if len(side
.__add
__(Decimal(1), context
=context
)._int
) >= context
.prec
:
1392 return context
._raise
_error
(DivisionImpossible
)[1]
1394 if self
._sign
== other
._sign
:
1395 r
= r
.__sub
__(other
, context
=context
)
1397 r
= r
.__add
__(other
, context
=context
)
1399 r
._sign
, comparison
._sign
= s1
, s2
1401 return r
._fix
(context
)
1403 def __floordiv__(self
, other
, context
=None):
1405 return self
._divide
(other
, 2, context
)[0]
1407 def __rfloordiv__(self
, other
, context
=None):
1408 """Swaps self/other and returns __floordiv__."""
1409 other
= _convert_other(other
)
1410 return other
.__floordiv
__(self
, context
=context
)
1412 def __float__(self
):
1413 """Float representation."""
1414 return float(str(self
))
1417 """Converts self to a int, truncating if necessary."""
1418 if self
._is
_special
:
1420 context
= getcontext()
1421 return context
._raise
_error
(InvalidContext
)
1422 elif self
._isinfinity
():
1423 raise OverflowError, "Cannot convert infinity to long"
1425 s
= ''.join(map(str, self
._int
)) + '0'*self
._exp
1427 s
= ''.join(map(str, self
._int
))[:self
._exp
]
1430 sign
= '-'*self
._sign
1431 return int(sign
+ s
)
1434 """Converts to a long.
1436 Equivalent to long(int(self))
1438 return long(self
.__int
__())
1440 def _fix(self
, context
):
1441 """Round if it is necessary to keep self within prec precision.
1443 Rounds and fixes the exponent. Does not raise on a sNaN.
1446 self - Decimal instance
1447 context - context used.
1449 if self
._is
_special
:
1452 context
= getcontext()
1454 ans
= self
._fixexponents
(context
)
1455 if len(ans
._int
) > prec
:
1456 ans
= ans
._round
(prec
, context
=context
)
1457 ans
= ans
._fixexponents
(context
)
1460 def _fixexponents(self
, context
):
1461 """Fix the exponents and return a copy with the exponent in bounds.
1462 Only call if known to not be a special value.
1464 folddown
= context
._clamp
1467 ans_adjusted
= ans
.adjusted()
1468 if ans_adjusted
< Emin
:
1469 Etiny
= context
.Etiny()
1470 if ans
._exp
< Etiny
:
1474 context
._raise
_error
(Clamped
)
1476 ans
= ans
._rescale
(Etiny
, context
=context
)
1477 #It isn't zero, and exp < Emin => subnormal
1478 context
._raise
_error
(Subnormal
)
1479 if context
.flags
[Inexact
]:
1480 context
._raise
_error
(Underflow
)
1483 #Only raise subnormal if non-zero.
1484 context
._raise
_error
(Subnormal
)
1486 Etop
= context
.Etop()
1487 if folddown
and ans
._exp
> Etop
:
1488 context
._raise
_error
(Clamped
)
1489 ans
= ans
._rescale
(Etop
, context
=context
)
1492 if ans_adjusted
> Emax
:
1496 context
._raise
_error
(Clamped
)
1498 context
._raise
_error
(Inexact
)
1499 context
._raise
_error
(Rounded
)
1500 return context
._raise
_error
(Overflow
, 'above Emax', ans
._sign
)
1503 def _round(self
, prec
=None, rounding
=None, context
=None):
1504 """Returns a rounded version of self.
1506 You can specify the precision or rounding method. Otherwise, the
1507 context determines it.
1510 if self
._is
_special
:
1511 ans
= self
._check
_nans
(context
=context
)
1515 if self
._isinfinity
():
1516 return Decimal(self
)
1519 context
= getcontext()
1521 if rounding
is None:
1522 rounding
= context
.rounding
1529 exp
= len(self
._int
) - prec
+ self
._exp
1532 exp
= len(self
._int
) + self
._exp
- prec
1533 ans
= Decimal((self
._sign
, dig
, exp
))
1534 context
._raise
_error
(Rounded
)
1538 temp
= Decimal(self
)
1539 temp
._int
= (0,)+temp
._int
1542 exp
= self
._exp
+ len(self
._int
) - prec
- 1
1543 temp
= Decimal( (self
._sign
, (0, 1), exp
))
1546 temp
= Decimal(self
)
1548 numdigits
= len(temp
._int
)
1549 if prec
== numdigits
:
1552 # See if we need to extend precision
1553 expdiff
= prec
- numdigits
1555 tmp
= list(temp
._int
)
1556 tmp
.extend([0] * expdiff
)
1557 ans
= Decimal( (temp
._sign
, tmp
, temp
._exp
- expdiff
))
1560 #OK, but maybe all the lost digits are 0.
1561 lostdigits
= self
._int
[expdiff
:]
1562 if lostdigits
== (0,) * len(lostdigits
):
1563 ans
= Decimal( (temp
._sign
, temp
._int
[:prec
], temp
._exp
- expdiff
))
1564 #Rounded, but not Inexact
1565 context
._raise
_error
(Rounded
)
1568 # Okay, let's round and lose data
1570 this_function
= getattr(temp
, self
._pick
_rounding
_function
[rounding
])
1571 #Now we've got the rounding function
1573 if prec
!= context
.prec
:
1574 context
= context
._shallow
_copy
()
1576 ans
= this_function(prec
, expdiff
, context
)
1577 context
._raise
_error
(Rounded
)
1578 context
._raise
_error
(Inexact
, 'Changed in rounding')
1582 _pick_rounding_function
= {}
1584 def _round_down(self
, prec
, expdiff
, context
):
1585 """Also known as round-towards-0, truncate."""
1586 return Decimal( (self
._sign
, self
._int
[:prec
], self
._exp
- expdiff
) )
1588 def _round_half_up(self
, prec
, expdiff
, context
, tmp
= None):
1589 """Rounds 5 up (away from 0)"""
1592 tmp
= Decimal( (self
._sign
,self
._int
[:prec
], self
._exp
- expdiff
))
1593 if self
._int
[prec
] >= 5:
1594 tmp
= tmp
._increment
(round=0, context
=context
)
1595 if len(tmp
._int
) > prec
:
1596 return Decimal( (tmp
._sign
, tmp
._int
[:-1], tmp
._exp
+ 1))
1599 def _round_half_even(self
, prec
, expdiff
, context
):
1600 """Round 5 to even, rest to nearest."""
1602 tmp
= Decimal( (self
._sign
, self
._int
[:prec
], self
._exp
- expdiff
))
1603 half
= (self
._int
[prec
] == 5)
1605 for digit
in self
._int
[prec
+1:]:
1610 if self
._int
[prec
-1] & 1 == 0:
1612 return self
._round
_half
_up
(prec
, expdiff
, context
, tmp
)
1614 def _round_half_down(self
, prec
, expdiff
, context
):
1617 tmp
= Decimal( (self
._sign
, self
._int
[:prec
], self
._exp
- expdiff
))
1618 half
= (self
._int
[prec
] == 5)
1620 for digit
in self
._int
[prec
+1:]:
1626 return self
._round
_half
_up
(prec
, expdiff
, context
, tmp
)
1628 def _round_up(self
, prec
, expdiff
, context
):
1629 """Rounds away from 0."""
1630 tmp
= Decimal( (self
._sign
, self
._int
[:prec
], self
._exp
- expdiff
) )
1631 for digit
in self
._int
[prec
:]:
1633 tmp
= tmp
._increment
(round=1, context
=context
)
1634 if len(tmp
._int
) > prec
:
1635 return Decimal( (tmp
._sign
, tmp
._int
[:-1], tmp
._exp
+ 1))
1640 def _round_ceiling(self
, prec
, expdiff
, context
):
1641 """Rounds up (not away from 0 if negative.)"""
1643 return self
._round
_down
(prec
, expdiff
, context
)
1645 return self
._round
_up
(prec
, expdiff
, context
)
1647 def _round_floor(self
, prec
, expdiff
, context
):
1648 """Rounds down (not towards 0 if negative)"""
1650 return self
._round
_down
(prec
, expdiff
, context
)
1652 return self
._round
_up
(prec
, expdiff
, context
)
1654 def __pow__(self
, n
, modulo
= None, context
=None):
1655 """Return self ** n (mod modulo)
1657 If modulo is None (default), don't take it mod modulo.
1659 n
= _convert_other(n
)
1662 context
= getcontext()
1664 if self
._is
_special
or n
._is
_special
or n
.adjusted() > 8:
1665 #Because the spot << doesn't work with really big exponents
1666 if n
._isinfinity
() or n
.adjusted() > 8:
1667 return context
._raise
_error
(InvalidOperation
, 'x ** INF')
1669 ans
= self
._check
_nans
(n
, context
)
1673 if not n
._isinteger
():
1674 return context
._raise
_error
(InvalidOperation
, 'x ** (non-integer)')
1676 if not self
and not n
:
1677 return context
._raise
_error
(InvalidOperation
, '0 ** 0')
1682 if self
== Decimal(1):
1685 sign
= self
._sign
and not n
._iseven
()
1688 if self
._isinfinity
():
1690 return context
._raise
_error
(InvalidOperation
, 'INF % x')
1692 return Infsign
[sign
]
1693 return Decimal( (sign
, (0,), 0) )
1695 #with ludicrously large exponent, just raise an overflow and return inf.
1696 if not modulo
and n
> 0 and (self
._exp
+ len(self
._int
) - 1) * n
> context
.Emax \
1699 tmp
= Decimal('inf')
1701 context
._raise
_error
(Rounded
)
1702 context
._raise
_error
(Inexact
)
1703 context
._raise
_error
(Overflow
, 'Big power', sign
)
1706 elength
= len(str(abs(n
)))
1707 firstprec
= context
.prec
1709 if not modulo
and firstprec
+ elength
+ 1 > DefaultContext
.Emax
:
1710 return context
._raise
_error
(Overflow
, 'Too much precision.', sign
)
1714 context
= context
._shallow
_copy
()
1715 context
.prec
= firstprec
+ elength
+ 1
1717 #n is a long now, not Decimal instance
1719 mul
= Decimal(1).__div
__(mul
, context
=context
)
1726 #Spot is the highest power of 2 less than n
1728 val
= val
.__mul
__(val
, context
=context
)
1729 if val
._isinfinity
():
1733 val
= val
.__mul
__(mul
, context
=context
)
1734 if modulo
is not None:
1735 val
= val
.__mod
__(modulo
, context
=context
)
1737 context
.prec
= firstprec
1739 if context
._rounding
_decision
== ALWAYS_ROUND
:
1740 return val
._fix
(context
)
1743 def __rpow__(self
, other
, context
=None):
1744 """Swaps self/other and returns __pow__."""
1745 other
= _convert_other(other
)
1746 return other
.__pow
__(self
, context
=context
)
1748 def normalize(self
, context
=None):
1749 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
1751 if self
._is
_special
:
1752 ans
= self
._check
_nans
(context
=context
)
1756 dup
= self
._fix
(context
)
1757 if dup
._isinfinity
():
1761 return Decimal( (dup
._sign
, (0,), 0) )
1764 while dup
._int
[end
-1] == 0:
1767 return Decimal( (dup
._sign
, dup
._int
[:end
], exp
) )
1770 def quantize(self
, exp
, rounding
=None, context
=None, watchexp
=1):
1771 """Quantize self so its exponent is the same as that of exp.
1773 Similar to self._rescale(exp._exp) but with error checking.
1775 if self
._is
_special
or exp
._is
_special
:
1776 ans
= self
._check
_nans
(exp
, context
)
1780 if exp
._isinfinity
() or self
._isinfinity
():
1781 if exp
._isinfinity
() and self
._isinfinity
():
1782 return self
#if both are inf, it is OK
1784 context
= getcontext()
1785 return context
._raise
_error
(InvalidOperation
,
1786 'quantize with one INF')
1787 return self
._rescale
(exp
._exp
, rounding
, context
, watchexp
)
1789 def same_quantum(self
, other
):
1790 """Test whether self and other have the same exponent.
1792 same as self._exp == other._exp, except NaN == sNaN
1794 if self
._is
_special
or other
._is
_special
:
1795 if self
._isnan
() or other
._isnan
():
1796 return self
._isnan
() and other
._isnan
() and True
1797 if self
._isinfinity
() or other
._isinfinity
():
1798 return self
._isinfinity
() and other
._isinfinity
() and True
1799 return self
._exp
== other
._exp
1801 def _rescale(self
, exp
, rounding
=None, context
=None, watchexp
=1):
1802 """Rescales so that the exponent is exp.
1804 exp = exp to scale to (an integer)
1805 rounding = rounding version
1806 watchexp: if set (default) an error is returned if exp is greater
1807 than Emax or less than Etiny.
1810 context
= getcontext()
1812 if self
._is
_special
:
1813 if self
._isinfinity
():
1814 return context
._raise
_error
(InvalidOperation
, 'rescale with an INF')
1816 ans
= self
._check
_nans
(context
=context
)
1820 if watchexp
and (context
.Emax
< exp
or context
.Etiny() > exp
):
1821 return context
._raise
_error
(InvalidOperation
, 'rescale(a, INF)')
1829 diff
= self
._exp
- exp
1830 digits
= len(self
._int
) + diff
1832 if watchexp
and digits
> context
.prec
:
1833 return context
._raise
_error
(InvalidOperation
, 'Rescale > prec')
1836 tmp
._int
= (0,) + tmp
._int
1840 tmp
._exp
= -digits
+ tmp
._exp
1843 tmp
= tmp
._round
(digits
, rounding
, context
=context
)
1845 if tmp
._int
[0] == 0 and len(tmp
._int
) > 1:
1846 tmp
._int
= tmp
._int
[1:]
1849 tmp_adjusted
= tmp
.adjusted()
1850 if tmp
and tmp_adjusted
< context
.Emin
:
1851 context
._raise
_error
(Subnormal
)
1852 elif tmp
and tmp_adjusted
> context
.Emax
:
1853 return context
._raise
_error
(InvalidOperation
, 'rescale(a, INF)')
1856 def to_integral(self
, rounding
=None, context
=None):
1857 """Rounds to the nearest integer, without raising inexact, rounded."""
1858 if self
._is
_special
:
1859 ans
= self
._check
_nans
(context
=context
)
1865 context
= getcontext()
1866 flags
= context
._ignore
_flags
(Rounded
, Inexact
)
1867 ans
= self
._rescale
(0, rounding
, context
=context
)
1868 context
._regard
_flags
(flags
)
1871 def sqrt(self
, context
=None):
1872 """Return the square root of self.
1874 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
1875 Should quadratically approach the right answer.
1877 if self
._is
_special
:
1878 ans
= self
._check
_nans
(context
=context
)
1882 if self
._isinfinity
() and self
._sign
== 0:
1883 return Decimal(self
)
1886 #exponent = self._exp / 2, using round_down.
1888 # exp = (self._exp+1) // 2
1890 exp
= (self
._exp
) // 2
1893 return Decimal( (1, (0,), exp
))
1895 return Decimal( (0, (0,), exp
))
1898 context
= getcontext()
1901 return context
._raise
_error
(InvalidOperation
, 'sqrt(-x), x > 0')
1905 expadd
= tmp
._exp
// 2
1912 context
= context
._shallow
_copy
()
1913 flags
= context
._ignore
_all
_flags
()
1914 firstprec
= context
.prec
1916 if tmp
.adjusted() & 1 == 0:
1917 ans
= Decimal( (0, (8,1,9), tmp
.adjusted() - 2) )
1918 ans
= ans
.__add
__(tmp
.__mul
__(Decimal((0, (2,5,9), -2)),
1919 context
=context
), context
=context
)
1920 ans
._exp
-= 1 + tmp
.adjusted() // 2
1922 ans
= Decimal( (0, (2,5,9), tmp
._exp
+ len(tmp
._int
)- 3) )
1923 ans
= ans
.__add
__(tmp
.__mul
__(Decimal((0, (8,1,9), -3)),
1924 context
=context
), context
=context
)
1925 ans
._exp
-= 1 + tmp
.adjusted() // 2
1927 #ans is now a linear approximation.
1929 Emax
, Emin
= context
.Emax
, context
.Emin
1930 context
.Emax
, context
.Emin
= DefaultContext
.Emax
, DefaultContext
.Emin
1932 half
= Decimal('0.5')
1934 maxp
= firstprec
+ 2
1935 rounding
= context
._set
_rounding
(ROUND_HALF_EVEN
)
1937 context
.prec
= min(2*context
.prec
- 2, maxp
)
1938 ans
= half
.__mul
__(ans
.__add
__(tmp
.__div
__(ans
, context
=context
),
1939 context
=context
), context
=context
)
1940 if context
.prec
== maxp
:
1943 #round to the answer's precision-- the only error can be 1 ulp.
1944 context
.prec
= firstprec
1945 prevexp
= ans
.adjusted()
1946 ans
= ans
._round
(context
=context
)
1948 #Now, check if the other last digits are better.
1949 context
.prec
= firstprec
+ 1
1950 # In case we rounded up another digit and we should actually go lower.
1951 if prevexp
!= ans
.adjusted():
1956 lower
= ans
.__sub
__(Decimal((0, (5,), ans
._exp
-1)), context
=context
)
1957 context
._set
_rounding
(ROUND_UP
)
1958 if lower
.__mul
__(lower
, context
=context
) > (tmp
):
1959 ans
= ans
.__sub
__(Decimal((0, (1,), ans
._exp
)), context
=context
)
1962 upper
= ans
.__add
__(Decimal((0, (5,), ans
._exp
-1)),context
=context
)
1963 context
._set
_rounding
(ROUND_DOWN
)
1964 if upper
.__mul
__(upper
, context
=context
) < tmp
:
1965 ans
= ans
.__add
__(Decimal((0, (1,), ans
._exp
)),context
=context
)
1969 context
.prec
= firstprec
1970 context
.rounding
= rounding
1971 ans
= ans
._fix
(context
)
1973 rounding
= context
._set
_rounding
_decision
(NEVER_ROUND
)
1974 if not ans
.__mul
__(ans
, context
=context
) == self
:
1975 # Only rounded/inexact if here.
1976 context
._regard
_flags
(flags
)
1977 context
._raise
_error
(Rounded
)
1978 context
._raise
_error
(Inexact
)
1980 #Exact answer, so let's set the exponent right.
1982 # exp = (self._exp +1)// 2
1984 exp
= self
._exp
// 2
1985 context
.prec
+= ans
._exp
- exp
1986 ans
= ans
._rescale
(exp
, context
=context
)
1987 context
.prec
= firstprec
1988 context
._regard
_flags
(flags
)
1989 context
.Emax
, context
.Emin
= Emax
, Emin
1991 return ans
._fix
(context
)
1993 def max(self
, other
, context
=None):
1994 """Returns the larger value.
1996 like max(self, other) except if one is not a number, returns
1997 NaN (and signals if one is sNaN). Also rounds.
1999 other
= _convert_other(other
)
2001 if self
._is
_special
or other
._is
_special
:
2002 # if one operand is a quiet NaN and the other is number, then the
2003 # number is always returned
2007 if on
== 1 and sn
!= 2:
2009 if sn
== 1 and on
!= 2:
2011 return self
._check
_nans
(other
, context
)
2014 c
= self
.__cmp
__(other
)
2016 # if both operands are finite and equal in numerical value
2017 # then an ordering is applied:
2019 # if the signs differ then max returns the operand with the
2020 # positive sign and min returns the operand with the negative sign
2022 # if the signs are the same then the exponent is used to select
2024 if self
._sign
!= other
._sign
:
2027 elif self
._exp
< other
._exp
and not self
._sign
:
2029 elif self
._exp
> other
._exp
and self
._sign
:
2035 context
= getcontext()
2036 if context
._rounding
_decision
== ALWAYS_ROUND
:
2037 return ans
._fix
(context
)
2040 def min(self
, other
, context
=None):
2041 """Returns the smaller value.
2043 like min(self, other) except if one is not a number, returns
2044 NaN (and signals if one is sNaN). Also rounds.
2046 other
= _convert_other(other
)
2048 if self
._is
_special
or other
._is
_special
:
2049 # if one operand is a quiet NaN and the other is number, then the
2050 # number is always returned
2054 if on
== 1 and sn
!= 2:
2056 if sn
== 1 and on
!= 2:
2058 return self
._check
_nans
(other
, context
)
2061 c
= self
.__cmp
__(other
)
2063 # if both operands are finite and equal in numerical value
2064 # then an ordering is applied:
2066 # if the signs differ then max returns the operand with the
2067 # positive sign and min returns the operand with the negative sign
2069 # if the signs are the same then the exponent is used to select
2071 if self
._sign
!= other
._sign
:
2074 elif self
._exp
> other
._exp
and not self
._sign
:
2076 elif self
._exp
< other
._exp
and self
._sign
:
2082 context
= getcontext()
2083 if context
._rounding
_decision
== ALWAYS_ROUND
:
2084 return ans
._fix
(context
)
2087 def _isinteger(self
):
2088 """Returns whether self is an integer"""
2091 rest
= self
._int
[self
._exp
:]
2092 return rest
== (0,)*len(rest
)
2095 """Returns 1 if self is even. Assumes self is an integer."""
2098 return self
._int
[-1+self
._exp
] & 1 == 0
2101 """Return the adjusted exponent of self"""
2103 return self
._exp
+ len(self
._int
) - 1
2104 #If NaN or Infinity, self._exp is string
2108 # support for pickling, copy, and deepcopy
2109 def __reduce__(self
):
2110 return (self
.__class
__, (str(self
),))
2113 if type(self
) == Decimal
:
2114 return self
# I'm immutable; therefore I am my own clone
2115 return self
.__class
__(str(self
))
2117 def __deepcopy__(self
, memo
):
2118 if type(self
) == Decimal
:
2119 return self
# My components are also immutable
2120 return self
.__class
__(str(self
))
2122 ##### Context class ###########################################
2125 # get rounding method function:
2126 rounding_functions
= [name
for name
in Decimal
.__dict
__.keys() if name
.startswith('_round_')]
2127 for name
in rounding_functions
:
2128 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
2129 globalname
= name
[1:].upper()
2130 val
= globals()[globalname
]
2131 Decimal
._pick
_rounding
_function
[val
] = name
2133 del name
, val
, globalname
, rounding_functions
2135 class Context(object):
2136 """Contains the context for a Decimal instance.
2139 prec - precision (for use in rounding, division, square roots..)
2140 rounding - rounding type. (how you round)
2141 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
2142 traps - If traps[exception] = 1, then the exception is
2143 raised when it is caused. Otherwise, a value is
2145 flags - When an exception is caused, flags[exception] is incremented.
2146 (Whether or not the trap_enabler is set)
2147 Should be reset by user of Decimal instance.
2148 Emin - Minimum exponent
2149 Emax - Maximum exponent
2150 capitals - If 1, 1*10^1 is printed as 1E+1.
2151 If 0, printed as 1e1
2152 _clamp - If 1, change exponents if too high (Default 0)
2155 def __init__(self
, prec
=None, rounding
=None,
2156 traps
=None, flags
=None,
2157 _rounding_decision
=None,
2158 Emin
=None, Emax
=None,
2159 capitals
=None, _clamp
=0,
2160 _ignored_flags
=None):
2163 if _ignored_flags
is None:
2165 if not isinstance(flags
, dict):
2166 flags
= dict([(s
,s
in flags
) for s
in _signals
])
2168 if traps
is not None and not isinstance(traps
, dict):
2169 traps
= dict([(s
,s
in traps
) for s
in _signals
])
2171 for name
, val
in locals().items():
2173 setattr(self
, name
, copy
.copy(getattr(DefaultContext
, name
)))
2175 setattr(self
, name
, val
)
2179 """Show the current context."""
2181 s
.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self
))
2182 s
.append('flags=[' + ', '.join([f
.__name
__ for f
, v
in self
.flags
.items() if v
]) + ']')
2183 s
.append('traps=[' + ', '.join([t
.__name
__ for t
, v
in self
.traps
.items() if v
]) + ']')
2184 return ', '.join(s
) + ')'
2186 def clear_flags(self
):
2187 """Reset all flags to zero"""
2188 for flag
in self
.flags
:
2189 self
.flags
[flag
] = 0
2191 def _shallow_copy(self
):
2192 """Returns a shallow copy from self."""
2193 nc
= Context(self
.prec
, self
.rounding
, self
.traps
, self
.flags
,
2194 self
._rounding
_decision
, self
.Emin
, self
.Emax
,
2195 self
.capitals
, self
._clamp
, self
._ignored
_flags
)
2199 """Returns a deep copy from self."""
2200 nc
= Context(self
.prec
, self
.rounding
, self
.traps
.copy(), self
.flags
.copy(),
2201 self
._rounding
_decision
, self
.Emin
, self
.Emax
,
2202 self
.capitals
, self
._clamp
, self
._ignored
_flags
)
2206 def _raise_error(self
, condition
, explanation
= None, *args
):
2209 If the flag is in _ignored_flags, returns the default response.
2210 Otherwise, it increments the flag, then, if the corresponding
2211 trap_enabler is set, it reaises the exception. Otherwise, it returns
2212 the default value after incrementing the flag.
2214 error
= _condition_map
.get(condition
, condition
)
2215 if error
in self
._ignored
_flags
:
2216 #Don't touch the flag
2217 return error().handle(self
, *args
)
2219 self
.flags
[error
] += 1
2220 if not self
.traps
[error
]:
2221 #The errors define how to handle themselves.
2222 return condition().handle(self
, *args
)
2224 # Errors should only be risked on copies of the context
2225 #self._ignored_flags = []
2226 raise error
, explanation
2228 def _ignore_all_flags(self
):
2229 """Ignore all flags, if they are raised"""
2230 return self
._ignore
_flags
(*_signals
)
2232 def _ignore_flags(self
, *flags
):
2233 """Ignore the flags, if they are raised"""
2234 # Do not mutate-- This way, copies of a context leave the original
2236 self
._ignored
_flags
= (self
._ignored
_flags
+ list(flags
))
2239 def _regard_flags(self
, *flags
):
2240 """Stop ignoring the flags, if they are raised"""
2241 if flags
and isinstance(flags
[0], (tuple,list)):
2244 self
._ignored
_flags
.remove(flag
)
2247 """A Context cannot be hashed."""
2248 # We inherit object.__hash__, so we must deny this explicitly
2249 raise TypeError, "Cannot hash a Context."
2252 """Returns Etiny (= Emin - prec + 1)"""
2253 return int(self
.Emin
- self
.prec
+ 1)
2256 """Returns maximum exponent (= Emax - prec + 1)"""
2257 return int(self
.Emax
- self
.prec
+ 1)
2259 def _set_rounding_decision(self
, type):
2260 """Sets the rounding decision.
2262 Sets the rounding decision, and returns the current (previous)
2263 rounding decision. Often used like:
2265 context = context._shallow_copy()
2266 # That so you don't change the calling context
2267 # if an error occurs in the middle (say DivisionImpossible is raised).
2269 rounding = context._set_rounding_decision(NEVER_ROUND)
2270 instance = instance / Decimal(2)
2271 context._set_rounding_decision(rounding)
2273 This will make it not round for that operation.
2276 rounding
= self
._rounding
_decision
2277 self
._rounding
_decision
= type
2280 def _set_rounding(self
, type):
2281 """Sets the rounding type.
2283 Sets the rounding type, and returns the current (previous)
2284 rounding type. Often used like:
2286 context = context.copy()
2287 # so you don't change the calling context
2288 # if an error occurs in the middle.
2289 rounding = context._set_rounding(ROUND_UP)
2290 val = self.__sub__(other, context=context)
2291 context._set_rounding(rounding)
2293 This will make it round up for that operation.
2295 rounding
= self
.rounding
2299 def create_decimal(self
, num
='0'):
2300 """Creates a new Decimal instance but using self as context."""
2301 d
= Decimal(num
, context
=self
)
2306 """Returns the absolute value of the operand.
2308 If the operand is negative, the result is the same as using the minus
2309 operation on the operand. Otherwise, the result is the same as using
2310 the plus operation on the operand.
2312 >>> ExtendedContext.abs(Decimal('2.1'))
2314 >>> ExtendedContext.abs(Decimal('-100'))
2316 >>> ExtendedContext.abs(Decimal('101.5'))
2318 >>> ExtendedContext.abs(Decimal('-101.5'))
2321 return a
.__abs
__(context
=self
)
2323 def add(self
, a
, b
):
2324 """Return the sum of the two operands.
2326 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
2328 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
2331 return a
.__add
__(b
, context
=self
)
2333 def _apply(self
, a
):
2334 return str(a
._fix
(self
))
2336 def compare(self
, a
, b
):
2337 """Compares values numerically.
2339 If the signs of the operands differ, a value representing each operand
2340 ('-1' if the operand is less than zero, '0' if the operand is zero or
2341 negative zero, or '1' if the operand is greater than zero) is used in
2342 place of that operand for the comparison instead of the actual
2345 The comparison is then effected by subtracting the second operand from
2346 the first and then returning a value according to the result of the
2347 subtraction: '-1' if the result is less than zero, '0' if the result is
2348 zero or negative zero, or '1' if the result is greater than zero.
2350 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
2352 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
2354 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
2356 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
2358 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
2360 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
2363 return a
.compare(b
, context
=self
)
2365 def divide(self
, a
, b
):
2366 """Decimal division in a specified context.
2368 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
2369 Decimal("0.333333333")
2370 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
2371 Decimal("0.666666667")
2372 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
2374 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
2376 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
2378 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
2380 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
2382 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
2384 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
2386 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
2389 return a
.__div
__(b
, context
=self
)
2391 def divide_int(self
, a
, b
):
2392 """Divides two numbers and returns the integer part of the result.
2394 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
2396 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
2398 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
2401 return a
.__floordiv
__(b
, context
=self
)
2403 def divmod(self
, a
, b
):
2404 return a
.__divmod
__(b
, context
=self
)
2407 """max compares two values numerically and returns the maximum.
2409 If either operand is a NaN then the general rules apply.
2410 Otherwise, the operands are compared as as though by the compare
2411 operation. If they are numerically equal then the left-hand operand
2412 is chosen as the result. Otherwise the maximum (closer to positive
2413 infinity) of the two operands is chosen as the result.
2415 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
2417 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
2419 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
2421 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
2424 return a
.max(b
, context
=self
)
2427 """min compares two values numerically and returns the minimum.
2429 If either operand is a NaN then the general rules apply.
2430 Otherwise, the operands are compared as as though by the compare
2431 operation. If they are numerically equal then the left-hand operand
2432 is chosen as the result. Otherwise the minimum (closer to negative
2433 infinity) of the two operands is chosen as the result.
2435 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
2437 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
2439 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
2441 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
2444 return a
.min(b
, context
=self
)
2447 """Minus corresponds to unary prefix minus in Python.
2449 The operation is evaluated using the same rules as subtract; the
2450 operation minus(a) is calculated as subtract('0', a) where the '0'
2451 has the same exponent as the operand.
2453 >>> ExtendedContext.minus(Decimal('1.3'))
2455 >>> ExtendedContext.minus(Decimal('-1.3'))
2458 return a
.__neg
__(context
=self
)
2460 def multiply(self
, a
, b
):
2461 """multiply multiplies two operands.
2463 If either operand is a special value then the general rules apply.
2464 Otherwise, the operands are multiplied together ('long multiplication'),
2465 resulting in a number which may be as long as the sum of the lengths
2466 of the two operands.
2468 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
2470 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
2472 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
2474 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
2476 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
2477 Decimal("4.28135971E+11")
2479 return a
.__mul
__(b
, context
=self
)
2481 def normalize(self
, a
):
2482 """normalize reduces an operand to its simplest form.
2484 Essentially a plus operation with all trailing zeros removed from the
2487 >>> ExtendedContext.normalize(Decimal('2.1'))
2489 >>> ExtendedContext.normalize(Decimal('-2.0'))
2491 >>> ExtendedContext.normalize(Decimal('1.200'))
2493 >>> ExtendedContext.normalize(Decimal('-120'))
2495 >>> ExtendedContext.normalize(Decimal('120.00'))
2497 >>> ExtendedContext.normalize(Decimal('0.00'))
2500 return a
.normalize(context
=self
)
2503 """Plus corresponds to unary prefix plus in Python.
2505 The operation is evaluated using the same rules as add; the
2506 operation plus(a) is calculated as add('0', a) where the '0'
2507 has the same exponent as the operand.
2509 >>> ExtendedContext.plus(Decimal('1.3'))
2511 >>> ExtendedContext.plus(Decimal('-1.3'))
2514 return a
.__pos
__(context
=self
)
2516 def power(self
, a
, b
, modulo
=None):
2517 """Raises a to the power of b, to modulo if given.
2519 The right-hand operand must be a whole number whose integer part (after
2520 any exponent has been applied) has no more than 9 digits and whose
2521 fractional part (if any) is all zeros before any rounding. The operand
2522 may be positive, negative, or zero; if negative, the absolute value of
2523 the power is used, and the left-hand operand is inverted (divided into
2526 If the increased precision needed for the intermediate calculations
2527 exceeds the capabilities of the implementation then an Invalid operation
2528 condition is raised.
2530 If, when raising to a negative power, an underflow occurs during the
2531 division into 1, the operation is not halted at that point but
2534 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
2536 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
2538 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
2539 Decimal("69.7575744")
2540 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
2542 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
2544 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
2546 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
2548 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
2550 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
2552 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
2554 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
2556 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
2557 Decimal("-Infinity")
2558 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
2560 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
2563 return a
.__pow
__(b
, modulo
, context
=self
)
2565 def quantize(self
, a
, b
):
2566 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
2568 The coefficient of the result is derived from that of the left-hand
2569 operand. It may be rounded using the current rounding setting (if the
2570 exponent is being increased), multiplied by a positive power of ten (if
2571 the exponent is being decreased), or is unchanged (if the exponent is
2572 already equal to that of the right-hand operand).
2574 Unlike other operations, if the length of the coefficient after the
2575 quantize operation would be greater than precision then an Invalid
2576 operation condition is raised. This guarantees that, unless there is an
2577 error condition, the exponent of the result of a quantize is always
2578 equal to that of the right-hand operand.
2580 Also unlike other operations, quantize will never raise Underflow, even
2581 if the result is subnormal and inexact.
2583 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
2585 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
2587 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
2589 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
2591 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
2593 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
2594 Decimal("-Infinity")
2595 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
2597 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
2599 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
2601 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
2603 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
2605 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
2607 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
2609 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
2611 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
2614 return a
.quantize(b
, context
=self
)
2616 def remainder(self
, a
, b
):
2617 """Returns the remainder from integer division.
2619 The result is the residue of the dividend after the operation of
2620 calculating integer division as described for divide-integer, rounded to
2621 precision digits if necessary. The sign of the result, if non-zero, is
2622 the same as that of the original dividend.
2624 This operation will fail under the same conditions as integer division
2625 (that is, if integer division on the same two operands would fail, the
2626 remainder cannot be calculated).
2628 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
2630 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
2632 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
2634 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
2636 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
2638 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
2641 return a
.__mod
__(b
, context
=self
)
2643 def remainder_near(self
, a
, b
):
2644 """Returns to be "a - b * n", where n is the integer nearest the exact
2645 value of "x / b" (if two integers are equally near then the even one
2646 is chosen). If the result is equal to 0 then its sign will be the
2649 This operation will fail under the same conditions as integer division
2650 (that is, if integer division on the same two operands would fail, the
2651 remainder cannot be calculated).
2653 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
2655 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
2657 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
2659 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
2661 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
2663 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
2665 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
2668 return a
.remainder_near(b
, context
=self
)
2670 def same_quantum(self
, a
, b
):
2671 """Returns True if the two operands have the same exponent.
2673 The result is never affected by either the sign or the coefficient of
2676 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
2678 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
2680 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
2682 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
2685 return a
.same_quantum(b
)
2688 """Returns the square root of a non-negative number to context precision.
2690 If the result must be inexact, it is rounded using the round-half-even
2693 >>> ExtendedContext.sqrt(Decimal('0'))
2695 >>> ExtendedContext.sqrt(Decimal('-0'))
2697 >>> ExtendedContext.sqrt(Decimal('0.39'))
2698 Decimal("0.624499800")
2699 >>> ExtendedContext.sqrt(Decimal('100'))
2701 >>> ExtendedContext.sqrt(Decimal('1'))
2703 >>> ExtendedContext.sqrt(Decimal('1.0'))
2705 >>> ExtendedContext.sqrt(Decimal('1.00'))
2707 >>> ExtendedContext.sqrt(Decimal('7'))
2708 Decimal("2.64575131")
2709 >>> ExtendedContext.sqrt(Decimal('10'))
2710 Decimal("3.16227766")
2711 >>> ExtendedContext.prec
2714 return a
.sqrt(context
=self
)
2716 def subtract(self
, a
, b
):
2717 """Return the sum of the two operands.
2719 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
2721 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
2723 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
2726 return a
.__sub
__(b
, context
=self
)
2728 def to_eng_string(self
, a
):
2729 """Converts a number to a string, using scientific notation.
2731 The operation is not affected by the context.
2733 return a
.to_eng_string(context
=self
)
2735 def to_sci_string(self
, a
):
2736 """Converts a number to a string, using scientific notation.
2738 The operation is not affected by the context.
2740 return a
.__str
__(context
=self
)
2742 def to_integral(self
, a
):
2743 """Rounds to an integer.
2745 When the operand has a negative exponent, the result is the same
2746 as using the quantize() operation using the given operand as the
2747 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2748 of the operand as the precision setting, except that no flags will
2749 be set. The rounding mode is taken from the context.
2751 >>> ExtendedContext.to_integral(Decimal('2.1'))
2753 >>> ExtendedContext.to_integral(Decimal('100'))
2755 >>> ExtendedContext.to_integral(Decimal('100.0'))
2757 >>> ExtendedContext.to_integral(Decimal('101.5'))
2759 >>> ExtendedContext.to_integral(Decimal('-101.5'))
2761 >>> ExtendedContext.to_integral(Decimal('10E+5'))
2763 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
2765 >>> ExtendedContext.to_integral(Decimal('-Inf'))
2766 Decimal("-Infinity")
2768 return a
.to_integral(context
=self
)
2770 class _WorkRep(object):
2771 __slots__
= ('sign','int','exp')
2774 # exp: None, int, or string
2776 def __init__(self
, value
=None):
2781 elif isinstance(value
, Decimal
):
2782 self
.sign
= value
._sign
2784 for digit
in value
._int
:
2785 cum
= cum
* 10 + digit
2787 self
.exp
= value
._exp
2789 # assert isinstance(value, tuple)
2790 self
.sign
= value
[0]
2795 return "(%r, %r, %r)" % (self
.sign
, self
.int, self
.exp
)
2801 def _normalize(op1
, op2
, shouldround
= 0, prec
= 0):
2802 """Normalizes op1, op2 to have the same exp and length of coefficient.
2804 Done during addition.
2806 # Yes, the exponent is a long, but the difference between exponents
2807 # must be an int-- otherwise you'd get a big memory problem.
2808 numdigits
= int(op1
.exp
- op2
.exp
)
2810 numdigits
= -numdigits
2818 if shouldround
and numdigits
> prec
+ 1:
2819 # Big difference in exponents - check the adjusted exponents
2820 tmp_len
= len(str(tmp
.int))
2821 other_len
= len(str(other
.int))
2822 if numdigits
> (other_len
+ prec
+ 1 - tmp_len
):
2823 # If the difference in adjusted exps is > prec+1, we know
2824 # other is insignificant, so might as well put a 1 after the precision.
2825 # (since this is only for addition.) Also stops use of massive longs.
2827 extend
= prec
+ 2 - tmp_len
2830 tmp
.int *= 10 ** extend
2836 tmp
.int *= 10 ** numdigits
2837 tmp
.exp
-= numdigits
2840 def _adjust_coefficients(op1
, op2
):
2841 """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
2843 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2845 Used on _WorkRep instances during division.
2848 #If op1 is smaller, make it larger
2849 while op2
.int > op1
.int:
2854 #If op2 is too small, make it larger
2855 while op1
.int >= (10 * op2
.int):
2860 return op1
, op2
, adjust
2862 ##### Helper Functions ########################################
2864 def _convert_other(other
):
2865 """Convert other to Decimal.
2867 Verifies that it's ok to use in an implicit construction.
2869 if isinstance(other
, Decimal
):
2871 if isinstance(other
, (int, long)):
2872 return Decimal(other
)
2874 raise TypeError, "You can interact Decimal only with int, long or Decimal data types."
2885 def _isinfinity(num
):
2886 """Determines whether a string or float is infinity.
2888 +1 for negative infinity; 0 for finite ; +1 for positive infinity
2890 num
= str(num
).lower()
2891 return _infinity_map
.get(num
, 0)
2894 """Determines whether a string or float is NaN
2896 (1, sign, diagnostic info as string) => NaN
2897 (2, sign, diagnostic info as string) => sNaN
2900 num
= str(num
).lower()
2904 #get the sign, get rid of trailing [+-]
2908 elif num
[0] == '-': #elif avoids '+-nan'
2912 if num
.startswith('nan'):
2913 if len(num
) > 3 and not num
[3:].isdigit(): #diagnostic info
2915 return (1, sign
, num
[3:].lstrip('0'))
2916 if num
.startswith('snan'):
2917 if len(num
) > 4 and not num
[4:].isdigit():
2919 return (2, sign
, num
[4:].lstrip('0'))
2923 ##### Setup Specific Contexts ################################
2925 # The default context prototype used by Context()
2926 # Is mutable, so that new contexts can have different default values
2928 DefaultContext
= Context(
2929 prec
=28, rounding
=ROUND_HALF_EVEN
,
2930 traps
=[DivisionByZero
, Overflow
, InvalidOperation
],
2932 _rounding_decision
=ALWAYS_ROUND
,
2938 # Pre-made alternate contexts offered by the specification
2939 # Don't change these; the user should be able to select these
2940 # contexts and be able to reproduce results from other implementations
2943 BasicContext
= Context(
2944 prec
=9, rounding
=ROUND_HALF_UP
,
2945 traps
=[DivisionByZero
, Overflow
, InvalidOperation
, Clamped
, Underflow
],
2949 ExtendedContext
= Context(
2950 prec
=9, rounding
=ROUND_HALF_EVEN
,
2956 ##### Useful Constants (internal use only) ####################
2959 Inf
= Decimal('Inf')
2960 negInf
= Decimal('-Inf')
2962 #Infsign[sign] is infinity w/ that sign
2963 Infsign
= (Inf
, negInf
)
2965 NaN
= Decimal('NaN')
2968 ##### crud for parsing strings #################################
2971 # There's an optional sign at the start, and an optional exponent
2972 # at the end. The exponent has an optional sign and at least one
2973 # digit. In between, must have either at least one digit followed
2974 # by an optional fraction, or a decimal point followed by at least
2977 _parser
= re
.compile(r
"""
2981 (?P<int>\d+) (\. (?P<frac>\d*))?
2983 \. (?P<onlyfrac>\d+)
2985 ([eE](?P<exp>[-+]? \d+))?
2988 """, re
.VERBOSE
).match
#Uncomment the \s* to allow leading or trailing spaces.
2992 # return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
2994 def _string2exact(s
):
2997 raise ValueError("invalid literal for Decimal: %r" % s
)
2999 if m
.group('sign') == "-":
3004 exp
= m
.group('exp')
3010 intpart
= m
.group('int')
3013 fracpart
= m
.group('onlyfrac')
3015 fracpart
= m
.group('frac')
3016 if fracpart
is None:
3019 exp
-= len(fracpart
)
3021 mantissa
= intpart
+ fracpart
3022 tmp
= map(int, mantissa
)
3024 while tmp
and tmp
[0] == 0:
3030 return (sign
, tuple(backup
), exp
)
3031 return (sign
, (0,), exp
)
3032 mantissa
= tuple(tmp
)
3034 return (sign
, mantissa
, exp
)
3037 if __name__
== '__main__':
3039 doctest
.testmod(sys
.modules
[__name__
])