blob: 7ae59d12d5b901433ab04b7d496c1aa977d38730 [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 +0000139
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000140#Rounding
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000141ROUND_DOWN = 'ROUND_DOWN'
142ROUND_HALF_UP = 'ROUND_HALF_UP'
143ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
144ROUND_CEILING = 'ROUND_CEILING'
145ROUND_FLOOR = 'ROUND_FLOOR'
146ROUND_UP = 'ROUND_UP'
147ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000148
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +0000149#Rounding decision (not part of the public API)
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000150NEVER_ROUND = 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY
151ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000152
153#Errors
154
155class DecimalException(ArithmeticError):
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000156 """Base exception class.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000157
158 Used exceptions derive from this.
159 If an exception derives from another exception besides this (such as
160 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
161 called if the others are present. This isn't actually used for
162 anything, though.
163
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000164 handle -- Called when context._raise_error is called and the
165 trap_enabler is set. First argument is self, second is the
166 context. More arguments can be given, those being after
167 the explanation in _raise_error (For example,
168 context._raise_error(NewError, '(-x)!', self._sign) would
169 call NewError().handle(context, self._sign).)
170
171 To define a new exception, it should be sufficient to have it derive
172 from DecimalException.
173 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000174 def handle(self, context, *args):
175 pass
176
177
178class Clamped(DecimalException):
179 """Exponent of a 0 changed to fit bounds.
180
181 This occurs and signals clamped if the exponent of a result has been
182 altered in order to fit the constraints of a specific concrete
183 representation. This may occur when the exponent of a zero result would
184 be outside the bounds of a representation, or when a large normal
185 number would have an encoded exponent that cannot be represented. In
186 this latter case, the exponent is reduced to fit and the corresponding
187 number of zero digits are appended to the coefficient ("fold-down").
188 """
189
190
191class InvalidOperation(DecimalException):
192 """An invalid operation was performed.
193
194 Various bad things cause this:
195
196 Something creates a signaling NaN
197 -INF + INF
198 0 * (+-)INF
199 (+-)INF / (+-)INF
200 x % 0
201 (+-)INF % x
202 x._rescale( non-integer )
203 sqrt(-x) , x > 0
204 0 ** 0
205 x ** (non-integer)
206 x ** (+-)INF
207 An operand is invalid
208 """
209 def handle(self, context, *args):
210 if args:
211 if args[0] == 1: #sNaN, must drop 's' but keep diagnostics
212 return Decimal( (args[1]._sign, args[1]._int, 'n') )
213 return NaN
214
215class ConversionSyntax(InvalidOperation):
216 """Trying to convert badly formed string.
217
218 This occurs and signals invalid-operation if an string is being
219 converted to a number and it does not conform to the numeric string
220 syntax. The result is [0,qNaN].
221 """
222
223 def handle(self, context, *args):
224 return (0, (0,), 'n') #Passed to something which uses a tuple.
225
226class DivisionByZero(DecimalException, ZeroDivisionError):
227 """Division by 0.
228
229 This occurs and signals division-by-zero if division of a finite number
230 by zero was attempted (during a divide-integer or divide operation, or a
231 power operation with negative right-hand operand), and the dividend was
232 not zero.
233
234 The result of the operation is [sign,inf], where sign is the exclusive
235 or of the signs of the operands for divide, or is 1 for an odd power of
236 -0, for power.
237 """
238
239 def handle(self, context, sign, double = None, *args):
240 if double is not None:
241 return (Infsign[sign],)*2
242 return Infsign[sign]
243
244class DivisionImpossible(InvalidOperation):
245 """Cannot perform the division adequately.
246
247 This occurs and signals invalid-operation if the integer result of a
248 divide-integer or remainder operation had too many digits (would be
249 longer than precision). The result is [0,qNaN].
250 """
251
252 def handle(self, context, *args):
253 return (NaN, NaN)
254
255class DivisionUndefined(InvalidOperation, ZeroDivisionError):
256 """Undefined result of division.
257
258 This occurs and signals invalid-operation if division by zero was
259 attempted (during a divide-integer, divide, or remainder operation), and
260 the dividend is also zero. The result is [0,qNaN].
261 """
262
263 def handle(self, context, tup=None, *args):
264 if tup is not None:
265 return (NaN, NaN) #for 0 %0, 0 // 0
266 return NaN
267
268class Inexact(DecimalException):
269 """Had to round, losing information.
270
271 This occurs and signals inexact whenever the result of an operation is
272 not exact (that is, it needed to be rounded and any discarded digits
273 were non-zero), or if an overflow or underflow condition occurs. The
274 result in all cases is unchanged.
275
276 The inexact signal may be tested (or trapped) to determine if a given
277 operation (or sequence of operations) was inexact.
278 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000279 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000280
281class InvalidContext(InvalidOperation):
282 """Invalid context. Unknown rounding, for example.
283
284 This occurs and signals invalid-operation if an invalid context was
285 detected during an operation. This can occur if contexts are not checked
286 on creation and either the precision exceeds the capability of the
287 underlying concrete representation or an unknown or unsupported rounding
288 was specified. These aspects of the context need only be checked when
289 the values are required to be used. The result is [0,qNaN].
290 """
291
292 def handle(self, context, *args):
293 return NaN
294
295class Rounded(DecimalException):
296 """Number got rounded (not necessarily changed during rounding).
297
298 This occurs and signals rounded whenever the result of an operation is
299 rounded (that is, some zero or non-zero digits were discarded from the
300 coefficient), or if an overflow or underflow condition occurs. The
301 result in all cases is unchanged.
302
303 The rounded signal may be tested (or trapped) to determine if a given
304 operation (or sequence of operations) caused a loss of precision.
305 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000306 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000307
308class Subnormal(DecimalException):
309 """Exponent < Emin before rounding.
310
311 This occurs and signals subnormal whenever the result of a conversion or
312 operation is subnormal (that is, its adjusted exponent is less than
313 Emin, before any rounding). The result in all cases is unchanged.
314
315 The subnormal signal may be tested (or trapped) to determine if a given
316 or operation (or sequence of operations) yielded a subnormal result.
317 """
318 pass
319
320class Overflow(Inexact, Rounded):
321 """Numerical overflow.
322
323 This occurs and signals overflow if the adjusted exponent of a result
324 (from a conversion or from an operation that is not an attempt to divide
325 by zero), after rounding, would be greater than the largest value that
326 can be handled by the implementation (the value Emax).
327
328 The result depends on the rounding mode:
329
330 For round-half-up and round-half-even (and for round-half-down and
331 round-up, if implemented), the result of the operation is [sign,inf],
332 where sign is the sign of the intermediate result. For round-down, the
333 result is the largest finite number that can be represented in the
334 current precision, with the sign of the intermediate result. For
335 round-ceiling, the result is the same as for round-down if the sign of
336 the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
337 the result is the same as for round-down if the sign of the intermediate
338 result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
339 will also be raised.
340 """
341
342 def handle(self, context, sign, *args):
343 if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
344 ROUND_HALF_DOWN, ROUND_UP):
345 return Infsign[sign]
346 if sign == 0:
347 if context.rounding == ROUND_CEILING:
348 return Infsign[sign]
349 return Decimal((sign, (9,)*context.prec,
350 context.Emax-context.prec+1))
351 if sign == 1:
352 if context.rounding == ROUND_FLOOR:
353 return Infsign[sign]
354 return Decimal( (sign, (9,)*context.prec,
355 context.Emax-context.prec+1))
356
357
358class Underflow(Inexact, Rounded, Subnormal):
359 """Numerical underflow with result rounded to 0.
360
361 This occurs and signals underflow if a result is inexact and the
362 adjusted exponent of the result would be smaller (more negative) than
363 the smallest value that can be handled by the implementation (the value
364 Emin). That is, the result is both inexact and subnormal.
365
366 The result after an underflow will be a subnormal number rounded, if
367 necessary, so that its exponent is not less than Etiny. This may result
368 in 0 with the sign of the intermediate result and an exponent of Etiny.
369
370 In all cases, Inexact, Rounded, and Subnormal will also be raised.
371 """
372
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000373# List of public traps and flags
Raymond Hettingerfed52962004-07-14 15:41:57 +0000374_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000375 Underflow, InvalidOperation, Subnormal]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000376
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000377# Map conditions (per the spec) to signals
378_condition_map = {ConversionSyntax:InvalidOperation,
379 DivisionImpossible:InvalidOperation,
380 DivisionUndefined:InvalidOperation,
381 InvalidContext:InvalidOperation}
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000382
383##### Context Functions #######################################
384
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000385# The getcontext() and setcontext() function manage access to a thread-local
386# current context. Py2.4 offers direct support for thread locals. If that
387# is not available, use threading.currentThread() which is slower but will
388# work for older Pythons.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000389
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000390try:
391 threading.local
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000392
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000393except AttributeError:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000394
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000395 #To fix reloading, force it to create a new context
396 #Old contexts have different exceptions in their dicts, making problems.
397 if hasattr(threading.currentThread(), '__decimal_context__'):
398 del threading.currentThread().__decimal_context__
399
400 def setcontext(context):
401 """Set this thread's context to context."""
402 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000403 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000404 context.clear_flags()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000405 threading.currentThread().__decimal_context__ = context
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000406
407 def getcontext():
408 """Returns this thread's context.
409
410 If this thread does not yet have a context, returns
411 a new context and sets this thread's context.
412 New contexts are copies of DefaultContext.
413 """
414 try:
415 return threading.currentThread().__decimal_context__
416 except AttributeError:
417 context = Context()
418 threading.currentThread().__decimal_context__ = context
419 return context
420
421else:
422
423 local = threading.local()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000424 if hasattr(local, '__decimal_context__'):
425 del local.__decimal_context__
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000426
427 def getcontext(_local=local):
428 """Returns this thread's context.
429
430 If this thread does not yet have a context, returns
431 a new context and sets this thread's context.
432 New contexts are copies of DefaultContext.
433 """
434 try:
435 return _local.__decimal_context__
436 except AttributeError:
437 context = Context()
438 _local.__decimal_context__ = context
439 return context
440
441 def setcontext(context, _local=local):
442 """Set this thread's context to context."""
443 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000444 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000445 context.clear_flags()
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000446 _local.__decimal_context__ = context
447
448 del threading, local # Don't contaminate the namespace
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000449
450
451##### Decimal class ###########################################
452
453class Decimal(object):
454 """Floating point class for decimal arithmetic."""
455
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000456 __slots__ = ('_exp','_int','_sign', '_is_special')
457 # Generally, the value of the Decimal instance is given by
458 # (-1)**_sign * _int * 10**_exp
459 # Special values are signified by _is_special == True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000460
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000461 # We're immutable, so use __new__ not __init__
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000462 def __new__(cls, value="0", context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000463 """Create a decimal point instance.
464
465 >>> Decimal('3.14') # string input
466 Decimal("3.14")
467 >>> Decimal((0, (3, 1, 4), -2)) # tuple input (sign, digit_tuple, exponent)
468 Decimal("3.14")
469 >>> Decimal(314) # int or long
470 Decimal("314")
471 >>> Decimal(Decimal(314)) # another decimal instance
472 Decimal("314")
473 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000474
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000475 self = object.__new__(cls)
476 self._is_special = False
477
478 # From an internal working value
479 if isinstance(value, _WorkRep):
480 if value.sign == 1:
481 self._sign = 0
482 else:
483 self._sign = 1
484 self._int = tuple(map(int, str(value.int)))
485 self._exp = int(value.exp)
486 return self
487
488 # From another decimal
489 if isinstance(value, Decimal):
490 self._exp = value._exp
491 self._sign = value._sign
492 self._int = value._int
493 self._is_special = value._is_special
494 return self
495
496 # From an integer
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000497 if isinstance(value, (int,long)):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000498 if value >= 0:
499 self._sign = 0
500 else:
501 self._sign = 1
502 self._exp = 0
503 self._int = tuple(map(int, str(abs(value))))
504 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000505
506 # tuple/list conversion (possibly from as_tuple())
507 if isinstance(value, (list,tuple)):
508 if len(value) != 3:
509 raise ValueError, 'Invalid arguments'
510 if value[0] not in [0,1]:
511 raise ValueError, 'Invalid sign'
512 for digit in value[1]:
513 if not isinstance(digit, (int,long)) or digit < 0:
514 raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
515
516 self._sign = value[0]
517 self._int = tuple(value[1])
518 if value[2] in ('F','n','N'):
519 self._exp = value[2]
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000520 self._is_special = True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000521 else:
522 self._exp = int(value[2])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000523 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000524
Raymond Hettingerbf440692004-07-10 14:14:37 +0000525 if isinstance(value, float):
526 raise TypeError("Cannot convert float to Decimal. " +
527 "First convert the float to a string")
528
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000529 # Other argument types may require the context during interpretation
530 if context is None:
531 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000532
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000533 # From a string
534 # REs insist on real strings, so we can too.
535 if isinstance(value, basestring):
536 if _isinfinity(value):
537 self._exp = 'F'
538 self._int = (0,)
539 self._is_special = True
540 if _isinfinity(value) == 1:
541 self._sign = 0
542 else:
543 self._sign = 1
544 return self
545 if _isnan(value):
546 sig, sign, diag = _isnan(value)
547 self._is_special = True
548 if len(diag) > context.prec: #Diagnostic info too long
549 self._sign, self._int, self._exp = \
550 context._raise_error(ConversionSyntax)
551 return self
552 if sig == 1:
553 self._exp = 'n' #qNaN
554 else: #sig == 2
555 self._exp = 'N' #sNaN
556 self._sign = sign
557 self._int = tuple(map(int, diag)) #Diagnostic info
558 return self
559 try:
560 self._sign, self._int, self._exp = _string2exact(value)
561 except ValueError:
562 self._is_special = True
563 self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
564 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000565
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000566 raise TypeError("Cannot convert %r to Decimal" % value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000567
568 def _isnan(self):
569 """Returns whether the number is not actually one.
570
571 0 if a number
572 1 if NaN
573 2 if sNaN
574 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000575 if self._is_special:
576 exp = self._exp
577 if exp == 'n':
578 return 1
579 elif exp == 'N':
580 return 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000581 return 0
582
583 def _isinfinity(self):
584 """Returns whether the number is infinite
585
586 0 if finite or not a number
587 1 if +INF
588 -1 if -INF
589 """
590 if self._exp == 'F':
591 if self._sign:
592 return -1
593 return 1
594 return 0
595
596 def _check_nans(self, other = None, context=None):
597 """Returns whether the number is not actually one.
598
599 if self, other are sNaN, signal
600 if self, other are NaN return nan
601 return 0
602
603 Done before operations.
604 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000605
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000606 self_is_nan = self._isnan()
607 if other is None:
608 other_is_nan = False
609 else:
610 other_is_nan = other._isnan()
611
612 if self_is_nan or other_is_nan:
613 if context is None:
614 context = getcontext()
615
616 if self_is_nan == 2:
617 return context._raise_error(InvalidOperation, 'sNaN',
618 1, self)
619 if other_is_nan == 2:
620 return context._raise_error(InvalidOperation, 'sNaN',
621 1, other)
622 if self_is_nan:
623 return self
624
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000625 return other
626 return 0
627
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000628 def __nonzero__(self):
629 """Is the number non-zero?
630
631 0 if self == 0
632 1 if self != 0
633 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000634 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000635 return 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000636 return sum(self._int) != 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000637
638 def __cmp__(self, other, context=None):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000639 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000640
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000641 if self._is_special or other._is_special:
642 ans = self._check_nans(other, context)
643 if ans:
644 return 1 # Comparison involving NaN's always reports self > other
645
646 # INF = INF
647 return cmp(self._isinfinity(), other._isinfinity())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000648
649 if not self and not other:
650 return 0 #If both 0, sign comparison isn't certain.
651
652 #If different signs, neg one is less
653 if other._sign < self._sign:
654 return -1
655 if self._sign < other._sign:
656 return 1
657
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000658 self_adjusted = self.adjusted()
659 other_adjusted = other.adjusted()
660 if self_adjusted == other_adjusted and \
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000661 self._int + (0,)*(self._exp - other._exp) == \
662 other._int + (0,)*(other._exp - self._exp):
663 return 0 #equal, except in precision. ([0]*(-x) = [])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000664 elif self_adjusted > other_adjusted and self._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000665 return (-1)**self._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000666 elif self_adjusted < other_adjusted and other._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000667 return -((-1)**self._sign)
668
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000669 # Need to round, so make sure we have a valid context
670 if context is None:
671 context = getcontext()
672
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000673 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000674 rounding = context._set_rounding(ROUND_UP) #round away from 0
675
676 flags = context._ignore_all_flags()
677 res = self.__sub__(other, context=context)
678
679 context._regard_flags(*flags)
680
681 context.rounding = rounding
682
683 if not res:
684 return 0
685 elif res._sign:
686 return -1
687 return 1
688
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000689 def __eq__(self, other):
690 if not isinstance(other, (Decimal, int, long)):
691 return False
692 return self.__cmp__(other) == 0
693
694 def __ne__(self, other):
695 if not isinstance(other, (Decimal, int, long)):
696 return True
697 return self.__cmp__(other) != 0
698
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000699 def compare(self, other, context=None):
700 """Compares one to another.
701
702 -1 => a < b
703 0 => a = b
704 1 => a > b
705 NaN => one is NaN
706 Like __cmp__, but returns Decimal instances.
707 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000708 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000709
710 #compare(NaN, NaN) = NaN
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000711 if (self._is_special or other and other._is_special):
712 ans = self._check_nans(other, context)
713 if ans:
714 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000715
716 return Decimal(self.__cmp__(other, context))
717
718 def __hash__(self):
719 """x.__hash__() <==> hash(x)"""
720 # Decimal integers must hash the same as the ints
721 # Non-integer decimals are normalized and hashed as strings
722 # Normalization assures that hast(100E-1) == hash(10)
723 i = int(self)
724 if self == Decimal(i):
725 return hash(i)
726 assert self.__nonzero__() # '-0' handled by integer case
727 return hash(str(self.normalize()))
728
729 def as_tuple(self):
730 """Represents the number as a triple tuple.
731
732 To show the internals exactly as they are.
733 """
734 return (self._sign, self._int, self._exp)
735
736 def __repr__(self):
737 """Represents the number as an instance of Decimal."""
738 # Invariant: eval(repr(d)) == d
739 return 'Decimal("%s")' % str(self)
740
741 def __str__(self, eng = 0, context=None):
742 """Return string representation of the number in scientific notation.
743
744 Captures all of the information in the underlying representation.
745 """
746
747 if self._isnan():
748 minus = '-'*self._sign
749 if self._int == (0,):
750 info = ''
751 else:
752 info = ''.join(map(str, self._int))
753 if self._isnan() == 2:
754 return minus + 'sNaN' + info
755 return minus + 'NaN' + info
756 if self._isinfinity():
757 minus = '-'*self._sign
758 return minus + 'Infinity'
759
760 if context is None:
761 context = getcontext()
762
763 tmp = map(str, self._int)
764 numdigits = len(self._int)
765 leftdigits = self._exp + numdigits
766 if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
767 if self._exp < 0 and self._exp >= -6: #short, no need for e/E
768 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
769 return s
770 #exp is closest mult. of 3 >= self._exp
771 exp = ((self._exp - 1)// 3 + 1) * 3
772 if exp != self._exp:
773 s = '0.'+'0'*(exp - self._exp)
774 else:
775 s = '0'
776 if exp != 0:
777 if context.capitals:
778 s += 'E'
779 else:
780 s += 'e'
781 if exp > 0:
782 s += '+' #0.0e+3, not 0.0e3
783 s += str(exp)
784 s = '-'*self._sign + s
785 return s
786 if eng:
787 dotplace = (leftdigits-1)%3+1
788 adjexp = leftdigits -1 - (leftdigits-1)%3
789 else:
790 adjexp = leftdigits-1
791 dotplace = 1
792 if self._exp == 0:
793 pass
794 elif self._exp < 0 and adjexp >= 0:
795 tmp.insert(leftdigits, '.')
796 elif self._exp < 0 and adjexp >= -6:
797 tmp[0:0] = ['0'] * int(-leftdigits)
798 tmp.insert(0, '0.')
799 else:
800 if numdigits > dotplace:
801 tmp.insert(dotplace, '.')
802 elif numdigits < dotplace:
803 tmp.extend(['0']*(dotplace-numdigits))
804 if adjexp:
805 if not context.capitals:
806 tmp.append('e')
807 else:
808 tmp.append('E')
809 if adjexp > 0:
810 tmp.append('+')
811 tmp.append(str(adjexp))
812 if eng:
813 while tmp[0:1] == ['0']:
814 tmp[0:1] = []
815 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
816 tmp[0:0] = ['0']
817 if self._sign:
818 tmp.insert(0, '-')
819
820 return ''.join(tmp)
821
822 def to_eng_string(self, context=None):
823 """Convert to engineering-type string.
824
825 Engineering notation has an exponent which is a multiple of 3, so there
826 are up to 3 digits left of the decimal place.
827
828 Same rules for when in exponential and when as a value as in __str__.
829 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000830 return self.__str__(eng=1, context=context)
831
832 def __neg__(self, context=None):
833 """Returns a copy with the sign switched.
834
835 Rounds, if it has reason.
836 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000837 if self._is_special:
838 ans = self._check_nans(context=context)
839 if ans:
840 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000841
842 if not self:
843 # -Decimal('0') is Decimal('0'), not Decimal('-0')
844 sign = 0
845 elif self._sign:
846 sign = 0
847 else:
848 sign = 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000849
850 if context is None:
851 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000852 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000853 return Decimal((sign, self._int, self._exp))._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000854 return Decimal( (sign, self._int, self._exp))
855
856 def __pos__(self, context=None):
857 """Returns a copy, unless it is a sNaN.
858
859 Rounds the number (if more then precision digits)
860 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000861 if self._is_special:
862 ans = self._check_nans(context=context)
863 if ans:
864 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000865
866 sign = self._sign
867 if not self:
868 # + (-0) = 0
869 sign = 0
870
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000871 if context is None:
872 context = getcontext()
873
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000874 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000875 ans = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000876 else:
877 ans = Decimal(self)
878 ans._sign = sign
879 return ans
880
881 def __abs__(self, round=1, context=None):
882 """Returns the absolute value of self.
883
884 If the second argument is 0, do not round.
885 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000886 if self._is_special:
887 ans = self._check_nans(context=context)
888 if ans:
889 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000890
891 if not round:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000892 if context is None:
893 context = getcontext()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000894 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000895 context._set_rounding_decision(NEVER_ROUND)
896
897 if self._sign:
898 ans = self.__neg__(context=context)
899 else:
900 ans = self.__pos__(context=context)
901
902 return ans
903
904 def __add__(self, other, context=None):
905 """Returns self + other.
906
907 -INF + INF (or the reverse) cause InvalidOperation errors.
908 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000909 other = _convert_other(other)
910
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000911 if context is None:
912 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000913
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000914 if self._is_special or other._is_special:
915 ans = self._check_nans(other, context)
916 if ans:
917 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000918
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000919 if self._isinfinity():
920 #If both INF, same sign => same as both, opposite => error.
921 if self._sign != other._sign and other._isinfinity():
922 return context._raise_error(InvalidOperation, '-INF + INF')
923 return Decimal(self)
924 if other._isinfinity():
925 return Decimal(other) #Can't both be infinity here
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000926
927 shouldround = context._rounding_decision == ALWAYS_ROUND
928
929 exp = min(self._exp, other._exp)
930 negativezero = 0
931 if context.rounding == ROUND_FLOOR and self._sign != other._sign:
932 #If the answer is 0, the sign should be negative, in this case.
933 negativezero = 1
934
935 if not self and not other:
936 sign = min(self._sign, other._sign)
937 if negativezero:
938 sign = 1
939 return Decimal( (sign, (0,), exp))
940 if not self:
941 if exp < other._exp - context.prec-1:
942 exp = other._exp - context.prec-1
943 ans = other._rescale(exp, watchexp=0, context=context)
944 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000945 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000946 return ans
947 if not other:
948 if exp < self._exp - context.prec-1:
949 exp = self._exp - context.prec-1
950 ans = self._rescale(exp, watchexp=0, context=context)
951 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000952 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000953 return ans
954
955 op1 = _WorkRep(self)
956 op2 = _WorkRep(other)
957 op1, op2 = _normalize(op1, op2, shouldround, context.prec)
958
959 result = _WorkRep()
960
961 if op1.sign != op2.sign:
962 diff = cmp(abs(op1), abs(op2))
963 # Equal and opposite
964 if diff == 0:
965 if exp < context.Etiny():
966 exp = context.Etiny()
967 context._raise_error(Clamped)
968 return Decimal((negativezero, (0,), exp))
969 if diff < 0:
970 op1, op2 = op2, op1
971 #OK, now abs(op1) > abs(op2)
972 if op1.sign == -1:
973 result.sign = -1
974 op1.sign, op2.sign = op2.sign, op1.sign
975 else:
976 result.sign = 1
977 #So we know the sign, and op1 > 0.
978 elif op1.sign == -1:
979 result.sign = -1
980 op1.sign, op2.sign = (1, 1)
981 else:
982 result.sign = 1
983 #Now, op1 > abs(op2) > 0
984
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000985 if op2.sign == 1:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000986 result.int = op1.int + op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000987 else:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000988 result.int = op1.int - op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000989
990 result.exp = op1.exp
991 ans = Decimal(result)
992 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000993 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000994 return ans
995
996 __radd__ = __add__
997
998 def __sub__(self, other, context=None):
999 """Return self + (-other)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001000 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001001
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001002 if self._is_special or other._is_special:
1003 ans = self._check_nans(other, context=context)
1004 if ans:
1005 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001006
1007 # -Decimal(0) = Decimal(0), which we don't want since
1008 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
1009 # so we change the sign directly to a copy
1010 tmp = Decimal(other)
1011 tmp._sign = 1-tmp._sign
1012
1013 return self.__add__(tmp, context=context)
1014
1015 def __rsub__(self, other, context=None):
1016 """Return other + (-self)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001017 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001018
1019 tmp = Decimal(self)
1020 tmp._sign = 1 - tmp._sign
1021 return other.__add__(tmp, context=context)
1022
1023 def _increment(self, round=1, context=None):
1024 """Special case of add, adding 1eExponent
1025
1026 Since it is common, (rounding, for example) this adds
1027 (sign)*one E self._exp to the number more efficiently than add.
1028
1029 For example:
1030 Decimal('5.624e10')._increment() == Decimal('5.625e10')
1031 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001032 if self._is_special:
1033 ans = self._check_nans(context=context)
1034 if ans:
1035 return ans
1036
1037 return Decimal(self) # Must be infinite, and incrementing makes no difference
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001038
1039 L = list(self._int)
1040 L[-1] += 1
1041 spot = len(L)-1
1042 while L[spot] == 10:
1043 L[spot] = 0
1044 if spot == 0:
1045 L[0:0] = [1]
1046 break
1047 L[spot-1] += 1
1048 spot -= 1
1049 ans = Decimal((self._sign, L, self._exp))
1050
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001051 if context is None:
1052 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001053 if round and context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001054 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001055 return ans
1056
1057 def __mul__(self, other, context=None):
1058 """Return self * other.
1059
1060 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1061 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001062 other = _convert_other(other)
1063
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001064 if context is None:
1065 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001066
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001067 resultsign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001068
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001069 if self._is_special or other._is_special:
1070 ans = self._check_nans(other, context)
1071 if ans:
1072 return ans
1073
1074 if self._isinfinity():
1075 if not other:
1076 return context._raise_error(InvalidOperation, '(+-)INF * 0')
1077 return Infsign[resultsign]
1078
1079 if other._isinfinity():
1080 if not self:
1081 return context._raise_error(InvalidOperation, '0 * (+-)INF')
1082 return Infsign[resultsign]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001083
1084 resultexp = self._exp + other._exp
1085 shouldround = context._rounding_decision == ALWAYS_ROUND
1086
1087 # Special case for multiplying by zero
1088 if not self or not other:
1089 ans = Decimal((resultsign, (0,), resultexp))
1090 if shouldround:
1091 #Fixing in case the exponent is out of bounds
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001092 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001093 return ans
1094
1095 # Special case for multiplying by power of 10
1096 if self._int == (1,):
1097 ans = Decimal((resultsign, other._int, resultexp))
1098 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001099 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001100 return ans
1101 if other._int == (1,):
1102 ans = Decimal((resultsign, self._int, resultexp))
1103 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001104 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001105 return ans
1106
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001107 op1 = _WorkRep(self)
1108 op2 = _WorkRep(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001109
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001110 ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001111 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001112 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001113
1114 return ans
1115 __rmul__ = __mul__
1116
1117 def __div__(self, other, context=None):
1118 """Return self / other."""
1119 return self._divide(other, context=context)
1120 __truediv__ = __div__
1121
1122 def _divide(self, other, divmod = 0, context=None):
1123 """Return a / b, to context.prec precision.
1124
1125 divmod:
1126 0 => true division
1127 1 => (a //b, a%b)
1128 2 => a //b
1129 3 => a%b
1130
1131 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1132 computing the other value are not raised.
1133 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001134 other = _convert_other(other)
1135
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001136 if context is None:
1137 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001138
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001139 sign = self._sign ^ other._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001140
1141 if self._is_special or other._is_special:
1142 ans = self._check_nans(other, context)
1143 if ans:
1144 if divmod:
1145 return (ans, ans)
1146 return ans
1147
1148 if self._isinfinity() and other._isinfinity():
1149 if divmod:
1150 return (context._raise_error(InvalidOperation,
1151 '(+-)INF // (+-)INF'),
1152 context._raise_error(InvalidOperation,
1153 '(+-)INF % (+-)INF'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001154 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001155
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001156 if self._isinfinity():
1157 if divmod == 1:
1158 return (Infsign[sign],
1159 context._raise_error(InvalidOperation, 'INF % x'))
1160 elif divmod == 2:
1161 return (Infsign[sign], NaN)
1162 elif divmod == 3:
1163 return (Infsign[sign],
1164 context._raise_error(InvalidOperation, 'INF % x'))
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001165 return Infsign[sign]
1166
1167 if other._isinfinity():
1168 if divmod:
1169 return (Decimal((sign, (0,), 0)), Decimal(self))
1170 context._raise_error(Clamped, 'Division by infinity')
1171 return Decimal((sign, (0,), context.Etiny()))
1172
1173 # Special cases for zeroes
1174 if not self and not other:
1175 if divmod:
1176 return context._raise_error(DivisionUndefined, '0 / 0', 1)
1177 return context._raise_error(DivisionUndefined, '0 / 0')
1178
1179 if not self:
1180 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001181 otherside = Decimal(self)
1182 otherside._exp = min(self._exp, other._exp)
1183 return (Decimal((sign, (0,), 0)), otherside)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001184 exp = self._exp - other._exp
1185 if exp < context.Etiny():
1186 exp = context.Etiny()
1187 context._raise_error(Clamped, '0e-x / y')
1188 if exp > context.Emax:
1189 exp = context.Emax
1190 context._raise_error(Clamped, '0e+x / y')
1191 return Decimal( (sign, (0,), exp) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001192
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001193 if not other:
1194 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001195 return context._raise_error(DivisionByZero, 'divmod(x,0)',
1196 sign, 1)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001197 return context._raise_error(DivisionByZero, 'x / 0', sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001198
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001199 #OK, so neither = 0, INF or NaN
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001200
1201 shouldround = context._rounding_decision == ALWAYS_ROUND
1202
1203 #If we're dividing into ints, and self < other, stop.
1204 #self.__abs__(0) does not round.
1205 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
1206
1207 if divmod == 1 or divmod == 3:
1208 exp = min(self._exp, other._exp)
1209 ans2 = self._rescale(exp, context=context, watchexp=0)
1210 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001211 ans2 = ans2._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001212 return (Decimal( (sign, (0,), 0) ),
1213 ans2)
1214
1215 elif divmod == 2:
1216 #Don't round the mod part, if we don't need it.
1217 return (Decimal( (sign, (0,), 0) ), Decimal(self))
1218
1219 if sign:
1220 sign = -1
1221 else:
1222 sign = 1
1223 adjust = 0
1224 op1 = _WorkRep(self)
1225 op2 = _WorkRep(other)
1226 op1, op2, adjust = _adjust_coefficients(op1, op2)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001227 res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001228 if divmod and res.exp > context.prec + 1:
1229 return context._raise_error(DivisionImpossible)
1230
1231 ans = None
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001232 prec_limit = 10 ** context.prec
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001233 while 1:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001234 while op2.int <= op1.int:
1235 res.int += 1
1236 op1.int -= op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001237 if res.exp == 0 and divmod:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001238 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001239 return context._raise_error(DivisionImpossible)
1240 otherside = Decimal(op1)
1241 frozen = context._ignore_all_flags()
1242
1243 exp = min(self._exp, other._exp)
1244 otherside = otherside._rescale(exp, context=context,
1245 watchexp=0)
1246 context._regard_flags(*frozen)
1247 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001248 otherside = otherside._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001249 return (Decimal(res), otherside)
1250
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001251 if op1.int == 0 and adjust >= 0 and not divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001252 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001253 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001254 if divmod:
1255 return context._raise_error(DivisionImpossible)
1256 shouldround=1
1257 # Really, the answer is a bit higher, so adding a one to
1258 # the end will make sure the rounding is right.
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001259 if op1.int != 0:
1260 res.int *= 10
1261 res.int += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001262 res.exp -= 1
1263
1264 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001265 res.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001266 res.exp -= 1
1267 adjust += 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001268 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001269 op1.exp -= 1
1270
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001271 if res.exp == 0 and divmod and op2.int > op1.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001272 #Solves an error in precision. Same as a previous block.
1273
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001274 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001275 return context._raise_error(DivisionImpossible)
1276 otherside = Decimal(op1)
1277 frozen = context._ignore_all_flags()
1278
1279 exp = min(self._exp, other._exp)
1280 otherside = otherside._rescale(exp, context=context)
1281
1282 context._regard_flags(*frozen)
1283
1284 return (Decimal(res), otherside)
1285
1286 ans = Decimal(res)
1287 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001288 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001289 return ans
1290
1291 def __rdiv__(self, other, context=None):
1292 """Swaps self/other and returns __div__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001293 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001294 return other.__div__(self, context=context)
1295 __rtruediv__ = __rdiv__
1296
1297 def __divmod__(self, other, context=None):
1298 """
1299 (self // other, self % other)
1300 """
1301 return self._divide(other, 1, context)
1302
1303 def __rdivmod__(self, other, context=None):
1304 """Swaps self/other and returns __divmod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001305 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001306 return other.__divmod__(self, context=context)
1307
1308 def __mod__(self, other, context=None):
1309 """
1310 self % other
1311 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001312 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001313
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001314 if self._is_special or other._is_special:
1315 ans = self._check_nans(other, context)
1316 if ans:
1317 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001318
1319 if self and not other:
1320 return context._raise_error(InvalidOperation, 'x % 0')
1321
1322 return self._divide(other, 3, context)[1]
1323
1324 def __rmod__(self, other, context=None):
1325 """Swaps self/other and returns __mod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001326 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001327 return other.__mod__(self, context=context)
1328
1329 def remainder_near(self, other, context=None):
1330 """
1331 Remainder nearest to 0- abs(remainder-near) <= other/2
1332 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001333 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001334
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001335 if self._is_special or other._is_special:
1336 ans = self._check_nans(other, context)
1337 if ans:
1338 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001339 if self and not other:
1340 return context._raise_error(InvalidOperation, 'x % 0')
1341
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001342 if context is None:
1343 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001344 # If DivisionImpossible causes an error, do not leave Rounded/Inexact
1345 # ignored in the calling function.
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001346 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001347 flags = context._ignore_flags(Rounded, Inexact)
1348 #keep DivisionImpossible flags
1349 (side, r) = self.__divmod__(other, context=context)
1350
1351 if r._isnan():
1352 context._regard_flags(*flags)
1353 return r
1354
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001355 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001356 rounding = context._set_rounding_decision(NEVER_ROUND)
1357
1358 if other._sign:
1359 comparison = other.__div__(Decimal(-2), context=context)
1360 else:
1361 comparison = other.__div__(Decimal(2), context=context)
1362
1363 context._set_rounding_decision(rounding)
1364 context._regard_flags(*flags)
1365
1366 s1, s2 = r._sign, comparison._sign
1367 r._sign, comparison._sign = 0, 0
1368
1369 if r < comparison:
1370 r._sign, comparison._sign = s1, s2
1371 #Get flags now
1372 self.__divmod__(other, context=context)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001373 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001374 r._sign, comparison._sign = s1, s2
1375
1376 rounding = context._set_rounding_decision(NEVER_ROUND)
1377
1378 (side, r) = self.__divmod__(other, context=context)
1379 context._set_rounding_decision(rounding)
1380 if r._isnan():
1381 return r
1382
1383 decrease = not side._iseven()
1384 rounding = context._set_rounding_decision(NEVER_ROUND)
1385 side = side.__abs__(context=context)
1386 context._set_rounding_decision(rounding)
1387
1388 s1, s2 = r._sign, comparison._sign
1389 r._sign, comparison._sign = 0, 0
1390 if r > comparison or decrease and r == comparison:
1391 r._sign, comparison._sign = s1, s2
1392 context.prec += 1
1393 if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
1394 context.prec -= 1
1395 return context._raise_error(DivisionImpossible)[1]
1396 context.prec -= 1
1397 if self._sign == other._sign:
1398 r = r.__sub__(other, context=context)
1399 else:
1400 r = r.__add__(other, context=context)
1401 else:
1402 r._sign, comparison._sign = s1, s2
1403
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001404 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001405
1406 def __floordiv__(self, other, context=None):
1407 """self // other"""
1408 return self._divide(other, 2, context)[0]
1409
1410 def __rfloordiv__(self, other, context=None):
1411 """Swaps self/other and returns __floordiv__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001412 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001413 return other.__floordiv__(self, context=context)
1414
1415 def __float__(self):
1416 """Float representation."""
1417 return float(str(self))
1418
1419 def __int__(self):
1420 """Converts self to a int, truncating if necessary."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001421 if self._is_special:
1422 if self._isnan():
1423 context = getcontext()
1424 return context._raise_error(InvalidContext)
1425 elif self._isinfinity():
1426 raise OverflowError, "Cannot convert infinity to long"
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001427 if not self:
1428 return 0
1429 sign = '-'*self._sign
1430 if self._exp >= 0:
1431 s = sign + ''.join(map(str, self._int)) + '0'*self._exp
1432 return int(s)
1433 s = sign + ''.join(map(str, self._int))[:self._exp]
1434 return int(s)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001435
1436 def __long__(self):
1437 """Converts to a long.
1438
1439 Equivalent to long(int(self))
1440 """
1441 return long(self.__int__())
1442
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001443 def _fix(self, context):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001444 """Round if it is necessary to keep self within prec precision.
1445
1446 Rounds and fixes the exponent. Does not raise on a sNaN.
1447
1448 Arguments:
1449 self - Decimal instance
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001450 context - context used.
1451 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001452 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001453 return self
1454 if context is None:
1455 context = getcontext()
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001456 prec = context.prec
1457 ans = self._fixexponents(prec, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001458 if len(ans._int) > prec:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001459 ans = ans._round(prec, context=context)
1460 ans = ans._fixexponents(prec, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001461 return ans
1462
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001463 def _fixexponents(self, prec, context):
1464 """Fix the exponents and return a copy with the exponent in bounds.
1465 Only call if known to not be a special value.
1466 """
1467 folddown = context._clamp
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001468 Emin = context.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001469 ans = Decimal(self)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001470 ans_adjusted = ans.adjusted()
1471 if ans_adjusted < Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001472 Etiny = context.Etiny()
1473 if ans._exp < Etiny:
1474 if not ans:
1475 ans._exp = Etiny
1476 context._raise_error(Clamped)
1477 return ans
1478 ans = ans._rescale(Etiny, context=context)
1479 #It isn't zero, and exp < Emin => subnormal
1480 context._raise_error(Subnormal)
1481 if context.flags[Inexact]:
1482 context._raise_error(Underflow)
1483 else:
1484 if ans:
1485 #Only raise subnormal if non-zero.
1486 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001487 else:
1488 Etop = context.Etop()
1489 if folddown and ans._exp > Etop:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001490 context._raise_error(Clamped)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001491 ans = ans._rescale(Etop, context=context)
1492 else:
1493 Emax = context.Emax
1494 if ans_adjusted > Emax:
1495 if not ans:
1496 ans._exp = Emax
1497 context._raise_error(Clamped)
1498 return ans
1499 context._raise_error(Inexact)
1500 context._raise_error(Rounded)
1501 return context._raise_error(Overflow, 'above Emax', ans._sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001502 return ans
1503
1504 def _round(self, prec=None, rounding=None, context=None):
1505 """Returns a rounded version of self.
1506
1507 You can specify the precision or rounding method. Otherwise, the
1508 context determines it.
1509 """
1510
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001511
1512 if self._is_special:
1513 ans = self._check_nans(context=context)
1514 if ans:
1515 return ans
1516
1517 if self._isinfinity():
1518 return Decimal(self)
1519
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001520 if context is None:
1521 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001522
1523 if rounding is None:
1524 rounding = context.rounding
1525 if prec is None:
1526 prec = context.prec
1527
1528 if not self:
1529 if prec <= 0:
1530 dig = (0,)
1531 exp = len(self._int) - prec + self._exp
1532 else:
1533 dig = (0,) * prec
1534 exp = len(self._int) + self._exp - prec
1535 ans = Decimal((self._sign, dig, exp))
1536 context._raise_error(Rounded)
1537 return ans
1538
1539 if prec == 0:
1540 temp = Decimal(self)
1541 temp._int = (0,)+temp._int
1542 prec = 1
1543 elif prec < 0:
1544 exp = self._exp + len(self._int) - prec - 1
1545 temp = Decimal( (self._sign, (0, 1), exp))
1546 prec = 1
1547 else:
1548 temp = Decimal(self)
1549
1550 numdigits = len(temp._int)
1551 if prec == numdigits:
1552 return temp
1553
1554 # See if we need to extend precision
1555 expdiff = prec - numdigits
1556 if expdiff > 0:
1557 tmp = list(temp._int)
1558 tmp.extend([0] * expdiff)
1559 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff))
1560 return ans
1561
1562 #OK, but maybe all the lost digits are 0.
1563 lostdigits = self._int[expdiff:]
1564 if lostdigits == (0,) * len(lostdigits):
1565 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
1566 #Rounded, but not Inexact
1567 context._raise_error(Rounded)
1568 return ans
1569
1570 # Okay, let's round and lose data
1571
1572 this_function = getattr(temp, self._pick_rounding_function[rounding])
1573 #Now we've got the rounding function
1574
1575 if prec != context.prec:
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001576 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001577 context.prec = prec
1578 ans = this_function(prec, expdiff, context)
1579 context._raise_error(Rounded)
1580 context._raise_error(Inexact, 'Changed in rounding')
1581
1582 return ans
1583
1584 _pick_rounding_function = {}
1585
1586 def _round_down(self, prec, expdiff, context):
1587 """Also known as round-towards-0, truncate."""
1588 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1589
1590 def _round_half_up(self, prec, expdiff, context, tmp = None):
1591 """Rounds 5 up (away from 0)"""
1592
1593 if tmp is None:
1594 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
1595 if self._int[prec] >= 5:
1596 tmp = tmp._increment(round=0, context=context)
1597 if len(tmp._int) > prec:
1598 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1599 return tmp
1600
1601 def _round_half_even(self, prec, expdiff, context):
1602 """Round 5 to even, rest to nearest."""
1603
1604 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1605 half = (self._int[prec] == 5)
1606 if half:
1607 for digit in self._int[prec+1:]:
1608 if digit != 0:
1609 half = 0
1610 break
1611 if half:
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001612 if self._int[prec-1] & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001613 return tmp
1614 return self._round_half_up(prec, expdiff, context, tmp)
1615
1616 def _round_half_down(self, prec, expdiff, context):
1617 """Round 5 down"""
1618
1619 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1620 half = (self._int[prec] == 5)
1621 if half:
1622 for digit in self._int[prec+1:]:
1623 if digit != 0:
1624 half = 0
1625 break
1626 if half:
1627 return tmp
1628 return self._round_half_up(prec, expdiff, context, tmp)
1629
1630 def _round_up(self, prec, expdiff, context):
1631 """Rounds away from 0."""
1632 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1633 for digit in self._int[prec:]:
1634 if digit != 0:
1635 tmp = tmp._increment(round=1, context=context)
1636 if len(tmp._int) > prec:
1637 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1638 else:
1639 return tmp
1640 return tmp
1641
1642 def _round_ceiling(self, prec, expdiff, context):
1643 """Rounds up (not away from 0 if negative.)"""
1644 if self._sign:
1645 return self._round_down(prec, expdiff, context)
1646 else:
1647 return self._round_up(prec, expdiff, context)
1648
1649 def _round_floor(self, prec, expdiff, context):
1650 """Rounds down (not towards 0 if negative)"""
1651 if not self._sign:
1652 return self._round_down(prec, expdiff, context)
1653 else:
1654 return self._round_up(prec, expdiff, context)
1655
1656 def __pow__(self, n, modulo = None, context=None):
1657 """Return self ** n (mod modulo)
1658
1659 If modulo is None (default), don't take it mod modulo.
1660 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001661 n = _convert_other(n)
1662
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001663 if context is None:
1664 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001665
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001666 if self._is_special or n._is_special or n.adjusted() > 8:
1667 #Because the spot << doesn't work with really big exponents
1668 if n._isinfinity() or n.adjusted() > 8:
1669 return context._raise_error(InvalidOperation, 'x ** INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001670
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001671 ans = self._check_nans(n, context)
1672 if ans:
1673 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001674
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001675 if not n._isinteger():
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001676 return context._raise_error(InvalidOperation, 'x ** (non-integer)')
1677
1678 if not self and not n:
1679 return context._raise_error(InvalidOperation, '0 ** 0')
1680
1681 if not n:
1682 return Decimal(1)
1683
1684 if self == Decimal(1):
1685 return Decimal(1)
1686
1687 sign = self._sign and not n._iseven()
1688 n = int(n)
1689
1690 if self._isinfinity():
1691 if modulo:
1692 return context._raise_error(InvalidOperation, 'INF % x')
1693 if n > 0:
1694 return Infsign[sign]
1695 return Decimal( (sign, (0,), 0) )
1696
1697 #with ludicrously large exponent, just raise an overflow and return inf.
1698 if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
1699 and self:
1700
1701 tmp = Decimal('inf')
1702 tmp._sign = sign
1703 context._raise_error(Rounded)
1704 context._raise_error(Inexact)
1705 context._raise_error(Overflow, 'Big power', sign)
1706 return tmp
1707
1708 elength = len(str(abs(n)))
1709 firstprec = context.prec
1710
Raymond Hettinger99148e72004-07-14 19:56:56 +00001711 if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001712 return context._raise_error(Overflow, 'Too much precision.', sign)
1713
1714 mul = Decimal(self)
1715 val = Decimal(1)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001716 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001717 context.prec = firstprec + elength + 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001718 if n < 0:
1719 #n is a long now, not Decimal instance
1720 n = -n
1721 mul = Decimal(1).__div__(mul, context=context)
1722
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001723 spot = 1
1724 while spot <= n:
1725 spot <<= 1
1726
1727 spot >>= 1
1728 #Spot is the highest power of 2 less than n
1729 while spot:
1730 val = val.__mul__(val, context=context)
1731 if val._isinfinity():
1732 val = Infsign[sign]
1733 break
1734 if spot & n:
1735 val = val.__mul__(mul, context=context)
1736 if modulo is not None:
1737 val = val.__mod__(modulo, context=context)
1738 spot >>= 1
1739 context.prec = firstprec
1740
Raymond Hettinger76e60d62004-10-20 06:58:28 +00001741 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001742 return val._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001743 return val
1744
1745 def __rpow__(self, other, context=None):
1746 """Swaps self/other and returns __pow__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001747 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001748 return other.__pow__(self, context=context)
1749
1750 def normalize(self, context=None):
1751 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001752
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001753 if self._is_special:
1754 ans = self._check_nans(context=context)
1755 if ans:
1756 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001757
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001758 dup = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001759 if dup._isinfinity():
1760 return dup
1761
1762 if not dup:
1763 return Decimal( (dup._sign, (0,), 0) )
1764 end = len(dup._int)
1765 exp = dup._exp
1766 while dup._int[end-1] == 0:
1767 exp += 1
1768 end -= 1
1769 return Decimal( (dup._sign, dup._int[:end], exp) )
1770
1771
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001772 def quantize(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001773 """Quantize self so its exponent is the same as that of exp.
1774
1775 Similar to self._rescale(exp._exp) but with error checking.
1776 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001777 if self._is_special or exp._is_special:
1778 ans = self._check_nans(exp, context)
1779 if ans:
1780 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001781
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001782 if exp._isinfinity() or self._isinfinity():
1783 if exp._isinfinity() and self._isinfinity():
1784 return self #if both are inf, it is OK
1785 if context is None:
1786 context = getcontext()
1787 return context._raise_error(InvalidOperation,
1788 'quantize with one INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001789 return self._rescale(exp._exp, rounding, context, watchexp)
1790
1791 def same_quantum(self, other):
1792 """Test whether self and other have the same exponent.
1793
1794 same as self._exp == other._exp, except NaN == sNaN
1795 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001796 if self._is_special or other._is_special:
1797 if self._isnan() or other._isnan():
1798 return self._isnan() and other._isnan() and True
1799 if self._isinfinity() or other._isinfinity():
1800 return self._isinfinity() and other._isinfinity() and True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001801 return self._exp == other._exp
1802
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001803 def _rescale(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001804 """Rescales so that the exponent is exp.
1805
1806 exp = exp to scale to (an integer)
1807 rounding = rounding version
1808 watchexp: if set (default) an error is returned if exp is greater
1809 than Emax or less than Etiny.
1810 """
1811 if context is None:
1812 context = getcontext()
1813
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001814 if self._is_special:
1815 if self._isinfinity():
1816 return context._raise_error(InvalidOperation, 'rescale with an INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001817
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001818 ans = self._check_nans(context=context)
1819 if ans:
1820 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001821
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001822 if watchexp and (context.Emax < exp or context.Etiny() > exp):
1823 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1824
1825 if not self:
1826 ans = Decimal(self)
1827 ans._int = (0,)
1828 ans._exp = exp
1829 return ans
1830
1831 diff = self._exp - exp
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001832 digits = len(self._int) + diff
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001833
1834 if watchexp and digits > context.prec:
1835 return context._raise_error(InvalidOperation, 'Rescale > prec')
1836
1837 tmp = Decimal(self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001838 tmp._int = (0,) + tmp._int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001839 digits += 1
1840
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001841 if digits < 0:
1842 tmp._exp = -digits + tmp._exp
1843 tmp._int = (0,1)
1844 digits = 1
1845 tmp = tmp._round(digits, rounding, context=context)
1846
1847 if tmp._int[0] == 0 and len(tmp._int) > 1:
1848 tmp._int = tmp._int[1:]
1849 tmp._exp = exp
1850
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001851 tmp_adjusted = tmp.adjusted()
1852 if tmp and tmp_adjusted < context.Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001853 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001854 elif tmp and tmp_adjusted > context.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001855 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1856 return tmp
1857
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001858 def to_integral(self, rounding=None, context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001859 """Rounds to the nearest integer, without raising inexact, rounded."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001860 if self._is_special:
1861 ans = self._check_nans(context=context)
1862 if ans:
1863 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001864 if self._exp >= 0:
1865 return self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001866 if context is None:
1867 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001868 flags = context._ignore_flags(Rounded, Inexact)
1869 ans = self._rescale(0, rounding, context=context)
1870 context._regard_flags(flags)
1871 return ans
1872
1873 def sqrt(self, context=None):
1874 """Return the square root of self.
1875
1876 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
1877 Should quadratically approach the right answer.
1878 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001879 if self._is_special:
1880 ans = self._check_nans(context=context)
1881 if ans:
1882 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001883
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001884 if self._isinfinity() and self._sign == 0:
1885 return Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001886
1887 if not self:
1888 #exponent = self._exp / 2, using round_down.
1889 #if self._exp < 0:
1890 # exp = (self._exp+1) // 2
1891 #else:
1892 exp = (self._exp) // 2
1893 if self._sign == 1:
1894 #sqrt(-0) = -0
1895 return Decimal( (1, (0,), exp))
1896 else:
1897 return Decimal( (0, (0,), exp))
1898
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001899 if context is None:
1900 context = getcontext()
1901
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001902 if self._sign == 1:
1903 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
1904
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001905 tmp = Decimal(self)
1906
Raymond Hettinger4837a222004-09-27 14:23:40 +00001907 expadd = tmp._exp // 2
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001908 if tmp._exp & 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001909 tmp._int += (0,)
1910 tmp._exp = 0
1911 else:
1912 tmp._exp = 0
1913
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001914 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001915 flags = context._ignore_all_flags()
1916 firstprec = context.prec
1917 context.prec = 3
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001918 if tmp.adjusted() & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001919 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) )
1920 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
1921 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00001922 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001923 else:
1924 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
1925 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
1926 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00001927 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001928
1929 #ans is now a linear approximation.
1930
1931 Emax, Emin = context.Emax, context.Emin
Raymond Hettinger99148e72004-07-14 19:56:56 +00001932 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001933
1934 half = Decimal('0.5')
1935
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001936 maxp = firstprec + 2
1937 rounding = context._set_rounding(ROUND_HALF_EVEN)
1938 while 1:
1939 context.prec = min(2*context.prec - 2, maxp)
1940 ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
1941 context=context), context=context)
1942 if context.prec == maxp:
1943 break
1944
1945 #round to the answer's precision-- the only error can be 1 ulp.
1946 context.prec = firstprec
1947 prevexp = ans.adjusted()
1948 ans = ans._round(context=context)
1949
1950 #Now, check if the other last digits are better.
1951 context.prec = firstprec + 1
1952 # In case we rounded up another digit and we should actually go lower.
1953 if prevexp != ans.adjusted():
1954 ans._int += (0,)
1955 ans._exp -= 1
1956
1957
1958 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
1959 context._set_rounding(ROUND_UP)
1960 if lower.__mul__(lower, context=context) > (tmp):
1961 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
1962
1963 else:
1964 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
1965 context._set_rounding(ROUND_DOWN)
1966 if upper.__mul__(upper, context=context) < tmp:
1967 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
1968
1969 ans._exp += expadd
1970
1971 context.prec = firstprec
1972 context.rounding = rounding
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001973 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001974
1975 rounding = context._set_rounding_decision(NEVER_ROUND)
1976 if not ans.__mul__(ans, context=context) == self:
1977 # Only rounded/inexact if here.
1978 context._regard_flags(flags)
1979 context._raise_error(Rounded)
1980 context._raise_error(Inexact)
1981 else:
1982 #Exact answer, so let's set the exponent right.
1983 #if self._exp < 0:
1984 # exp = (self._exp +1)// 2
1985 #else:
1986 exp = self._exp // 2
1987 context.prec += ans._exp - exp
1988 ans = ans._rescale(exp, context=context)
1989 context.prec = firstprec
1990 context._regard_flags(flags)
1991 context.Emax, context.Emin = Emax, Emin
1992
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001993 return ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001994
1995 def max(self, other, context=None):
1996 """Returns the larger value.
1997
1998 like max(self, other) except if one is not a number, returns
1999 NaN (and signals if one is sNaN). Also rounds.
2000 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002001 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002002
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002003 if self._is_special or other._is_special:
2004 # if one operand is a quiet NaN and the other is number, then the
2005 # number is always returned
2006 sn = self._isnan()
2007 on = other._isnan()
2008 if sn or on:
2009 if on == 1 and sn != 2:
2010 return self
2011 if sn == 1 and on != 2:
2012 return other
2013 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002014
2015 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002016 c = self.__cmp__(other)
2017 if c == 0:
2018 # if both operands are finite and equal in numerical value
2019 # then an ordering is applied:
2020 #
2021 # if the signs differ then max returns the operand with the
2022 # positive sign and min returns the operand with the negative sign
2023 #
2024 # if the signs are the same then the exponent is used to select
2025 # the result.
2026 if self._sign != other._sign:
2027 if self._sign:
2028 ans = other
2029 elif self._exp < other._exp and not self._sign:
2030 ans = other
2031 elif self._exp > other._exp and self._sign:
2032 ans = other
2033 elif c == -1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002034 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002035
2036 if context is None:
2037 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002038 if context._rounding_decision == ALWAYS_ROUND:
2039 return ans._fix(context)
2040 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002041
2042 def min(self, other, context=None):
2043 """Returns the smaller value.
2044
2045 like min(self, other) except if one is not a number, returns
2046 NaN (and signals if one is sNaN). Also rounds.
2047 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002048 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002049
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002050 if self._is_special or other._is_special:
2051 # if one operand is a quiet NaN and the other is number, then the
2052 # number is always returned
2053 sn = self._isnan()
2054 on = other._isnan()
2055 if sn or on:
2056 if on == 1 and sn != 2:
2057 return self
2058 if sn == 1 and on != 2:
2059 return other
2060 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002061
2062 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002063 c = self.__cmp__(other)
2064 if c == 0:
2065 # if both operands are finite and equal in numerical value
2066 # then an ordering is applied:
2067 #
2068 # if the signs differ then max returns the operand with the
2069 # positive sign and min returns the operand with the negative sign
2070 #
2071 # if the signs are the same then the exponent is used to select
2072 # the result.
2073 if self._sign != other._sign:
2074 if other._sign:
2075 ans = other
2076 elif self._exp > other._exp and not self._sign:
2077 ans = other
2078 elif self._exp < other._exp and self._sign:
2079 ans = other
2080 elif c == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002081 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002082
2083 if context is None:
2084 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002085 if context._rounding_decision == ALWAYS_ROUND:
2086 return ans._fix(context)
2087 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002088
2089 def _isinteger(self):
2090 """Returns whether self is an integer"""
2091 if self._exp >= 0:
2092 return True
2093 rest = self._int[self._exp:]
2094 return rest == (0,)*len(rest)
2095
2096 def _iseven(self):
2097 """Returns 1 if self is even. Assumes self is an integer."""
2098 if self._exp > 0:
2099 return 1
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002100 return self._int[-1+self._exp] & 1 == 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002101
2102 def adjusted(self):
2103 """Return the adjusted exponent of self"""
2104 try:
2105 return self._exp + len(self._int) - 1
2106 #If NaN or Infinity, self._exp is string
2107 except TypeError:
2108 return 0
2109
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002110 # support for pickling, copy, and deepcopy
2111 def __reduce__(self):
2112 return (self.__class__, (str(self),))
2113
2114 def __copy__(self):
2115 if type(self) == Decimal:
2116 return self # I'm immutable; therefore I am my own clone
2117 return self.__class__(str(self))
2118
2119 def __deepcopy__(self, memo):
2120 if type(self) == Decimal:
2121 return self # My components are also immutable
2122 return self.__class__(str(self))
2123
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002124##### Context class ###########################################
2125
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002126
2127# get rounding method function:
2128rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
2129for name in rounding_functions:
2130 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
2131 globalname = name[1:].upper()
2132 val = globals()[globalname]
2133 Decimal._pick_rounding_function[val] = name
2134
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002135del name, val, globalname, rounding_functions
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002136
2137class Context(object):
2138 """Contains the context for a Decimal instance.
2139
2140 Contains:
2141 prec - precision (for use in rounding, division, square roots..)
2142 rounding - rounding type. (how you round)
2143 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
Raymond Hettingerbf440692004-07-10 14:14:37 +00002144 traps - If traps[exception] = 1, then the exception is
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002145 raised when it is caused. Otherwise, a value is
2146 substituted in.
2147 flags - When an exception is caused, flags[exception] is incremented.
2148 (Whether or not the trap_enabler is set)
2149 Should be reset by user of Decimal instance.
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002150 Emin - Minimum exponent
2151 Emax - Maximum exponent
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002152 capitals - If 1, 1*10^1 is printed as 1E+1.
2153 If 0, printed as 1e1
Raymond Hettingere0f15812004-07-05 05:36:39 +00002154 _clamp - If 1, change exponents if too high (Default 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002155 """
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002156
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002157 def __init__(self, prec=None, rounding=None,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002158 traps=None, flags=None,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002159 _rounding_decision=None,
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002160 Emin=None, Emax=None,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002161 capitals=None, _clamp=0,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002162 _ignored_flags=None):
2163 if flags is None:
2164 flags = []
2165 if _ignored_flags is None:
2166 _ignored_flags = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002167 if not isinstance(flags, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002168 flags = dict([(s,s in flags) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002169 del s
Raymond Hettingerbf440692004-07-10 14:14:37 +00002170 if traps is not None and not isinstance(traps, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002171 traps = dict([(s,s in traps) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002172 del s
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002173 for name, val in locals().items():
2174 if val is None:
2175 setattr(self, name, copy.copy(getattr(DefaultContext, name)))
2176 else:
2177 setattr(self, name, val)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002178 del self.self
2179
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002180 def __repr__(self):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002181 """Show the current context."""
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002182 s = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002183 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
2184 s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
2185 s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002186 return ', '.join(s) + ')'
2187
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002188 def clear_flags(self):
2189 """Reset all flags to zero"""
2190 for flag in self.flags:
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002191 self.flags[flag] = 0
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002192
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002193 def _shallow_copy(self):
2194 """Returns a shallow copy from self."""
Raymond Hettingerbf440692004-07-10 14:14:37 +00002195 nc = Context(self.prec, self.rounding, self.traps, self.flags,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002196 self._rounding_decision, self.Emin, self.Emax,
2197 self.capitals, self._clamp, self._ignored_flags)
2198 return nc
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002199
2200 def copy(self):
2201 """Returns a deep copy from self."""
2202 nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
2203 self._rounding_decision, self.Emin, self.Emax,
2204 self.capitals, self._clamp, self._ignored_flags)
2205 return nc
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002206 __copy__ = copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002207
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002208 def _raise_error(self, condition, explanation = None, *args):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002209 """Handles an error
2210
2211 If the flag is in _ignored_flags, returns the default response.
2212 Otherwise, it increments the flag, then, if the corresponding
2213 trap_enabler is set, it reaises the exception. Otherwise, it returns
2214 the default value after incrementing the flag.
2215 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002216 error = _condition_map.get(condition, condition)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002217 if error in self._ignored_flags:
2218 #Don't touch the flag
2219 return error().handle(self, *args)
2220
2221 self.flags[error] += 1
Raymond Hettingerbf440692004-07-10 14:14:37 +00002222 if not self.traps[error]:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002223 #The errors define how to handle themselves.
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002224 return condition().handle(self, *args)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002225
2226 # Errors should only be risked on copies of the context
2227 #self._ignored_flags = []
2228 raise error, explanation
2229
2230 def _ignore_all_flags(self):
2231 """Ignore all flags, if they are raised"""
Raymond Hettingerfed52962004-07-14 15:41:57 +00002232 return self._ignore_flags(*_signals)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002233
2234 def _ignore_flags(self, *flags):
2235 """Ignore the flags, if they are raised"""
2236 # Do not mutate-- This way, copies of a context leave the original
2237 # alone.
2238 self._ignored_flags = (self._ignored_flags + list(flags))
2239 return list(flags)
2240
2241 def _regard_flags(self, *flags):
2242 """Stop ignoring the flags, if they are raised"""
2243 if flags and isinstance(flags[0], (tuple,list)):
2244 flags = flags[0]
2245 for flag in flags:
2246 self._ignored_flags.remove(flag)
2247
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002248 def __hash__(self):
2249 """A Context cannot be hashed."""
2250 # We inherit object.__hash__, so we must deny this explicitly
2251 raise TypeError, "Cannot hash a Context."
2252
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002253 def Etiny(self):
2254 """Returns Etiny (= Emin - prec + 1)"""
2255 return int(self.Emin - self.prec + 1)
2256
2257 def Etop(self):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002258 """Returns maximum exponent (= Emax - prec + 1)"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002259 return int(self.Emax - self.prec + 1)
2260
2261 def _set_rounding_decision(self, type):
2262 """Sets the rounding decision.
2263
2264 Sets the rounding decision, and returns the current (previous)
2265 rounding decision. Often used like:
2266
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002267 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002268 # That so you don't change the calling context
2269 # if an error occurs in the middle (say DivisionImpossible is raised).
2270
2271 rounding = context._set_rounding_decision(NEVER_ROUND)
2272 instance = instance / Decimal(2)
2273 context._set_rounding_decision(rounding)
2274
2275 This will make it not round for that operation.
2276 """
2277
2278 rounding = self._rounding_decision
2279 self._rounding_decision = type
2280 return rounding
2281
2282 def _set_rounding(self, type):
2283 """Sets the rounding type.
2284
2285 Sets the rounding type, and returns the current (previous)
2286 rounding type. Often used like:
2287
2288 context = context.copy()
2289 # so you don't change the calling context
2290 # if an error occurs in the middle.
2291 rounding = context._set_rounding(ROUND_UP)
2292 val = self.__sub__(other, context=context)
2293 context._set_rounding(rounding)
2294
2295 This will make it round up for that operation.
2296 """
2297 rounding = self.rounding
2298 self.rounding= type
2299 return rounding
2300
Raymond Hettingerfed52962004-07-14 15:41:57 +00002301 def create_decimal(self, num='0'):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002302 """Creates a new Decimal instance but using self as context."""
2303 d = Decimal(num, context=self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002304 return d._fix(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002305
2306 #Methods
2307 def abs(self, a):
2308 """Returns the absolute value of the operand.
2309
2310 If the operand is negative, the result is the same as using the minus
2311 operation on the operand. Otherwise, the result is the same as using
2312 the plus operation on the operand.
2313
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002314 >>> ExtendedContext.abs(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002315 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002316 >>> ExtendedContext.abs(Decimal('-100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002317 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002318 >>> ExtendedContext.abs(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002319 Decimal("101.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002320 >>> ExtendedContext.abs(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002321 Decimal("101.5")
2322 """
2323 return a.__abs__(context=self)
2324
2325 def add(self, a, b):
2326 """Return the sum of the two operands.
2327
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002328 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002329 Decimal("19.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002330 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002331 Decimal("1.02E+4")
2332 """
2333 return a.__add__(b, context=self)
2334
2335 def _apply(self, a):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002336 return str(a._fix(self))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002337
2338 def compare(self, a, b):
2339 """Compares values numerically.
2340
2341 If the signs of the operands differ, a value representing each operand
2342 ('-1' if the operand is less than zero, '0' if the operand is zero or
2343 negative zero, or '1' if the operand is greater than zero) is used in
2344 place of that operand for the comparison instead of the actual
2345 operand.
2346
2347 The comparison is then effected by subtracting the second operand from
2348 the first and then returning a value according to the result of the
2349 subtraction: '-1' if the result is less than zero, '0' if the result is
2350 zero or negative zero, or '1' if the result is greater than zero.
2351
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002352 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002353 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002354 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002355 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002356 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002357 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002358 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002359 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002360 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002361 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002362 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002363 Decimal("-1")
2364 """
2365 return a.compare(b, context=self)
2366
2367 def divide(self, a, b):
2368 """Decimal division in a specified context.
2369
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002370 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002371 Decimal("0.333333333")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002372 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002373 Decimal("0.666666667")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002374 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002375 Decimal("2.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002376 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002377 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002378 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002379 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002380 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002381 Decimal("4.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002382 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002383 Decimal("1.20")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002384 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002385 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002386 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002387 Decimal("1000")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002388 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002389 Decimal("1.20E+6")
2390 """
2391 return a.__div__(b, context=self)
2392
2393 def divide_int(self, a, b):
2394 """Divides two numbers and returns the integer part of the result.
2395
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002396 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002397 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002398 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002399 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002400 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002401 Decimal("3")
2402 """
2403 return a.__floordiv__(b, context=self)
2404
2405 def divmod(self, a, b):
2406 return a.__divmod__(b, context=self)
2407
2408 def max(self, a,b):
2409 """max compares two values numerically and returns the maximum.
2410
2411 If either operand is a NaN then the general rules apply.
2412 Otherwise, the operands are compared as as though by the compare
2413 operation. If they are numerically equal then the left-hand operand
2414 is chosen as the result. Otherwise the maximum (closer to positive
2415 infinity) of the two operands is chosen as the result.
2416
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002417 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002418 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002419 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002420 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002421 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002422 Decimal("1")
2423 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
2424 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002425 """
2426 return a.max(b, context=self)
2427
2428 def min(self, a,b):
2429 """min compares two values numerically and returns the minimum.
2430
2431 If either operand is a NaN then the general rules apply.
2432 Otherwise, the operands are compared as as though by the compare
2433 operation. If they are numerically equal then the left-hand operand
2434 is chosen as the result. Otherwise the minimum (closer to negative
2435 infinity) of the two operands is chosen as the result.
2436
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002437 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002438 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002439 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002440 Decimal("-10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002441 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002442 Decimal("1.0")
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002443 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
2444 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002445 """
2446 return a.min(b, context=self)
2447
2448 def minus(self, a):
2449 """Minus corresponds to unary prefix minus in Python.
2450
2451 The operation is evaluated using the same rules as subtract; the
2452 operation minus(a) is calculated as subtract('0', a) where the '0'
2453 has the same exponent as the operand.
2454
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002455 >>> ExtendedContext.minus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002456 Decimal("-1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002457 >>> ExtendedContext.minus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002458 Decimal("1.3")
2459 """
2460 return a.__neg__(context=self)
2461
2462 def multiply(self, a, b):
2463 """multiply multiplies two operands.
2464
2465 If either operand is a special value then the general rules apply.
2466 Otherwise, the operands are multiplied together ('long multiplication'),
2467 resulting in a number which may be as long as the sum of the lengths
2468 of the two operands.
2469
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002470 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002471 Decimal("3.60")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002472 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002473 Decimal("21")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002474 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002475 Decimal("0.72")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002476 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002477 Decimal("-0.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002478 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002479 Decimal("4.28135971E+11")
2480 """
2481 return a.__mul__(b, context=self)
2482
2483 def normalize(self, a):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002484 """normalize reduces an operand to its simplest form.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002485
2486 Essentially a plus operation with all trailing zeros removed from the
2487 result.
2488
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002489 >>> ExtendedContext.normalize(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002490 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002491 >>> ExtendedContext.normalize(Decimal('-2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002492 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002493 >>> ExtendedContext.normalize(Decimal('1.200'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002494 Decimal("1.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002495 >>> ExtendedContext.normalize(Decimal('-120'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002496 Decimal("-1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002497 >>> ExtendedContext.normalize(Decimal('120.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002498 Decimal("1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002499 >>> ExtendedContext.normalize(Decimal('0.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002500 Decimal("0")
2501 """
2502 return a.normalize(context=self)
2503
2504 def plus(self, a):
2505 """Plus corresponds to unary prefix plus in Python.
2506
2507 The operation is evaluated using the same rules as add; the
2508 operation plus(a) is calculated as add('0', a) where the '0'
2509 has the same exponent as the operand.
2510
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002511 >>> ExtendedContext.plus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002512 Decimal("1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002513 >>> ExtendedContext.plus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002514 Decimal("-1.3")
2515 """
2516 return a.__pos__(context=self)
2517
2518 def power(self, a, b, modulo=None):
2519 """Raises a to the power of b, to modulo if given.
2520
2521 The right-hand operand must be a whole number whose integer part (after
2522 any exponent has been applied) has no more than 9 digits and whose
2523 fractional part (if any) is all zeros before any rounding. The operand
2524 may be positive, negative, or zero; if negative, the absolute value of
2525 the power is used, and the left-hand operand is inverted (divided into
2526 1) before use.
2527
2528 If the increased precision needed for the intermediate calculations
2529 exceeds the capabilities of the implementation then an Invalid operation
2530 condition is raised.
2531
2532 If, when raising to a negative power, an underflow occurs during the
2533 division into 1, the operation is not halted at that point but
2534 continues.
2535
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002536 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002537 Decimal("8")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002538 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002539 Decimal("0.125")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002540 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002541 Decimal("69.7575744")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002542 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002543 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002544 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002545 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002546 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002547 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002548 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002549 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002550 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002551 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002552 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002553 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002554 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002555 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002556 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002557 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002558 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002559 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002560 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002561 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002562 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002563 Decimal("NaN")
2564 """
2565 return a.__pow__(b, modulo, context=self)
2566
2567 def quantize(self, a, b):
2568 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
2569
2570 The coefficient of the result is derived from that of the left-hand
2571 operand. It may be rounded using the current rounding setting (if the
2572 exponent is being increased), multiplied by a positive power of ten (if
2573 the exponent is being decreased), or is unchanged (if the exponent is
2574 already equal to that of the right-hand operand).
2575
2576 Unlike other operations, if the length of the coefficient after the
2577 quantize operation would be greater than precision then an Invalid
2578 operation condition is raised. This guarantees that, unless there is an
2579 error condition, the exponent of the result of a quantize is always
2580 equal to that of the right-hand operand.
2581
2582 Also unlike other operations, quantize will never raise Underflow, even
2583 if the result is subnormal and inexact.
2584
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002585 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002586 Decimal("2.170")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002587 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002588 Decimal("2.17")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002589 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002590 Decimal("2.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002591 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002592 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002593 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002594 Decimal("0E+1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002595 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002596 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002597 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002598 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002599 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002600 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002601 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002602 Decimal("-0E+5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002603 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002604 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002605 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002606 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002607 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002608 Decimal("217.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002609 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002610 Decimal("217")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002611 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002612 Decimal("2.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002613 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002614 Decimal("2E+2")
2615 """
2616 return a.quantize(b, context=self)
2617
2618 def remainder(self, a, b):
2619 """Returns the remainder from integer division.
2620
2621 The result is the residue of the dividend after the operation of
2622 calculating integer division as described for divide-integer, rounded to
2623 precision digits if necessary. The sign of the result, if non-zero, is
2624 the same as that of the original dividend.
2625
2626 This operation will fail under the same conditions as integer division
2627 (that is, if integer division on the same two operands would fail, the
2628 remainder cannot be calculated).
2629
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002630 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002631 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002632 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002633 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002634 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002635 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002636 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002637 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002638 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002639 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002640 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002641 Decimal("1.0")
2642 """
2643 return a.__mod__(b, context=self)
2644
2645 def remainder_near(self, a, b):
2646 """Returns to be "a - b * n", where n is the integer nearest the exact
2647 value of "x / b" (if two integers are equally near then the even one
2648 is chosen). If the result is equal to 0 then its sign will be the
2649 sign of a.
2650
2651 This operation will fail under the same conditions as integer division
2652 (that is, if integer division on the same two operands would fail, the
2653 remainder cannot be calculated).
2654
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002655 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002656 Decimal("-0.9")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002657 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002658 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002659 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002660 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002661 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002662 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002663 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002664 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002665 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002666 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002667 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002668 Decimal("-0.3")
2669 """
2670 return a.remainder_near(b, context=self)
2671
2672 def same_quantum(self, a, b):
2673 """Returns True if the two operands have the same exponent.
2674
2675 The result is never affected by either the sign or the coefficient of
2676 either operand.
2677
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002678 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002679 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002680 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002681 True
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002682 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002683 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002684 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002685 True
2686 """
2687 return a.same_quantum(b)
2688
2689 def sqrt(self, a):
2690 """Returns the square root of a non-negative number to context precision.
2691
2692 If the result must be inexact, it is rounded using the round-half-even
2693 algorithm.
2694
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002695 >>> ExtendedContext.sqrt(Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002696 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002697 >>> ExtendedContext.sqrt(Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002698 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002699 >>> ExtendedContext.sqrt(Decimal('0.39'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002700 Decimal("0.624499800")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002701 >>> ExtendedContext.sqrt(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002702 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002703 >>> ExtendedContext.sqrt(Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002704 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002705 >>> ExtendedContext.sqrt(Decimal('1.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002706 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002707 >>> ExtendedContext.sqrt(Decimal('1.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002708 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002709 >>> ExtendedContext.sqrt(Decimal('7'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002710 Decimal("2.64575131")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002711 >>> ExtendedContext.sqrt(Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002712 Decimal("3.16227766")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002713 >>> ExtendedContext.prec
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002714 9
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002715 """
2716 return a.sqrt(context=self)
2717
2718 def subtract(self, a, b):
2719 """Return the sum of the two operands.
2720
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002721 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002722 Decimal("0.23")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002723 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002724 Decimal("0.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002725 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002726 Decimal("-0.77")
2727 """
2728 return a.__sub__(b, context=self)
2729
2730 def to_eng_string(self, a):
2731 """Converts a number to a string, using scientific notation.
2732
2733 The operation is not affected by the context.
2734 """
2735 return a.to_eng_string(context=self)
2736
2737 def to_sci_string(self, a):
2738 """Converts a number to a string, using scientific notation.
2739
2740 The operation is not affected by the context.
2741 """
2742 return a.__str__(context=self)
2743
2744 def to_integral(self, a):
2745 """Rounds to an integer.
2746
2747 When the operand has a negative exponent, the result is the same
2748 as using the quantize() operation using the given operand as the
2749 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2750 of the operand as the precision setting, except that no flags will
2751 be set. The rounding mode is taken from the context.
2752
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002753 >>> ExtendedContext.to_integral(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002754 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002755 >>> ExtendedContext.to_integral(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002756 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002757 >>> ExtendedContext.to_integral(Decimal('100.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002758 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002759 >>> ExtendedContext.to_integral(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002760 Decimal("102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002761 >>> ExtendedContext.to_integral(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002762 Decimal("-102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002763 >>> ExtendedContext.to_integral(Decimal('10E+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002764 Decimal("1.0E+6")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002765 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002766 Decimal("7.89E+77")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002767 >>> ExtendedContext.to_integral(Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002768 Decimal("-Infinity")
2769 """
2770 return a.to_integral(context=self)
2771
2772class _WorkRep(object):
2773 __slots__ = ('sign','int','exp')
2774 # sign: -1 None 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002775 # int: int or long
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002776 # exp: None, int, or string
2777
2778 def __init__(self, value=None):
2779 if value is None:
2780 self.sign = None
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002781 self.int = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002782 self.exp = None
2783 if isinstance(value, Decimal):
2784 if value._sign:
2785 self.sign = -1
2786 else:
2787 self.sign = 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002788 cum = 0
2789 for digit in value._int:
2790 cum = cum * 10 + digit
2791 self.int = cum
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002792 self.exp = value._exp
2793 if isinstance(value, tuple):
2794 self.sign = value[0]
2795 self.int = value[1]
2796 self.exp = value[2]
2797
2798 def __repr__(self):
2799 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2800
2801 __str__ = __repr__
2802
2803 def __neg__(self):
2804 if self.sign == 1:
2805 return _WorkRep( (-1, self.int, self.exp) )
2806 else:
2807 return _WorkRep( (1, self.int, self.exp) )
2808
2809 def __abs__(self):
2810 if self.sign == -1:
2811 return -self
2812 else:
2813 return self
2814
2815 def __cmp__(self, other):
2816 if self.exp != other.exp:
2817 raise ValueError("Operands not normalized: %r, %r" % (self, other))
2818 if self.sign != other.sign:
2819 if self.sign == -1:
2820 return -1
2821 else:
2822 return 1
2823 if self.sign == -1:
2824 direction = -1
2825 else:
2826 direction = 1
2827 int1 = self.int
2828 int2 = other.int
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002829 if int1 > int2:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002830 return direction * 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002831 if int1 < int2:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002832 return direction * -1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002833 return 0
2834
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002835
2836
2837def _normalize(op1, op2, shouldround = 0, prec = 0):
2838 """Normalizes op1, op2 to have the same exp and length of coefficient.
2839
2840 Done during addition.
2841 """
2842 # Yes, the exponent is a long, but the difference between exponents
2843 # must be an int-- otherwise you'd get a big memory problem.
2844 numdigits = int(op1.exp - op2.exp)
2845 if numdigits < 0:
2846 numdigits = -numdigits
2847 tmp = op2
2848 other = op1
2849 else:
2850 tmp = op1
2851 other = op2
2852
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002853
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002854 if shouldround and numdigits > prec + 1:
2855 # Big difference in exponents - check the adjusted exponents
2856 tmp_len = len(str(tmp.int))
2857 other_len = len(str(other.int))
2858 if numdigits > (other_len + prec + 1 - tmp_len):
2859 # If the difference in adjusted exps is > prec+1, we know
2860 # other is insignificant, so might as well put a 1 after the precision.
2861 # (since this is only for addition.) Also stops use of massive longs.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002862
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002863 extend = prec + 2 - tmp_len
2864 if extend <= 0:
2865 extend = 1
2866 tmp.int *= 10 ** extend
2867 tmp.exp -= extend
2868 other.int = 1
2869 other.exp = tmp.exp
2870 return op1, op2
2871
2872 tmp.int *= 10 ** numdigits
2873 tmp.exp -= numdigits
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002874 return op1, op2
2875
2876def _adjust_coefficients(op1, op2):
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002877 """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002878
2879 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2880
2881 Used on _WorkRep instances during division.
2882 """
2883 adjust = 0
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002884 #If op1 is smaller, make it larger
2885 while op2.int > op1.int:
2886 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002887 op1.exp -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002888 adjust += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002889
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002890 #If op2 is too small, make it larger
2891 while op1.int >= (10 * op2.int):
2892 op2.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002893 op2.exp -= 1
2894 adjust -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002895
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002896 return op1, op2, adjust
2897
2898##### Helper Functions ########################################
2899
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002900def _convert_other(other):
2901 """Convert other to Decimal.
2902
2903 Verifies that it's ok to use in an implicit construction.
2904 """
2905 if isinstance(other, Decimal):
2906 return other
2907 if isinstance(other, (int, long)):
2908 return Decimal(other)
2909
2910 raise TypeError, "You can interact Decimal only with int, long or Decimal data types."
2911
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002912_infinity_map = {
2913 'inf' : 1,
2914 'infinity' : 1,
2915 '+inf' : 1,
2916 '+infinity' : 1,
2917 '-inf' : -1,
2918 '-infinity' : -1
2919}
2920
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002921def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002922 """Determines whether a string or float is infinity.
2923
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002924 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002925 """
2926 num = str(num).lower()
2927 return _infinity_map.get(num, 0)
2928
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002929def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002930 """Determines whether a string or float is NaN
2931
2932 (1, sign, diagnostic info as string) => NaN
2933 (2, sign, diagnostic info as string) => sNaN
2934 0 => not a NaN
2935 """
2936 num = str(num).lower()
2937 if not num:
2938 return 0
2939
2940 #get the sign, get rid of trailing [+-]
2941 sign = 0
2942 if num[0] == '+':
2943 num = num[1:]
2944 elif num[0] == '-': #elif avoids '+-nan'
2945 num = num[1:]
2946 sign = 1
2947
2948 if num.startswith('nan'):
2949 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
2950 return 0
2951 return (1, sign, num[3:].lstrip('0'))
2952 if num.startswith('snan'):
2953 if len(num) > 4 and not num[4:].isdigit():
2954 return 0
2955 return (2, sign, num[4:].lstrip('0'))
2956 return 0
2957
2958
2959##### Setup Specific Contexts ################################
2960
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002961# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00002962# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002963
2964DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002965 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002966 traps=[DivisionByZero, Overflow, InvalidOperation],
2967 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002968 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00002969 Emax=999999999,
2970 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002971 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002972)
2973
2974# Pre-made alternate contexts offered by the specification
2975# Don't change these; the user should be able to select these
2976# contexts and be able to reproduce results from other implementations
2977# of the spec.
2978
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002979BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002980 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002981 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
2982 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002983)
2984
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002985ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002986 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002987 traps=[],
2988 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002989)
2990
2991
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002992##### Useful Constants (internal use only) ####################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002993
2994#Reusable defaults
2995Inf = Decimal('Inf')
2996negInf = Decimal('-Inf')
2997
2998#Infsign[sign] is infinity w/ that sign
2999Infsign = (Inf, negInf)
3000
3001NaN = Decimal('NaN')
3002
3003
3004##### crud for parsing strings #################################
3005import re
3006
3007# There's an optional sign at the start, and an optional exponent
3008# at the end. The exponent has an optional sign and at least one
3009# digit. In between, must have either at least one digit followed
3010# by an optional fraction, or a decimal point followed by at least
3011# one digit. Yuck.
3012
3013_parser = re.compile(r"""
3014# \s*
3015 (?P<sign>[-+])?
3016 (
3017 (?P<int>\d+) (\. (?P<frac>\d*))?
3018 |
3019 \. (?P<onlyfrac>\d+)
3020 )
3021 ([eE](?P<exp>[-+]? \d+))?
3022# \s*
3023 $
3024""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
3025
3026del re
3027
3028# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
3029
3030def _string2exact(s):
3031 m = _parser(s)
3032 if m is None:
3033 raise ValueError("invalid literal for Decimal: %r" % s)
3034
3035 if m.group('sign') == "-":
3036 sign = 1
3037 else:
3038 sign = 0
3039
3040 exp = m.group('exp')
3041 if exp is None:
3042 exp = 0
3043 else:
3044 exp = int(exp)
3045
3046 intpart = m.group('int')
3047 if intpart is None:
3048 intpart = ""
3049 fracpart = m.group('onlyfrac')
3050 else:
3051 fracpart = m.group('frac')
3052 if fracpart is None:
3053 fracpart = ""
3054
3055 exp -= len(fracpart)
3056
3057 mantissa = intpart + fracpart
3058 tmp = map(int, mantissa)
3059 backup = tmp
3060 while tmp and tmp[0] == 0:
3061 del tmp[0]
3062
3063 # It's a zero
3064 if not tmp:
3065 if backup:
3066 return (sign, tuple(backup), exp)
3067 return (sign, (0,), exp)
3068 mantissa = tuple(tmp)
3069
3070 return (sign, mantissa, exp)
3071
3072
3073if __name__ == '__main__':
3074 import doctest, sys
3075 doctest.testmod(sys.modules[__name__])