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