blob: 717c6b7f3ba97aa8f2910f13dee078a62f6184a8 [file] [log] [blame]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001# Copyright (c) 2004 Python Software Foundation.
2# All rights reserved.
3
4# Written by Eric Price <eprice at tjhsst.edu>
5# and Facundo Batista <facundo at taniquetil.com.ar>
6# and Raymond Hettinger <python at rcn.com>
Fred Drake1f34eb12004-07-01 14:28:36 +00007# and Aahz <aahz at pobox.com>
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00008# and Tim Peters
9
10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000011"""
12This is a Py2.3 implementation of decimal floating point arithmetic based on
13the General Decimal Arithmetic Specification:
14
15 www2.hursley.ibm.com/decimal/decarith.html
16
Raymond Hettinger0ea241e2004-07-04 13:53:24 +000017and IEEE standard 854-1987:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000018
19 www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html
20
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000021Decimal floating point has finite precision with arbitrarily large bounds.
22
23The purpose of the module is to support arithmetic using familiar
24"schoolhouse" rules and to avoid the some of tricky representation
25issues associated with binary floating point. The package is especially
26useful for financial applications or for contexts where users have
27expectations that are at odds with binary floating point (for instance,
28in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead
29of the expected Decimal("0.00") returned by decimal floating point).
30
31Here are some examples of using the decimal module:
32
33>>> from decimal import *
Raymond Hettingerbd7f76d2004-07-08 00:49:18 +000034>>> setcontext(ExtendedContext)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000035>>> Decimal(0)
36Decimal("0")
37>>> Decimal("1")
38Decimal("1")
39>>> Decimal("-.0123")
40Decimal("-0.0123")
41>>> Decimal(123456)
42Decimal("123456")
43>>> Decimal("123.45e12345678901234567890")
44Decimal("1.2345E+12345678901234567892")
45>>> Decimal("1.33") + Decimal("1.27")
46Decimal("2.60")
47>>> Decimal("12.34") + Decimal("3.87") - Decimal("18.41")
48Decimal("-2.20")
49>>> dig = Decimal(1)
50>>> print dig / Decimal(3)
510.333333333
52>>> getcontext().prec = 18
53>>> print dig / Decimal(3)
540.333333333333333333
55>>> print dig.sqrt()
561
57>>> print Decimal(3).sqrt()
581.73205080756887729
59>>> print Decimal(3) ** 123
604.85192780976896427E+58
61>>> inf = Decimal(1) / Decimal(0)
62>>> print inf
63Infinity
64>>> neginf = Decimal(-1) / Decimal(0)
65>>> print neginf
66-Infinity
67>>> print neginf + inf
68NaN
69>>> print neginf * inf
70-Infinity
71>>> print dig / 0
72Infinity
Raymond Hettingerbf440692004-07-10 14:14:37 +000073>>> getcontext().traps[DivisionByZero] = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000074>>> print dig / 0
75Traceback (most recent call last):
76 ...
77 ...
78 ...
79DivisionByZero: x / 0
80>>> c = Context()
Raymond Hettingerbf440692004-07-10 14:14:37 +000081>>> c.traps[InvalidOperation] = 0
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000082>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000830
84>>> c.divide(Decimal(0), Decimal(0))
85Decimal("NaN")
Raymond Hettingerbf440692004-07-10 14:14:37 +000086>>> c.traps[InvalidOperation] = 1
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000087>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000881
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000089>>> c.flags[InvalidOperation] = 0
90>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000910
92>>> print c.divide(Decimal(0), Decimal(0))
93Traceback (most recent call last):
94 ...
95 ...
96 ...
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000097InvalidOperation: 0 / 0
98>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000991
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000100>>> c.flags[InvalidOperation] = 0
Raymond Hettingerbf440692004-07-10 14:14:37 +0000101>>> c.traps[InvalidOperation] = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000102>>> print c.divide(Decimal(0), Decimal(0))
103NaN
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000104>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001051
106>>>
107"""
108
109__all__ = [
110 # Two major classes
111 'Decimal', 'Context',
112
113 # Contexts
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +0000114 'DefaultContext', 'BasicContext', 'ExtendedContext',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000115
116 # Exceptions
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +0000117 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
118 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000119
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000120 # Constants for use in setting up contexts
121 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING',
122 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000123
124 # Functions for manipulating contexts
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000125 'setcontext', 'getcontext'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000126]
127
128import threading
129import copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000130import operator
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000131
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000132#Rounding
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000133ROUND_DOWN = 'ROUND_DOWN'
134ROUND_HALF_UP = 'ROUND_HALF_UP'
135ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
136ROUND_CEILING = 'ROUND_CEILING'
137ROUND_FLOOR = 'ROUND_FLOOR'
138ROUND_UP = 'ROUND_UP'
139ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000140
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +0000141#Rounding decision (not part of the public API)
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000142NEVER_ROUND = 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY
143ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000144
145#Errors
146
147class DecimalException(ArithmeticError):
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000148 """Base exception class.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000149
150 Used exceptions derive from this.
151 If an exception derives from another exception besides this (such as
152 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
153 called if the others are present. This isn't actually used for
154 anything, though.
155
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000156 handle -- Called when context._raise_error is called and the
157 trap_enabler is set. First argument is self, second is the
158 context. More arguments can be given, those being after
159 the explanation in _raise_error (For example,
160 context._raise_error(NewError, '(-x)!', self._sign) would
161 call NewError().handle(context, self._sign).)
162
163 To define a new exception, it should be sufficient to have it derive
164 from DecimalException.
165 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000166 def handle(self, context, *args):
167 pass
168
169
170class Clamped(DecimalException):
171 """Exponent of a 0 changed to fit bounds.
172
173 This occurs and signals clamped if the exponent of a result has been
174 altered in order to fit the constraints of a specific concrete
175 representation. This may occur when the exponent of a zero result would
176 be outside the bounds of a representation, or when a large normal
177 number would have an encoded exponent that cannot be represented. In
178 this latter case, the exponent is reduced to fit and the corresponding
179 number of zero digits are appended to the coefficient ("fold-down").
180 """
181
182
183class InvalidOperation(DecimalException):
184 """An invalid operation was performed.
185
186 Various bad things cause this:
187
188 Something creates a signaling NaN
189 -INF + INF
190 0 * (+-)INF
191 (+-)INF / (+-)INF
192 x % 0
193 (+-)INF % x
194 x._rescale( non-integer )
195 sqrt(-x) , x > 0
196 0 ** 0
197 x ** (non-integer)
198 x ** (+-)INF
199 An operand is invalid
200 """
201 def handle(self, context, *args):
202 if args:
203 if args[0] == 1: #sNaN, must drop 's' but keep diagnostics
204 return Decimal( (args[1]._sign, args[1]._int, 'n') )
205 return NaN
206
207class ConversionSyntax(InvalidOperation):
208 """Trying to convert badly formed string.
209
210 This occurs and signals invalid-operation if an string is being
211 converted to a number and it does not conform to the numeric string
212 syntax. The result is [0,qNaN].
213 """
214
215 def handle(self, context, *args):
216 return (0, (0,), 'n') #Passed to something which uses a tuple.
217
218class DivisionByZero(DecimalException, ZeroDivisionError):
219 """Division by 0.
220
221 This occurs and signals division-by-zero if division of a finite number
222 by zero was attempted (during a divide-integer or divide operation, or a
223 power operation with negative right-hand operand), and the dividend was
224 not zero.
225
226 The result of the operation is [sign,inf], where sign is the exclusive
227 or of the signs of the operands for divide, or is 1 for an odd power of
228 -0, for power.
229 """
230
231 def handle(self, context, sign, double = None, *args):
232 if double is not None:
233 return (Infsign[sign],)*2
234 return Infsign[sign]
235
236class DivisionImpossible(InvalidOperation):
237 """Cannot perform the division adequately.
238
239 This occurs and signals invalid-operation if the integer result of a
240 divide-integer or remainder operation had too many digits (would be
241 longer than precision). The result is [0,qNaN].
242 """
243
244 def handle(self, context, *args):
245 return (NaN, NaN)
246
247class DivisionUndefined(InvalidOperation, ZeroDivisionError):
248 """Undefined result of division.
249
250 This occurs and signals invalid-operation if division by zero was
251 attempted (during a divide-integer, divide, or remainder operation), and
252 the dividend is also zero. The result is [0,qNaN].
253 """
254
255 def handle(self, context, tup=None, *args):
256 if tup is not None:
257 return (NaN, NaN) #for 0 %0, 0 // 0
258 return NaN
259
260class Inexact(DecimalException):
261 """Had to round, losing information.
262
263 This occurs and signals inexact whenever the result of an operation is
264 not exact (that is, it needed to be rounded and any discarded digits
265 were non-zero), or if an overflow or underflow condition occurs. The
266 result in all cases is unchanged.
267
268 The inexact signal may be tested (or trapped) to determine if a given
269 operation (or sequence of operations) was inexact.
270 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000271 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000272
273class InvalidContext(InvalidOperation):
274 """Invalid context. Unknown rounding, for example.
275
276 This occurs and signals invalid-operation if an invalid context was
277 detected during an operation. This can occur if contexts are not checked
278 on creation and either the precision exceeds the capability of the
279 underlying concrete representation or an unknown or unsupported rounding
280 was specified. These aspects of the context need only be checked when
281 the values are required to be used. The result is [0,qNaN].
282 """
283
284 def handle(self, context, *args):
285 return NaN
286
287class Rounded(DecimalException):
288 """Number got rounded (not necessarily changed during rounding).
289
290 This occurs and signals rounded whenever the result of an operation is
291 rounded (that is, some zero or non-zero digits were discarded from the
292 coefficient), or if an overflow or underflow condition occurs. The
293 result in all cases is unchanged.
294
295 The rounded signal may be tested (or trapped) to determine if a given
296 operation (or sequence of operations) caused a loss of precision.
297 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000298 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000299
300class Subnormal(DecimalException):
301 """Exponent < Emin before rounding.
302
303 This occurs and signals subnormal whenever the result of a conversion or
304 operation is subnormal (that is, its adjusted exponent is less than
305 Emin, before any rounding). The result in all cases is unchanged.
306
307 The subnormal signal may be tested (or trapped) to determine if a given
308 or operation (or sequence of operations) yielded a subnormal result.
309 """
310 pass
311
312class Overflow(Inexact, Rounded):
313 """Numerical overflow.
314
315 This occurs and signals overflow if the adjusted exponent of a result
316 (from a conversion or from an operation that is not an attempt to divide
317 by zero), after rounding, would be greater than the largest value that
318 can be handled by the implementation (the value Emax).
319
320 The result depends on the rounding mode:
321
322 For round-half-up and round-half-even (and for round-half-down and
323 round-up, if implemented), the result of the operation is [sign,inf],
324 where sign is the sign of the intermediate result. For round-down, the
325 result is the largest finite number that can be represented in the
326 current precision, with the sign of the intermediate result. For
327 round-ceiling, the result is the same as for round-down if the sign of
328 the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
329 the result is the same as for round-down if the sign of the intermediate
330 result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
331 will also be raised.
332 """
333
334 def handle(self, context, sign, *args):
335 if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
336 ROUND_HALF_DOWN, ROUND_UP):
337 return Infsign[sign]
338 if sign == 0:
339 if context.rounding == ROUND_CEILING:
340 return Infsign[sign]
341 return Decimal((sign, (9,)*context.prec,
342 context.Emax-context.prec+1))
343 if sign == 1:
344 if context.rounding == ROUND_FLOOR:
345 return Infsign[sign]
346 return Decimal( (sign, (9,)*context.prec,
347 context.Emax-context.prec+1))
348
349
350class Underflow(Inexact, Rounded, Subnormal):
351 """Numerical underflow with result rounded to 0.
352
353 This occurs and signals underflow if a result is inexact and the
354 adjusted exponent of the result would be smaller (more negative) than
355 the smallest value that can be handled by the implementation (the value
356 Emin). That is, the result is both inexact and subnormal.
357
358 The result after an underflow will be a subnormal number rounded, if
359 necessary, so that its exponent is not less than Etiny. This may result
360 in 0 with the sign of the intermediate result and an exponent of Etiny.
361
362 In all cases, Inexact, Rounded, and Subnormal will also be raised.
363 """
364
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000365# List of public traps and flags
Raymond Hettingerfed52962004-07-14 15:41:57 +0000366_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000367 Underflow, InvalidOperation, Subnormal]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000368
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000369# Map conditions (per the spec) to signals
370_condition_map = {ConversionSyntax:InvalidOperation,
371 DivisionImpossible:InvalidOperation,
372 DivisionUndefined:InvalidOperation,
373 InvalidContext:InvalidOperation}
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000374
375##### Context Functions #######################################
376
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000377# The getcontext() and setcontext() function manage access to a thread-local
378# current context. Py2.4 offers direct support for thread locals. If that
379# is not available, use threading.currentThread() which is slower but will
380# work for older Pythons.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000381
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000382try:
383 threading.local
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000384
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000385except AttributeError:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000386
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000387 #To fix reloading, force it to create a new context
388 #Old contexts have different exceptions in their dicts, making problems.
389 if hasattr(threading.currentThread(), '__decimal_context__'):
390 del threading.currentThread().__decimal_context__
391
392 def setcontext(context):
393 """Set this thread's context to context."""
394 if context in (DefaultContext, BasicContext, ExtendedContext):
395 context = context.copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000396 threading.currentThread().__decimal_context__ = context
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000397
398 def getcontext():
399 """Returns this thread's context.
400
401 If this thread does not yet have a context, returns
402 a new context and sets this thread's context.
403 New contexts are copies of DefaultContext.
404 """
405 try:
406 return threading.currentThread().__decimal_context__
407 except AttributeError:
408 context = Context()
409 threading.currentThread().__decimal_context__ = context
410 return context
411
412else:
413
414 local = threading.local()
415
416 def getcontext(_local=local):
417 """Returns this thread's context.
418
419 If this thread does not yet have a context, returns
420 a new context and sets this thread's context.
421 New contexts are copies of DefaultContext.
422 """
423 try:
424 return _local.__decimal_context__
425 except AttributeError:
426 context = Context()
427 _local.__decimal_context__ = context
428 return context
429
430 def setcontext(context, _local=local):
431 """Set this thread's context to context."""
432 if context in (DefaultContext, BasicContext, ExtendedContext):
433 context = context.copy()
434 _local.__decimal_context__ = context
435
436 del threading, local # Don't contaminate the namespace
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000437
438
439##### Decimal class ###########################################
440
441class Decimal(object):
442 """Floating point class for decimal arithmetic."""
443
444 __slots__ = ('_exp','_int','_sign')
445
446 def __init__(self, value="0", context=None):
447 """Create a decimal point instance.
448
449 >>> Decimal('3.14') # string input
450 Decimal("3.14")
451 >>> Decimal((0, (3, 1, 4), -2)) # tuple input (sign, digit_tuple, exponent)
452 Decimal("3.14")
453 >>> Decimal(314) # int or long
454 Decimal("314")
455 >>> Decimal(Decimal(314)) # another decimal instance
456 Decimal("314")
457 """
458 if context is None:
459 context = getcontext()
460
461 if isinstance(value, (int,long)):
462 value = str(value)
463
464 # String?
465 # REs insist on real strings, so we can too.
466 if isinstance(value, basestring):
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000467 if _isinfinity(value):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000468 self._exp = 'F'
469 self._int = (0,)
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000470 sign = _isinfinity(value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000471 if sign == 1:
472 self._sign = 0
473 else:
474 self._sign = 1
475 return
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000476 if _isnan(value):
477 sig, sign, diag = _isnan(value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000478 if len(diag) > context.prec: #Diagnostic info too long
479 self._sign, self._int, self._exp = \
480 context._raise_error(ConversionSyntax)
481 return
482 if sig == 1:
483 self._exp = 'n' #qNaN
484 else: #sig == 2
485 self._exp = 'N' #sNaN
486 self._sign = sign
487 self._int = tuple(map(int, diag)) #Diagnostic info
488 return
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +0000489 try:
490 self._sign, self._int, self._exp = _string2exact(value)
491 except ValueError:
492 self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000493 return
494
495 # tuple/list conversion (possibly from as_tuple())
496 if isinstance(value, (list,tuple)):
497 if len(value) != 3:
498 raise ValueError, 'Invalid arguments'
499 if value[0] not in [0,1]:
500 raise ValueError, 'Invalid sign'
501 for digit in value[1]:
502 if not isinstance(digit, (int,long)) or digit < 0:
503 raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
504
505 self._sign = value[0]
506 self._int = tuple(value[1])
507 if value[2] in ('F','n','N'):
508 self._exp = value[2]
509 else:
510 self._exp = int(value[2])
511 return
512
513 # Turn an intermediate value back to Decimal()
514 if isinstance(value, _WorkRep):
515 if value.sign == 1:
516 self._sign = 0
517 else:
518 self._sign = 1
519 self._int = tuple(value.int)
520 self._exp = int(value.exp)
521 return
522
523 if isinstance(value, Decimal):
Tim Peters4e0e1b62004-07-07 20:54:48 +0000524 self._exp = value._exp
525 self._sign = value._sign
526 self._int = value._int
527 return
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000528
Raymond Hettingerbf440692004-07-10 14:14:37 +0000529 if isinstance(value, float):
530 raise TypeError("Cannot convert float to Decimal. " +
531 "First convert the float to a string")
532
533 raise TypeError("Cannot convert %r" % value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000534
535 def _convert_other(self, other):
536 """Convert other to Decimal.
537
538 Verifies that it's ok to use in an implicit construction.
539 """
540 if isinstance(other, Decimal):
541 return other
542 if isinstance(other, (int, long)):
543 other = Decimal(other)
544 return other
545
546 raise TypeError, "You can interact Decimal only with int, long or Decimal data types."
547
548 def _isnan(self):
549 """Returns whether the number is not actually one.
550
551 0 if a number
552 1 if NaN
553 2 if sNaN
554 """
555 if self._exp == 'n':
556 return 1
557 elif self._exp == 'N':
558 return 2
559 return 0
560
561 def _isinfinity(self):
562 """Returns whether the number is infinite
563
564 0 if finite or not a number
565 1 if +INF
566 -1 if -INF
567 """
568 if self._exp == 'F':
569 if self._sign:
570 return -1
571 return 1
572 return 0
573
574 def _check_nans(self, other = None, context=None):
575 """Returns whether the number is not actually one.
576
577 if self, other are sNaN, signal
578 if self, other are NaN return nan
579 return 0
580
581 Done before operations.
582 """
583 if context is None:
584 context = getcontext()
585
586 if self._isnan() == 2:
587 return context._raise_error(InvalidOperation, 'sNaN',
588 1, self)
589 if other is not None and other._isnan() == 2:
590 return context._raise_error(InvalidOperation, 'sNaN',
591 1, other)
592 if self._isnan():
593 return self
594 if other is not None and other._isnan():
595 return other
596 return 0
597
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000598 def __nonzero__(self):
599 """Is the number non-zero?
600
601 0 if self == 0
602 1 if self != 0
603 """
604 if isinstance(self._exp, str):
605 return 1
606 return self._int != (0,)*len(self._int)
607
608 def __cmp__(self, other, context=None):
609 if context is None:
610 context = getcontext()
611 other = self._convert_other(other)
612
613 ans = self._check_nans(other, context)
614 if ans:
615 return 1
616
617 if not self and not other:
618 return 0 #If both 0, sign comparison isn't certain.
619
620 #If different signs, neg one is less
621 if other._sign < self._sign:
622 return -1
623 if self._sign < other._sign:
624 return 1
625
626 # INF = INF
627 if self._isinfinity() and other._isinfinity():
628 return 0
629 if self._isinfinity():
630 return (-1)**self._sign
631 if other._isinfinity():
632 return -((-1)**other._sign)
633
634 if self.adjusted() == other.adjusted() and \
635 self._int + (0,)*(self._exp - other._exp) == \
636 other._int + (0,)*(other._exp - self._exp):
637 return 0 #equal, except in precision. ([0]*(-x) = [])
638 elif self.adjusted() > other.adjusted() and self._int[0] != 0:
639 return (-1)**self._sign
640 elif self.adjusted < other.adjusted() and other._int[0] != 0:
641 return -((-1)**self._sign)
642
643 context = context.copy()
644 rounding = context._set_rounding(ROUND_UP) #round away from 0
645
646 flags = context._ignore_all_flags()
647 res = self.__sub__(other, context=context)
648
649 context._regard_flags(*flags)
650
651 context.rounding = rounding
652
653 if not res:
654 return 0
655 elif res._sign:
656 return -1
657 return 1
658
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000659 def __eq__(self, other):
660 if not isinstance(other, (Decimal, int, long)):
661 return False
662 return self.__cmp__(other) == 0
663
664 def __ne__(self, other):
665 if not isinstance(other, (Decimal, int, long)):
666 return True
667 return self.__cmp__(other) != 0
668
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000669 def compare(self, other, context=None):
670 """Compares one to another.
671
672 -1 => a < b
673 0 => a = b
674 1 => a > b
675 NaN => one is NaN
676 Like __cmp__, but returns Decimal instances.
677 """
678 if context is None:
679 context = getcontext()
680 other = self._convert_other(other)
681
682 #compare(NaN, NaN) = NaN
683 ans = self._check_nans(other, context)
684 if ans:
685 return ans
686
687 return Decimal(self.__cmp__(other, context))
688
689 def __hash__(self):
690 """x.__hash__() <==> hash(x)"""
691 # Decimal integers must hash the same as the ints
692 # Non-integer decimals are normalized and hashed as strings
693 # Normalization assures that hast(100E-1) == hash(10)
694 i = int(self)
695 if self == Decimal(i):
696 return hash(i)
697 assert self.__nonzero__() # '-0' handled by integer case
698 return hash(str(self.normalize()))
699
700 def as_tuple(self):
701 """Represents the number as a triple tuple.
702
703 To show the internals exactly as they are.
704 """
705 return (self._sign, self._int, self._exp)
706
707 def __repr__(self):
708 """Represents the number as an instance of Decimal."""
709 # Invariant: eval(repr(d)) == d
710 return 'Decimal("%s")' % str(self)
711
712 def __str__(self, eng = 0, context=None):
713 """Return string representation of the number in scientific notation.
714
715 Captures all of the information in the underlying representation.
716 """
717
718 if self._isnan():
719 minus = '-'*self._sign
720 if self._int == (0,):
721 info = ''
722 else:
723 info = ''.join(map(str, self._int))
724 if self._isnan() == 2:
725 return minus + 'sNaN' + info
726 return minus + 'NaN' + info
727 if self._isinfinity():
728 minus = '-'*self._sign
729 return minus + 'Infinity'
730
731 if context is None:
732 context = getcontext()
733
734 tmp = map(str, self._int)
735 numdigits = len(self._int)
736 leftdigits = self._exp + numdigits
737 if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
738 if self._exp < 0 and self._exp >= -6: #short, no need for e/E
739 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
740 return s
741 #exp is closest mult. of 3 >= self._exp
742 exp = ((self._exp - 1)// 3 + 1) * 3
743 if exp != self._exp:
744 s = '0.'+'0'*(exp - self._exp)
745 else:
746 s = '0'
747 if exp != 0:
748 if context.capitals:
749 s += 'E'
750 else:
751 s += 'e'
752 if exp > 0:
753 s += '+' #0.0e+3, not 0.0e3
754 s += str(exp)
755 s = '-'*self._sign + s
756 return s
757 if eng:
758 dotplace = (leftdigits-1)%3+1
759 adjexp = leftdigits -1 - (leftdigits-1)%3
760 else:
761 adjexp = leftdigits-1
762 dotplace = 1
763 if self._exp == 0:
764 pass
765 elif self._exp < 0 and adjexp >= 0:
766 tmp.insert(leftdigits, '.')
767 elif self._exp < 0 and adjexp >= -6:
768 tmp[0:0] = ['0'] * int(-leftdigits)
769 tmp.insert(0, '0.')
770 else:
771 if numdigits > dotplace:
772 tmp.insert(dotplace, '.')
773 elif numdigits < dotplace:
774 tmp.extend(['0']*(dotplace-numdigits))
775 if adjexp:
776 if not context.capitals:
777 tmp.append('e')
778 else:
779 tmp.append('E')
780 if adjexp > 0:
781 tmp.append('+')
782 tmp.append(str(adjexp))
783 if eng:
784 while tmp[0:1] == ['0']:
785 tmp[0:1] = []
786 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
787 tmp[0:0] = ['0']
788 if self._sign:
789 tmp.insert(0, '-')
790
791 return ''.join(tmp)
792
793 def to_eng_string(self, context=None):
794 """Convert to engineering-type string.
795
796 Engineering notation has an exponent which is a multiple of 3, so there
797 are up to 3 digits left of the decimal place.
798
799 Same rules for when in exponential and when as a value as in __str__.
800 """
801 if context is None:
802 context = getcontext()
803 return self.__str__(eng=1, context=context)
804
805 def __neg__(self, context=None):
806 """Returns a copy with the sign switched.
807
808 Rounds, if it has reason.
809 """
810 if context is None:
811 context = getcontext()
812 ans = self._check_nans(context=context)
813 if ans:
814 return ans
815
816 if not self:
817 # -Decimal('0') is Decimal('0'), not Decimal('-0')
818 sign = 0
819 elif self._sign:
820 sign = 0
821 else:
822 sign = 1
823 if context._rounding_decision == ALWAYS_ROUND:
824 return Decimal((sign, self._int, self._exp))._fix(context=context)
825 return Decimal( (sign, self._int, self._exp))
826
827 def __pos__(self, context=None):
828 """Returns a copy, unless it is a sNaN.
829
830 Rounds the number (if more then precision digits)
831 """
832 if context is None:
833 context = getcontext()
834 ans = self._check_nans(context=context)
835 if ans:
836 return ans
837
838 sign = self._sign
839 if not self:
840 # + (-0) = 0
841 sign = 0
842
843 if context._rounding_decision == ALWAYS_ROUND:
844 ans = self._fix(context=context)
845 else:
846 ans = Decimal(self)
847 ans._sign = sign
848 return ans
849
850 def __abs__(self, round=1, context=None):
851 """Returns the absolute value of self.
852
853 If the second argument is 0, do not round.
854 """
855 if context is None:
856 context = getcontext()
857 ans = self._check_nans(context=context)
858 if ans:
859 return ans
860
861 if not round:
862 context = context.copy()
863 context._set_rounding_decision(NEVER_ROUND)
864
865 if self._sign:
866 ans = self.__neg__(context=context)
867 else:
868 ans = self.__pos__(context=context)
869
870 return ans
871
872 def __add__(self, other, context=None):
873 """Returns self + other.
874
875 -INF + INF (or the reverse) cause InvalidOperation errors.
876 """
877 if context is None:
878 context = getcontext()
879 other = self._convert_other(other)
880
881 ans = self._check_nans(other, context)
882 if ans:
883 return ans
884
885 if self._isinfinity():
886 #If both INF, same sign => same as both, opposite => error.
887 if self._sign != other._sign and other._isinfinity():
888 return context._raise_error(InvalidOperation, '-INF + INF')
889 return Decimal(self)
890 if other._isinfinity():
891 return Decimal(other) #Can't both be infinity here
892
893 shouldround = context._rounding_decision == ALWAYS_ROUND
894
895 exp = min(self._exp, other._exp)
896 negativezero = 0
897 if context.rounding == ROUND_FLOOR and self._sign != other._sign:
898 #If the answer is 0, the sign should be negative, in this case.
899 negativezero = 1
900
901 if not self and not other:
902 sign = min(self._sign, other._sign)
903 if negativezero:
904 sign = 1
905 return Decimal( (sign, (0,), exp))
906 if not self:
907 if exp < other._exp - context.prec-1:
908 exp = other._exp - context.prec-1
909 ans = other._rescale(exp, watchexp=0, context=context)
910 if shouldround:
911 ans = ans._fix(context=context)
912 return ans
913 if not other:
914 if exp < self._exp - context.prec-1:
915 exp = self._exp - context.prec-1
916 ans = self._rescale(exp, watchexp=0, context=context)
917 if shouldround:
918 ans = ans._fix(context=context)
919 return ans
920
921 op1 = _WorkRep(self)
922 op2 = _WorkRep(other)
923 op1, op2 = _normalize(op1, op2, shouldround, context.prec)
924
925 result = _WorkRep()
926
927 if op1.sign != op2.sign:
928 diff = cmp(abs(op1), abs(op2))
929 # Equal and opposite
930 if diff == 0:
931 if exp < context.Etiny():
932 exp = context.Etiny()
933 context._raise_error(Clamped)
934 return Decimal((negativezero, (0,), exp))
935 if diff < 0:
936 op1, op2 = op2, op1
937 #OK, now abs(op1) > abs(op2)
938 if op1.sign == -1:
939 result.sign = -1
940 op1.sign, op2.sign = op2.sign, op1.sign
941 else:
942 result.sign = 1
943 #So we know the sign, and op1 > 0.
944 elif op1.sign == -1:
945 result.sign = -1
946 op1.sign, op2.sign = (1, 1)
947 else:
948 result.sign = 1
949 #Now, op1 > abs(op2) > 0
950
951 op1.int.reverse()
952 op2.int.reverse()
953
954 if op2.sign == 1:
955 result.int = resultint = map(operator.add, op1.int, op2.int)
956 carry = 0
957 for i in xrange(len(op1.int)):
958 tmp = resultint[i] + carry
959 carry = 0
960 if tmp > 9:
961 carry = 1
962 tmp -= 10
963 resultint[i] = tmp
964 if carry:
965 resultint.append(1)
966 else:
967 result.int = resultint = map(operator.sub, op1.int, op2.int)
968 loan = 0
969 for i in xrange(len(op1.int)):
970 tmp = resultint[i] - loan
971 loan = 0
972 if tmp < 0:
973 loan = 1
974 tmp += 10
975 resultint[i] = tmp
976 assert not loan
977
978 while resultint[-1] == 0:
979 resultint.pop()
980 resultint.reverse()
981
982 result.exp = op1.exp
983 ans = Decimal(result)
984 if shouldround:
985 ans = ans._fix(context=context)
986 return ans
987
988 __radd__ = __add__
989
990 def __sub__(self, other, context=None):
991 """Return self + (-other)"""
992 if context is None:
993 context = getcontext()
994 other = self._convert_other(other)
995
996 ans = self._check_nans(other, context=context)
997 if ans:
998 return ans
999
1000 # -Decimal(0) = Decimal(0), which we don't want since
1001 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
1002 # so we change the sign directly to a copy
1003 tmp = Decimal(other)
1004 tmp._sign = 1-tmp._sign
1005
1006 return self.__add__(tmp, context=context)
1007
1008 def __rsub__(self, other, context=None):
1009 """Return other + (-self)"""
1010 if context is None:
1011 context = getcontext()
1012 other = self._convert_other(other)
1013
1014 tmp = Decimal(self)
1015 tmp._sign = 1 - tmp._sign
1016 return other.__add__(tmp, context=context)
1017
1018 def _increment(self, round=1, context=None):
1019 """Special case of add, adding 1eExponent
1020
1021 Since it is common, (rounding, for example) this adds
1022 (sign)*one E self._exp to the number more efficiently than add.
1023
1024 For example:
1025 Decimal('5.624e10')._increment() == Decimal('5.625e10')
1026 """
1027 if context is None:
1028 context = getcontext()
1029 ans = self._check_nans(context=context)
1030 if ans:
1031 return ans
1032
1033 L = list(self._int)
1034 L[-1] += 1
1035 spot = len(L)-1
1036 while L[spot] == 10:
1037 L[spot] = 0
1038 if spot == 0:
1039 L[0:0] = [1]
1040 break
1041 L[spot-1] += 1
1042 spot -= 1
1043 ans = Decimal((self._sign, L, self._exp))
1044
1045 if round and context._rounding_decision == ALWAYS_ROUND:
1046 ans = ans._fix(context=context)
1047 return ans
1048
1049 def __mul__(self, other, context=None):
1050 """Return self * other.
1051
1052 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1053 """
1054 if context is None:
1055 context = getcontext()
1056 other = self._convert_other(other)
1057
1058 ans = self._check_nans(other, context)
1059 if ans:
1060 return ans
1061
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001062 resultsign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001063 if self._isinfinity():
1064 if not other:
1065 return context._raise_error(InvalidOperation, '(+-)INF * 0')
1066 return Infsign[resultsign]
1067
1068 if other._isinfinity():
1069 if not self:
1070 return context._raise_error(InvalidOperation, '0 * (+-)INF')
1071 return Infsign[resultsign]
1072
1073 resultexp = self._exp + other._exp
1074 shouldround = context._rounding_decision == ALWAYS_ROUND
1075
1076 # Special case for multiplying by zero
1077 if not self or not other:
1078 ans = Decimal((resultsign, (0,), resultexp))
1079 if shouldround:
1080 #Fixing in case the exponent is out of bounds
1081 ans = ans._fix(context=context)
1082 return ans
1083
1084 # Special case for multiplying by power of 10
1085 if self._int == (1,):
1086 ans = Decimal((resultsign, other._int, resultexp))
1087 if shouldround:
1088 ans = ans._fix(context=context)
1089 return ans
1090 if other._int == (1,):
1091 ans = Decimal((resultsign, self._int, resultexp))
1092 if shouldround:
1093 ans = ans._fix(context=context)
1094 return ans
1095
1096 op1 = list(self._int)
1097 op2 = list(other._int)
1098 op1.reverse()
1099 op2.reverse()
1100 # Minimize Decimal additions
1101 if len(op2) > len(op1):
1102 op1, op2 = op2, op1
1103
1104 _divmod = divmod
1105 accumulator = [0]*(len(self._int) + len(other._int))
1106 for i in xrange(len(op2)):
1107 if op2[i] == 0:
1108 continue
1109 mult = op2[i]
1110 carry = 0
1111 for j in xrange(len(op1)):
1112 carry, accumulator[i+j] = _divmod( mult * op1[j] + carry
1113 + accumulator[i+j], 10)
1114
1115 if carry:
1116 accumulator[i + j + 1] += carry
1117 while not accumulator[-1]:
1118 accumulator.pop()
1119 accumulator.reverse()
1120
1121 ans = Decimal( (resultsign, accumulator, resultexp))
1122 if shouldround:
1123 ans = ans._fix(context=context)
1124
1125 return ans
1126 __rmul__ = __mul__
1127
1128 def __div__(self, other, context=None):
1129 """Return self / other."""
1130 return self._divide(other, context=context)
1131 __truediv__ = __div__
1132
1133 def _divide(self, other, divmod = 0, context=None):
1134 """Return a / b, to context.prec precision.
1135
1136 divmod:
1137 0 => true division
1138 1 => (a //b, a%b)
1139 2 => a //b
1140 3 => a%b
1141
1142 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1143 computing the other value are not raised.
1144 """
1145 if context is None:
1146 context = getcontext()
1147 other = self._convert_other(other)
1148
1149 ans = self._check_nans(other, context)
1150 if ans:
1151 if divmod:
1152 return (ans, ans)
1153 else:
1154 return ans
1155
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001156 sign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001157 if not self and not other:
1158 if divmod:
1159 return context._raise_error(DivisionUndefined, '0 / 0', 1)
1160 return context._raise_error(DivisionUndefined, '0 / 0')
1161 if self._isinfinity() and other._isinfinity():
1162 if not divmod:
1163 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
1164 else:
1165 return (context._raise_error(InvalidOperation,
1166 '(+-)INF // (+-)INF'),
1167 context._raise_error(InvalidOperation,
1168 '(+-)INF % (+-)INF'))
1169
1170 if not divmod:
1171 if other._isinfinity():
1172 context._raise_error(Clamped, 'Division by infinity')
1173 return Decimal((sign, (0,), context.Etiny()))
1174 if self._isinfinity():
1175 return Infsign[sign]
1176 #These two have different precision.
1177 if not self:
1178 exp = self._exp - other._exp
1179 if exp < context.Etiny():
1180 exp = context.Etiny()
1181 context._raise_error(Clamped, '0e-x / y')
1182 if exp > context.Emax:
1183 exp = context.Emax
1184 context._raise_error(Clamped, '0e+x / y')
1185 return Decimal( (sign, (0,), exp) )
1186
1187 if not other:
1188 return context._raise_error(DivisionByZero, 'x / 0', sign)
1189 if divmod:
1190 if other._isinfinity():
1191 return (Decimal((sign, (0,), 0)), Decimal(self))
1192 if self._isinfinity():
1193 if divmod == 1:
1194 return (Infsign[sign],
1195 context._raise_error(InvalidOperation, 'INF % x'))
1196 elif divmod == 2:
1197 return (Infsign[sign], NaN)
1198 elif divmod == 3:
1199 return (Infsign[sign],
1200 context._raise_error(InvalidOperation, 'INF % x'))
1201 if not self:
1202 otherside = Decimal(self)
1203 otherside._exp = min(self._exp, other._exp)
1204 return (Decimal((sign, (0,), 0)), otherside)
1205
1206 if not other:
1207 return context._raise_error(DivisionByZero, 'divmod(x,0)',
1208 sign, 1)
1209
1210 #OK, so neither = 0, INF
1211
1212 shouldround = context._rounding_decision == ALWAYS_ROUND
1213
1214 #If we're dividing into ints, and self < other, stop.
1215 #self.__abs__(0) does not round.
1216 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
1217
1218 if divmod == 1 or divmod == 3:
1219 exp = min(self._exp, other._exp)
1220 ans2 = self._rescale(exp, context=context, watchexp=0)
1221 if shouldround:
1222 ans2 = ans2._fix(context=context)
1223 return (Decimal( (sign, (0,), 0) ),
1224 ans2)
1225
1226 elif divmod == 2:
1227 #Don't round the mod part, if we don't need it.
1228 return (Decimal( (sign, (0,), 0) ), Decimal(self))
1229
1230 if sign:
1231 sign = -1
1232 else:
1233 sign = 1
1234 adjust = 0
1235 op1 = _WorkRep(self)
1236 op2 = _WorkRep(other)
1237 op1, op2, adjust = _adjust_coefficients(op1, op2)
1238 res = _WorkRep( (sign, [0], (op1.exp - op2.exp)) )
1239 if divmod and res.exp > context.prec + 1:
1240 return context._raise_error(DivisionImpossible)
1241
1242 ans = None
1243 while 1:
1244 while( (len(op2.int) < len(op1.int) and op1.int[0]) or
1245 (len(op2.int) == len(op1.int) and op2.int <= op1.int)):
1246 #Meaning, while op2.int < op1.int, when normalized.
1247 res._increment()
1248 op1.subtract(op2.int)
1249 if res.exp == 0 and divmod:
1250 if len(res.int) > context.prec and shouldround:
1251 return context._raise_error(DivisionImpossible)
1252 otherside = Decimal(op1)
1253 frozen = context._ignore_all_flags()
1254
1255 exp = min(self._exp, other._exp)
1256 otherside = otherside._rescale(exp, context=context,
1257 watchexp=0)
1258 context._regard_flags(*frozen)
1259 if shouldround:
1260 otherside = otherside._fix(context=context)
1261 return (Decimal(res), otherside)
1262
1263 if op1.int == [0]*len(op1.int) and adjust >= 0 and not divmod:
1264 break
1265 if (len(res.int) > context.prec) and shouldround:
1266 if divmod:
1267 return context._raise_error(DivisionImpossible)
1268 shouldround=1
1269 # Really, the answer is a bit higher, so adding a one to
1270 # the end will make sure the rounding is right.
1271 if op1.int != [0]*len(op1.int):
1272 res.int.append(1)
1273 res.exp -= 1
1274
1275 break
1276 res.exp -= 1
1277 adjust += 1
1278 res.int.append(0)
1279 op1.int.append(0)
1280 op1.exp -= 1
1281
1282 if res.exp == 0 and divmod and (len(op2.int) > len(op1.int) or
1283 (len(op2.int) == len(op1.int) and
1284 op2.int > op1.int)):
1285 #Solves an error in precision. Same as a previous block.
1286
1287 if len(res.int) > context.prec and shouldround:
1288 return context._raise_error(DivisionImpossible)
1289 otherside = Decimal(op1)
1290 frozen = context._ignore_all_flags()
1291
1292 exp = min(self._exp, other._exp)
1293 otherside = otherside._rescale(exp, context=context)
1294
1295 context._regard_flags(*frozen)
1296
1297 return (Decimal(res), otherside)
1298
1299 ans = Decimal(res)
1300 if shouldround:
1301 ans = ans._fix(context=context)
1302 return ans
1303
1304 def __rdiv__(self, other, context=None):
1305 """Swaps self/other and returns __div__."""
1306 other = self._convert_other(other)
1307 return other.__div__(self, context=context)
1308 __rtruediv__ = __rdiv__
1309
1310 def __divmod__(self, other, context=None):
1311 """
1312 (self // other, self % other)
1313 """
1314 return self._divide(other, 1, context)
1315
1316 def __rdivmod__(self, other, context=None):
1317 """Swaps self/other and returns __divmod__."""
1318 other = self._convert_other(other)
1319 return other.__divmod__(self, context=context)
1320
1321 def __mod__(self, other, context=None):
1322 """
1323 self % other
1324 """
1325 if context is None:
1326 context = getcontext()
1327 other = self._convert_other(other)
1328
1329 ans = self._check_nans(other, context)
1330 if ans:
1331 return ans
1332
1333 if self and not other:
1334 return context._raise_error(InvalidOperation, 'x % 0')
1335
1336 return self._divide(other, 3, context)[1]
1337
1338 def __rmod__(self, other, context=None):
1339 """Swaps self/other and returns __mod__."""
1340 other = self._convert_other(other)
1341 return other.__mod__(self, context=context)
1342
1343 def remainder_near(self, other, context=None):
1344 """
1345 Remainder nearest to 0- abs(remainder-near) <= other/2
1346 """
1347 if context is None:
1348 context = getcontext()
1349 other = self._convert_other(other)
1350
1351 ans = self._check_nans(other, context)
1352 if ans:
1353 return ans
1354 if self and not other:
1355 return context._raise_error(InvalidOperation, 'x % 0')
1356
1357 # If DivisionImpossible causes an error, do not leave Rounded/Inexact
1358 # ignored in the calling function.
1359 context = context.copy()
1360 flags = context._ignore_flags(Rounded, Inexact)
1361 #keep DivisionImpossible flags
1362 (side, r) = self.__divmod__(other, context=context)
1363
1364 if r._isnan():
1365 context._regard_flags(*flags)
1366 return r
1367
1368 context = context.copy()
1369 rounding = context._set_rounding_decision(NEVER_ROUND)
1370
1371 if other._sign:
1372 comparison = other.__div__(Decimal(-2), context=context)
1373 else:
1374 comparison = other.__div__(Decimal(2), context=context)
1375
1376 context._set_rounding_decision(rounding)
1377 context._regard_flags(*flags)
1378
1379 s1, s2 = r._sign, comparison._sign
1380 r._sign, comparison._sign = 0, 0
1381
1382 if r < comparison:
1383 r._sign, comparison._sign = s1, s2
1384 #Get flags now
1385 self.__divmod__(other, context=context)
1386 return r._fix(context=context)
1387 r._sign, comparison._sign = s1, s2
1388
1389 rounding = context._set_rounding_decision(NEVER_ROUND)
1390
1391 (side, r) = self.__divmod__(other, context=context)
1392 context._set_rounding_decision(rounding)
1393 if r._isnan():
1394 return r
1395
1396 decrease = not side._iseven()
1397 rounding = context._set_rounding_decision(NEVER_ROUND)
1398 side = side.__abs__(context=context)
1399 context._set_rounding_decision(rounding)
1400
1401 s1, s2 = r._sign, comparison._sign
1402 r._sign, comparison._sign = 0, 0
1403 if r > comparison or decrease and r == comparison:
1404 r._sign, comparison._sign = s1, s2
1405 context.prec += 1
1406 if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
1407 context.prec -= 1
1408 return context._raise_error(DivisionImpossible)[1]
1409 context.prec -= 1
1410 if self._sign == other._sign:
1411 r = r.__sub__(other, context=context)
1412 else:
1413 r = r.__add__(other, context=context)
1414 else:
1415 r._sign, comparison._sign = s1, s2
1416
1417 return r._fix(context=context)
1418
1419 def __floordiv__(self, other, context=None):
1420 """self // other"""
1421 return self._divide(other, 2, context)[0]
1422
1423 def __rfloordiv__(self, other, context=None):
1424 """Swaps self/other and returns __floordiv__."""
1425 other = self._convert_other(other)
1426 return other.__floordiv__(self, context=context)
1427
1428 def __float__(self):
1429 """Float representation."""
1430 return float(str(self))
1431
1432 def __int__(self):
1433 """Converts self to a int, truncating if necessary."""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001434 if self._isnan():
1435 context = getcontext()
1436 return context._raise_error(InvalidContext)
1437 elif self._isinfinity():
1438 raise OverflowError, "Cannot convert infinity to long"
1439 if not self:
1440 return 0
1441 sign = '-'*self._sign
1442 if self._exp >= 0:
1443 s = sign + ''.join(map(str, self._int)) + '0'*self._exp
1444 return int(s)
1445 s = sign + ''.join(map(str, self._int))[:self._exp]
1446 return int(s)
1447 tmp = list(self._int)
1448 tmp.reverse()
1449 val = 0
1450 while tmp:
1451 val *= 10
1452 val += tmp.pop()
1453 return int(((-1) ** self._sign) * val * 10.**int(self._exp))
1454
1455 def __long__(self):
1456 """Converts to a long.
1457
1458 Equivalent to long(int(self))
1459 """
1460 return long(self.__int__())
1461
1462 def _fix(self, prec=None, rounding=None, folddown=None, context=None):
1463 """Round if it is necessary to keep self within prec precision.
1464
1465 Rounds and fixes the exponent. Does not raise on a sNaN.
1466
1467 Arguments:
1468 self - Decimal instance
1469 prec - precision to which to round. By default, the context decides.
1470 rounding - Rounding method. By default, the context decides.
1471 folddown - Fold down high elements, by default context._clamp
1472 context - context used.
1473 """
1474 if self._isinfinity() or self._isnan():
1475 return self
1476 if context is None:
1477 context = getcontext()
1478 if prec is None:
1479 prec = context.prec
1480 ans = Decimal(self)
1481 ans = ans._fixexponents(prec, rounding, folddown=folddown,
1482 context=context)
1483 if len(ans._int) > prec:
1484 ans = ans._round(prec, rounding, context=context)
1485 ans = ans._fixexponents(prec, rounding, folddown=folddown,
1486 context=context)
1487 return ans
1488
1489 def _fixexponents(self, prec=None, rounding=None, folddown=None,
1490 context=None):
1491 """Fix the exponents and return a copy with the exponent in bounds."""
1492 if self._isinfinity():
1493 return self
1494 if context is None:
1495 context = getcontext()
1496 if prec is None:
1497 prec = context.prec
1498 if folddown is None:
1499 folddown = context._clamp
1500 Emin, Emax = context.Emin, context.Emax
1501 Etop = context.Etop()
1502 ans = Decimal(self)
1503 if ans.adjusted() < Emin:
1504 Etiny = context.Etiny()
1505 if ans._exp < Etiny:
1506 if not ans:
1507 ans._exp = Etiny
1508 context._raise_error(Clamped)
1509 return ans
1510 ans = ans._rescale(Etiny, context=context)
1511 #It isn't zero, and exp < Emin => subnormal
1512 context._raise_error(Subnormal)
1513 if context.flags[Inexact]:
1514 context._raise_error(Underflow)
1515 else:
1516 if ans:
1517 #Only raise subnormal if non-zero.
1518 context._raise_error(Subnormal)
1519 elif folddown and ans._exp > Etop:
1520 context._raise_error(Clamped)
1521 ans = ans._rescale(Etop, context=context)
1522 elif ans.adjusted() > Emax:
1523 if not ans:
1524 ans._exp = Emax
1525 context._raise_error(Clamped)
1526 return ans
1527 context._raise_error(Inexact)
1528 context._raise_error(Rounded)
1529 return context._raise_error(Overflow, 'above Emax', ans._sign)
1530 return ans
1531
1532 def _round(self, prec=None, rounding=None, context=None):
1533 """Returns a rounded version of self.
1534
1535 You can specify the precision or rounding method. Otherwise, the
1536 context determines it.
1537 """
1538
1539 if context is None:
1540 context = getcontext()
1541 ans = self._check_nans(context=context)
1542 if ans:
1543 return ans
1544
1545 if self._isinfinity():
1546 return Decimal(self)
1547
1548 if rounding is None:
1549 rounding = context.rounding
1550 if prec is None:
1551 prec = context.prec
1552
1553 if not self:
1554 if prec <= 0:
1555 dig = (0,)
1556 exp = len(self._int) - prec + self._exp
1557 else:
1558 dig = (0,) * prec
1559 exp = len(self._int) + self._exp - prec
1560 ans = Decimal((self._sign, dig, exp))
1561 context._raise_error(Rounded)
1562 return ans
1563
1564 if prec == 0:
1565 temp = Decimal(self)
1566 temp._int = (0,)+temp._int
1567 prec = 1
1568 elif prec < 0:
1569 exp = self._exp + len(self._int) - prec - 1
1570 temp = Decimal( (self._sign, (0, 1), exp))
1571 prec = 1
1572 else:
1573 temp = Decimal(self)
1574
1575 numdigits = len(temp._int)
1576 if prec == numdigits:
1577 return temp
1578
1579 # See if we need to extend precision
1580 expdiff = prec - numdigits
1581 if expdiff > 0:
1582 tmp = list(temp._int)
1583 tmp.extend([0] * expdiff)
1584 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff))
1585 return ans
1586
1587 #OK, but maybe all the lost digits are 0.
1588 lostdigits = self._int[expdiff:]
1589 if lostdigits == (0,) * len(lostdigits):
1590 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
1591 #Rounded, but not Inexact
1592 context._raise_error(Rounded)
1593 return ans
1594
1595 # Okay, let's round and lose data
1596
1597 this_function = getattr(temp, self._pick_rounding_function[rounding])
1598 #Now we've got the rounding function
1599
1600 if prec != context.prec:
1601 context = context.copy()
1602 context.prec = prec
1603 ans = this_function(prec, expdiff, context)
1604 context._raise_error(Rounded)
1605 context._raise_error(Inexact, 'Changed in rounding')
1606
1607 return ans
1608
1609 _pick_rounding_function = {}
1610
1611 def _round_down(self, prec, expdiff, context):
1612 """Also known as round-towards-0, truncate."""
1613 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1614
1615 def _round_half_up(self, prec, expdiff, context, tmp = None):
1616 """Rounds 5 up (away from 0)"""
1617
1618 if tmp is None:
1619 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
1620 if self._int[prec] >= 5:
1621 tmp = tmp._increment(round=0, context=context)
1622 if len(tmp._int) > prec:
1623 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1624 return tmp
1625
1626 def _round_half_even(self, prec, expdiff, context):
1627 """Round 5 to even, rest to nearest."""
1628
1629 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1630 half = (self._int[prec] == 5)
1631 if half:
1632 for digit in self._int[prec+1:]:
1633 if digit != 0:
1634 half = 0
1635 break
1636 if half:
1637 if self._int[prec-1] %2 == 0:
1638 return tmp
1639 return self._round_half_up(prec, expdiff, context, tmp)
1640
1641 def _round_half_down(self, prec, expdiff, context):
1642 """Round 5 down"""
1643
1644 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1645 half = (self._int[prec] == 5)
1646 if half:
1647 for digit in self._int[prec+1:]:
1648 if digit != 0:
1649 half = 0
1650 break
1651 if half:
1652 return tmp
1653 return self._round_half_up(prec, expdiff, context, tmp)
1654
1655 def _round_up(self, prec, expdiff, context):
1656 """Rounds away from 0."""
1657 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1658 for digit in self._int[prec:]:
1659 if digit != 0:
1660 tmp = tmp._increment(round=1, context=context)
1661 if len(tmp._int) > prec:
1662 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1663 else:
1664 return tmp
1665 return tmp
1666
1667 def _round_ceiling(self, prec, expdiff, context):
1668 """Rounds up (not away from 0 if negative.)"""
1669 if self._sign:
1670 return self._round_down(prec, expdiff, context)
1671 else:
1672 return self._round_up(prec, expdiff, context)
1673
1674 def _round_floor(self, prec, expdiff, context):
1675 """Rounds down (not towards 0 if negative)"""
1676 if not self._sign:
1677 return self._round_down(prec, expdiff, context)
1678 else:
1679 return self._round_up(prec, expdiff, context)
1680
1681 def __pow__(self, n, modulo = None, context=None):
1682 """Return self ** n (mod modulo)
1683
1684 If modulo is None (default), don't take it mod modulo.
1685 """
1686 if context is None:
1687 context = getcontext()
1688 n = self._convert_other(n)
1689
1690 #Because the spot << doesn't work with really big exponents
1691 if n._isinfinity() or n.adjusted() > 8:
1692 return context._raise_error(InvalidOperation, 'x ** INF')
1693
1694 ans = self._check_nans(n, context)
1695 if ans:
1696 return ans
1697
1698 if not n._isinfinity() and not n._isinteger():
1699 return context._raise_error(InvalidOperation, 'x ** (non-integer)')
1700
1701 if not self and not n:
1702 return context._raise_error(InvalidOperation, '0 ** 0')
1703
1704 if not n:
1705 return Decimal(1)
1706
1707 if self == Decimal(1):
1708 return Decimal(1)
1709
1710 sign = self._sign and not n._iseven()
1711 n = int(n)
1712
1713 if self._isinfinity():
1714 if modulo:
1715 return context._raise_error(InvalidOperation, 'INF % x')
1716 if n > 0:
1717 return Infsign[sign]
1718 return Decimal( (sign, (0,), 0) )
1719
1720 #with ludicrously large exponent, just raise an overflow and return inf.
1721 if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
1722 and self:
1723
1724 tmp = Decimal('inf')
1725 tmp._sign = sign
1726 context._raise_error(Rounded)
1727 context._raise_error(Inexact)
1728 context._raise_error(Overflow, 'Big power', sign)
1729 return tmp
1730
1731 elength = len(str(abs(n)))
1732 firstprec = context.prec
1733
Raymond Hettinger99148e72004-07-14 19:56:56 +00001734 if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001735 return context._raise_error(Overflow, 'Too much precision.', sign)
1736
1737 mul = Decimal(self)
1738 val = Decimal(1)
1739 context = context.copy()
1740 context.prec = firstprec + elength + 1
1741 rounding = context.rounding
1742 if n < 0:
1743 #n is a long now, not Decimal instance
1744 n = -n
1745 mul = Decimal(1).__div__(mul, context=context)
1746
1747 shouldround = context._rounding_decision == ALWAYS_ROUND
1748
1749 spot = 1
1750 while spot <= n:
1751 spot <<= 1
1752
1753 spot >>= 1
1754 #Spot is the highest power of 2 less than n
1755 while spot:
1756 val = val.__mul__(val, context=context)
1757 if val._isinfinity():
1758 val = Infsign[sign]
1759 break
1760 if spot & n:
1761 val = val.__mul__(mul, context=context)
1762 if modulo is not None:
1763 val = val.__mod__(modulo, context=context)
1764 spot >>= 1
1765 context.prec = firstprec
1766
1767 if shouldround:
1768 return val._fix(context=context)
1769 return val
1770
1771 def __rpow__(self, other, context=None):
1772 """Swaps self/other and returns __pow__."""
1773 other = self._convert_other(other)
1774 return other.__pow__(self, context=context)
1775
1776 def normalize(self, context=None):
1777 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
1778 if context is None:
1779 context = getcontext()
1780
1781 ans = self._check_nans(context=context)
1782 if ans:
1783 return ans
1784
1785 dup = self._fix(context=context)
1786 if dup._isinfinity():
1787 return dup
1788
1789 if not dup:
1790 return Decimal( (dup._sign, (0,), 0) )
1791 end = len(dup._int)
1792 exp = dup._exp
1793 while dup._int[end-1] == 0:
1794 exp += 1
1795 end -= 1
1796 return Decimal( (dup._sign, dup._int[:end], exp) )
1797
1798
1799 def quantize(self, exp, rounding = None, context=None, watchexp = 1):
1800 """Quantize self so its exponent is the same as that of exp.
1801
1802 Similar to self._rescale(exp._exp) but with error checking.
1803 """
1804 if context is None:
1805 context = getcontext()
1806
1807 ans = self._check_nans(exp, context)
1808 if ans:
1809 return ans
1810
1811 if exp._isinfinity() or self._isinfinity():
1812 if exp._isinfinity() and self._isinfinity():
1813 return self #if both are inf, it is OK
1814 return context._raise_error(InvalidOperation,
1815 'quantize with one INF')
1816 return self._rescale(exp._exp, rounding, context, watchexp)
1817
1818 def same_quantum(self, other):
1819 """Test whether self and other have the same exponent.
1820
1821 same as self._exp == other._exp, except NaN == sNaN
1822 """
1823 if self._isnan() or other._isnan():
1824 return self._isnan() and other._isnan() and True
1825 if self._isinfinity() or other._isinfinity():
1826 return self._isinfinity() and other._isinfinity() and True
1827 return self._exp == other._exp
1828
1829 def _rescale(self, exp, rounding = None, context=None, watchexp = 1):
1830 """Rescales so that the exponent is exp.
1831
1832 exp = exp to scale to (an integer)
1833 rounding = rounding version
1834 watchexp: if set (default) an error is returned if exp is greater
1835 than Emax or less than Etiny.
1836 """
1837 if context is None:
1838 context = getcontext()
1839
1840 if self._isinfinity():
1841 return context._raise_error(InvalidOperation, 'rescale with an INF')
1842
1843 ans = self._check_nans(context=context)
1844 if ans:
1845 return ans
1846
1847 out = 0
1848
1849 if watchexp and (context.Emax < exp or context.Etiny() > exp):
1850 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1851
1852 if not self:
1853 ans = Decimal(self)
1854 ans._int = (0,)
1855 ans._exp = exp
1856 return ans
1857
1858 diff = self._exp - exp
1859 digits = len(self._int)+diff
1860
1861 if watchexp and digits > context.prec:
1862 return context._raise_error(InvalidOperation, 'Rescale > prec')
1863
1864 tmp = Decimal(self)
1865 tmp._int = (0,)+tmp._int
1866 digits += 1
1867
1868 prevexact = context.flags[Inexact]
1869 if digits < 0:
1870 tmp._exp = -digits + tmp._exp
1871 tmp._int = (0,1)
1872 digits = 1
1873 tmp = tmp._round(digits, rounding, context=context)
1874
1875 if tmp._int[0] == 0 and len(tmp._int) > 1:
1876 tmp._int = tmp._int[1:]
1877 tmp._exp = exp
1878
1879 if tmp and tmp.adjusted() < context.Emin:
1880 context._raise_error(Subnormal)
1881 elif tmp and tmp.adjusted() > context.Emax:
1882 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1883 return tmp
1884
1885 def to_integral(self, rounding = None, context=None):
1886 """Rounds to the nearest integer, without raising inexact, rounded."""
1887 if context is None:
1888 context = getcontext()
1889 ans = self._check_nans(context=context)
1890 if ans:
1891 return ans
1892 if self._exp >= 0:
1893 return self
1894 flags = context._ignore_flags(Rounded, Inexact)
1895 ans = self._rescale(0, rounding, context=context)
1896 context._regard_flags(flags)
1897 return ans
1898
1899 def sqrt(self, context=None):
1900 """Return the square root of self.
1901
1902 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
1903 Should quadratically approach the right answer.
1904 """
1905 if context is None:
1906 context = getcontext()
1907
1908 ans = self._check_nans(context=context)
1909 if ans:
1910 return ans
1911
1912 if not self:
1913 #exponent = self._exp / 2, using round_down.
1914 #if self._exp < 0:
1915 # exp = (self._exp+1) // 2
1916 #else:
1917 exp = (self._exp) // 2
1918 if self._sign == 1:
1919 #sqrt(-0) = -0
1920 return Decimal( (1, (0,), exp))
1921 else:
1922 return Decimal( (0, (0,), exp))
1923
1924 if self._sign == 1:
1925 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
1926
1927 if self._isinfinity():
1928 return Decimal(self)
1929
1930 tmp = Decimal(self)
1931
1932 expadd = tmp._exp / 2
1933 if tmp._exp % 2 == 1:
1934 tmp._int += (0,)
1935 tmp._exp = 0
1936 else:
1937 tmp._exp = 0
1938
1939 context = context.copy()
1940 flags = context._ignore_all_flags()
1941 firstprec = context.prec
1942 context.prec = 3
1943 if tmp.adjusted() % 2 == 0:
1944 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) )
1945 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
1946 context=context), context=context)
1947 ans._exp -= 1 + tmp.adjusted()/2
1948 else:
1949 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
1950 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
1951 context=context), context=context)
1952 ans._exp -= 1 + tmp.adjusted()/2
1953
1954 #ans is now a linear approximation.
1955
1956 Emax, Emin = context.Emax, context.Emin
Raymond Hettinger99148e72004-07-14 19:56:56 +00001957 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001958
1959 half = Decimal('0.5')
1960
1961 count = 1
1962 maxp = firstprec + 2
1963 rounding = context._set_rounding(ROUND_HALF_EVEN)
1964 while 1:
1965 context.prec = min(2*context.prec - 2, maxp)
1966 ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
1967 context=context), context=context)
1968 if context.prec == maxp:
1969 break
1970
1971 #round to the answer's precision-- the only error can be 1 ulp.
1972 context.prec = firstprec
1973 prevexp = ans.adjusted()
1974 ans = ans._round(context=context)
1975
1976 #Now, check if the other last digits are better.
1977 context.prec = firstprec + 1
1978 # In case we rounded up another digit and we should actually go lower.
1979 if prevexp != ans.adjusted():
1980 ans._int += (0,)
1981 ans._exp -= 1
1982
1983
1984 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
1985 context._set_rounding(ROUND_UP)
1986 if lower.__mul__(lower, context=context) > (tmp):
1987 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
1988
1989 else:
1990 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
1991 context._set_rounding(ROUND_DOWN)
1992 if upper.__mul__(upper, context=context) < tmp:
1993 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
1994
1995 ans._exp += expadd
1996
1997 context.prec = firstprec
1998 context.rounding = rounding
1999 ans = ans._fix(context=context)
2000
2001 rounding = context._set_rounding_decision(NEVER_ROUND)
2002 if not ans.__mul__(ans, context=context) == self:
2003 # Only rounded/inexact if here.
2004 context._regard_flags(flags)
2005 context._raise_error(Rounded)
2006 context._raise_error(Inexact)
2007 else:
2008 #Exact answer, so let's set the exponent right.
2009 #if self._exp < 0:
2010 # exp = (self._exp +1)// 2
2011 #else:
2012 exp = self._exp // 2
2013 context.prec += ans._exp - exp
2014 ans = ans._rescale(exp, context=context)
2015 context.prec = firstprec
2016 context._regard_flags(flags)
2017 context.Emax, context.Emin = Emax, Emin
2018
2019 return ans._fix(context=context)
2020
2021 def max(self, other, context=None):
2022 """Returns the larger value.
2023
2024 like max(self, other) except if one is not a number, returns
2025 NaN (and signals if one is sNaN). Also rounds.
2026 """
2027 if context is None:
2028 context = getcontext()
2029 other = self._convert_other(other)
2030
2031 ans = self._check_nans(other, context)
2032 if ans:
2033 return ans
2034
2035 ans = self
2036 if self < other:
2037 ans = other
2038 shouldround = context._rounding_decision == ALWAYS_ROUND
2039 if shouldround:
2040 ans = ans._fix(context=context)
2041 return ans
2042
2043 def min(self, other, context=None):
2044 """Returns the smaller value.
2045
2046 like min(self, other) except if one is not a number, returns
2047 NaN (and signals if one is sNaN). Also rounds.
2048 """
2049 if context is None:
2050 context = getcontext()
2051 other = self._convert_other(other)
2052
2053 ans = self._check_nans(other, context)
2054 if ans:
2055 return ans
2056
2057 ans = self
2058
2059 if self > other:
2060 ans = other
2061
2062 if context._rounding_decision == ALWAYS_ROUND:
2063 ans = ans._fix(context=context)
2064
2065 return ans
2066
2067 def _isinteger(self):
2068 """Returns whether self is an integer"""
2069 if self._exp >= 0:
2070 return True
2071 rest = self._int[self._exp:]
2072 return rest == (0,)*len(rest)
2073
2074 def _iseven(self):
2075 """Returns 1 if self is even. Assumes self is an integer."""
2076 if self._exp > 0:
2077 return 1
2078 return self._int[-1+self._exp] % 2 == 0
2079
2080 def adjusted(self):
2081 """Return the adjusted exponent of self"""
2082 try:
2083 return self._exp + len(self._int) - 1
2084 #If NaN or Infinity, self._exp is string
2085 except TypeError:
2086 return 0
2087
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002088 # support for pickling, copy, and deepcopy
2089 def __reduce__(self):
2090 return (self.__class__, (str(self),))
2091
2092 def __copy__(self):
2093 if type(self) == Decimal:
2094 return self # I'm immutable; therefore I am my own clone
2095 return self.__class__(str(self))
2096
2097 def __deepcopy__(self, memo):
2098 if type(self) == Decimal:
2099 return self # My components are also immutable
2100 return self.__class__(str(self))
2101
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002102##### Context class ###########################################
2103
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002104
2105# get rounding method function:
2106rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
2107for name in rounding_functions:
2108 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
2109 globalname = name[1:].upper()
2110 val = globals()[globalname]
2111 Decimal._pick_rounding_function[val] = name
2112
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002113del name, val, globalname, rounding_functions
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002114
2115class Context(object):
2116 """Contains the context for a Decimal instance.
2117
2118 Contains:
2119 prec - precision (for use in rounding, division, square roots..)
2120 rounding - rounding type. (how you round)
2121 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
Raymond Hettingerbf440692004-07-10 14:14:37 +00002122 traps - If traps[exception] = 1, then the exception is
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002123 raised when it is caused. Otherwise, a value is
2124 substituted in.
2125 flags - When an exception is caused, flags[exception] is incremented.
2126 (Whether or not the trap_enabler is set)
2127 Should be reset by user of Decimal instance.
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002128 Emin - Minimum exponent
2129 Emax - Maximum exponent
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002130 capitals - If 1, 1*10^1 is printed as 1E+1.
2131 If 0, printed as 1e1
Raymond Hettingere0f15812004-07-05 05:36:39 +00002132 _clamp - If 1, change exponents if too high (Default 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002133 """
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002134
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002135 def __init__(self, prec=None, rounding=None,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002136 traps=None, flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002137 _rounding_decision=None,
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002138 Emin=None, Emax=None,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002139 capitals=None, _clamp=0,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002140 _ignored_flags=[]):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002141 if not isinstance(flags, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002142 flags = dict([(s,s in flags) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002143 del s
Raymond Hettingerbf440692004-07-10 14:14:37 +00002144 if traps is not None and not isinstance(traps, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002145 traps = dict([(s,s in traps) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002146 del s
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002147 for name, val in locals().items():
2148 if val is None:
2149 setattr(self, name, copy.copy(getattr(DefaultContext, name)))
2150 else:
2151 setattr(self, name, val)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002152 del self.self
2153
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002154 def __repr__(self):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002155 """Show the current context."""
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002156 s = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002157 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
2158 s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
2159 s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002160 return ', '.join(s) + ')'
2161
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002162 def clear_flags(self):
2163 """Reset all flags to zero"""
2164 for flag in self.flags:
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002165 self.flags[flag] = 0
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002166
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002167 def copy(self):
2168 """Returns a copy from self."""
Raymond Hettingerbf440692004-07-10 14:14:37 +00002169 nc = Context(self.prec, self.rounding, self.traps, self.flags,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002170 self._rounding_decision, self.Emin, self.Emax,
2171 self.capitals, self._clamp, self._ignored_flags)
2172 return nc
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002173 __copy__ = copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002174
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002175 def _raise_error(self, condition, explanation = None, *args):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002176 """Handles an error
2177
2178 If the flag is in _ignored_flags, returns the default response.
2179 Otherwise, it increments the flag, then, if the corresponding
2180 trap_enabler is set, it reaises the exception. Otherwise, it returns
2181 the default value after incrementing the flag.
2182 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002183 error = _condition_map.get(condition, condition)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002184 if error in self._ignored_flags:
2185 #Don't touch the flag
2186 return error().handle(self, *args)
2187
2188 self.flags[error] += 1
Raymond Hettingerbf440692004-07-10 14:14:37 +00002189 if not self.traps[error]:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002190 #The errors define how to handle themselves.
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002191 return condition().handle(self, *args)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002192
2193 # Errors should only be risked on copies of the context
2194 #self._ignored_flags = []
2195 raise error, explanation
2196
2197 def _ignore_all_flags(self):
2198 """Ignore all flags, if they are raised"""
Raymond Hettingerfed52962004-07-14 15:41:57 +00002199 return self._ignore_flags(*_signals)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002200
2201 def _ignore_flags(self, *flags):
2202 """Ignore the flags, if they are raised"""
2203 # Do not mutate-- This way, copies of a context leave the original
2204 # alone.
2205 self._ignored_flags = (self._ignored_flags + list(flags))
2206 return list(flags)
2207
2208 def _regard_flags(self, *flags):
2209 """Stop ignoring the flags, if they are raised"""
2210 if flags and isinstance(flags[0], (tuple,list)):
2211 flags = flags[0]
2212 for flag in flags:
2213 self._ignored_flags.remove(flag)
2214
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002215 def __hash__(self):
2216 """A Context cannot be hashed."""
2217 # We inherit object.__hash__, so we must deny this explicitly
2218 raise TypeError, "Cannot hash a Context."
2219
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002220 def Etiny(self):
2221 """Returns Etiny (= Emin - prec + 1)"""
2222 return int(self.Emin - self.prec + 1)
2223
2224 def Etop(self):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002225 """Returns maximum exponent (= Emax - prec + 1)"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002226 return int(self.Emax - self.prec + 1)
2227
2228 def _set_rounding_decision(self, type):
2229 """Sets the rounding decision.
2230
2231 Sets the rounding decision, and returns the current (previous)
2232 rounding decision. Often used like:
2233
2234 context = context.copy()
2235 # That so you don't change the calling context
2236 # if an error occurs in the middle (say DivisionImpossible is raised).
2237
2238 rounding = context._set_rounding_decision(NEVER_ROUND)
2239 instance = instance / Decimal(2)
2240 context._set_rounding_decision(rounding)
2241
2242 This will make it not round for that operation.
2243 """
2244
2245 rounding = self._rounding_decision
2246 self._rounding_decision = type
2247 return rounding
2248
2249 def _set_rounding(self, type):
2250 """Sets the rounding type.
2251
2252 Sets the rounding type, and returns the current (previous)
2253 rounding type. Often used like:
2254
2255 context = context.copy()
2256 # so you don't change the calling context
2257 # if an error occurs in the middle.
2258 rounding = context._set_rounding(ROUND_UP)
2259 val = self.__sub__(other, context=context)
2260 context._set_rounding(rounding)
2261
2262 This will make it round up for that operation.
2263 """
2264 rounding = self.rounding
2265 self.rounding= type
2266 return rounding
2267
Raymond Hettingerfed52962004-07-14 15:41:57 +00002268 def create_decimal(self, num='0'):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002269 """Creates a new Decimal instance but using self as context."""
2270 d = Decimal(num, context=self)
2271 return d._fix(context=self)
2272
2273 #Methods
2274 def abs(self, a):
2275 """Returns the absolute value of the operand.
2276
2277 If the operand is negative, the result is the same as using the minus
2278 operation on the operand. Otherwise, the result is the same as using
2279 the plus operation on the operand.
2280
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002281 >>> ExtendedContext.abs(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002282 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002283 >>> ExtendedContext.abs(Decimal('-100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002284 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002285 >>> ExtendedContext.abs(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002286 Decimal("101.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002287 >>> ExtendedContext.abs(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002288 Decimal("101.5")
2289 """
2290 return a.__abs__(context=self)
2291
2292 def add(self, a, b):
2293 """Return the sum of the two operands.
2294
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002295 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002296 Decimal("19.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002297 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002298 Decimal("1.02E+4")
2299 """
2300 return a.__add__(b, context=self)
2301
2302 def _apply(self, a):
2303 return str(a._fix(context=self))
2304
2305 def compare(self, a, b):
2306 """Compares values numerically.
2307
2308 If the signs of the operands differ, a value representing each operand
2309 ('-1' if the operand is less than zero, '0' if the operand is zero or
2310 negative zero, or '1' if the operand is greater than zero) is used in
2311 place of that operand for the comparison instead of the actual
2312 operand.
2313
2314 The comparison is then effected by subtracting the second operand from
2315 the first and then returning a value according to the result of the
2316 subtraction: '-1' if the result is less than zero, '0' if the result is
2317 zero or negative zero, or '1' if the result is greater than zero.
2318
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002319 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002320 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002321 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002322 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002323 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002324 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002325 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002326 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002327 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002328 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002329 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002330 Decimal("-1")
2331 """
2332 return a.compare(b, context=self)
2333
2334 def divide(self, a, b):
2335 """Decimal division in a specified context.
2336
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002337 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002338 Decimal("0.333333333")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002339 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002340 Decimal("0.666666667")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002341 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002342 Decimal("2.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002343 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002344 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002345 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002346 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002347 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002348 Decimal("4.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002349 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002350 Decimal("1.20")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002351 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002352 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002353 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002354 Decimal("1000")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002355 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002356 Decimal("1.20E+6")
2357 """
2358 return a.__div__(b, context=self)
2359
2360 def divide_int(self, a, b):
2361 """Divides two numbers and returns the integer part of the result.
2362
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002363 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002364 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002365 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002366 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002367 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002368 Decimal("3")
2369 """
2370 return a.__floordiv__(b, context=self)
2371
2372 def divmod(self, a, b):
2373 return a.__divmod__(b, context=self)
2374
2375 def max(self, a,b):
2376 """max compares two values numerically and returns the maximum.
2377
2378 If either operand is a NaN then the general rules apply.
2379 Otherwise, the operands are compared as as though by the compare
2380 operation. If they are numerically equal then the left-hand operand
2381 is chosen as the result. Otherwise the maximum (closer to positive
2382 infinity) of the two operands is chosen as the result.
2383
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002384 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002385 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002386 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002387 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002388 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002389 Decimal("1.0")
2390 """
2391 return a.max(b, context=self)
2392
2393 def min(self, a,b):
2394 """min compares two values numerically and returns the minimum.
2395
2396 If either operand is a NaN then the general rules apply.
2397 Otherwise, the operands are compared as as though by the compare
2398 operation. If they are numerically equal then the left-hand operand
2399 is chosen as the result. Otherwise the minimum (closer to negative
2400 infinity) of the two operands is chosen as the result.
2401
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002402 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002403 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002404 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002405 Decimal("-10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002406 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002407 Decimal("1.0")
2408 """
2409 return a.min(b, context=self)
2410
2411 def minus(self, a):
2412 """Minus corresponds to unary prefix minus in Python.
2413
2414 The operation is evaluated using the same rules as subtract; the
2415 operation minus(a) is calculated as subtract('0', a) where the '0'
2416 has the same exponent as the operand.
2417
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002418 >>> ExtendedContext.minus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002419 Decimal("-1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002420 >>> ExtendedContext.minus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002421 Decimal("1.3")
2422 """
2423 return a.__neg__(context=self)
2424
2425 def multiply(self, a, b):
2426 """multiply multiplies two operands.
2427
2428 If either operand is a special value then the general rules apply.
2429 Otherwise, the operands are multiplied together ('long multiplication'),
2430 resulting in a number which may be as long as the sum of the lengths
2431 of the two operands.
2432
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002433 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002434 Decimal("3.60")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002435 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002436 Decimal("21")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002437 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002438 Decimal("0.72")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002439 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002440 Decimal("-0.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002441 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002442 Decimal("4.28135971E+11")
2443 """
2444 return a.__mul__(b, context=self)
2445
2446 def normalize(self, a):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002447 """normalize reduces an operand to its simplest form.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002448
2449 Essentially a plus operation with all trailing zeros removed from the
2450 result.
2451
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002452 >>> ExtendedContext.normalize(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002453 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002454 >>> ExtendedContext.normalize(Decimal('-2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002455 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002456 >>> ExtendedContext.normalize(Decimal('1.200'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002457 Decimal("1.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002458 >>> ExtendedContext.normalize(Decimal('-120'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002459 Decimal("-1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002460 >>> ExtendedContext.normalize(Decimal('120.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002461 Decimal("1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002462 >>> ExtendedContext.normalize(Decimal('0.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002463 Decimal("0")
2464 """
2465 return a.normalize(context=self)
2466
2467 def plus(self, a):
2468 """Plus corresponds to unary prefix plus in Python.
2469
2470 The operation is evaluated using the same rules as add; the
2471 operation plus(a) is calculated as add('0', a) where the '0'
2472 has the same exponent as the operand.
2473
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002474 >>> ExtendedContext.plus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002475 Decimal("1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002476 >>> ExtendedContext.plus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002477 Decimal("-1.3")
2478 """
2479 return a.__pos__(context=self)
2480
2481 def power(self, a, b, modulo=None):
2482 """Raises a to the power of b, to modulo if given.
2483
2484 The right-hand operand must be a whole number whose integer part (after
2485 any exponent has been applied) has no more than 9 digits and whose
2486 fractional part (if any) is all zeros before any rounding. The operand
2487 may be positive, negative, or zero; if negative, the absolute value of
2488 the power is used, and the left-hand operand is inverted (divided into
2489 1) before use.
2490
2491 If the increased precision needed for the intermediate calculations
2492 exceeds the capabilities of the implementation then an Invalid operation
2493 condition is raised.
2494
2495 If, when raising to a negative power, an underflow occurs during the
2496 division into 1, the operation is not halted at that point but
2497 continues.
2498
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002499 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002500 Decimal("8")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002501 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002502 Decimal("0.125")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002503 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002504 Decimal("69.7575744")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002505 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002506 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002507 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002508 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002509 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002510 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002511 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002512 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002513 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002514 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002515 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002516 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002517 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002518 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002519 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002520 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002521 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002522 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002523 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002524 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002525 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002526 Decimal("NaN")
2527 """
2528 return a.__pow__(b, modulo, context=self)
2529
2530 def quantize(self, a, b):
2531 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
2532
2533 The coefficient of the result is derived from that of the left-hand
2534 operand. It may be rounded using the current rounding setting (if the
2535 exponent is being increased), multiplied by a positive power of ten (if
2536 the exponent is being decreased), or is unchanged (if the exponent is
2537 already equal to that of the right-hand operand).
2538
2539 Unlike other operations, if the length of the coefficient after the
2540 quantize operation would be greater than precision then an Invalid
2541 operation condition is raised. This guarantees that, unless there is an
2542 error condition, the exponent of the result of a quantize is always
2543 equal to that of the right-hand operand.
2544
2545 Also unlike other operations, quantize will never raise Underflow, even
2546 if the result is subnormal and inexact.
2547
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002548 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002549 Decimal("2.170")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002550 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002551 Decimal("2.17")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002552 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002553 Decimal("2.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002554 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002555 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002556 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002557 Decimal("0E+1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002558 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002559 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002560 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002561 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002562 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002563 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002564 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002565 Decimal("-0E+5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002566 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002567 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002568 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002569 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002570 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002571 Decimal("217.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002572 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002573 Decimal("217")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002574 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002575 Decimal("2.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002576 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002577 Decimal("2E+2")
2578 """
2579 return a.quantize(b, context=self)
2580
2581 def remainder(self, a, b):
2582 """Returns the remainder from integer division.
2583
2584 The result is the residue of the dividend after the operation of
2585 calculating integer division as described for divide-integer, rounded to
2586 precision digits if necessary. The sign of the result, if non-zero, is
2587 the same as that of the original dividend.
2588
2589 This operation will fail under the same conditions as integer division
2590 (that is, if integer division on the same two operands would fail, the
2591 remainder cannot be calculated).
2592
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002593 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002594 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002595 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002596 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002597 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002598 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002599 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002600 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002601 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002602 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002603 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002604 Decimal("1.0")
2605 """
2606 return a.__mod__(b, context=self)
2607
2608 def remainder_near(self, a, b):
2609 """Returns to be "a - b * n", where n is the integer nearest the exact
2610 value of "x / b" (if two integers are equally near then the even one
2611 is chosen). If the result is equal to 0 then its sign will be the
2612 sign of a.
2613
2614 This operation will fail under the same conditions as integer division
2615 (that is, if integer division on the same two operands would fail, the
2616 remainder cannot be calculated).
2617
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002618 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002619 Decimal("-0.9")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002620 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002621 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002622 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002623 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002624 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002625 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002626 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002627 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002628 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002629 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002630 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002631 Decimal("-0.3")
2632 """
2633 return a.remainder_near(b, context=self)
2634
2635 def same_quantum(self, a, b):
2636 """Returns True if the two operands have the same exponent.
2637
2638 The result is never affected by either the sign or the coefficient of
2639 either operand.
2640
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002641 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002642 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002643 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002644 True
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002645 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002646 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002647 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002648 True
2649 """
2650 return a.same_quantum(b)
2651
2652 def sqrt(self, a):
2653 """Returns the square root of a non-negative number to context precision.
2654
2655 If the result must be inexact, it is rounded using the round-half-even
2656 algorithm.
2657
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002658 >>> ExtendedContext.sqrt(Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002659 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002660 >>> ExtendedContext.sqrt(Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002661 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002662 >>> ExtendedContext.sqrt(Decimal('0.39'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002663 Decimal("0.624499800")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002664 >>> ExtendedContext.sqrt(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002665 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002666 >>> ExtendedContext.sqrt(Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002667 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002668 >>> ExtendedContext.sqrt(Decimal('1.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002669 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002670 >>> ExtendedContext.sqrt(Decimal('1.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002671 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002672 >>> ExtendedContext.sqrt(Decimal('7'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002673 Decimal("2.64575131")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002674 >>> ExtendedContext.sqrt(Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002675 Decimal("3.16227766")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002676 >>> ExtendedContext.prec
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002677 9
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002678 """
2679 return a.sqrt(context=self)
2680
2681 def subtract(self, a, b):
2682 """Return the sum of the two operands.
2683
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002684 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002685 Decimal("0.23")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002686 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002687 Decimal("0.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002688 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002689 Decimal("-0.77")
2690 """
2691 return a.__sub__(b, context=self)
2692
2693 def to_eng_string(self, a):
2694 """Converts a number to a string, using scientific notation.
2695
2696 The operation is not affected by the context.
2697 """
2698 return a.to_eng_string(context=self)
2699
2700 def to_sci_string(self, a):
2701 """Converts a number to a string, using scientific notation.
2702
2703 The operation is not affected by the context.
2704 """
2705 return a.__str__(context=self)
2706
2707 def to_integral(self, a):
2708 """Rounds to an integer.
2709
2710 When the operand has a negative exponent, the result is the same
2711 as using the quantize() operation using the given operand as the
2712 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2713 of the operand as the precision setting, except that no flags will
2714 be set. The rounding mode is taken from the context.
2715
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002716 >>> ExtendedContext.to_integral(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002717 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002718 >>> ExtendedContext.to_integral(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002719 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002720 >>> ExtendedContext.to_integral(Decimal('100.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002721 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002722 >>> ExtendedContext.to_integral(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002723 Decimal("102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002724 >>> ExtendedContext.to_integral(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002725 Decimal("-102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002726 >>> ExtendedContext.to_integral(Decimal('10E+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002727 Decimal("1.0E+6")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002728 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002729 Decimal("7.89E+77")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002730 >>> ExtendedContext.to_integral(Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002731 Decimal("-Infinity")
2732 """
2733 return a.to_integral(context=self)
2734
2735class _WorkRep(object):
2736 __slots__ = ('sign','int','exp')
2737 # sign: -1 None 1
2738 # int: list
2739 # exp: None, int, or string
2740
2741 def __init__(self, value=None):
2742 if value is None:
2743 self.sign = None
2744 self.int = []
2745 self.exp = None
2746 if isinstance(value, Decimal):
2747 if value._sign:
2748 self.sign = -1
2749 else:
2750 self.sign = 1
2751 self.int = list(value._int)
2752 self.exp = value._exp
2753 if isinstance(value, tuple):
2754 self.sign = value[0]
2755 self.int = value[1]
2756 self.exp = value[2]
2757
2758 def __repr__(self):
2759 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2760
2761 __str__ = __repr__
2762
2763 def __neg__(self):
2764 if self.sign == 1:
2765 return _WorkRep( (-1, self.int, self.exp) )
2766 else:
2767 return _WorkRep( (1, self.int, self.exp) )
2768
2769 def __abs__(self):
2770 if self.sign == -1:
2771 return -self
2772 else:
2773 return self
2774
2775 def __cmp__(self, other):
2776 if self.exp != other.exp:
2777 raise ValueError("Operands not normalized: %r, %r" % (self, other))
2778 if self.sign != other.sign:
2779 if self.sign == -1:
2780 return -1
2781 else:
2782 return 1
2783 if self.sign == -1:
2784 direction = -1
2785 else:
2786 direction = 1
2787 int1 = self.int
2788 int2 = other.int
2789 if len(int1) > len(int2):
2790 return direction * 1
2791 if len(int1) < len(int2):
2792 return direction * -1
2793 for i in xrange(len(int1)):
2794 if int1[i] > int2[i]:
2795 return direction * 1
2796 if int1[i] < int2[i]:
2797 return direction * -1
2798 return 0
2799
2800 def _increment(self):
2801 curspot = len(self.int) - 1
2802 self.int[curspot]+= 1
2803 while (self.int[curspot] >= 10):
2804 self.int[curspot] -= 10
2805 if curspot == 0:
2806 self.int[0:0] = [1]
2807 break
2808 self.int[curspot-1] += 1
2809 curspot -= 1
2810
2811 def subtract(self, alist):
2812 """Subtract a list from the current int (in place).
2813
2814 It is assured that (len(list) = len(self.int) and list < self.int) or
2815 len(list) = len(self.int)-1
2816 (i.e. that int(join(list)) < int(join(self.int)))
2817 """
2818
2819 selfint = self.int
2820 selfint.reverse()
2821 alist.reverse()
2822
2823 carry = 0
2824 for x in xrange(len(alist)):
2825 selfint[x] -= alist[x] + carry
2826 if selfint[x] < 0:
2827 carry = 1
2828 selfint[x] += 10
2829 else:
Tim Peters4e0e1b62004-07-07 20:54:48 +00002830 carry = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002831 if carry:
2832 selfint[x+1] -= 1
2833 last = len(selfint)-1
2834 while len(selfint) > 1 and selfint[last] == 0:
2835 last -= 1
2836 if last == 0:
2837 break
2838 selfint[last+1:]=[]
2839 selfint.reverse()
2840 alist.reverse()
2841 return
2842
2843
2844def _normalize(op1, op2, shouldround = 0, prec = 0):
2845 """Normalizes op1, op2 to have the same exp and length of coefficient.
2846
2847 Done during addition.
2848 """
2849 # Yes, the exponent is a long, but the difference between exponents
2850 # must be an int-- otherwise you'd get a big memory problem.
2851 numdigits = int(op1.exp - op2.exp)
2852 if numdigits < 0:
2853 numdigits = -numdigits
2854 tmp = op2
2855 other = op1
2856 else:
2857 tmp = op1
2858 other = op2
2859
2860 if shouldround and numdigits > len(other.int) + prec + 1 -len(tmp.int):
2861 # If the difference in adjusted exps is > prec+1, we know
2862 # other is insignificant, so might as well put a 1 after the precision.
2863 # (since this is only for addition.) Also stops MemoryErrors.
2864
2865 extend = prec + 2 -len(tmp.int)
2866 if extend <= 0:
2867 extend = 1
2868 tmp.int.extend([0]*extend)
2869 tmp.exp -= extend
2870 other.int[:] = [0]*(len(tmp.int)-1)+[1]
2871 other.exp = tmp.exp
2872 return op1, op2
2873
2874 tmp.int.extend([0] * numdigits)
2875 tmp.exp = tmp.exp - numdigits
2876 numdigits = len(op1.int) - len(op2.int)
2877 # numdigits != 0 => They have the same exponent, but not the same length
2878 # of the coefficient.
2879 if numdigits < 0:
2880 numdigits = -numdigits
2881 tmp = op1
2882 else:
2883 tmp = op2
2884 tmp.int[0:0] = [0] * numdigits
2885 return op1, op2
2886
2887def _adjust_coefficients(op1, op2):
2888 """Adjust op1, op2 so that op2.int+[0] > op1.int >= op2.int.
2889
2890 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2891
2892 Used on _WorkRep instances during division.
2893 """
2894 adjust = 0
2895 #If op1 is smaller, get it to same size
2896 if len(op2.int) > len(op1.int):
2897 diff = len(op2.int) - len(op1.int)
2898 op1.int.extend([0]*diff)
2899 op1.exp -= diff
2900 adjust = diff
2901
2902 #Same length, wrong order
2903 if len(op1.int) == len(op2.int) and op1.int < op2.int:
2904 op1.int.append(0)
2905 op1.exp -= 1
2906 adjust+= 1
2907 return op1, op2, adjust
2908
2909 if len(op1.int) > len(op2.int) + 1:
2910 diff = len(op1.int) - len(op2.int) - 1
2911 op2.int.extend([0]*diff)
2912 op2.exp -= diff
2913 adjust -= diff
2914
2915 if len(op1.int) == len(op2.int)+1 and op1.int > op2.int:
2916
2917 op2.int.append(0)
2918 op2.exp -= 1
2919 adjust -= 1
2920 return op1, op2, adjust
2921
2922##### Helper Functions ########################################
2923
2924_infinity_map = {
2925 'inf' : 1,
2926 'infinity' : 1,
2927 '+inf' : 1,
2928 '+infinity' : 1,
2929 '-inf' : -1,
2930 '-infinity' : -1
2931}
2932
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002933def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002934 """Determines whether a string or float is infinity.
2935
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002936 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002937 """
2938 num = str(num).lower()
2939 return _infinity_map.get(num, 0)
2940
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002941def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002942 """Determines whether a string or float is NaN
2943
2944 (1, sign, diagnostic info as string) => NaN
2945 (2, sign, diagnostic info as string) => sNaN
2946 0 => not a NaN
2947 """
2948 num = str(num).lower()
2949 if not num:
2950 return 0
2951
2952 #get the sign, get rid of trailing [+-]
2953 sign = 0
2954 if num[0] == '+':
2955 num = num[1:]
2956 elif num[0] == '-': #elif avoids '+-nan'
2957 num = num[1:]
2958 sign = 1
2959
2960 if num.startswith('nan'):
2961 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
2962 return 0
2963 return (1, sign, num[3:].lstrip('0'))
2964 if num.startswith('snan'):
2965 if len(num) > 4 and not num[4:].isdigit():
2966 return 0
2967 return (2, sign, num[4:].lstrip('0'))
2968 return 0
2969
2970
2971##### Setup Specific Contexts ################################
2972
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002973# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00002974# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002975
2976DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002977 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002978 traps=[DivisionByZero, Overflow, InvalidOperation],
2979 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002980 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00002981 Emax=999999999,
2982 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002983 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002984)
2985
2986# Pre-made alternate contexts offered by the specification
2987# Don't change these; the user should be able to select these
2988# contexts and be able to reproduce results from other implementations
2989# of the spec.
2990
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002991BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002992 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002993 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
2994 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002995)
2996
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002997ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002998 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002999 traps=[],
3000 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003001)
3002
3003
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00003004##### Useful Constants (internal use only) ####################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003005
3006#Reusable defaults
3007Inf = Decimal('Inf')
3008negInf = Decimal('-Inf')
3009
3010#Infsign[sign] is infinity w/ that sign
3011Infsign = (Inf, negInf)
3012
3013NaN = Decimal('NaN')
3014
3015
3016##### crud for parsing strings #################################
3017import re
3018
3019# There's an optional sign at the start, and an optional exponent
3020# at the end. The exponent has an optional sign and at least one
3021# digit. In between, must have either at least one digit followed
3022# by an optional fraction, or a decimal point followed by at least
3023# one digit. Yuck.
3024
3025_parser = re.compile(r"""
3026# \s*
3027 (?P<sign>[-+])?
3028 (
3029 (?P<int>\d+) (\. (?P<frac>\d*))?
3030 |
3031 \. (?P<onlyfrac>\d+)
3032 )
3033 ([eE](?P<exp>[-+]? \d+))?
3034# \s*
3035 $
3036""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
3037
3038del re
3039
3040# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
3041
3042def _string2exact(s):
3043 m = _parser(s)
3044 if m is None:
3045 raise ValueError("invalid literal for Decimal: %r" % s)
3046
3047 if m.group('sign') == "-":
3048 sign = 1
3049 else:
3050 sign = 0
3051
3052 exp = m.group('exp')
3053 if exp is None:
3054 exp = 0
3055 else:
3056 exp = int(exp)
3057
3058 intpart = m.group('int')
3059 if intpart is None:
3060 intpart = ""
3061 fracpart = m.group('onlyfrac')
3062 else:
3063 fracpart = m.group('frac')
3064 if fracpart is None:
3065 fracpart = ""
3066
3067 exp -= len(fracpart)
3068
3069 mantissa = intpart + fracpart
3070 tmp = map(int, mantissa)
3071 backup = tmp
3072 while tmp and tmp[0] == 0:
3073 del tmp[0]
3074
3075 # It's a zero
3076 if not tmp:
3077 if backup:
3078 return (sign, tuple(backup), exp)
3079 return (sign, (0,), exp)
3080 mantissa = tuple(tmp)
3081
3082 return (sign, mantissa, exp)
3083
3084
3085if __name__ == '__main__':
3086 import doctest, sys
3087 doctest.testmod(sys.modules[__name__])