blob: b7c893d5f6194bc0a1f9cbcfd53b6a5593438fca [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
Raymond Hettinger27dbcf22004-08-19 22:39:55 +000010# This module is currently Py2.3 compatible and should be kept that way
11# unless a major compelling advantage arises. IOW, 2.3 compatibility is
12# strongly preferred, but not guaranteed.
13
14# Also, this module should be kept in sync with the latest updates of
15# the IBM specification as it evolves. Those updates will be treated
16# as bug fixes (deviation from the spec is a compatibility, usability
17# bug) and will be backported. At this point the spec is stabilizing
18# and the updates are becoming fewer, smaller, and less significant.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000019
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000020"""
21This is a Py2.3 implementation of decimal floating point arithmetic based on
22the General Decimal Arithmetic Specification:
23
24 www2.hursley.ibm.com/decimal/decarith.html
25
Raymond Hettinger0ea241e2004-07-04 13:53:24 +000026and IEEE standard 854-1987:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000027
28 www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html
29
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000030Decimal floating point has finite precision with arbitrarily large bounds.
31
32The purpose of the module is to support arithmetic using familiar
33"schoolhouse" rules and to avoid the some of tricky representation
34issues associated with binary floating point. The package is especially
35useful for financial applications or for contexts where users have
36expectations that are at odds with binary floating point (for instance,
37in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead
38of the expected Decimal("0.00") returned by decimal floating point).
39
40Here are some examples of using the decimal module:
41
42>>> from decimal import *
Raymond Hettingerbd7f76d2004-07-08 00:49:18 +000043>>> setcontext(ExtendedContext)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000044>>> Decimal(0)
45Decimal("0")
46>>> Decimal("1")
47Decimal("1")
48>>> Decimal("-.0123")
49Decimal("-0.0123")
50>>> Decimal(123456)
51Decimal("123456")
52>>> Decimal("123.45e12345678901234567890")
53Decimal("1.2345E+12345678901234567892")
54>>> Decimal("1.33") + Decimal("1.27")
55Decimal("2.60")
56>>> Decimal("12.34") + Decimal("3.87") - Decimal("18.41")
57Decimal("-2.20")
58>>> dig = Decimal(1)
59>>> print dig / Decimal(3)
600.333333333
61>>> getcontext().prec = 18
62>>> print dig / Decimal(3)
630.333333333333333333
64>>> print dig.sqrt()
651
66>>> print Decimal(3).sqrt()
671.73205080756887729
68>>> print Decimal(3) ** 123
694.85192780976896427E+58
70>>> inf = Decimal(1) / Decimal(0)
71>>> print inf
72Infinity
73>>> neginf = Decimal(-1) / Decimal(0)
74>>> print neginf
75-Infinity
76>>> print neginf + inf
77NaN
78>>> print neginf * inf
79-Infinity
80>>> print dig / 0
81Infinity
Raymond Hettingerbf440692004-07-10 14:14:37 +000082>>> getcontext().traps[DivisionByZero] = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000083>>> print dig / 0
84Traceback (most recent call last):
85 ...
86 ...
87 ...
88DivisionByZero: x / 0
89>>> c = Context()
Raymond Hettingerbf440692004-07-10 14:14:37 +000090>>> c.traps[InvalidOperation] = 0
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000091>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000920
93>>> c.divide(Decimal(0), Decimal(0))
94Decimal("NaN")
Raymond Hettingerbf440692004-07-10 14:14:37 +000095>>> c.traps[InvalidOperation] = 1
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000096>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000971
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000098>>> c.flags[InvalidOperation] = 0
99>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001000
101>>> print c.divide(Decimal(0), Decimal(0))
102Traceback (most recent call last):
103 ...
104 ...
105 ...
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000106InvalidOperation: 0 / 0
107>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001081
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000109>>> c.flags[InvalidOperation] = 0
Raymond Hettingerbf440692004-07-10 14:14:37 +0000110>>> c.traps[InvalidOperation] = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000111>>> print c.divide(Decimal(0), Decimal(0))
112NaN
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000113>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001141
115>>>
116"""
117
118__all__ = [
119 # Two major classes
120 'Decimal', 'Context',
121
122 # Contexts
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +0000123 'DefaultContext', 'BasicContext', 'ExtendedContext',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000124
125 # Exceptions
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +0000126 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
127 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000128
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000129 # Constants for use in setting up contexts
130 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING',
131 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000132
133 # Functions for manipulating contexts
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000134 'setcontext', 'getcontext'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000135]
136
137import threading
138import copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000139import operator
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000140
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000141#Rounding
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000142ROUND_DOWN = 'ROUND_DOWN'
143ROUND_HALF_UP = 'ROUND_HALF_UP'
144ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
145ROUND_CEILING = 'ROUND_CEILING'
146ROUND_FLOOR = 'ROUND_FLOOR'
147ROUND_UP = 'ROUND_UP'
148ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000149
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +0000150#Rounding decision (not part of the public API)
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000151NEVER_ROUND = 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY
152ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000153
154#Errors
155
156class DecimalException(ArithmeticError):
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000157 """Base exception class.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000158
159 Used exceptions derive from this.
160 If an exception derives from another exception besides this (such as
161 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
162 called if the others are present. This isn't actually used for
163 anything, though.
164
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000165 handle -- Called when context._raise_error is called and the
166 trap_enabler is set. First argument is self, second is the
167 context. More arguments can be given, those being after
168 the explanation in _raise_error (For example,
169 context._raise_error(NewError, '(-x)!', self._sign) would
170 call NewError().handle(context, self._sign).)
171
172 To define a new exception, it should be sufficient to have it derive
173 from DecimalException.
174 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000175 def handle(self, context, *args):
176 pass
177
178
179class Clamped(DecimalException):
180 """Exponent of a 0 changed to fit bounds.
181
182 This occurs and signals clamped if the exponent of a result has been
183 altered in order to fit the constraints of a specific concrete
184 representation. This may occur when the exponent of a zero result would
185 be outside the bounds of a representation, or when a large normal
186 number would have an encoded exponent that cannot be represented. In
187 this latter case, the exponent is reduced to fit and the corresponding
188 number of zero digits are appended to the coefficient ("fold-down").
189 """
190
191
192class InvalidOperation(DecimalException):
193 """An invalid operation was performed.
194
195 Various bad things cause this:
196
197 Something creates a signaling NaN
198 -INF + INF
199 0 * (+-)INF
200 (+-)INF / (+-)INF
201 x % 0
202 (+-)INF % x
203 x._rescale( non-integer )
204 sqrt(-x) , x > 0
205 0 ** 0
206 x ** (non-integer)
207 x ** (+-)INF
208 An operand is invalid
209 """
210 def handle(self, context, *args):
211 if args:
212 if args[0] == 1: #sNaN, must drop 's' but keep diagnostics
213 return Decimal( (args[1]._sign, args[1]._int, 'n') )
214 return NaN
215
216class ConversionSyntax(InvalidOperation):
217 """Trying to convert badly formed string.
218
219 This occurs and signals invalid-operation if an string is being
220 converted to a number and it does not conform to the numeric string
221 syntax. The result is [0,qNaN].
222 """
223
224 def handle(self, context, *args):
225 return (0, (0,), 'n') #Passed to something which uses a tuple.
226
227class DivisionByZero(DecimalException, ZeroDivisionError):
228 """Division by 0.
229
230 This occurs and signals division-by-zero if division of a finite number
231 by zero was attempted (during a divide-integer or divide operation, or a
232 power operation with negative right-hand operand), and the dividend was
233 not zero.
234
235 The result of the operation is [sign,inf], where sign is the exclusive
236 or of the signs of the operands for divide, or is 1 for an odd power of
237 -0, for power.
238 """
239
240 def handle(self, context, sign, double = None, *args):
241 if double is not None:
242 return (Infsign[sign],)*2
243 return Infsign[sign]
244
245class DivisionImpossible(InvalidOperation):
246 """Cannot perform the division adequately.
247
248 This occurs and signals invalid-operation if the integer result of a
249 divide-integer or remainder operation had too many digits (would be
250 longer than precision). The result is [0,qNaN].
251 """
252
253 def handle(self, context, *args):
254 return (NaN, NaN)
255
256class DivisionUndefined(InvalidOperation, ZeroDivisionError):
257 """Undefined result of division.
258
259 This occurs and signals invalid-operation if division by zero was
260 attempted (during a divide-integer, divide, or remainder operation), and
261 the dividend is also zero. The result is [0,qNaN].
262 """
263
264 def handle(self, context, tup=None, *args):
265 if tup is not None:
266 return (NaN, NaN) #for 0 %0, 0 // 0
267 return NaN
268
269class Inexact(DecimalException):
270 """Had to round, losing information.
271
272 This occurs and signals inexact whenever the result of an operation is
273 not exact (that is, it needed to be rounded and any discarded digits
274 were non-zero), or if an overflow or underflow condition occurs. The
275 result in all cases is unchanged.
276
277 The inexact signal may be tested (or trapped) to determine if a given
278 operation (or sequence of operations) was inexact.
279 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000280 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000281
282class InvalidContext(InvalidOperation):
283 """Invalid context. Unknown rounding, for example.
284
285 This occurs and signals invalid-operation if an invalid context was
286 detected during an operation. This can occur if contexts are not checked
287 on creation and either the precision exceeds the capability of the
288 underlying concrete representation or an unknown or unsupported rounding
289 was specified. These aspects of the context need only be checked when
290 the values are required to be used. The result is [0,qNaN].
291 """
292
293 def handle(self, context, *args):
294 return NaN
295
296class Rounded(DecimalException):
297 """Number got rounded (not necessarily changed during rounding).
298
299 This occurs and signals rounded whenever the result of an operation is
300 rounded (that is, some zero or non-zero digits were discarded from the
301 coefficient), or if an overflow or underflow condition occurs. The
302 result in all cases is unchanged.
303
304 The rounded signal may be tested (or trapped) to determine if a given
305 operation (or sequence of operations) caused a loss of precision.
306 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000307 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000308
309class Subnormal(DecimalException):
310 """Exponent < Emin before rounding.
311
312 This occurs and signals subnormal whenever the result of a conversion or
313 operation is subnormal (that is, its adjusted exponent is less than
314 Emin, before any rounding). The result in all cases is unchanged.
315
316 The subnormal signal may be tested (or trapped) to determine if a given
317 or operation (or sequence of operations) yielded a subnormal result.
318 """
319 pass
320
321class Overflow(Inexact, Rounded):
322 """Numerical overflow.
323
324 This occurs and signals overflow if the adjusted exponent of a result
325 (from a conversion or from an operation that is not an attempt to divide
326 by zero), after rounding, would be greater than the largest value that
327 can be handled by the implementation (the value Emax).
328
329 The result depends on the rounding mode:
330
331 For round-half-up and round-half-even (and for round-half-down and
332 round-up, if implemented), the result of the operation is [sign,inf],
333 where sign is the sign of the intermediate result. For round-down, the
334 result is the largest finite number that can be represented in the
335 current precision, with the sign of the intermediate result. For
336 round-ceiling, the result is the same as for round-down if the sign of
337 the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
338 the result is the same as for round-down if the sign of the intermediate
339 result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
340 will also be raised.
341 """
342
343 def handle(self, context, sign, *args):
344 if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
345 ROUND_HALF_DOWN, ROUND_UP):
346 return Infsign[sign]
347 if sign == 0:
348 if context.rounding == ROUND_CEILING:
349 return Infsign[sign]
350 return Decimal((sign, (9,)*context.prec,
351 context.Emax-context.prec+1))
352 if sign == 1:
353 if context.rounding == ROUND_FLOOR:
354 return Infsign[sign]
355 return Decimal( (sign, (9,)*context.prec,
356 context.Emax-context.prec+1))
357
358
359class Underflow(Inexact, Rounded, Subnormal):
360 """Numerical underflow with result rounded to 0.
361
362 This occurs and signals underflow if a result is inexact and the
363 adjusted exponent of the result would be smaller (more negative) than
364 the smallest value that can be handled by the implementation (the value
365 Emin). That is, the result is both inexact and subnormal.
366
367 The result after an underflow will be a subnormal number rounded, if
368 necessary, so that its exponent is not less than Etiny. This may result
369 in 0 with the sign of the intermediate result and an exponent of Etiny.
370
371 In all cases, Inexact, Rounded, and Subnormal will also be raised.
372 """
373
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000374# List of public traps and flags
Raymond Hettingerfed52962004-07-14 15:41:57 +0000375_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000376 Underflow, InvalidOperation, Subnormal]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000377
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000378# Map conditions (per the spec) to signals
379_condition_map = {ConversionSyntax:InvalidOperation,
380 DivisionImpossible:InvalidOperation,
381 DivisionUndefined:InvalidOperation,
382 InvalidContext:InvalidOperation}
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000383
384##### Context Functions #######################################
385
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000386# The getcontext() and setcontext() function manage access to a thread-local
387# current context. Py2.4 offers direct support for thread locals. If that
388# is not available, use threading.currentThread() which is slower but will
389# work for older Pythons.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000390
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000391try:
392 threading.local
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000393
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000394except AttributeError:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000395
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000396 #To fix reloading, force it to create a new context
397 #Old contexts have different exceptions in their dicts, making problems.
398 if hasattr(threading.currentThread(), '__decimal_context__'):
399 del threading.currentThread().__decimal_context__
400
401 def setcontext(context):
402 """Set this thread's context to context."""
403 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000404 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000405 context.clear_flags()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000406 threading.currentThread().__decimal_context__ = context
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000407
408 def getcontext():
409 """Returns this thread's context.
410
411 If this thread does not yet have a context, returns
412 a new context and sets this thread's context.
413 New contexts are copies of DefaultContext.
414 """
415 try:
416 return threading.currentThread().__decimal_context__
417 except AttributeError:
418 context = Context()
419 threading.currentThread().__decimal_context__ = context
420 return context
421
422else:
423
424 local = threading.local()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000425 if hasattr(local, '__decimal_context__'):
426 del local.__decimal_context__
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000427
428 def getcontext(_local=local):
429 """Returns this thread's context.
430
431 If this thread does not yet have a context, returns
432 a new context and sets this thread's context.
433 New contexts are copies of DefaultContext.
434 """
435 try:
436 return _local.__decimal_context__
437 except AttributeError:
438 context = Context()
439 _local.__decimal_context__ = context
440 return context
441
442 def setcontext(context, _local=local):
443 """Set this thread's context to context."""
444 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000445 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000446 context.clear_flags()
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000447 _local.__decimal_context__ = context
448
449 del threading, local # Don't contaminate the namespace
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000450
451
452##### Decimal class ###########################################
453
454class Decimal(object):
455 """Floating point class for decimal arithmetic."""
456
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000457 __slots__ = ('_exp','_int','_sign', '_is_special')
458 # Generally, the value of the Decimal instance is given by
459 # (-1)**_sign * _int * 10**_exp
460 # Special values are signified by _is_special == True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000461
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000462 # We're immutable, so use _new__ not __init__
463 def __new__(cls, value="0", context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000464 """Create a decimal point instance.
465
466 >>> Decimal('3.14') # string input
467 Decimal("3.14")
468 >>> Decimal((0, (3, 1, 4), -2)) # tuple input (sign, digit_tuple, exponent)
469 Decimal("3.14")
470 >>> Decimal(314) # int or long
471 Decimal("314")
472 >>> Decimal(Decimal(314)) # another decimal instance
473 Decimal("314")
474 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000475
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000476 self = object.__new__(cls)
477 self._is_special = False
478
479 # From an internal working value
480 if isinstance(value, _WorkRep):
481 if value.sign == 1:
482 self._sign = 0
483 else:
484 self._sign = 1
485 self._int = tuple(map(int, str(value.int)))
486 self._exp = int(value.exp)
487 return self
488
489 # From another decimal
490 if isinstance(value, Decimal):
491 self._exp = value._exp
492 self._sign = value._sign
493 self._int = value._int
494 self._is_special = value._is_special
495 return self
496
497 # From an integer
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000498 if isinstance(value, (int,long)):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000499 if value >= 0:
500 self._sign = 0
501 else:
502 self._sign = 1
503 self._exp = 0
504 self._int = tuple(map(int, str(abs(value))))
505 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000506
507 # tuple/list conversion (possibly from as_tuple())
508 if isinstance(value, (list,tuple)):
509 if len(value) != 3:
510 raise ValueError, 'Invalid arguments'
511 if value[0] not in [0,1]:
512 raise ValueError, 'Invalid sign'
513 for digit in value[1]:
514 if not isinstance(digit, (int,long)) or digit < 0:
515 raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
516
517 self._sign = value[0]
518 self._int = tuple(value[1])
519 if value[2] in ('F','n','N'):
520 self._exp = value[2]
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000521 self._is_special = True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000522 else:
523 self._exp = int(value[2])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000524 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000525
Raymond Hettingerbf440692004-07-10 14:14:37 +0000526 if isinstance(value, float):
527 raise TypeError("Cannot convert float to Decimal. " +
528 "First convert the float to a string")
529
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000530 # Other argument types may require the context during interpretation
531 if context is None:
532 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000533
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000534 # From a string
535 # REs insist on real strings, so we can too.
536 if isinstance(value, basestring):
537 if _isinfinity(value):
538 self._exp = 'F'
539 self._int = (0,)
540 self._is_special = True
541 if _isinfinity(value) == 1:
542 self._sign = 0
543 else:
544 self._sign = 1
545 return self
546 if _isnan(value):
547 sig, sign, diag = _isnan(value)
548 self._is_special = True
549 if len(diag) > context.prec: #Diagnostic info too long
550 self._sign, self._int, self._exp = \
551 context._raise_error(ConversionSyntax)
552 return self
553 if sig == 1:
554 self._exp = 'n' #qNaN
555 else: #sig == 2
556 self._exp = 'N' #sNaN
557 self._sign = sign
558 self._int = tuple(map(int, diag)) #Diagnostic info
559 return self
560 try:
561 self._sign, self._int, self._exp = _string2exact(value)
562 except ValueError:
563 self._is_special = True
564 self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
565 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000566
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000567 raise TypeError("Cannot convert %r to Decimal" % value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000568
569 def _isnan(self):
570 """Returns whether the number is not actually one.
571
572 0 if a number
573 1 if NaN
574 2 if sNaN
575 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000576 if self._is_special:
577 exp = self._exp
578 if exp == 'n':
579 return 1
580 elif exp == 'N':
581 return 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000582 return 0
583
584 def _isinfinity(self):
585 """Returns whether the number is infinite
586
587 0 if finite or not a number
588 1 if +INF
589 -1 if -INF
590 """
591 if self._exp == 'F':
592 if self._sign:
593 return -1
594 return 1
595 return 0
596
597 def _check_nans(self, other = None, context=None):
598 """Returns whether the number is not actually one.
599
600 if self, other are sNaN, signal
601 if self, other are NaN return nan
602 return 0
603
604 Done before operations.
605 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000606
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000607 self_is_nan = self._isnan()
608 if other is None:
609 other_is_nan = False
610 else:
611 other_is_nan = other._isnan()
612
613 if self_is_nan or other_is_nan:
614 if context is None:
615 context = getcontext()
616
617 if self_is_nan == 2:
618 return context._raise_error(InvalidOperation, 'sNaN',
619 1, self)
620 if other_is_nan == 2:
621 return context._raise_error(InvalidOperation, 'sNaN',
622 1, other)
623 if self_is_nan:
624 return self
625
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000626 return other
627 return 0
628
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000629 def __nonzero__(self):
630 """Is the number non-zero?
631
632 0 if self == 0
633 1 if self != 0
634 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000635 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000636 return 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000637 return sum(self._int) != 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000638
639 def __cmp__(self, other, context=None):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000640 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000641
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000642 if self._is_special or other._is_special:
643 ans = self._check_nans(other, context)
644 if ans:
645 return 1 # Comparison involving NaN's always reports self > other
646
647 # INF = INF
648 return cmp(self._isinfinity(), other._isinfinity())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000649
650 if not self and not other:
651 return 0 #If both 0, sign comparison isn't certain.
652
653 #If different signs, neg one is less
654 if other._sign < self._sign:
655 return -1
656 if self._sign < other._sign:
657 return 1
658
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000659 self_adjusted = self.adjusted()
660 other_adjusted = other.adjusted()
661 if self_adjusted == other_adjusted and \
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000662 self._int + (0,)*(self._exp - other._exp) == \
663 other._int + (0,)*(other._exp - self._exp):
664 return 0 #equal, except in precision. ([0]*(-x) = [])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000665 elif self_adjusted > other_adjusted and self._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000666 return (-1)**self._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000667 elif self_adjusted < other_adjusted and other._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000668 return -((-1)**self._sign)
669
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000670 # Need to round, so make sure we have a valid context
671 if context is None:
672 context = getcontext()
673
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000674 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000675 rounding = context._set_rounding(ROUND_UP) #round away from 0
676
677 flags = context._ignore_all_flags()
678 res = self.__sub__(other, context=context)
679
680 context._regard_flags(*flags)
681
682 context.rounding = rounding
683
684 if not res:
685 return 0
686 elif res._sign:
687 return -1
688 return 1
689
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000690 def __eq__(self, other):
691 if not isinstance(other, (Decimal, int, long)):
692 return False
693 return self.__cmp__(other) == 0
694
695 def __ne__(self, other):
696 if not isinstance(other, (Decimal, int, long)):
697 return True
698 return self.__cmp__(other) != 0
699
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000700 def compare(self, other, context=None):
701 """Compares one to another.
702
703 -1 => a < b
704 0 => a = b
705 1 => a > b
706 NaN => one is NaN
707 Like __cmp__, but returns Decimal instances.
708 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000709 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000710
711 #compare(NaN, NaN) = NaN
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000712 if (self._is_special or other and other._is_special):
713 ans = self._check_nans(other, context)
714 if ans:
715 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000716
717 return Decimal(self.__cmp__(other, context))
718
719 def __hash__(self):
720 """x.__hash__() <==> hash(x)"""
721 # Decimal integers must hash the same as the ints
722 # Non-integer decimals are normalized and hashed as strings
723 # Normalization assures that hast(100E-1) == hash(10)
724 i = int(self)
725 if self == Decimal(i):
726 return hash(i)
727 assert self.__nonzero__() # '-0' handled by integer case
728 return hash(str(self.normalize()))
729
730 def as_tuple(self):
731 """Represents the number as a triple tuple.
732
733 To show the internals exactly as they are.
734 """
735 return (self._sign, self._int, self._exp)
736
737 def __repr__(self):
738 """Represents the number as an instance of Decimal."""
739 # Invariant: eval(repr(d)) == d
740 return 'Decimal("%s")' % str(self)
741
742 def __str__(self, eng = 0, context=None):
743 """Return string representation of the number in scientific notation.
744
745 Captures all of the information in the underlying representation.
746 """
747
748 if self._isnan():
749 minus = '-'*self._sign
750 if self._int == (0,):
751 info = ''
752 else:
753 info = ''.join(map(str, self._int))
754 if self._isnan() == 2:
755 return minus + 'sNaN' + info
756 return minus + 'NaN' + info
757 if self._isinfinity():
758 minus = '-'*self._sign
759 return minus + 'Infinity'
760
761 if context is None:
762 context = getcontext()
763
764 tmp = map(str, self._int)
765 numdigits = len(self._int)
766 leftdigits = self._exp + numdigits
767 if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
768 if self._exp < 0 and self._exp >= -6: #short, no need for e/E
769 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
770 return s
771 #exp is closest mult. of 3 >= self._exp
772 exp = ((self._exp - 1)// 3 + 1) * 3
773 if exp != self._exp:
774 s = '0.'+'0'*(exp - self._exp)
775 else:
776 s = '0'
777 if exp != 0:
778 if context.capitals:
779 s += 'E'
780 else:
781 s += 'e'
782 if exp > 0:
783 s += '+' #0.0e+3, not 0.0e3
784 s += str(exp)
785 s = '-'*self._sign + s
786 return s
787 if eng:
788 dotplace = (leftdigits-1)%3+1
789 adjexp = leftdigits -1 - (leftdigits-1)%3
790 else:
791 adjexp = leftdigits-1
792 dotplace = 1
793 if self._exp == 0:
794 pass
795 elif self._exp < 0 and adjexp >= 0:
796 tmp.insert(leftdigits, '.')
797 elif self._exp < 0 and adjexp >= -6:
798 tmp[0:0] = ['0'] * int(-leftdigits)
799 tmp.insert(0, '0.')
800 else:
801 if numdigits > dotplace:
802 tmp.insert(dotplace, '.')
803 elif numdigits < dotplace:
804 tmp.extend(['0']*(dotplace-numdigits))
805 if adjexp:
806 if not context.capitals:
807 tmp.append('e')
808 else:
809 tmp.append('E')
810 if adjexp > 0:
811 tmp.append('+')
812 tmp.append(str(adjexp))
813 if eng:
814 while tmp[0:1] == ['0']:
815 tmp[0:1] = []
816 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
817 tmp[0:0] = ['0']
818 if self._sign:
819 tmp.insert(0, '-')
820
821 return ''.join(tmp)
822
823 def to_eng_string(self, context=None):
824 """Convert to engineering-type string.
825
826 Engineering notation has an exponent which is a multiple of 3, so there
827 are up to 3 digits left of the decimal place.
828
829 Same rules for when in exponential and when as a value as in __str__.
830 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000831 return self.__str__(eng=1, context=context)
832
833 def __neg__(self, context=None):
834 """Returns a copy with the sign switched.
835
836 Rounds, if it has reason.
837 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000838 if self._is_special:
839 ans = self._check_nans(context=context)
840 if ans:
841 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000842
843 if not self:
844 # -Decimal('0') is Decimal('0'), not Decimal('-0')
845 sign = 0
846 elif self._sign:
847 sign = 0
848 else:
849 sign = 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000850
851 if context is None:
852 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000853 if context._rounding_decision == ALWAYS_ROUND:
854 return Decimal((sign, self._int, self._exp))._fix(context=context)
855 return Decimal( (sign, self._int, self._exp))
856
857 def __pos__(self, context=None):
858 """Returns a copy, unless it is a sNaN.
859
860 Rounds the number (if more then precision digits)
861 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000862 if self._is_special:
863 ans = self._check_nans(context=context)
864 if ans:
865 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000866
867 sign = self._sign
868 if not self:
869 # + (-0) = 0
870 sign = 0
871
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000872 if context is None:
873 context = getcontext()
874
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000875 if context._rounding_decision == ALWAYS_ROUND:
876 ans = self._fix(context=context)
877 else:
878 ans = Decimal(self)
879 ans._sign = sign
880 return ans
881
882 def __abs__(self, round=1, context=None):
883 """Returns the absolute value of self.
884
885 If the second argument is 0, do not round.
886 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000887 if self._is_special:
888 ans = self._check_nans(context=context)
889 if ans:
890 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000891
892 if not round:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000893 if context is None:
894 context = getcontext()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000895 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000896 context._set_rounding_decision(NEVER_ROUND)
897
898 if self._sign:
899 ans = self.__neg__(context=context)
900 else:
901 ans = self.__pos__(context=context)
902
903 return ans
904
905 def __add__(self, other, context=None):
906 """Returns self + other.
907
908 -INF + INF (or the reverse) cause InvalidOperation errors.
909 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000910 other = _convert_other(other)
911
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000912 if context is None:
913 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000914
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000915 if self._is_special or other._is_special:
916 ans = self._check_nans(other, context)
917 if ans:
918 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000919
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000920 if self._isinfinity():
921 #If both INF, same sign => same as both, opposite => error.
922 if self._sign != other._sign and other._isinfinity():
923 return context._raise_error(InvalidOperation, '-INF + INF')
924 return Decimal(self)
925 if other._isinfinity():
926 return Decimal(other) #Can't both be infinity here
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000927
928 shouldround = context._rounding_decision == ALWAYS_ROUND
929
930 exp = min(self._exp, other._exp)
931 negativezero = 0
932 if context.rounding == ROUND_FLOOR and self._sign != other._sign:
933 #If the answer is 0, the sign should be negative, in this case.
934 negativezero = 1
935
936 if not self and not other:
937 sign = min(self._sign, other._sign)
938 if negativezero:
939 sign = 1
940 return Decimal( (sign, (0,), exp))
941 if not self:
942 if exp < other._exp - context.prec-1:
943 exp = other._exp - context.prec-1
944 ans = other._rescale(exp, watchexp=0, context=context)
945 if shouldround:
946 ans = ans._fix(context=context)
947 return ans
948 if not other:
949 if exp < self._exp - context.prec-1:
950 exp = self._exp - context.prec-1
951 ans = self._rescale(exp, watchexp=0, context=context)
952 if shouldround:
953 ans = ans._fix(context=context)
954 return ans
955
956 op1 = _WorkRep(self)
957 op2 = _WorkRep(other)
958 op1, op2 = _normalize(op1, op2, shouldround, context.prec)
959
960 result = _WorkRep()
961
962 if op1.sign != op2.sign:
963 diff = cmp(abs(op1), abs(op2))
964 # Equal and opposite
965 if diff == 0:
966 if exp < context.Etiny():
967 exp = context.Etiny()
968 context._raise_error(Clamped)
969 return Decimal((negativezero, (0,), exp))
970 if diff < 0:
971 op1, op2 = op2, op1
972 #OK, now abs(op1) > abs(op2)
973 if op1.sign == -1:
974 result.sign = -1
975 op1.sign, op2.sign = op2.sign, op1.sign
976 else:
977 result.sign = 1
978 #So we know the sign, and op1 > 0.
979 elif op1.sign == -1:
980 result.sign = -1
981 op1.sign, op2.sign = (1, 1)
982 else:
983 result.sign = 1
984 #Now, op1 > abs(op2) > 0
985
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000986 if op2.sign == 1:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000987 result.int = op1.int + op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000988 else:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000989 result.int = op1.int - op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000990
991 result.exp = op1.exp
992 ans = Decimal(result)
993 if shouldround:
994 ans = ans._fix(context=context)
995 return ans
996
997 __radd__ = __add__
998
999 def __sub__(self, other, context=None):
1000 """Return self + (-other)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001001 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001002
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001003 if self._is_special or other._is_special:
1004 ans = self._check_nans(other, context=context)
1005 if ans:
1006 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001007
1008 # -Decimal(0) = Decimal(0), which we don't want since
1009 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
1010 # so we change the sign directly to a copy
1011 tmp = Decimal(other)
1012 tmp._sign = 1-tmp._sign
1013
1014 return self.__add__(tmp, context=context)
1015
1016 def __rsub__(self, other, context=None):
1017 """Return other + (-self)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001018 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001019
1020 tmp = Decimal(self)
1021 tmp._sign = 1 - tmp._sign
1022 return other.__add__(tmp, context=context)
1023
1024 def _increment(self, round=1, context=None):
1025 """Special case of add, adding 1eExponent
1026
1027 Since it is common, (rounding, for example) this adds
1028 (sign)*one E self._exp to the number more efficiently than add.
1029
1030 For example:
1031 Decimal('5.624e10')._increment() == Decimal('5.625e10')
1032 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001033 if self._is_special:
1034 ans = self._check_nans(context=context)
1035 if ans:
1036 return ans
1037
1038 return Decimal(self) # Must be infinite, and incrementing makes no difference
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001039
1040 L = list(self._int)
1041 L[-1] += 1
1042 spot = len(L)-1
1043 while L[spot] == 10:
1044 L[spot] = 0
1045 if spot == 0:
1046 L[0:0] = [1]
1047 break
1048 L[spot-1] += 1
1049 spot -= 1
1050 ans = Decimal((self._sign, L, self._exp))
1051
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001052 if context is None:
1053 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001054 if round and context._rounding_decision == ALWAYS_ROUND:
1055 ans = ans._fix(context=context)
1056 return ans
1057
1058 def __mul__(self, other, context=None):
1059 """Return self * other.
1060
1061 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1062 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001063 other = _convert_other(other)
1064
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001065 if context is None:
1066 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001067
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001068 resultsign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001069
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001070 if self._is_special or other._is_special:
1071 ans = self._check_nans(other, context)
1072 if ans:
1073 return ans
1074
1075 if self._isinfinity():
1076 if not other:
1077 return context._raise_error(InvalidOperation, '(+-)INF * 0')
1078 return Infsign[resultsign]
1079
1080 if other._isinfinity():
1081 if not self:
1082 return context._raise_error(InvalidOperation, '0 * (+-)INF')
1083 return Infsign[resultsign]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001084
1085 resultexp = self._exp + other._exp
1086 shouldround = context._rounding_decision == ALWAYS_ROUND
1087
1088 # Special case for multiplying by zero
1089 if not self or not other:
1090 ans = Decimal((resultsign, (0,), resultexp))
1091 if shouldround:
1092 #Fixing in case the exponent is out of bounds
1093 ans = ans._fix(context=context)
1094 return ans
1095
1096 # Special case for multiplying by power of 10
1097 if self._int == (1,):
1098 ans = Decimal((resultsign, other._int, resultexp))
1099 if shouldround:
1100 ans = ans._fix(context=context)
1101 return ans
1102 if other._int == (1,):
1103 ans = Decimal((resultsign, self._int, resultexp))
1104 if shouldround:
1105 ans = ans._fix(context=context)
1106 return ans
1107
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001108 op1 = _WorkRep(self)
1109 op2 = _WorkRep(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001110
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001111 ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001112 if shouldround:
1113 ans = ans._fix(context=context)
1114
1115 return ans
1116 __rmul__ = __mul__
1117
1118 def __div__(self, other, context=None):
1119 """Return self / other."""
1120 return self._divide(other, context=context)
1121 __truediv__ = __div__
1122
1123 def _divide(self, other, divmod = 0, context=None):
1124 """Return a / b, to context.prec precision.
1125
1126 divmod:
1127 0 => true division
1128 1 => (a //b, a%b)
1129 2 => a //b
1130 3 => a%b
1131
1132 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1133 computing the other value are not raised.
1134 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001135 other = _convert_other(other)
1136
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001137 if context is None:
1138 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001139
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001140 sign = self._sign ^ other._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001141
1142 if self._is_special or other._is_special:
1143 ans = self._check_nans(other, context)
1144 if ans:
1145 if divmod:
1146 return (ans, ans)
1147 return ans
1148
1149 if self._isinfinity() and other._isinfinity():
1150 if divmod:
1151 return (context._raise_error(InvalidOperation,
1152 '(+-)INF // (+-)INF'),
1153 context._raise_error(InvalidOperation,
1154 '(+-)INF % (+-)INF'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001155 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001156
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001157 if self._isinfinity():
1158 if divmod == 1:
1159 return (Infsign[sign],
1160 context._raise_error(InvalidOperation, 'INF % x'))
1161 elif divmod == 2:
1162 return (Infsign[sign], NaN)
1163 elif divmod == 3:
1164 return (Infsign[sign],
1165 context._raise_error(InvalidOperation, 'INF % x'))
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001166 return Infsign[sign]
1167
1168 if other._isinfinity():
1169 if divmod:
1170 return (Decimal((sign, (0,), 0)), Decimal(self))
1171 context._raise_error(Clamped, 'Division by infinity')
1172 return Decimal((sign, (0,), context.Etiny()))
1173
1174 # Special cases for zeroes
1175 if not self and not other:
1176 if divmod:
1177 return context._raise_error(DivisionUndefined, '0 / 0', 1)
1178 return context._raise_error(DivisionUndefined, '0 / 0')
1179
1180 if not self:
1181 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001182 otherside = Decimal(self)
1183 otherside._exp = min(self._exp, other._exp)
1184 return (Decimal((sign, (0,), 0)), otherside)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001185 exp = self._exp - other._exp
1186 if exp < context.Etiny():
1187 exp = context.Etiny()
1188 context._raise_error(Clamped, '0e-x / y')
1189 if exp > context.Emax:
1190 exp = context.Emax
1191 context._raise_error(Clamped, '0e+x / y')
1192 return Decimal( (sign, (0,), exp) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001193
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001194 if not other:
1195 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001196 return context._raise_error(DivisionByZero, 'divmod(x,0)',
1197 sign, 1)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001198 return context._raise_error(DivisionByZero, 'x / 0', sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001199
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001200 #OK, so neither = 0, INF or NaN
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001201
1202 shouldround = context._rounding_decision == ALWAYS_ROUND
1203
1204 #If we're dividing into ints, and self < other, stop.
1205 #self.__abs__(0) does not round.
1206 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
1207
1208 if divmod == 1 or divmod == 3:
1209 exp = min(self._exp, other._exp)
1210 ans2 = self._rescale(exp, context=context, watchexp=0)
1211 if shouldround:
1212 ans2 = ans2._fix(context=context)
1213 return (Decimal( (sign, (0,), 0) ),
1214 ans2)
1215
1216 elif divmod == 2:
1217 #Don't round the mod part, if we don't need it.
1218 return (Decimal( (sign, (0,), 0) ), Decimal(self))
1219
1220 if sign:
1221 sign = -1
1222 else:
1223 sign = 1
1224 adjust = 0
1225 op1 = _WorkRep(self)
1226 op2 = _WorkRep(other)
1227 op1, op2, adjust = _adjust_coefficients(op1, op2)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001228 res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001229 if divmod and res.exp > context.prec + 1:
1230 return context._raise_error(DivisionImpossible)
1231
1232 ans = None
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001233 prec_limit = 10 ** context.prec
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001234 while 1:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001235 while op2.int <= op1.int:
1236 res.int += 1
1237 op1.int -= op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001238 if res.exp == 0 and divmod:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001239 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001240 return context._raise_error(DivisionImpossible)
1241 otherside = Decimal(op1)
1242 frozen = context._ignore_all_flags()
1243
1244 exp = min(self._exp, other._exp)
1245 otherside = otherside._rescale(exp, context=context,
1246 watchexp=0)
1247 context._regard_flags(*frozen)
1248 if shouldround:
1249 otherside = otherside._fix(context=context)
1250 return (Decimal(res), otherside)
1251
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001252 if op1.int == 0 and adjust >= 0 and not divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001253 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001254 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001255 if divmod:
1256 return context._raise_error(DivisionImpossible)
1257 shouldround=1
1258 # Really, the answer is a bit higher, so adding a one to
1259 # the end will make sure the rounding is right.
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001260 if op1.int != 0:
1261 res.int *= 10
1262 res.int += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001263 res.exp -= 1
1264
1265 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001266 res.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001267 res.exp -= 1
1268 adjust += 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001269 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001270 op1.exp -= 1
1271
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001272 if res.exp == 0 and divmod and op2.int > op1.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001273 #Solves an error in precision. Same as a previous block.
1274
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001275 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001276 return context._raise_error(DivisionImpossible)
1277 otherside = Decimal(op1)
1278 frozen = context._ignore_all_flags()
1279
1280 exp = min(self._exp, other._exp)
1281 otherside = otherside._rescale(exp, context=context)
1282
1283 context._regard_flags(*frozen)
1284
1285 return (Decimal(res), otherside)
1286
1287 ans = Decimal(res)
1288 if shouldround:
1289 ans = ans._fix(context=context)
1290 return ans
1291
1292 def __rdiv__(self, other, context=None):
1293 """Swaps self/other and returns __div__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001294 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001295 return other.__div__(self, context=context)
1296 __rtruediv__ = __rdiv__
1297
1298 def __divmod__(self, other, context=None):
1299 """
1300 (self // other, self % other)
1301 """
1302 return self._divide(other, 1, context)
1303
1304 def __rdivmod__(self, other, context=None):
1305 """Swaps self/other and returns __divmod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001306 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001307 return other.__divmod__(self, context=context)
1308
1309 def __mod__(self, other, context=None):
1310 """
1311 self % other
1312 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001313 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001314
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001315 if self._is_special or other._is_special:
1316 ans = self._check_nans(other, context)
1317 if ans:
1318 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001319
1320 if self and not other:
1321 return context._raise_error(InvalidOperation, 'x % 0')
1322
1323 return self._divide(other, 3, context)[1]
1324
1325 def __rmod__(self, other, context=None):
1326 """Swaps self/other and returns __mod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001327 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001328 return other.__mod__(self, context=context)
1329
1330 def remainder_near(self, other, context=None):
1331 """
1332 Remainder nearest to 0- abs(remainder-near) <= other/2
1333 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001334 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001335
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001336 if self._is_special or other._is_special:
1337 ans = self._check_nans(other, context)
1338 if ans:
1339 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001340 if self and not other:
1341 return context._raise_error(InvalidOperation, 'x % 0')
1342
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001343 if context is None:
1344 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001345 # If DivisionImpossible causes an error, do not leave Rounded/Inexact
1346 # ignored in the calling function.
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001347 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001348 flags = context._ignore_flags(Rounded, Inexact)
1349 #keep DivisionImpossible flags
1350 (side, r) = self.__divmod__(other, context=context)
1351
1352 if r._isnan():
1353 context._regard_flags(*flags)
1354 return r
1355
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001356 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001357 rounding = context._set_rounding_decision(NEVER_ROUND)
1358
1359 if other._sign:
1360 comparison = other.__div__(Decimal(-2), context=context)
1361 else:
1362 comparison = other.__div__(Decimal(2), context=context)
1363
1364 context._set_rounding_decision(rounding)
1365 context._regard_flags(*flags)
1366
1367 s1, s2 = r._sign, comparison._sign
1368 r._sign, comparison._sign = 0, 0
1369
1370 if r < comparison:
1371 r._sign, comparison._sign = s1, s2
1372 #Get flags now
1373 self.__divmod__(other, context=context)
1374 return r._fix(context=context)
1375 r._sign, comparison._sign = s1, s2
1376
1377 rounding = context._set_rounding_decision(NEVER_ROUND)
1378
1379 (side, r) = self.__divmod__(other, context=context)
1380 context._set_rounding_decision(rounding)
1381 if r._isnan():
1382 return r
1383
1384 decrease = not side._iseven()
1385 rounding = context._set_rounding_decision(NEVER_ROUND)
1386 side = side.__abs__(context=context)
1387 context._set_rounding_decision(rounding)
1388
1389 s1, s2 = r._sign, comparison._sign
1390 r._sign, comparison._sign = 0, 0
1391 if r > comparison or decrease and r == comparison:
1392 r._sign, comparison._sign = s1, s2
1393 context.prec += 1
1394 if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
1395 context.prec -= 1
1396 return context._raise_error(DivisionImpossible)[1]
1397 context.prec -= 1
1398 if self._sign == other._sign:
1399 r = r.__sub__(other, context=context)
1400 else:
1401 r = r.__add__(other, context=context)
1402 else:
1403 r._sign, comparison._sign = s1, s2
1404
1405 return r._fix(context=context)
1406
1407 def __floordiv__(self, other, context=None):
1408 """self // other"""
1409 return self._divide(other, 2, context)[0]
1410
1411 def __rfloordiv__(self, other, context=None):
1412 """Swaps self/other and returns __floordiv__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001413 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001414 return other.__floordiv__(self, context=context)
1415
1416 def __float__(self):
1417 """Float representation."""
1418 return float(str(self))
1419
1420 def __int__(self):
1421 """Converts self to a int, truncating if necessary."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001422 if self._is_special:
1423 if self._isnan():
1424 context = getcontext()
1425 return context._raise_error(InvalidContext)
1426 elif self._isinfinity():
1427 raise OverflowError, "Cannot convert infinity to long"
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001428 if not self:
1429 return 0
1430 sign = '-'*self._sign
1431 if self._exp >= 0:
1432 s = sign + ''.join(map(str, self._int)) + '0'*self._exp
1433 return int(s)
1434 s = sign + ''.join(map(str, self._int))[:self._exp]
1435 return int(s)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001436
1437 def __long__(self):
1438 """Converts to a long.
1439
1440 Equivalent to long(int(self))
1441 """
1442 return long(self.__int__())
1443
1444 def _fix(self, prec=None, rounding=None, folddown=None, context=None):
1445 """Round if it is necessary to keep self within prec precision.
1446
1447 Rounds and fixes the exponent. Does not raise on a sNaN.
1448
1449 Arguments:
1450 self - Decimal instance
1451 prec - precision to which to round. By default, the context decides.
1452 rounding - Rounding method. By default, the context decides.
1453 folddown - Fold down high elements, by default context._clamp
1454 context - context used.
1455 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001456 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001457 return self
1458 if context is None:
1459 context = getcontext()
1460 if prec is None:
1461 prec = context.prec
1462 ans = Decimal(self)
1463 ans = ans._fixexponents(prec, rounding, folddown=folddown,
1464 context=context)
1465 if len(ans._int) > prec:
1466 ans = ans._round(prec, rounding, context=context)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001467 ans = ans._fixexponents(prec, rounding, folddown=folddown,
1468 context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001469 return ans
1470
1471 def _fixexponents(self, prec=None, rounding=None, folddown=None,
1472 context=None):
1473 """Fix the exponents and return a copy with the exponent in bounds."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001474 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001475 return self
1476 if context is None:
1477 context = getcontext()
1478 if prec is None:
1479 prec = context.prec
1480 if folddown is None:
1481 folddown = context._clamp
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001482 Emin = context.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001483 ans = Decimal(self)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001484 ans_adjusted = ans.adjusted()
1485 if ans_adjusted < Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001486 Etiny = context.Etiny()
1487 if ans._exp < Etiny:
1488 if not ans:
1489 ans._exp = Etiny
1490 context._raise_error(Clamped)
1491 return ans
1492 ans = ans._rescale(Etiny, context=context)
1493 #It isn't zero, and exp < Emin => subnormal
1494 context._raise_error(Subnormal)
1495 if context.flags[Inexact]:
1496 context._raise_error(Underflow)
1497 else:
1498 if ans:
1499 #Only raise subnormal if non-zero.
1500 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001501 else:
1502 Etop = context.Etop()
1503 if folddown and ans._exp > Etop:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001504 context._raise_error(Clamped)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001505 ans = ans._rescale(Etop, context=context)
1506 else:
1507 Emax = context.Emax
1508 if ans_adjusted > Emax:
1509 if not ans:
1510 ans._exp = Emax
1511 context._raise_error(Clamped)
1512 return ans
1513 context._raise_error(Inexact)
1514 context._raise_error(Rounded)
1515 return context._raise_error(Overflow, 'above Emax', ans._sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001516 return ans
1517
1518 def _round(self, prec=None, rounding=None, context=None):
1519 """Returns a rounded version of self.
1520
1521 You can specify the precision or rounding method. Otherwise, the
1522 context determines it.
1523 """
1524
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001525
1526 if self._is_special:
1527 ans = self._check_nans(context=context)
1528 if ans:
1529 return ans
1530
1531 if self._isinfinity():
1532 return Decimal(self)
1533
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001534 if context is None:
1535 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001536
1537 if rounding is None:
1538 rounding = context.rounding
1539 if prec is None:
1540 prec = context.prec
1541
1542 if not self:
1543 if prec <= 0:
1544 dig = (0,)
1545 exp = len(self._int) - prec + self._exp
1546 else:
1547 dig = (0,) * prec
1548 exp = len(self._int) + self._exp - prec
1549 ans = Decimal((self._sign, dig, exp))
1550 context._raise_error(Rounded)
1551 return ans
1552
1553 if prec == 0:
1554 temp = Decimal(self)
1555 temp._int = (0,)+temp._int
1556 prec = 1
1557 elif prec < 0:
1558 exp = self._exp + len(self._int) - prec - 1
1559 temp = Decimal( (self._sign, (0, 1), exp))
1560 prec = 1
1561 else:
1562 temp = Decimal(self)
1563
1564 numdigits = len(temp._int)
1565 if prec == numdigits:
1566 return temp
1567
1568 # See if we need to extend precision
1569 expdiff = prec - numdigits
1570 if expdiff > 0:
1571 tmp = list(temp._int)
1572 tmp.extend([0] * expdiff)
1573 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff))
1574 return ans
1575
1576 #OK, but maybe all the lost digits are 0.
1577 lostdigits = self._int[expdiff:]
1578 if lostdigits == (0,) * len(lostdigits):
1579 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
1580 #Rounded, but not Inexact
1581 context._raise_error(Rounded)
1582 return ans
1583
1584 # Okay, let's round and lose data
1585
1586 this_function = getattr(temp, self._pick_rounding_function[rounding])
1587 #Now we've got the rounding function
1588
1589 if prec != context.prec:
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001590 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001591 context.prec = prec
1592 ans = this_function(prec, expdiff, context)
1593 context._raise_error(Rounded)
1594 context._raise_error(Inexact, 'Changed in rounding')
1595
1596 return ans
1597
1598 _pick_rounding_function = {}
1599
1600 def _round_down(self, prec, expdiff, context):
1601 """Also known as round-towards-0, truncate."""
1602 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1603
1604 def _round_half_up(self, prec, expdiff, context, tmp = None):
1605 """Rounds 5 up (away from 0)"""
1606
1607 if tmp is None:
1608 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
1609 if self._int[prec] >= 5:
1610 tmp = tmp._increment(round=0, context=context)
1611 if len(tmp._int) > prec:
1612 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1613 return tmp
1614
1615 def _round_half_even(self, prec, expdiff, context):
1616 """Round 5 to even, rest to nearest."""
1617
1618 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1619 half = (self._int[prec] == 5)
1620 if half:
1621 for digit in self._int[prec+1:]:
1622 if digit != 0:
1623 half = 0
1624 break
1625 if half:
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001626 if self._int[prec-1] & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001627 return tmp
1628 return self._round_half_up(prec, expdiff, context, tmp)
1629
1630 def _round_half_down(self, prec, expdiff, context):
1631 """Round 5 down"""
1632
1633 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1634 half = (self._int[prec] == 5)
1635 if half:
1636 for digit in self._int[prec+1:]:
1637 if digit != 0:
1638 half = 0
1639 break
1640 if half:
1641 return tmp
1642 return self._round_half_up(prec, expdiff, context, tmp)
1643
1644 def _round_up(self, prec, expdiff, context):
1645 """Rounds away from 0."""
1646 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1647 for digit in self._int[prec:]:
1648 if digit != 0:
1649 tmp = tmp._increment(round=1, context=context)
1650 if len(tmp._int) > prec:
1651 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1652 else:
1653 return tmp
1654 return tmp
1655
1656 def _round_ceiling(self, prec, expdiff, context):
1657 """Rounds up (not away from 0 if negative.)"""
1658 if self._sign:
1659 return self._round_down(prec, expdiff, context)
1660 else:
1661 return self._round_up(prec, expdiff, context)
1662
1663 def _round_floor(self, prec, expdiff, context):
1664 """Rounds down (not towards 0 if negative)"""
1665 if not self._sign:
1666 return self._round_down(prec, expdiff, context)
1667 else:
1668 return self._round_up(prec, expdiff, context)
1669
1670 def __pow__(self, n, modulo = None, context=None):
1671 """Return self ** n (mod modulo)
1672
1673 If modulo is None (default), don't take it mod modulo.
1674 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001675 n = _convert_other(n)
1676
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001677 if context is None:
1678 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001679
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001680 if self._is_special or n._is_special or n.adjusted() > 8:
1681 #Because the spot << doesn't work with really big exponents
1682 if n._isinfinity() or n.adjusted() > 8:
1683 return context._raise_error(InvalidOperation, 'x ** INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001684
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001685 ans = self._check_nans(n, context)
1686 if ans:
1687 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001688
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001689 if not n._isinteger():
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001690 return context._raise_error(InvalidOperation, 'x ** (non-integer)')
1691
1692 if not self and not n:
1693 return context._raise_error(InvalidOperation, '0 ** 0')
1694
1695 if not n:
1696 return Decimal(1)
1697
1698 if self == Decimal(1):
1699 return Decimal(1)
1700
1701 sign = self._sign and not n._iseven()
1702 n = int(n)
1703
1704 if self._isinfinity():
1705 if modulo:
1706 return context._raise_error(InvalidOperation, 'INF % x')
1707 if n > 0:
1708 return Infsign[sign]
1709 return Decimal( (sign, (0,), 0) )
1710
1711 #with ludicrously large exponent, just raise an overflow and return inf.
1712 if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
1713 and self:
1714
1715 tmp = Decimal('inf')
1716 tmp._sign = sign
1717 context._raise_error(Rounded)
1718 context._raise_error(Inexact)
1719 context._raise_error(Overflow, 'Big power', sign)
1720 return tmp
1721
1722 elength = len(str(abs(n)))
1723 firstprec = context.prec
1724
Raymond Hettinger99148e72004-07-14 19:56:56 +00001725 if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001726 return context._raise_error(Overflow, 'Too much precision.', sign)
1727
1728 mul = Decimal(self)
1729 val = Decimal(1)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001730 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001731 context.prec = firstprec + elength + 1
1732 rounding = context.rounding
1733 if n < 0:
1734 #n is a long now, not Decimal instance
1735 n = -n
1736 mul = Decimal(1).__div__(mul, context=context)
1737
1738 shouldround = context._rounding_decision == ALWAYS_ROUND
1739
1740 spot = 1
1741 while spot <= n:
1742 spot <<= 1
1743
1744 spot >>= 1
1745 #Spot is the highest power of 2 less than n
1746 while spot:
1747 val = val.__mul__(val, context=context)
1748 if val._isinfinity():
1749 val = Infsign[sign]
1750 break
1751 if spot & n:
1752 val = val.__mul__(mul, context=context)
1753 if modulo is not None:
1754 val = val.__mod__(modulo, context=context)
1755 spot >>= 1
1756 context.prec = firstprec
1757
1758 if shouldround:
1759 return val._fix(context=context)
1760 return val
1761
1762 def __rpow__(self, other, context=None):
1763 """Swaps self/other and returns __pow__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001764 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001765 return other.__pow__(self, context=context)
1766
1767 def normalize(self, context=None):
1768 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001769
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001770 if self._is_special:
1771 ans = self._check_nans(context=context)
1772 if ans:
1773 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001774
1775 dup = self._fix(context=context)
1776 if dup._isinfinity():
1777 return dup
1778
1779 if not dup:
1780 return Decimal( (dup._sign, (0,), 0) )
1781 end = len(dup._int)
1782 exp = dup._exp
1783 while dup._int[end-1] == 0:
1784 exp += 1
1785 end -= 1
1786 return Decimal( (dup._sign, dup._int[:end], exp) )
1787
1788
1789 def quantize(self, exp, rounding = None, context=None, watchexp = 1):
1790 """Quantize self so its exponent is the same as that of exp.
1791
1792 Similar to self._rescale(exp._exp) but with error checking.
1793 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001794 if self._is_special or exp._is_special:
1795 ans = self._check_nans(exp, context)
1796 if ans:
1797 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001798
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001799 if exp._isinfinity() or self._isinfinity():
1800 if exp._isinfinity() and self._isinfinity():
1801 return self #if both are inf, it is OK
1802 if context is None:
1803 context = getcontext()
1804 return context._raise_error(InvalidOperation,
1805 'quantize with one INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001806 return self._rescale(exp._exp, rounding, context, watchexp)
1807
1808 def same_quantum(self, other):
1809 """Test whether self and other have the same exponent.
1810
1811 same as self._exp == other._exp, except NaN == sNaN
1812 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001813 if self._is_special or other._is_special:
1814 if self._isnan() or other._isnan():
1815 return self._isnan() and other._isnan() and True
1816 if self._isinfinity() or other._isinfinity():
1817 return self._isinfinity() and other._isinfinity() and True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001818 return self._exp == other._exp
1819
1820 def _rescale(self, exp, rounding = None, context=None, watchexp = 1):
1821 """Rescales so that the exponent is exp.
1822
1823 exp = exp to scale to (an integer)
1824 rounding = rounding version
1825 watchexp: if set (default) an error is returned if exp is greater
1826 than Emax or less than Etiny.
1827 """
1828 if context is None:
1829 context = getcontext()
1830
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001831 if self._is_special:
1832 if self._isinfinity():
1833 return context._raise_error(InvalidOperation, 'rescale with an INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001834
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001835 ans = self._check_nans(context=context)
1836 if ans:
1837 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001838
1839 out = 0
1840
1841 if watchexp and (context.Emax < exp or context.Etiny() > exp):
1842 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1843
1844 if not self:
1845 ans = Decimal(self)
1846 ans._int = (0,)
1847 ans._exp = exp
1848 return ans
1849
1850 diff = self._exp - exp
1851 digits = len(self._int)+diff
1852
1853 if watchexp and digits > context.prec:
1854 return context._raise_error(InvalidOperation, 'Rescale > prec')
1855
1856 tmp = Decimal(self)
1857 tmp._int = (0,)+tmp._int
1858 digits += 1
1859
1860 prevexact = context.flags[Inexact]
1861 if digits < 0:
1862 tmp._exp = -digits + tmp._exp
1863 tmp._int = (0,1)
1864 digits = 1
1865 tmp = tmp._round(digits, rounding, context=context)
1866
1867 if tmp._int[0] == 0 and len(tmp._int) > 1:
1868 tmp._int = tmp._int[1:]
1869 tmp._exp = exp
1870
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001871 tmp_adjusted = tmp.adjusted()
1872 if tmp and tmp_adjusted < context.Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001873 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001874 elif tmp and tmp_adjusted > context.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001875 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1876 return tmp
1877
1878 def to_integral(self, rounding = None, context=None):
1879 """Rounds to the nearest integer, without raising inexact, rounded."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001880 if self._is_special:
1881 ans = self._check_nans(context=context)
1882 if ans:
1883 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001884 if self._exp >= 0:
1885 return self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001886 if context is None:
1887 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001888 flags = context._ignore_flags(Rounded, Inexact)
1889 ans = self._rescale(0, rounding, context=context)
1890 context._regard_flags(flags)
1891 return ans
1892
1893 def sqrt(self, context=None):
1894 """Return the square root of self.
1895
1896 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
1897 Should quadratically approach the right answer.
1898 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001899 if self._is_special:
1900 ans = self._check_nans(context=context)
1901 if ans:
1902 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001903
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001904 if self._isinfinity() and self._sign == 0:
1905 return Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001906
1907 if not self:
1908 #exponent = self._exp / 2, using round_down.
1909 #if self._exp < 0:
1910 # exp = (self._exp+1) // 2
1911 #else:
1912 exp = (self._exp) // 2
1913 if self._sign == 1:
1914 #sqrt(-0) = -0
1915 return Decimal( (1, (0,), exp))
1916 else:
1917 return Decimal( (0, (0,), exp))
1918
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001919 if context is None:
1920 context = getcontext()
1921
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001922 if self._sign == 1:
1923 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
1924
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001925 tmp = Decimal(self)
1926
Raymond Hettinger4837a222004-09-27 14:23:40 +00001927 expadd = tmp._exp // 2
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001928 if tmp._exp & 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001929 tmp._int += (0,)
1930 tmp._exp = 0
1931 else:
1932 tmp._exp = 0
1933
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001934 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001935 flags = context._ignore_all_flags()
1936 firstprec = context.prec
1937 context.prec = 3
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001938 if tmp.adjusted() & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001939 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) )
1940 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
1941 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00001942 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001943 else:
1944 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
1945 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
1946 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00001947 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001948
1949 #ans is now a linear approximation.
1950
1951 Emax, Emin = context.Emax, context.Emin
Raymond Hettinger99148e72004-07-14 19:56:56 +00001952 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001953
1954 half = Decimal('0.5')
1955
1956 count = 1
1957 maxp = firstprec + 2
1958 rounding = context._set_rounding(ROUND_HALF_EVEN)
1959 while 1:
1960 context.prec = min(2*context.prec - 2, maxp)
1961 ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
1962 context=context), context=context)
1963 if context.prec == maxp:
1964 break
1965
1966 #round to the answer's precision-- the only error can be 1 ulp.
1967 context.prec = firstprec
1968 prevexp = ans.adjusted()
1969 ans = ans._round(context=context)
1970
1971 #Now, check if the other last digits are better.
1972 context.prec = firstprec + 1
1973 # In case we rounded up another digit and we should actually go lower.
1974 if prevexp != ans.adjusted():
1975 ans._int += (0,)
1976 ans._exp -= 1
1977
1978
1979 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
1980 context._set_rounding(ROUND_UP)
1981 if lower.__mul__(lower, context=context) > (tmp):
1982 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
1983
1984 else:
1985 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
1986 context._set_rounding(ROUND_DOWN)
1987 if upper.__mul__(upper, context=context) < tmp:
1988 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
1989
1990 ans._exp += expadd
1991
1992 context.prec = firstprec
1993 context.rounding = rounding
1994 ans = ans._fix(context=context)
1995
1996 rounding = context._set_rounding_decision(NEVER_ROUND)
1997 if not ans.__mul__(ans, context=context) == self:
1998 # Only rounded/inexact if here.
1999 context._regard_flags(flags)
2000 context._raise_error(Rounded)
2001 context._raise_error(Inexact)
2002 else:
2003 #Exact answer, so let's set the exponent right.
2004 #if self._exp < 0:
2005 # exp = (self._exp +1)// 2
2006 #else:
2007 exp = self._exp // 2
2008 context.prec += ans._exp - exp
2009 ans = ans._rescale(exp, context=context)
2010 context.prec = firstprec
2011 context._regard_flags(flags)
2012 context.Emax, context.Emin = Emax, Emin
2013
2014 return ans._fix(context=context)
2015
2016 def max(self, other, context=None):
2017 """Returns the larger value.
2018
2019 like max(self, other) except if one is not a number, returns
2020 NaN (and signals if one is sNaN). Also rounds.
2021 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002022 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002023
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002024 if self._is_special or other._is_special:
2025 # if one operand is a quiet NaN and the other is number, then the
2026 # number is always returned
2027 sn = self._isnan()
2028 on = other._isnan()
2029 if sn or on:
2030 if on == 1 and sn != 2:
2031 return self
2032 if sn == 1 and on != 2:
2033 return other
2034 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002035
2036 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002037 c = self.__cmp__(other)
2038 if c == 0:
2039 # if both operands are finite and equal in numerical value
2040 # then an ordering is applied:
2041 #
2042 # if the signs differ then max returns the operand with the
2043 # positive sign and min returns the operand with the negative sign
2044 #
2045 # if the signs are the same then the exponent is used to select
2046 # the result.
2047 if self._sign != other._sign:
2048 if self._sign:
2049 ans = other
2050 elif self._exp < other._exp and not self._sign:
2051 ans = other
2052 elif self._exp > other._exp and self._sign:
2053 ans = other
2054 elif c == -1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002055 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002056
2057 if context is None:
2058 context = getcontext()
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002059 context._rounding_decision == ALWAYS_ROUND
2060 return ans._fix(context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002061
2062 def min(self, other, context=None):
2063 """Returns the smaller value.
2064
2065 like min(self, other) except if one is not a number, returns
2066 NaN (and signals if one is sNaN). Also rounds.
2067 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002068 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002069
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002070 if self._is_special or other._is_special:
2071 # if one operand is a quiet NaN and the other is number, then the
2072 # number is always returned
2073 sn = self._isnan()
2074 on = other._isnan()
2075 if sn or on:
2076 if on == 1 and sn != 2:
2077 return self
2078 if sn == 1 and on != 2:
2079 return other
2080 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002081
2082 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002083 c = self.__cmp__(other)
2084 if c == 0:
2085 # if both operands are finite and equal in numerical value
2086 # then an ordering is applied:
2087 #
2088 # if the signs differ then max returns the operand with the
2089 # positive sign and min returns the operand with the negative sign
2090 #
2091 # if the signs are the same then the exponent is used to select
2092 # the result.
2093 if self._sign != other._sign:
2094 if other._sign:
2095 ans = other
2096 elif self._exp > other._exp and not self._sign:
2097 ans = other
2098 elif self._exp < other._exp and self._sign:
2099 ans = other
2100 elif c == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002101 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002102
2103 if context is None:
2104 context = getcontext()
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002105 context._rounding_decision == ALWAYS_ROUND
2106 return ans._fix(context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002107
2108 def _isinteger(self):
2109 """Returns whether self is an integer"""
2110 if self._exp >= 0:
2111 return True
2112 rest = self._int[self._exp:]
2113 return rest == (0,)*len(rest)
2114
2115 def _iseven(self):
2116 """Returns 1 if self is even. Assumes self is an integer."""
2117 if self._exp > 0:
2118 return 1
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002119 return self._int[-1+self._exp] & 1 == 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002120
2121 def adjusted(self):
2122 """Return the adjusted exponent of self"""
2123 try:
2124 return self._exp + len(self._int) - 1
2125 #If NaN or Infinity, self._exp is string
2126 except TypeError:
2127 return 0
2128
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002129 # support for pickling, copy, and deepcopy
2130 def __reduce__(self):
2131 return (self.__class__, (str(self),))
2132
2133 def __copy__(self):
2134 if type(self) == Decimal:
2135 return self # I'm immutable; therefore I am my own clone
2136 return self.__class__(str(self))
2137
2138 def __deepcopy__(self, memo):
2139 if type(self) == Decimal:
2140 return self # My components are also immutable
2141 return self.__class__(str(self))
2142
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002143##### Context class ###########################################
2144
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002145
2146# get rounding method function:
2147rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
2148for name in rounding_functions:
2149 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
2150 globalname = name[1:].upper()
2151 val = globals()[globalname]
2152 Decimal._pick_rounding_function[val] = name
2153
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002154del name, val, globalname, rounding_functions
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002155
2156class Context(object):
2157 """Contains the context for a Decimal instance.
2158
2159 Contains:
2160 prec - precision (for use in rounding, division, square roots..)
2161 rounding - rounding type. (how you round)
2162 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
Raymond Hettingerbf440692004-07-10 14:14:37 +00002163 traps - If traps[exception] = 1, then the exception is
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002164 raised when it is caused. Otherwise, a value is
2165 substituted in.
2166 flags - When an exception is caused, flags[exception] is incremented.
2167 (Whether or not the trap_enabler is set)
2168 Should be reset by user of Decimal instance.
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002169 Emin - Minimum exponent
2170 Emax - Maximum exponent
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002171 capitals - If 1, 1*10^1 is printed as 1E+1.
2172 If 0, printed as 1e1
Raymond Hettingere0f15812004-07-05 05:36:39 +00002173 _clamp - If 1, change exponents if too high (Default 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002174 """
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002175
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002176 def __init__(self, prec=None, rounding=None,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002177 traps=None, flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002178 _rounding_decision=None,
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002179 Emin=None, Emax=None,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002180 capitals=None, _clamp=0,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002181 _ignored_flags=[]):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002182 if not isinstance(flags, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002183 flags = dict([(s,s in flags) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002184 del s
Raymond Hettingerbf440692004-07-10 14:14:37 +00002185 if traps is not None and not isinstance(traps, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002186 traps = dict([(s,s in traps) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002187 del s
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002188 for name, val in locals().items():
2189 if val is None:
2190 setattr(self, name, copy.copy(getattr(DefaultContext, name)))
2191 else:
2192 setattr(self, name, val)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002193 del self.self
2194
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002195 def __repr__(self):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002196 """Show the current context."""
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002197 s = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002198 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
2199 s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
2200 s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002201 return ', '.join(s) + ')'
2202
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002203 def clear_flags(self):
2204 """Reset all flags to zero"""
2205 for flag in self.flags:
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002206 self.flags[flag] = 0
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002207
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002208 def _shallow_copy(self):
2209 """Returns a shallow copy from self."""
Raymond Hettingerbf440692004-07-10 14:14:37 +00002210 nc = Context(self.prec, self.rounding, self.traps, self.flags,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002211 self._rounding_decision, self.Emin, self.Emax,
2212 self.capitals, self._clamp, self._ignored_flags)
2213 return nc
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002214
2215 def copy(self):
2216 """Returns a deep copy from self."""
2217 nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
2218 self._rounding_decision, self.Emin, self.Emax,
2219 self.capitals, self._clamp, self._ignored_flags)
2220 return nc
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002221 __copy__ = copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002222
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002223 def _raise_error(self, condition, explanation = None, *args):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002224 """Handles an error
2225
2226 If the flag is in _ignored_flags, returns the default response.
2227 Otherwise, it increments the flag, then, if the corresponding
2228 trap_enabler is set, it reaises the exception. Otherwise, it returns
2229 the default value after incrementing the flag.
2230 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002231 error = _condition_map.get(condition, condition)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002232 if error in self._ignored_flags:
2233 #Don't touch the flag
2234 return error().handle(self, *args)
2235
2236 self.flags[error] += 1
Raymond Hettingerbf440692004-07-10 14:14:37 +00002237 if not self.traps[error]:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002238 #The errors define how to handle themselves.
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002239 return condition().handle(self, *args)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002240
2241 # Errors should only be risked on copies of the context
2242 #self._ignored_flags = []
2243 raise error, explanation
2244
2245 def _ignore_all_flags(self):
2246 """Ignore all flags, if they are raised"""
Raymond Hettingerfed52962004-07-14 15:41:57 +00002247 return self._ignore_flags(*_signals)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002248
2249 def _ignore_flags(self, *flags):
2250 """Ignore the flags, if they are raised"""
2251 # Do not mutate-- This way, copies of a context leave the original
2252 # alone.
2253 self._ignored_flags = (self._ignored_flags + list(flags))
2254 return list(flags)
2255
2256 def _regard_flags(self, *flags):
2257 """Stop ignoring the flags, if they are raised"""
2258 if flags and isinstance(flags[0], (tuple,list)):
2259 flags = flags[0]
2260 for flag in flags:
2261 self._ignored_flags.remove(flag)
2262
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002263 def __hash__(self):
2264 """A Context cannot be hashed."""
2265 # We inherit object.__hash__, so we must deny this explicitly
2266 raise TypeError, "Cannot hash a Context."
2267
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002268 def Etiny(self):
2269 """Returns Etiny (= Emin - prec + 1)"""
2270 return int(self.Emin - self.prec + 1)
2271
2272 def Etop(self):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002273 """Returns maximum exponent (= Emax - prec + 1)"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002274 return int(self.Emax - self.prec + 1)
2275
2276 def _set_rounding_decision(self, type):
2277 """Sets the rounding decision.
2278
2279 Sets the rounding decision, and returns the current (previous)
2280 rounding decision. Often used like:
2281
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002282 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002283 # That so you don't change the calling context
2284 # if an error occurs in the middle (say DivisionImpossible is raised).
2285
2286 rounding = context._set_rounding_decision(NEVER_ROUND)
2287 instance = instance / Decimal(2)
2288 context._set_rounding_decision(rounding)
2289
2290 This will make it not round for that operation.
2291 """
2292
2293 rounding = self._rounding_decision
2294 self._rounding_decision = type
2295 return rounding
2296
2297 def _set_rounding(self, type):
2298 """Sets the rounding type.
2299
2300 Sets the rounding type, and returns the current (previous)
2301 rounding type. Often used like:
2302
2303 context = context.copy()
2304 # so you don't change the calling context
2305 # if an error occurs in the middle.
2306 rounding = context._set_rounding(ROUND_UP)
2307 val = self.__sub__(other, context=context)
2308 context._set_rounding(rounding)
2309
2310 This will make it round up for that operation.
2311 """
2312 rounding = self.rounding
2313 self.rounding= type
2314 return rounding
2315
Raymond Hettingerfed52962004-07-14 15:41:57 +00002316 def create_decimal(self, num='0'):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002317 """Creates a new Decimal instance but using self as context."""
2318 d = Decimal(num, context=self)
2319 return d._fix(context=self)
2320
2321 #Methods
2322 def abs(self, a):
2323 """Returns the absolute value of the operand.
2324
2325 If the operand is negative, the result is the same as using the minus
2326 operation on the operand. Otherwise, the result is the same as using
2327 the plus operation on the operand.
2328
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002329 >>> ExtendedContext.abs(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002330 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002331 >>> ExtendedContext.abs(Decimal('-100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002332 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002333 >>> ExtendedContext.abs(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002334 Decimal("101.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002335 >>> ExtendedContext.abs(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002336 Decimal("101.5")
2337 """
2338 return a.__abs__(context=self)
2339
2340 def add(self, a, b):
2341 """Return the sum of the two operands.
2342
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002343 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002344 Decimal("19.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002345 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002346 Decimal("1.02E+4")
2347 """
2348 return a.__add__(b, context=self)
2349
2350 def _apply(self, a):
2351 return str(a._fix(context=self))
2352
2353 def compare(self, a, b):
2354 """Compares values numerically.
2355
2356 If the signs of the operands differ, a value representing each operand
2357 ('-1' if the operand is less than zero, '0' if the operand is zero or
2358 negative zero, or '1' if the operand is greater than zero) is used in
2359 place of that operand for the comparison instead of the actual
2360 operand.
2361
2362 The comparison is then effected by subtracting the second operand from
2363 the first and then returning a value according to the result of the
2364 subtraction: '-1' if the result is less than zero, '0' if the result is
2365 zero or negative zero, or '1' if the result is greater than zero.
2366
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002367 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002368 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002369 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002370 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002371 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002372 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002373 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002374 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002375 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002376 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002377 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002378 Decimal("-1")
2379 """
2380 return a.compare(b, context=self)
2381
2382 def divide(self, a, b):
2383 """Decimal division in a specified context.
2384
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002385 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002386 Decimal("0.333333333")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002387 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002388 Decimal("0.666666667")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002389 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002390 Decimal("2.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002391 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002392 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002393 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002394 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002395 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002396 Decimal("4.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002397 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002398 Decimal("1.20")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002399 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002400 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002401 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002402 Decimal("1000")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002403 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002404 Decimal("1.20E+6")
2405 """
2406 return a.__div__(b, context=self)
2407
2408 def divide_int(self, a, b):
2409 """Divides two numbers and returns the integer part of the result.
2410
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002411 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002412 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002413 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002414 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002415 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002416 Decimal("3")
2417 """
2418 return a.__floordiv__(b, context=self)
2419
2420 def divmod(self, a, b):
2421 return a.__divmod__(b, context=self)
2422
2423 def max(self, a,b):
2424 """max compares two values numerically and returns the maximum.
2425
2426 If either operand is a NaN then the general rules apply.
2427 Otherwise, the operands are compared as as though by the compare
2428 operation. If they are numerically equal then the left-hand operand
2429 is chosen as the result. Otherwise the maximum (closer to positive
2430 infinity) of the two operands is chosen as the result.
2431
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002432 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002433 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002434 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002435 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002436 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002437 Decimal("1")
2438 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
2439 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002440 """
2441 return a.max(b, context=self)
2442
2443 def min(self, a,b):
2444 """min compares two values numerically and returns the minimum.
2445
2446 If either operand is a NaN then the general rules apply.
2447 Otherwise, the operands are compared as as though by the compare
2448 operation. If they are numerically equal then the left-hand operand
2449 is chosen as the result. Otherwise the minimum (closer to negative
2450 infinity) of the two operands is chosen as the result.
2451
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002452 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002453 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002454 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002455 Decimal("-10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002456 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002457 Decimal("1.0")
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002458 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
2459 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002460 """
2461 return a.min(b, context=self)
2462
2463 def minus(self, a):
2464 """Minus corresponds to unary prefix minus in Python.
2465
2466 The operation is evaluated using the same rules as subtract; the
2467 operation minus(a) is calculated as subtract('0', a) where the '0'
2468 has the same exponent as the operand.
2469
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002470 >>> ExtendedContext.minus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002471 Decimal("-1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002472 >>> ExtendedContext.minus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002473 Decimal("1.3")
2474 """
2475 return a.__neg__(context=self)
2476
2477 def multiply(self, a, b):
2478 """multiply multiplies two operands.
2479
2480 If either operand is a special value then the general rules apply.
2481 Otherwise, the operands are multiplied together ('long multiplication'),
2482 resulting in a number which may be as long as the sum of the lengths
2483 of the two operands.
2484
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002485 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002486 Decimal("3.60")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002487 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002488 Decimal("21")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002489 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002490 Decimal("0.72")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002491 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002492 Decimal("-0.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002493 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002494 Decimal("4.28135971E+11")
2495 """
2496 return a.__mul__(b, context=self)
2497
2498 def normalize(self, a):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002499 """normalize reduces an operand to its simplest form.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002500
2501 Essentially a plus operation with all trailing zeros removed from the
2502 result.
2503
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002504 >>> ExtendedContext.normalize(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002505 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002506 >>> ExtendedContext.normalize(Decimal('-2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002507 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002508 >>> ExtendedContext.normalize(Decimal('1.200'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002509 Decimal("1.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002510 >>> ExtendedContext.normalize(Decimal('-120'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002511 Decimal("-1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002512 >>> ExtendedContext.normalize(Decimal('120.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002513 Decimal("1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002514 >>> ExtendedContext.normalize(Decimal('0.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002515 Decimal("0")
2516 """
2517 return a.normalize(context=self)
2518
2519 def plus(self, a):
2520 """Plus corresponds to unary prefix plus in Python.
2521
2522 The operation is evaluated using the same rules as add; the
2523 operation plus(a) is calculated as add('0', a) where the '0'
2524 has the same exponent as the operand.
2525
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002526 >>> ExtendedContext.plus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002527 Decimal("1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002528 >>> ExtendedContext.plus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002529 Decimal("-1.3")
2530 """
2531 return a.__pos__(context=self)
2532
2533 def power(self, a, b, modulo=None):
2534 """Raises a to the power of b, to modulo if given.
2535
2536 The right-hand operand must be a whole number whose integer part (after
2537 any exponent has been applied) has no more than 9 digits and whose
2538 fractional part (if any) is all zeros before any rounding. The operand
2539 may be positive, negative, or zero; if negative, the absolute value of
2540 the power is used, and the left-hand operand is inverted (divided into
2541 1) before use.
2542
2543 If the increased precision needed for the intermediate calculations
2544 exceeds the capabilities of the implementation then an Invalid operation
2545 condition is raised.
2546
2547 If, when raising to a negative power, an underflow occurs during the
2548 division into 1, the operation is not halted at that point but
2549 continues.
2550
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002551 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002552 Decimal("8")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002553 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002554 Decimal("0.125")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002555 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002556 Decimal("69.7575744")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002557 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002558 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002559 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002560 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002561 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002562 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002563 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002564 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002565 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002566 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002567 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002568 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002569 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002570 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002571 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002572 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002573 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002574 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002575 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002576 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002577 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002578 Decimal("NaN")
2579 """
2580 return a.__pow__(b, modulo, context=self)
2581
2582 def quantize(self, a, b):
2583 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
2584
2585 The coefficient of the result is derived from that of the left-hand
2586 operand. It may be rounded using the current rounding setting (if the
2587 exponent is being increased), multiplied by a positive power of ten (if
2588 the exponent is being decreased), or is unchanged (if the exponent is
2589 already equal to that of the right-hand operand).
2590
2591 Unlike other operations, if the length of the coefficient after the
2592 quantize operation would be greater than precision then an Invalid
2593 operation condition is raised. This guarantees that, unless there is an
2594 error condition, the exponent of the result of a quantize is always
2595 equal to that of the right-hand operand.
2596
2597 Also unlike other operations, quantize will never raise Underflow, even
2598 if the result is subnormal and inexact.
2599
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002600 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002601 Decimal("2.170")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002602 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002603 Decimal("2.17")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002604 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002605 Decimal("2.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002606 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002607 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002608 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002609 Decimal("0E+1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002610 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002611 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002612 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002613 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002614 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002615 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002616 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002617 Decimal("-0E+5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002618 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002619 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002620 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002621 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002622 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002623 Decimal("217.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002624 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002625 Decimal("217")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002626 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002627 Decimal("2.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002628 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002629 Decimal("2E+2")
2630 """
2631 return a.quantize(b, context=self)
2632
2633 def remainder(self, a, b):
2634 """Returns the remainder from integer division.
2635
2636 The result is the residue of the dividend after the operation of
2637 calculating integer division as described for divide-integer, rounded to
2638 precision digits if necessary. The sign of the result, if non-zero, is
2639 the same as that of the original dividend.
2640
2641 This operation will fail under the same conditions as integer division
2642 (that is, if integer division on the same two operands would fail, the
2643 remainder cannot be calculated).
2644
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002645 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002646 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002647 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002648 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002649 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002650 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002651 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002652 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002653 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002654 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002655 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002656 Decimal("1.0")
2657 """
2658 return a.__mod__(b, context=self)
2659
2660 def remainder_near(self, a, b):
2661 """Returns to be "a - b * n", where n is the integer nearest the exact
2662 value of "x / b" (if two integers are equally near then the even one
2663 is chosen). If the result is equal to 0 then its sign will be the
2664 sign of a.
2665
2666 This operation will fail under the same conditions as integer division
2667 (that is, if integer division on the same two operands would fail, the
2668 remainder cannot be calculated).
2669
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002670 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002671 Decimal("-0.9")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002672 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002673 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002674 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002675 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002676 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002677 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002678 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002679 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002680 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002681 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002682 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002683 Decimal("-0.3")
2684 """
2685 return a.remainder_near(b, context=self)
2686
2687 def same_quantum(self, a, b):
2688 """Returns True if the two operands have the same exponent.
2689
2690 The result is never affected by either the sign or the coefficient of
2691 either operand.
2692
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002693 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002694 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002695 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002696 True
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002697 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002698 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002699 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002700 True
2701 """
2702 return a.same_quantum(b)
2703
2704 def sqrt(self, a):
2705 """Returns the square root of a non-negative number to context precision.
2706
2707 If the result must be inexact, it is rounded using the round-half-even
2708 algorithm.
2709
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002710 >>> ExtendedContext.sqrt(Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002711 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002712 >>> ExtendedContext.sqrt(Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002713 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002714 >>> ExtendedContext.sqrt(Decimal('0.39'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002715 Decimal("0.624499800")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002716 >>> ExtendedContext.sqrt(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002717 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002718 >>> ExtendedContext.sqrt(Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002719 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002720 >>> ExtendedContext.sqrt(Decimal('1.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002721 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002722 >>> ExtendedContext.sqrt(Decimal('1.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002723 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002724 >>> ExtendedContext.sqrt(Decimal('7'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002725 Decimal("2.64575131")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002726 >>> ExtendedContext.sqrt(Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002727 Decimal("3.16227766")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002728 >>> ExtendedContext.prec
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002729 9
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002730 """
2731 return a.sqrt(context=self)
2732
2733 def subtract(self, a, b):
2734 """Return the sum of the two operands.
2735
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002736 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002737 Decimal("0.23")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002738 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002739 Decimal("0.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002740 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002741 Decimal("-0.77")
2742 """
2743 return a.__sub__(b, context=self)
2744
2745 def to_eng_string(self, a):
2746 """Converts a number to a string, using scientific notation.
2747
2748 The operation is not affected by the context.
2749 """
2750 return a.to_eng_string(context=self)
2751
2752 def to_sci_string(self, a):
2753 """Converts a number to a string, using scientific notation.
2754
2755 The operation is not affected by the context.
2756 """
2757 return a.__str__(context=self)
2758
2759 def to_integral(self, a):
2760 """Rounds to an integer.
2761
2762 When the operand has a negative exponent, the result is the same
2763 as using the quantize() operation using the given operand as the
2764 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2765 of the operand as the precision setting, except that no flags will
2766 be set. The rounding mode is taken from the context.
2767
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002768 >>> ExtendedContext.to_integral(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002769 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002770 >>> ExtendedContext.to_integral(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002771 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002772 >>> ExtendedContext.to_integral(Decimal('100.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002773 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002774 >>> ExtendedContext.to_integral(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002775 Decimal("102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002776 >>> ExtendedContext.to_integral(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002777 Decimal("-102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002778 >>> ExtendedContext.to_integral(Decimal('10E+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002779 Decimal("1.0E+6")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002780 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002781 Decimal("7.89E+77")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002782 >>> ExtendedContext.to_integral(Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002783 Decimal("-Infinity")
2784 """
2785 return a.to_integral(context=self)
2786
2787class _WorkRep(object):
2788 __slots__ = ('sign','int','exp')
2789 # sign: -1 None 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002790 # int: int or long
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002791 # exp: None, int, or string
2792
2793 def __init__(self, value=None):
2794 if value is None:
2795 self.sign = None
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002796 self.int = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002797 self.exp = None
2798 if isinstance(value, Decimal):
2799 if value._sign:
2800 self.sign = -1
2801 else:
2802 self.sign = 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002803 cum = 0
2804 for digit in value._int:
2805 cum = cum * 10 + digit
2806 self.int = cum
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002807 self.exp = value._exp
2808 if isinstance(value, tuple):
2809 self.sign = value[0]
2810 self.int = value[1]
2811 self.exp = value[2]
2812
2813 def __repr__(self):
2814 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2815
2816 __str__ = __repr__
2817
2818 def __neg__(self):
2819 if self.sign == 1:
2820 return _WorkRep( (-1, self.int, self.exp) )
2821 else:
2822 return _WorkRep( (1, self.int, self.exp) )
2823
2824 def __abs__(self):
2825 if self.sign == -1:
2826 return -self
2827 else:
2828 return self
2829
2830 def __cmp__(self, other):
2831 if self.exp != other.exp:
2832 raise ValueError("Operands not normalized: %r, %r" % (self, other))
2833 if self.sign != other.sign:
2834 if self.sign == -1:
2835 return -1
2836 else:
2837 return 1
2838 if self.sign == -1:
2839 direction = -1
2840 else:
2841 direction = 1
2842 int1 = self.int
2843 int2 = other.int
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002844 if int1 > int2:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002845 return direction * 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002846 if int1 < int2:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002847 return direction * -1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002848 return 0
2849
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002850
2851
2852def _normalize(op1, op2, shouldround = 0, prec = 0):
2853 """Normalizes op1, op2 to have the same exp and length of coefficient.
2854
2855 Done during addition.
2856 """
2857 # Yes, the exponent is a long, but the difference between exponents
2858 # must be an int-- otherwise you'd get a big memory problem.
2859 numdigits = int(op1.exp - op2.exp)
2860 if numdigits < 0:
2861 numdigits = -numdigits
2862 tmp = op2
2863 other = op1
2864 else:
2865 tmp = op1
2866 other = op2
2867
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002868
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002869 if shouldround and numdigits > prec + 1:
2870 # Big difference in exponents - check the adjusted exponents
2871 tmp_len = len(str(tmp.int))
2872 other_len = len(str(other.int))
2873 if numdigits > (other_len + prec + 1 - tmp_len):
2874 # If the difference in adjusted exps is > prec+1, we know
2875 # other is insignificant, so might as well put a 1 after the precision.
2876 # (since this is only for addition.) Also stops use of massive longs.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002877
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002878 extend = prec + 2 - tmp_len
2879 if extend <= 0:
2880 extend = 1
2881 tmp.int *= 10 ** extend
2882 tmp.exp -= extend
2883 other.int = 1
2884 other.exp = tmp.exp
2885 return op1, op2
2886
2887 tmp.int *= 10 ** numdigits
2888 tmp.exp -= numdigits
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002889 return op1, op2
2890
2891def _adjust_coefficients(op1, op2):
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002892 """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002893
2894 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2895
2896 Used on _WorkRep instances during division.
2897 """
2898 adjust = 0
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002899 #If op1 is smaller, make it larger
2900 while op2.int > op1.int:
2901 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002902 op1.exp -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002903 adjust += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002904
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002905 #If op2 is too small, make it larger
2906 while op1.int >= (10 * op2.int):
2907 op2.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002908 op2.exp -= 1
2909 adjust -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002910
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002911 return op1, op2, adjust
2912
2913##### Helper Functions ########################################
2914
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002915def _convert_other(other):
2916 """Convert other to Decimal.
2917
2918 Verifies that it's ok to use in an implicit construction.
2919 """
2920 if isinstance(other, Decimal):
2921 return other
2922 if isinstance(other, (int, long)):
2923 return Decimal(other)
2924
2925 raise TypeError, "You can interact Decimal only with int, long or Decimal data types."
2926
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002927_infinity_map = {
2928 'inf' : 1,
2929 'infinity' : 1,
2930 '+inf' : 1,
2931 '+infinity' : 1,
2932 '-inf' : -1,
2933 '-infinity' : -1
2934}
2935
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002936def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002937 """Determines whether a string or float is infinity.
2938
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002939 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002940 """
2941 num = str(num).lower()
2942 return _infinity_map.get(num, 0)
2943
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002944def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002945 """Determines whether a string or float is NaN
2946
2947 (1, sign, diagnostic info as string) => NaN
2948 (2, sign, diagnostic info as string) => sNaN
2949 0 => not a NaN
2950 """
2951 num = str(num).lower()
2952 if not num:
2953 return 0
2954
2955 #get the sign, get rid of trailing [+-]
2956 sign = 0
2957 if num[0] == '+':
2958 num = num[1:]
2959 elif num[0] == '-': #elif avoids '+-nan'
2960 num = num[1:]
2961 sign = 1
2962
2963 if num.startswith('nan'):
2964 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
2965 return 0
2966 return (1, sign, num[3:].lstrip('0'))
2967 if num.startswith('snan'):
2968 if len(num) > 4 and not num[4:].isdigit():
2969 return 0
2970 return (2, sign, num[4:].lstrip('0'))
2971 return 0
2972
2973
2974##### Setup Specific Contexts ################################
2975
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002976# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00002977# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002978
2979DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002980 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002981 traps=[DivisionByZero, Overflow, InvalidOperation],
2982 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002983 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00002984 Emax=999999999,
2985 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002986 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002987)
2988
2989# Pre-made alternate contexts offered by the specification
2990# Don't change these; the user should be able to select these
2991# contexts and be able to reproduce results from other implementations
2992# of the spec.
2993
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002994BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002995 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002996 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
2997 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002998)
2999
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003000ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003001 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003002 traps=[],
3003 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003004)
3005
3006
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00003007##### Useful Constants (internal use only) ####################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003008
3009#Reusable defaults
3010Inf = Decimal('Inf')
3011negInf = Decimal('-Inf')
3012
3013#Infsign[sign] is infinity w/ that sign
3014Infsign = (Inf, negInf)
3015
3016NaN = Decimal('NaN')
3017
3018
3019##### crud for parsing strings #################################
3020import re
3021
3022# There's an optional sign at the start, and an optional exponent
3023# at the end. The exponent has an optional sign and at least one
3024# digit. In between, must have either at least one digit followed
3025# by an optional fraction, or a decimal point followed by at least
3026# one digit. Yuck.
3027
3028_parser = re.compile(r"""
3029# \s*
3030 (?P<sign>[-+])?
3031 (
3032 (?P<int>\d+) (\. (?P<frac>\d*))?
3033 |
3034 \. (?P<onlyfrac>\d+)
3035 )
3036 ([eE](?P<exp>[-+]? \d+))?
3037# \s*
3038 $
3039""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
3040
3041del re
3042
3043# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
3044
3045def _string2exact(s):
3046 m = _parser(s)
3047 if m is None:
3048 raise ValueError("invalid literal for Decimal: %r" % s)
3049
3050 if m.group('sign') == "-":
3051 sign = 1
3052 else:
3053 sign = 0
3054
3055 exp = m.group('exp')
3056 if exp is None:
3057 exp = 0
3058 else:
3059 exp = int(exp)
3060
3061 intpart = m.group('int')
3062 if intpart is None:
3063 intpart = ""
3064 fracpart = m.group('onlyfrac')
3065 else:
3066 fracpart = m.group('frac')
3067 if fracpart is None:
3068 fracpart = ""
3069
3070 exp -= len(fracpart)
3071
3072 mantissa = intpart + fracpart
3073 tmp = map(int, mantissa)
3074 backup = tmp
3075 while tmp and tmp[0] == 0:
3076 del tmp[0]
3077
3078 # It's a zero
3079 if not tmp:
3080 if backup:
3081 return (sign, tuple(backup), exp)
3082 return (sign, (0,), exp)
3083 mantissa = tuple(tmp)
3084
3085 return (sign, mantissa, exp)
3086
3087
3088if __name__ == '__main__':
3089 import doctest, sys
3090 doctest.testmod(sys.modules[__name__])