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