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