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