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