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