blob: 98a83424d5639746821a6f77836c562c6ca1e076 [file] [log] [blame]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001# Copyright (c) 2004 Python Software Foundation.
2# All rights reserved.
3
4# Written by Eric Price <eprice at tjhsst.edu>
5# and Facundo Batista <facundo at taniquetil.com.ar>
6# and Raymond Hettinger <python at rcn.com>
Fred Drake1f34eb12004-07-01 14:28:36 +00007# and Aahz <aahz at pobox.com>
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00008# and Tim Peters
9
Raymond Hettinger27dbcf22004-08-19 22:39:55 +000010# This module is currently Py2.3 compatible and should be kept that way
11# unless a major compelling advantage arises. IOW, 2.3 compatibility is
12# strongly preferred, but not guaranteed.
13
14# Also, this module should be kept in sync with the latest updates of
15# the IBM specification as it evolves. Those updates will be treated
16# as bug fixes (deviation from the spec is a compatibility, usability
17# bug) and will be backported. At this point the spec is stabilizing
18# and the updates are becoming fewer, smaller, and less significant.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000019
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000020"""
21This is a Py2.3 implementation of decimal floating point arithmetic based on
22the General Decimal Arithmetic Specification:
23
24 www2.hursley.ibm.com/decimal/decarith.html
25
Raymond Hettinger0ea241e2004-07-04 13:53:24 +000026and IEEE standard 854-1987:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000027
28 www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html
29
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000030Decimal floating point has finite precision with arbitrarily large bounds.
31
32The purpose of the module is to support arithmetic using familiar
33"schoolhouse" rules and to avoid the some of tricky representation
34issues associated with binary floating point. The package is especially
35useful for financial applications or for contexts where users have
36expectations that are at odds with binary floating point (for instance,
37in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead
38of the expected Decimal("0.00") returned by decimal floating point).
39
40Here are some examples of using the decimal module:
41
42>>> from decimal import *
Raymond Hettingerbd7f76d2004-07-08 00:49:18 +000043>>> setcontext(ExtendedContext)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000044>>> Decimal(0)
45Decimal("0")
46>>> Decimal("1")
47Decimal("1")
48>>> Decimal("-.0123")
49Decimal("-0.0123")
50>>> Decimal(123456)
51Decimal("123456")
52>>> Decimal("123.45e12345678901234567890")
53Decimal("1.2345E+12345678901234567892")
54>>> Decimal("1.33") + Decimal("1.27")
55Decimal("2.60")
56>>> Decimal("12.34") + Decimal("3.87") - Decimal("18.41")
57Decimal("-2.20")
58>>> dig = Decimal(1)
59>>> print dig / Decimal(3)
600.333333333
61>>> getcontext().prec = 18
62>>> print dig / Decimal(3)
630.333333333333333333
64>>> print dig.sqrt()
651
66>>> print Decimal(3).sqrt()
671.73205080756887729
68>>> print Decimal(3) ** 123
694.85192780976896427E+58
70>>> inf = Decimal(1) / Decimal(0)
71>>> print inf
72Infinity
73>>> neginf = Decimal(-1) / Decimal(0)
74>>> print neginf
75-Infinity
76>>> print neginf + inf
77NaN
78>>> print neginf * inf
79-Infinity
80>>> print dig / 0
81Infinity
Raymond Hettingerbf440692004-07-10 14:14:37 +000082>>> getcontext().traps[DivisionByZero] = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000083>>> print dig / 0
84Traceback (most recent call last):
85 ...
86 ...
87 ...
88DivisionByZero: x / 0
89>>> c = Context()
Raymond Hettingerbf440692004-07-10 14:14:37 +000090>>> c.traps[InvalidOperation] = 0
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000091>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000920
93>>> c.divide(Decimal(0), Decimal(0))
94Decimal("NaN")
Raymond Hettingerbf440692004-07-10 14:14:37 +000095>>> c.traps[InvalidOperation] = 1
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000096>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000971
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000098>>> c.flags[InvalidOperation] = 0
99>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001000
101>>> print c.divide(Decimal(0), Decimal(0))
102Traceback (most recent call last):
103 ...
104 ...
105 ...
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000106InvalidOperation: 0 / 0
107>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001081
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000109>>> c.flags[InvalidOperation] = 0
Raymond Hettingerbf440692004-07-10 14:14:37 +0000110>>> c.traps[InvalidOperation] = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000111>>> print c.divide(Decimal(0), Decimal(0))
112NaN
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000113>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001141
115>>>
116"""
117
118__all__ = [
119 # Two major classes
120 'Decimal', 'Context',
121
122 # Contexts
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +0000123 'DefaultContext', 'BasicContext', 'ExtendedContext',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000124
125 # Exceptions
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +0000126 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
127 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000128
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000129 # Constants for use in setting up contexts
130 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING',
131 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000132
133 # Functions for manipulating contexts
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000134 'setcontext', 'getcontext'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000135]
136
137import threading
138import copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000139import operator
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000140
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000141#Rounding
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000142ROUND_DOWN = 'ROUND_DOWN'
143ROUND_HALF_UP = 'ROUND_HALF_UP'
144ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
145ROUND_CEILING = 'ROUND_CEILING'
146ROUND_FLOOR = 'ROUND_FLOOR'
147ROUND_UP = 'ROUND_UP'
148ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000149
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +0000150#Rounding decision (not part of the public API)
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000151NEVER_ROUND = 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY
152ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000153
154#Errors
155
156class DecimalException(ArithmeticError):
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000157 """Base exception class.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000158
159 Used exceptions derive from this.
160 If an exception derives from another exception besides this (such as
161 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
162 called if the others are present. This isn't actually used for
163 anything, though.
164
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000165 handle -- Called when context._raise_error is called and the
166 trap_enabler is set. First argument is self, second is the
167 context. More arguments can be given, those being after
168 the explanation in _raise_error (For example,
169 context._raise_error(NewError, '(-x)!', self._sign) would
170 call NewError().handle(context, self._sign).)
171
172 To define a new exception, it should be sufficient to have it derive
173 from DecimalException.
174 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000175 def handle(self, context, *args):
176 pass
177
178
179class Clamped(DecimalException):
180 """Exponent of a 0 changed to fit bounds.
181
182 This occurs and signals clamped if the exponent of a result has been
183 altered in order to fit the constraints of a specific concrete
184 representation. This may occur when the exponent of a zero result would
185 be outside the bounds of a representation, or when a large normal
186 number would have an encoded exponent that cannot be represented. In
187 this latter case, the exponent is reduced to fit and the corresponding
188 number of zero digits are appended to the coefficient ("fold-down").
189 """
190
191
192class InvalidOperation(DecimalException):
193 """An invalid operation was performed.
194
195 Various bad things cause this:
196
197 Something creates a signaling NaN
198 -INF + INF
199 0 * (+-)INF
200 (+-)INF / (+-)INF
201 x % 0
202 (+-)INF % x
203 x._rescale( non-integer )
204 sqrt(-x) , x > 0
205 0 ** 0
206 x ** (non-integer)
207 x ** (+-)INF
208 An operand is invalid
209 """
210 def handle(self, context, *args):
211 if args:
212 if args[0] == 1: #sNaN, must drop 's' but keep diagnostics
213 return Decimal( (args[1]._sign, args[1]._int, 'n') )
214 return NaN
215
216class ConversionSyntax(InvalidOperation):
217 """Trying to convert badly formed string.
218
219 This occurs and signals invalid-operation if an string is being
220 converted to a number and it does not conform to the numeric string
221 syntax. The result is [0,qNaN].
222 """
223
224 def handle(self, context, *args):
225 return (0, (0,), 'n') #Passed to something which uses a tuple.
226
227class DivisionByZero(DecimalException, ZeroDivisionError):
228 """Division by 0.
229
230 This occurs and signals division-by-zero if division of a finite number
231 by zero was attempted (during a divide-integer or divide operation, or a
232 power operation with negative right-hand operand), and the dividend was
233 not zero.
234
235 The result of the operation is [sign,inf], where sign is the exclusive
236 or of the signs of the operands for divide, or is 1 for an odd power of
237 -0, for power.
238 """
239
240 def handle(self, context, sign, double = None, *args):
241 if double is not None:
242 return (Infsign[sign],)*2
243 return Infsign[sign]
244
245class DivisionImpossible(InvalidOperation):
246 """Cannot perform the division adequately.
247
248 This occurs and signals invalid-operation if the integer result of a
249 divide-integer or remainder operation had too many digits (would be
250 longer than precision). The result is [0,qNaN].
251 """
252
253 def handle(self, context, *args):
254 return (NaN, NaN)
255
256class DivisionUndefined(InvalidOperation, ZeroDivisionError):
257 """Undefined result of division.
258
259 This occurs and signals invalid-operation if division by zero was
260 attempted (during a divide-integer, divide, or remainder operation), and
261 the dividend is also zero. The result is [0,qNaN].
262 """
263
264 def handle(self, context, tup=None, *args):
265 if tup is not None:
266 return (NaN, NaN) #for 0 %0, 0 // 0
267 return NaN
268
269class Inexact(DecimalException):
270 """Had to round, losing information.
271
272 This occurs and signals inexact whenever the result of an operation is
273 not exact (that is, it needed to be rounded and any discarded digits
274 were non-zero), or if an overflow or underflow condition occurs. The
275 result in all cases is unchanged.
276
277 The inexact signal may be tested (or trapped) to determine if a given
278 operation (or sequence of operations) was inexact.
279 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000280 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000281
282class InvalidContext(InvalidOperation):
283 """Invalid context. Unknown rounding, for example.
284
285 This occurs and signals invalid-operation if an invalid context was
286 detected during an operation. This can occur if contexts are not checked
287 on creation and either the precision exceeds the capability of the
288 underlying concrete representation or an unknown or unsupported rounding
289 was specified. These aspects of the context need only be checked when
290 the values are required to be used. The result is [0,qNaN].
291 """
292
293 def handle(self, context, *args):
294 return NaN
295
296class Rounded(DecimalException):
297 """Number got rounded (not necessarily changed during rounding).
298
299 This occurs and signals rounded whenever the result of an operation is
300 rounded (that is, some zero or non-zero digits were discarded from the
301 coefficient), or if an overflow or underflow condition occurs. The
302 result in all cases is unchanged.
303
304 The rounded signal may be tested (or trapped) to determine if a given
305 operation (or sequence of operations) caused a loss of precision.
306 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000307 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000308
309class Subnormal(DecimalException):
310 """Exponent < Emin before rounding.
311
312 This occurs and signals subnormal whenever the result of a conversion or
313 operation is subnormal (that is, its adjusted exponent is less than
314 Emin, before any rounding). The result in all cases is unchanged.
315
316 The subnormal signal may be tested (or trapped) to determine if a given
317 or operation (or sequence of operations) yielded a subnormal result.
318 """
319 pass
320
321class Overflow(Inexact, Rounded):
322 """Numerical overflow.
323
324 This occurs and signals overflow if the adjusted exponent of a result
325 (from a conversion or from an operation that is not an attempt to divide
326 by zero), after rounding, would be greater than the largest value that
327 can be handled by the implementation (the value Emax).
328
329 The result depends on the rounding mode:
330
331 For round-half-up and round-half-even (and for round-half-down and
332 round-up, if implemented), the result of the operation is [sign,inf],
333 where sign is the sign of the intermediate result. For round-down, the
334 result is the largest finite number that can be represented in the
335 current precision, with the sign of the intermediate result. For
336 round-ceiling, the result is the same as for round-down if the sign of
337 the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
338 the result is the same as for round-down if the sign of the intermediate
339 result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
340 will also be raised.
341 """
342
343 def handle(self, context, sign, *args):
344 if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
345 ROUND_HALF_DOWN, ROUND_UP):
346 return Infsign[sign]
347 if sign == 0:
348 if context.rounding == ROUND_CEILING:
349 return Infsign[sign]
350 return Decimal((sign, (9,)*context.prec,
351 context.Emax-context.prec+1))
352 if sign == 1:
353 if context.rounding == ROUND_FLOOR:
354 return Infsign[sign]
355 return Decimal( (sign, (9,)*context.prec,
356 context.Emax-context.prec+1))
357
358
359class Underflow(Inexact, Rounded, Subnormal):
360 """Numerical underflow with result rounded to 0.
361
362 This occurs and signals underflow if a result is inexact and the
363 adjusted exponent of the result would be smaller (more negative) than
364 the smallest value that can be handled by the implementation (the value
365 Emin). That is, the result is both inexact and subnormal.
366
367 The result after an underflow will be a subnormal number rounded, if
368 necessary, so that its exponent is not less than Etiny. This may result
369 in 0 with the sign of the intermediate result and an exponent of Etiny.
370
371 In all cases, Inexact, Rounded, and Subnormal will also be raised.
372 """
373
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000374# List of public traps and flags
Raymond Hettingerfed52962004-07-14 15:41:57 +0000375_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000376 Underflow, InvalidOperation, Subnormal]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000377
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000378# Map conditions (per the spec) to signals
379_condition_map = {ConversionSyntax:InvalidOperation,
380 DivisionImpossible:InvalidOperation,
381 DivisionUndefined:InvalidOperation,
382 InvalidContext:InvalidOperation}
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000383
384##### Context Functions #######################################
385
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000386# The getcontext() and setcontext() function manage access to a thread-local
387# current context. Py2.4 offers direct support for thread locals. If that
388# is not available, use threading.currentThread() which is slower but will
389# work for older Pythons.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000390
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000391try:
392 threading.local
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000393
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000394except AttributeError:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000395
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000396 #To fix reloading, force it to create a new context
397 #Old contexts have different exceptions in their dicts, making problems.
398 if hasattr(threading.currentThread(), '__decimal_context__'):
399 del threading.currentThread().__decimal_context__
400
401 def setcontext(context):
402 """Set this thread's context to context."""
403 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000404 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000405 context.clear_flags()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000406 threading.currentThread().__decimal_context__ = context
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000407
408 def getcontext():
409 """Returns this thread's context.
410
411 If this thread does not yet have a context, returns
412 a new context and sets this thread's context.
413 New contexts are copies of DefaultContext.
414 """
415 try:
416 return threading.currentThread().__decimal_context__
417 except AttributeError:
418 context = Context()
419 threading.currentThread().__decimal_context__ = context
420 return context
421
422else:
423
424 local = threading.local()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000425 if hasattr(local, '__decimal_context__'):
426 del local.__decimal_context__
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000427
428 def getcontext(_local=local):
429 """Returns this thread's context.
430
431 If this thread does not yet have a context, returns
432 a new context and sets this thread's context.
433 New contexts are copies of DefaultContext.
434 """
435 try:
436 return _local.__decimal_context__
437 except AttributeError:
438 context = Context()
439 _local.__decimal_context__ = context
440 return context
441
442 def setcontext(context, _local=local):
443 """Set this thread's context to context."""
444 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000445 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000446 context.clear_flags()
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000447 _local.__decimal_context__ = context
448
449 del threading, local # Don't contaminate the namespace
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000450
451
452##### Decimal class ###########################################
453
454class Decimal(object):
455 """Floating point class for decimal arithmetic."""
456
457 __slots__ = ('_exp','_int','_sign')
458
459 def __init__(self, value="0", context=None):
460 """Create a decimal point instance.
461
462 >>> Decimal('3.14') # string input
463 Decimal("3.14")
464 >>> Decimal((0, (3, 1, 4), -2)) # tuple input (sign, digit_tuple, exponent)
465 Decimal("3.14")
466 >>> Decimal(314) # int or long
467 Decimal("314")
468 >>> Decimal(Decimal(314)) # another decimal instance
469 Decimal("314")
470 """
471 if context is None:
472 context = getcontext()
473
474 if isinstance(value, (int,long)):
475 value = str(value)
476
477 # String?
478 # REs insist on real strings, so we can too.
479 if isinstance(value, basestring):
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000480 if _isinfinity(value):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000481 self._exp = 'F'
482 self._int = (0,)
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000483 sign = _isinfinity(value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000484 if sign == 1:
485 self._sign = 0
486 else:
487 self._sign = 1
488 return
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000489 if _isnan(value):
490 sig, sign, diag = _isnan(value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000491 if len(diag) > context.prec: #Diagnostic info too long
492 self._sign, self._int, self._exp = \
493 context._raise_error(ConversionSyntax)
494 return
495 if sig == 1:
496 self._exp = 'n' #qNaN
497 else: #sig == 2
498 self._exp = 'N' #sNaN
499 self._sign = sign
500 self._int = tuple(map(int, diag)) #Diagnostic info
501 return
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +0000502 try:
503 self._sign, self._int, self._exp = _string2exact(value)
504 except ValueError:
505 self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000506 return
507
508 # tuple/list conversion (possibly from as_tuple())
509 if isinstance(value, (list,tuple)):
510 if len(value) != 3:
511 raise ValueError, 'Invalid arguments'
512 if value[0] not in [0,1]:
513 raise ValueError, 'Invalid sign'
514 for digit in value[1]:
515 if not isinstance(digit, (int,long)) or digit < 0:
516 raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
517
518 self._sign = value[0]
519 self._int = tuple(value[1])
520 if value[2] in ('F','n','N'):
521 self._exp = value[2]
522 else:
523 self._exp = int(value[2])
524 return
525
526 # Turn an intermediate value back to Decimal()
527 if isinstance(value, _WorkRep):
528 if value.sign == 1:
529 self._sign = 0
530 else:
531 self._sign = 1
532 self._int = tuple(value.int)
533 self._exp = int(value.exp)
534 return
535
536 if isinstance(value, Decimal):
Tim Peters4e0e1b62004-07-07 20:54:48 +0000537 self._exp = value._exp
538 self._sign = value._sign
539 self._int = value._int
540 return
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000541
Raymond Hettingerbf440692004-07-10 14:14:37 +0000542 if isinstance(value, float):
543 raise TypeError("Cannot convert float to Decimal. " +
544 "First convert the float to a string")
545
546 raise TypeError("Cannot convert %r" % value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000547
548 def _convert_other(self, other):
549 """Convert other to Decimal.
550
551 Verifies that it's ok to use in an implicit construction.
552 """
553 if isinstance(other, Decimal):
554 return other
555 if isinstance(other, (int, long)):
556 other = Decimal(other)
557 return other
558
559 raise TypeError, "You can interact Decimal only with int, long or Decimal data types."
560
561 def _isnan(self):
562 """Returns whether the number is not actually one.
563
564 0 if a number
565 1 if NaN
566 2 if sNaN
567 """
568 if self._exp == 'n':
569 return 1
570 elif self._exp == 'N':
571 return 2
572 return 0
573
574 def _isinfinity(self):
575 """Returns whether the number is infinite
576
577 0 if finite or not a number
578 1 if +INF
579 -1 if -INF
580 """
581 if self._exp == 'F':
582 if self._sign:
583 return -1
584 return 1
585 return 0
586
587 def _check_nans(self, other = None, context=None):
588 """Returns whether the number is not actually one.
589
590 if self, other are sNaN, signal
591 if self, other are NaN return nan
592 return 0
593
594 Done before operations.
595 """
596 if context is None:
597 context = getcontext()
598
599 if self._isnan() == 2:
600 return context._raise_error(InvalidOperation, 'sNaN',
601 1, self)
602 if other is not None and other._isnan() == 2:
603 return context._raise_error(InvalidOperation, 'sNaN',
604 1, other)
605 if self._isnan():
606 return self
607 if other is not None and other._isnan():
608 return other
609 return 0
610
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000611 def __nonzero__(self):
612 """Is the number non-zero?
613
614 0 if self == 0
615 1 if self != 0
616 """
617 if isinstance(self._exp, str):
618 return 1
619 return self._int != (0,)*len(self._int)
620
621 def __cmp__(self, other, context=None):
622 if context is None:
623 context = getcontext()
624 other = self._convert_other(other)
625
626 ans = self._check_nans(other, context)
627 if ans:
628 return 1
629
630 if not self and not other:
631 return 0 #If both 0, sign comparison isn't certain.
632
633 #If different signs, neg one is less
634 if other._sign < self._sign:
635 return -1
636 if self._sign < other._sign:
637 return 1
638
639 # INF = INF
640 if self._isinfinity() and other._isinfinity():
641 return 0
642 if self._isinfinity():
643 return (-1)**self._sign
644 if other._isinfinity():
645 return -((-1)**other._sign)
646
647 if self.adjusted() == other.adjusted() and \
648 self._int + (0,)*(self._exp - other._exp) == \
649 other._int + (0,)*(other._exp - self._exp):
650 return 0 #equal, except in precision. ([0]*(-x) = [])
651 elif self.adjusted() > other.adjusted() and self._int[0] != 0:
652 return (-1)**self._sign
653 elif self.adjusted < other.adjusted() and other._int[0] != 0:
654 return -((-1)**self._sign)
655
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000656 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000657 rounding = context._set_rounding(ROUND_UP) #round away from 0
658
659 flags = context._ignore_all_flags()
660 res = self.__sub__(other, context=context)
661
662 context._regard_flags(*flags)
663
664 context.rounding = rounding
665
666 if not res:
667 return 0
668 elif res._sign:
669 return -1
670 return 1
671
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000672 def __eq__(self, other):
673 if not isinstance(other, (Decimal, int, long)):
674 return False
675 return self.__cmp__(other) == 0
676
677 def __ne__(self, other):
678 if not isinstance(other, (Decimal, int, long)):
679 return True
680 return self.__cmp__(other) != 0
681
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000682 def compare(self, other, context=None):
683 """Compares one to another.
684
685 -1 => a < b
686 0 => a = b
687 1 => a > b
688 NaN => one is NaN
689 Like __cmp__, but returns Decimal instances.
690 """
691 if context is None:
692 context = getcontext()
693 other = self._convert_other(other)
694
695 #compare(NaN, NaN) = NaN
696 ans = self._check_nans(other, context)
697 if ans:
698 return ans
699
700 return Decimal(self.__cmp__(other, context))
701
702 def __hash__(self):
703 """x.__hash__() <==> hash(x)"""
704 # Decimal integers must hash the same as the ints
705 # Non-integer decimals are normalized and hashed as strings
706 # Normalization assures that hast(100E-1) == hash(10)
707 i = int(self)
708 if self == Decimal(i):
709 return hash(i)
710 assert self.__nonzero__() # '-0' handled by integer case
711 return hash(str(self.normalize()))
712
713 def as_tuple(self):
714 """Represents the number as a triple tuple.
715
716 To show the internals exactly as they are.
717 """
718 return (self._sign, self._int, self._exp)
719
720 def __repr__(self):
721 """Represents the number as an instance of Decimal."""
722 # Invariant: eval(repr(d)) == d
723 return 'Decimal("%s")' % str(self)
724
725 def __str__(self, eng = 0, context=None):
726 """Return string representation of the number in scientific notation.
727
728 Captures all of the information in the underlying representation.
729 """
730
731 if self._isnan():
732 minus = '-'*self._sign
733 if self._int == (0,):
734 info = ''
735 else:
736 info = ''.join(map(str, self._int))
737 if self._isnan() == 2:
738 return minus + 'sNaN' + info
739 return minus + 'NaN' + info
740 if self._isinfinity():
741 minus = '-'*self._sign
742 return minus + 'Infinity'
743
744 if context is None:
745 context = getcontext()
746
747 tmp = map(str, self._int)
748 numdigits = len(self._int)
749 leftdigits = self._exp + numdigits
750 if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
751 if self._exp < 0 and self._exp >= -6: #short, no need for e/E
752 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
753 return s
754 #exp is closest mult. of 3 >= self._exp
755 exp = ((self._exp - 1)// 3 + 1) * 3
756 if exp != self._exp:
757 s = '0.'+'0'*(exp - self._exp)
758 else:
759 s = '0'
760 if exp != 0:
761 if context.capitals:
762 s += 'E'
763 else:
764 s += 'e'
765 if exp > 0:
766 s += '+' #0.0e+3, not 0.0e3
767 s += str(exp)
768 s = '-'*self._sign + s
769 return s
770 if eng:
771 dotplace = (leftdigits-1)%3+1
772 adjexp = leftdigits -1 - (leftdigits-1)%3
773 else:
774 adjexp = leftdigits-1
775 dotplace = 1
776 if self._exp == 0:
777 pass
778 elif self._exp < 0 and adjexp >= 0:
779 tmp.insert(leftdigits, '.')
780 elif self._exp < 0 and adjexp >= -6:
781 tmp[0:0] = ['0'] * int(-leftdigits)
782 tmp.insert(0, '0.')
783 else:
784 if numdigits > dotplace:
785 tmp.insert(dotplace, '.')
786 elif numdigits < dotplace:
787 tmp.extend(['0']*(dotplace-numdigits))
788 if adjexp:
789 if not context.capitals:
790 tmp.append('e')
791 else:
792 tmp.append('E')
793 if adjexp > 0:
794 tmp.append('+')
795 tmp.append(str(adjexp))
796 if eng:
797 while tmp[0:1] == ['0']:
798 tmp[0:1] = []
799 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
800 tmp[0:0] = ['0']
801 if self._sign:
802 tmp.insert(0, '-')
803
804 return ''.join(tmp)
805
806 def to_eng_string(self, context=None):
807 """Convert to engineering-type string.
808
809 Engineering notation has an exponent which is a multiple of 3, so there
810 are up to 3 digits left of the decimal place.
811
812 Same rules for when in exponential and when as a value as in __str__.
813 """
814 if context is None:
815 context = getcontext()
816 return self.__str__(eng=1, context=context)
817
818 def __neg__(self, context=None):
819 """Returns a copy with the sign switched.
820
821 Rounds, if it has reason.
822 """
823 if context is None:
824 context = getcontext()
825 ans = self._check_nans(context=context)
826 if ans:
827 return ans
828
829 if not self:
830 # -Decimal('0') is Decimal('0'), not Decimal('-0')
831 sign = 0
832 elif self._sign:
833 sign = 0
834 else:
835 sign = 1
836 if context._rounding_decision == ALWAYS_ROUND:
837 return Decimal((sign, self._int, self._exp))._fix(context=context)
838 return Decimal( (sign, self._int, self._exp))
839
840 def __pos__(self, context=None):
841 """Returns a copy, unless it is a sNaN.
842
843 Rounds the number (if more then precision digits)
844 """
845 if context is None:
846 context = getcontext()
847 ans = self._check_nans(context=context)
848 if ans:
849 return ans
850
851 sign = self._sign
852 if not self:
853 # + (-0) = 0
854 sign = 0
855
856 if context._rounding_decision == ALWAYS_ROUND:
857 ans = self._fix(context=context)
858 else:
859 ans = Decimal(self)
860 ans._sign = sign
861 return ans
862
863 def __abs__(self, round=1, context=None):
864 """Returns the absolute value of self.
865
866 If the second argument is 0, do not round.
867 """
868 if context is None:
869 context = getcontext()
870 ans = self._check_nans(context=context)
871 if ans:
872 return ans
873
874 if not round:
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000875 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000876 context._set_rounding_decision(NEVER_ROUND)
877
878 if self._sign:
879 ans = self.__neg__(context=context)
880 else:
881 ans = self.__pos__(context=context)
882
883 return ans
884
885 def __add__(self, other, context=None):
886 """Returns self + other.
887
888 -INF + INF (or the reverse) cause InvalidOperation errors.
889 """
890 if context is None:
891 context = getcontext()
892 other = self._convert_other(other)
893
894 ans = self._check_nans(other, context)
895 if ans:
896 return ans
897
898 if self._isinfinity():
899 #If both INF, same sign => same as both, opposite => error.
900 if self._sign != other._sign and other._isinfinity():
901 return context._raise_error(InvalidOperation, '-INF + INF')
902 return Decimal(self)
903 if other._isinfinity():
904 return Decimal(other) #Can't both be infinity here
905
906 shouldround = context._rounding_decision == ALWAYS_ROUND
907
908 exp = min(self._exp, other._exp)
909 negativezero = 0
910 if context.rounding == ROUND_FLOOR and self._sign != other._sign:
911 #If the answer is 0, the sign should be negative, in this case.
912 negativezero = 1
913
914 if not self and not other:
915 sign = min(self._sign, other._sign)
916 if negativezero:
917 sign = 1
918 return Decimal( (sign, (0,), exp))
919 if not self:
920 if exp < other._exp - context.prec-1:
921 exp = other._exp - context.prec-1
922 ans = other._rescale(exp, watchexp=0, context=context)
923 if shouldround:
924 ans = ans._fix(context=context)
925 return ans
926 if not other:
927 if exp < self._exp - context.prec-1:
928 exp = self._exp - context.prec-1
929 ans = self._rescale(exp, watchexp=0, context=context)
930 if shouldround:
931 ans = ans._fix(context=context)
932 return ans
933
934 op1 = _WorkRep(self)
935 op2 = _WorkRep(other)
936 op1, op2 = _normalize(op1, op2, shouldround, context.prec)
937
938 result = _WorkRep()
939
940 if op1.sign != op2.sign:
941 diff = cmp(abs(op1), abs(op2))
942 # Equal and opposite
943 if diff == 0:
944 if exp < context.Etiny():
945 exp = context.Etiny()
946 context._raise_error(Clamped)
947 return Decimal((negativezero, (0,), exp))
948 if diff < 0:
949 op1, op2 = op2, op1
950 #OK, now abs(op1) > abs(op2)
951 if op1.sign == -1:
952 result.sign = -1
953 op1.sign, op2.sign = op2.sign, op1.sign
954 else:
955 result.sign = 1
956 #So we know the sign, and op1 > 0.
957 elif op1.sign == -1:
958 result.sign = -1
959 op1.sign, op2.sign = (1, 1)
960 else:
961 result.sign = 1
962 #Now, op1 > abs(op2) > 0
963
964 op1.int.reverse()
965 op2.int.reverse()
966
967 if op2.sign == 1:
968 result.int = resultint = map(operator.add, op1.int, op2.int)
969 carry = 0
970 for i in xrange(len(op1.int)):
971 tmp = resultint[i] + carry
972 carry = 0
973 if tmp > 9:
974 carry = 1
975 tmp -= 10
976 resultint[i] = tmp
977 if carry:
978 resultint.append(1)
979 else:
980 result.int = resultint = map(operator.sub, op1.int, op2.int)
981 loan = 0
982 for i in xrange(len(op1.int)):
983 tmp = resultint[i] - loan
984 loan = 0
985 if tmp < 0:
986 loan = 1
987 tmp += 10
988 resultint[i] = tmp
989 assert not loan
990
991 while resultint[-1] == 0:
992 resultint.pop()
993 resultint.reverse()
994
995 result.exp = op1.exp
996 ans = Decimal(result)
997 if shouldround:
998 ans = ans._fix(context=context)
999 return ans
1000
1001 __radd__ = __add__
1002
1003 def __sub__(self, other, context=None):
1004 """Return self + (-other)"""
1005 if context is None:
1006 context = getcontext()
1007 other = self._convert_other(other)
1008
1009 ans = self._check_nans(other, context=context)
1010 if ans:
1011 return ans
1012
1013 # -Decimal(0) = Decimal(0), which we don't want since
1014 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
1015 # so we change the sign directly to a copy
1016 tmp = Decimal(other)
1017 tmp._sign = 1-tmp._sign
1018
1019 return self.__add__(tmp, context=context)
1020
1021 def __rsub__(self, other, context=None):
1022 """Return other + (-self)"""
1023 if context is None:
1024 context = getcontext()
1025 other = self._convert_other(other)
1026
1027 tmp = Decimal(self)
1028 tmp._sign = 1 - tmp._sign
1029 return other.__add__(tmp, context=context)
1030
1031 def _increment(self, round=1, context=None):
1032 """Special case of add, adding 1eExponent
1033
1034 Since it is common, (rounding, for example) this adds
1035 (sign)*one E self._exp to the number more efficiently than add.
1036
1037 For example:
1038 Decimal('5.624e10')._increment() == Decimal('5.625e10')
1039 """
1040 if context is None:
1041 context = getcontext()
1042 ans = self._check_nans(context=context)
1043 if ans:
1044 return ans
1045
1046 L = list(self._int)
1047 L[-1] += 1
1048 spot = len(L)-1
1049 while L[spot] == 10:
1050 L[spot] = 0
1051 if spot == 0:
1052 L[0:0] = [1]
1053 break
1054 L[spot-1] += 1
1055 spot -= 1
1056 ans = Decimal((self._sign, L, self._exp))
1057
1058 if round and context._rounding_decision == ALWAYS_ROUND:
1059 ans = ans._fix(context=context)
1060 return ans
1061
1062 def __mul__(self, other, context=None):
1063 """Return self * other.
1064
1065 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1066 """
1067 if context is None:
1068 context = getcontext()
1069 other = self._convert_other(other)
1070
1071 ans = self._check_nans(other, context)
1072 if ans:
1073 return ans
1074
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001075 resultsign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001076 if self._isinfinity():
1077 if not other:
1078 return context._raise_error(InvalidOperation, '(+-)INF * 0')
1079 return Infsign[resultsign]
1080
1081 if other._isinfinity():
1082 if not self:
1083 return context._raise_error(InvalidOperation, '0 * (+-)INF')
1084 return Infsign[resultsign]
1085
1086 resultexp = self._exp + other._exp
1087 shouldround = context._rounding_decision == ALWAYS_ROUND
1088
1089 # Special case for multiplying by zero
1090 if not self or not other:
1091 ans = Decimal((resultsign, (0,), resultexp))
1092 if shouldround:
1093 #Fixing in case the exponent is out of bounds
1094 ans = ans._fix(context=context)
1095 return ans
1096
1097 # Special case for multiplying by power of 10
1098 if self._int == (1,):
1099 ans = Decimal((resultsign, other._int, resultexp))
1100 if shouldround:
1101 ans = ans._fix(context=context)
1102 return ans
1103 if other._int == (1,):
1104 ans = Decimal((resultsign, self._int, resultexp))
1105 if shouldround:
1106 ans = ans._fix(context=context)
1107 return ans
1108
1109 op1 = list(self._int)
1110 op2 = list(other._int)
1111 op1.reverse()
1112 op2.reverse()
1113 # Minimize Decimal additions
1114 if len(op2) > len(op1):
1115 op1, op2 = op2, op1
1116
1117 _divmod = divmod
1118 accumulator = [0]*(len(self._int) + len(other._int))
1119 for i in xrange(len(op2)):
1120 if op2[i] == 0:
1121 continue
1122 mult = op2[i]
1123 carry = 0
1124 for j in xrange(len(op1)):
1125 carry, accumulator[i+j] = _divmod( mult * op1[j] + carry
1126 + accumulator[i+j], 10)
1127
1128 if carry:
1129 accumulator[i + j + 1] += carry
1130 while not accumulator[-1]:
1131 accumulator.pop()
1132 accumulator.reverse()
1133
1134 ans = Decimal( (resultsign, accumulator, resultexp))
1135 if shouldround:
1136 ans = ans._fix(context=context)
1137
1138 return ans
1139 __rmul__ = __mul__
1140
1141 def __div__(self, other, context=None):
1142 """Return self / other."""
1143 return self._divide(other, context=context)
1144 __truediv__ = __div__
1145
1146 def _divide(self, other, divmod = 0, context=None):
1147 """Return a / b, to context.prec precision.
1148
1149 divmod:
1150 0 => true division
1151 1 => (a //b, a%b)
1152 2 => a //b
1153 3 => a%b
1154
1155 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1156 computing the other value are not raised.
1157 """
1158 if context is None:
1159 context = getcontext()
1160 other = self._convert_other(other)
1161
1162 ans = self._check_nans(other, context)
1163 if ans:
1164 if divmod:
1165 return (ans, ans)
1166 else:
1167 return ans
1168
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001169 sign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001170 if not self and not other:
1171 if divmod:
1172 return context._raise_error(DivisionUndefined, '0 / 0', 1)
1173 return context._raise_error(DivisionUndefined, '0 / 0')
1174 if self._isinfinity() and other._isinfinity():
1175 if not divmod:
1176 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
1177 else:
1178 return (context._raise_error(InvalidOperation,
1179 '(+-)INF // (+-)INF'),
1180 context._raise_error(InvalidOperation,
1181 '(+-)INF % (+-)INF'))
1182
1183 if not divmod:
1184 if other._isinfinity():
1185 context._raise_error(Clamped, 'Division by infinity')
1186 return Decimal((sign, (0,), context.Etiny()))
1187 if self._isinfinity():
1188 return Infsign[sign]
1189 #These two have different precision.
1190 if not self:
1191 exp = self._exp - other._exp
1192 if exp < context.Etiny():
1193 exp = context.Etiny()
1194 context._raise_error(Clamped, '0e-x / y')
1195 if exp > context.Emax:
1196 exp = context.Emax
1197 context._raise_error(Clamped, '0e+x / y')
1198 return Decimal( (sign, (0,), exp) )
1199
1200 if not other:
1201 return context._raise_error(DivisionByZero, 'x / 0', sign)
1202 if divmod:
1203 if other._isinfinity():
1204 return (Decimal((sign, (0,), 0)), Decimal(self))
1205 if self._isinfinity():
1206 if divmod == 1:
1207 return (Infsign[sign],
1208 context._raise_error(InvalidOperation, 'INF % x'))
1209 elif divmod == 2:
1210 return (Infsign[sign], NaN)
1211 elif divmod == 3:
1212 return (Infsign[sign],
1213 context._raise_error(InvalidOperation, 'INF % x'))
1214 if not self:
1215 otherside = Decimal(self)
1216 otherside._exp = min(self._exp, other._exp)
1217 return (Decimal((sign, (0,), 0)), otherside)
1218
1219 if not other:
1220 return context._raise_error(DivisionByZero, 'divmod(x,0)',
1221 sign, 1)
1222
1223 #OK, so neither = 0, INF
1224
1225 shouldround = context._rounding_decision == ALWAYS_ROUND
1226
1227 #If we're dividing into ints, and self < other, stop.
1228 #self.__abs__(0) does not round.
1229 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
1230
1231 if divmod == 1 or divmod == 3:
1232 exp = min(self._exp, other._exp)
1233 ans2 = self._rescale(exp, context=context, watchexp=0)
1234 if shouldround:
1235 ans2 = ans2._fix(context=context)
1236 return (Decimal( (sign, (0,), 0) ),
1237 ans2)
1238
1239 elif divmod == 2:
1240 #Don't round the mod part, if we don't need it.
1241 return (Decimal( (sign, (0,), 0) ), Decimal(self))
1242
1243 if sign:
1244 sign = -1
1245 else:
1246 sign = 1
1247 adjust = 0
1248 op1 = _WorkRep(self)
1249 op2 = _WorkRep(other)
1250 op1, op2, adjust = _adjust_coefficients(op1, op2)
1251 res = _WorkRep( (sign, [0], (op1.exp - op2.exp)) )
1252 if divmod and res.exp > context.prec + 1:
1253 return context._raise_error(DivisionImpossible)
1254
1255 ans = None
1256 while 1:
1257 while( (len(op2.int) < len(op1.int) and op1.int[0]) or
1258 (len(op2.int) == len(op1.int) and op2.int <= op1.int)):
1259 #Meaning, while op2.int < op1.int, when normalized.
1260 res._increment()
1261 op1.subtract(op2.int)
1262 if res.exp == 0 and divmod:
1263 if len(res.int) > context.prec and shouldround:
1264 return context._raise_error(DivisionImpossible)
1265 otherside = Decimal(op1)
1266 frozen = context._ignore_all_flags()
1267
1268 exp = min(self._exp, other._exp)
1269 otherside = otherside._rescale(exp, context=context,
1270 watchexp=0)
1271 context._regard_flags(*frozen)
1272 if shouldround:
1273 otherside = otherside._fix(context=context)
1274 return (Decimal(res), otherside)
1275
1276 if op1.int == [0]*len(op1.int) and adjust >= 0 and not divmod:
1277 break
1278 if (len(res.int) > context.prec) and shouldround:
1279 if divmod:
1280 return context._raise_error(DivisionImpossible)
1281 shouldround=1
1282 # Really, the answer is a bit higher, so adding a one to
1283 # the end will make sure the rounding is right.
1284 if op1.int != [0]*len(op1.int):
1285 res.int.append(1)
1286 res.exp -= 1
1287
1288 break
1289 res.exp -= 1
1290 adjust += 1
1291 res.int.append(0)
1292 op1.int.append(0)
1293 op1.exp -= 1
1294
1295 if res.exp == 0 and divmod and (len(op2.int) > len(op1.int) or
1296 (len(op2.int) == len(op1.int) and
1297 op2.int > op1.int)):
1298 #Solves an error in precision. Same as a previous block.
1299
1300 if len(res.int) > context.prec and shouldround:
1301 return context._raise_error(DivisionImpossible)
1302 otherside = Decimal(op1)
1303 frozen = context._ignore_all_flags()
1304
1305 exp = min(self._exp, other._exp)
1306 otherside = otherside._rescale(exp, context=context)
1307
1308 context._regard_flags(*frozen)
1309
1310 return (Decimal(res), otherside)
1311
1312 ans = Decimal(res)
1313 if shouldround:
1314 ans = ans._fix(context=context)
1315 return ans
1316
1317 def __rdiv__(self, other, context=None):
1318 """Swaps self/other and returns __div__."""
1319 other = self._convert_other(other)
1320 return other.__div__(self, context=context)
1321 __rtruediv__ = __rdiv__
1322
1323 def __divmod__(self, other, context=None):
1324 """
1325 (self // other, self % other)
1326 """
1327 return self._divide(other, 1, context)
1328
1329 def __rdivmod__(self, other, context=None):
1330 """Swaps self/other and returns __divmod__."""
1331 other = self._convert_other(other)
1332 return other.__divmod__(self, context=context)
1333
1334 def __mod__(self, other, context=None):
1335 """
1336 self % other
1337 """
1338 if context is None:
1339 context = getcontext()
1340 other = self._convert_other(other)
1341
1342 ans = self._check_nans(other, context)
1343 if ans:
1344 return ans
1345
1346 if self and not other:
1347 return context._raise_error(InvalidOperation, 'x % 0')
1348
1349 return self._divide(other, 3, context)[1]
1350
1351 def __rmod__(self, other, context=None):
1352 """Swaps self/other and returns __mod__."""
1353 other = self._convert_other(other)
1354 return other.__mod__(self, context=context)
1355
1356 def remainder_near(self, other, context=None):
1357 """
1358 Remainder nearest to 0- abs(remainder-near) <= other/2
1359 """
1360 if context is None:
1361 context = getcontext()
1362 other = self._convert_other(other)
1363
1364 ans = self._check_nans(other, context)
1365 if ans:
1366 return ans
1367 if self and not other:
1368 return context._raise_error(InvalidOperation, 'x % 0')
1369
1370 # If DivisionImpossible causes an error, do not leave Rounded/Inexact
1371 # ignored in the calling function.
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001372 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001373 flags = context._ignore_flags(Rounded, Inexact)
1374 #keep DivisionImpossible flags
1375 (side, r) = self.__divmod__(other, context=context)
1376
1377 if r._isnan():
1378 context._regard_flags(*flags)
1379 return r
1380
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001381 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001382 rounding = context._set_rounding_decision(NEVER_ROUND)
1383
1384 if other._sign:
1385 comparison = other.__div__(Decimal(-2), context=context)
1386 else:
1387 comparison = other.__div__(Decimal(2), context=context)
1388
1389 context._set_rounding_decision(rounding)
1390 context._regard_flags(*flags)
1391
1392 s1, s2 = r._sign, comparison._sign
1393 r._sign, comparison._sign = 0, 0
1394
1395 if r < comparison:
1396 r._sign, comparison._sign = s1, s2
1397 #Get flags now
1398 self.__divmod__(other, context=context)
1399 return r._fix(context=context)
1400 r._sign, comparison._sign = s1, s2
1401
1402 rounding = context._set_rounding_decision(NEVER_ROUND)
1403
1404 (side, r) = self.__divmod__(other, context=context)
1405 context._set_rounding_decision(rounding)
1406 if r._isnan():
1407 return r
1408
1409 decrease = not side._iseven()
1410 rounding = context._set_rounding_decision(NEVER_ROUND)
1411 side = side.__abs__(context=context)
1412 context._set_rounding_decision(rounding)
1413
1414 s1, s2 = r._sign, comparison._sign
1415 r._sign, comparison._sign = 0, 0
1416 if r > comparison or decrease and r == comparison:
1417 r._sign, comparison._sign = s1, s2
1418 context.prec += 1
1419 if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
1420 context.prec -= 1
1421 return context._raise_error(DivisionImpossible)[1]
1422 context.prec -= 1
1423 if self._sign == other._sign:
1424 r = r.__sub__(other, context=context)
1425 else:
1426 r = r.__add__(other, context=context)
1427 else:
1428 r._sign, comparison._sign = s1, s2
1429
1430 return r._fix(context=context)
1431
1432 def __floordiv__(self, other, context=None):
1433 """self // other"""
1434 return self._divide(other, 2, context)[0]
1435
1436 def __rfloordiv__(self, other, context=None):
1437 """Swaps self/other and returns __floordiv__."""
1438 other = self._convert_other(other)
1439 return other.__floordiv__(self, context=context)
1440
1441 def __float__(self):
1442 """Float representation."""
1443 return float(str(self))
1444
1445 def __int__(self):
1446 """Converts self to a int, truncating if necessary."""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001447 if self._isnan():
1448 context = getcontext()
1449 return context._raise_error(InvalidContext)
1450 elif self._isinfinity():
1451 raise OverflowError, "Cannot convert infinity to long"
1452 if not self:
1453 return 0
1454 sign = '-'*self._sign
1455 if self._exp >= 0:
1456 s = sign + ''.join(map(str, self._int)) + '0'*self._exp
1457 return int(s)
1458 s = sign + ''.join(map(str, self._int))[:self._exp]
1459 return int(s)
1460 tmp = list(self._int)
1461 tmp.reverse()
1462 val = 0
1463 while tmp:
1464 val *= 10
1465 val += tmp.pop()
1466 return int(((-1) ** self._sign) * val * 10.**int(self._exp))
1467
1468 def __long__(self):
1469 """Converts to a long.
1470
1471 Equivalent to long(int(self))
1472 """
1473 return long(self.__int__())
1474
1475 def _fix(self, prec=None, rounding=None, folddown=None, context=None):
1476 """Round if it is necessary to keep self within prec precision.
1477
1478 Rounds and fixes the exponent. Does not raise on a sNaN.
1479
1480 Arguments:
1481 self - Decimal instance
1482 prec - precision to which to round. By default, the context decides.
1483 rounding - Rounding method. By default, the context decides.
1484 folddown - Fold down high elements, by default context._clamp
1485 context - context used.
1486 """
1487 if self._isinfinity() or self._isnan():
1488 return self
1489 if context is None:
1490 context = getcontext()
1491 if prec is None:
1492 prec = context.prec
1493 ans = Decimal(self)
1494 ans = ans._fixexponents(prec, rounding, folddown=folddown,
1495 context=context)
1496 if len(ans._int) > prec:
1497 ans = ans._round(prec, rounding, context=context)
1498 ans = ans._fixexponents(prec, rounding, folddown=folddown,
1499 context=context)
1500 return ans
1501
1502 def _fixexponents(self, prec=None, rounding=None, folddown=None,
1503 context=None):
1504 """Fix the exponents and return a copy with the exponent in bounds."""
1505 if self._isinfinity():
1506 return self
1507 if context is None:
1508 context = getcontext()
1509 if prec is None:
1510 prec = context.prec
1511 if folddown is None:
1512 folddown = context._clamp
1513 Emin, Emax = context.Emin, context.Emax
1514 Etop = context.Etop()
1515 ans = Decimal(self)
1516 if ans.adjusted() < Emin:
1517 Etiny = context.Etiny()
1518 if ans._exp < Etiny:
1519 if not ans:
1520 ans._exp = Etiny
1521 context._raise_error(Clamped)
1522 return ans
1523 ans = ans._rescale(Etiny, context=context)
1524 #It isn't zero, and exp < Emin => subnormal
1525 context._raise_error(Subnormal)
1526 if context.flags[Inexact]:
1527 context._raise_error(Underflow)
1528 else:
1529 if ans:
1530 #Only raise subnormal if non-zero.
1531 context._raise_error(Subnormal)
1532 elif folddown and ans._exp > Etop:
1533 context._raise_error(Clamped)
1534 ans = ans._rescale(Etop, context=context)
1535 elif ans.adjusted() > Emax:
1536 if not ans:
1537 ans._exp = Emax
1538 context._raise_error(Clamped)
1539 return ans
1540 context._raise_error(Inexact)
1541 context._raise_error(Rounded)
1542 return context._raise_error(Overflow, 'above Emax', ans._sign)
1543 return ans
1544
1545 def _round(self, prec=None, rounding=None, context=None):
1546 """Returns a rounded version of self.
1547
1548 You can specify the precision or rounding method. Otherwise, the
1549 context determines it.
1550 """
1551
1552 if context is None:
1553 context = getcontext()
1554 ans = self._check_nans(context=context)
1555 if ans:
1556 return ans
1557
1558 if self._isinfinity():
1559 return Decimal(self)
1560
1561 if rounding is None:
1562 rounding = context.rounding
1563 if prec is None:
1564 prec = context.prec
1565
1566 if not self:
1567 if prec <= 0:
1568 dig = (0,)
1569 exp = len(self._int) - prec + self._exp
1570 else:
1571 dig = (0,) * prec
1572 exp = len(self._int) + self._exp - prec
1573 ans = Decimal((self._sign, dig, exp))
1574 context._raise_error(Rounded)
1575 return ans
1576
1577 if prec == 0:
1578 temp = Decimal(self)
1579 temp._int = (0,)+temp._int
1580 prec = 1
1581 elif prec < 0:
1582 exp = self._exp + len(self._int) - prec - 1
1583 temp = Decimal( (self._sign, (0, 1), exp))
1584 prec = 1
1585 else:
1586 temp = Decimal(self)
1587
1588 numdigits = len(temp._int)
1589 if prec == numdigits:
1590 return temp
1591
1592 # See if we need to extend precision
1593 expdiff = prec - numdigits
1594 if expdiff > 0:
1595 tmp = list(temp._int)
1596 tmp.extend([0] * expdiff)
1597 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff))
1598 return ans
1599
1600 #OK, but maybe all the lost digits are 0.
1601 lostdigits = self._int[expdiff:]
1602 if lostdigits == (0,) * len(lostdigits):
1603 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
1604 #Rounded, but not Inexact
1605 context._raise_error(Rounded)
1606 return ans
1607
1608 # Okay, let's round and lose data
1609
1610 this_function = getattr(temp, self._pick_rounding_function[rounding])
1611 #Now we've got the rounding function
1612
1613 if prec != context.prec:
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001614 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001615 context.prec = prec
1616 ans = this_function(prec, expdiff, context)
1617 context._raise_error(Rounded)
1618 context._raise_error(Inexact, 'Changed in rounding')
1619
1620 return ans
1621
1622 _pick_rounding_function = {}
1623
1624 def _round_down(self, prec, expdiff, context):
1625 """Also known as round-towards-0, truncate."""
1626 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1627
1628 def _round_half_up(self, prec, expdiff, context, tmp = None):
1629 """Rounds 5 up (away from 0)"""
1630
1631 if tmp is None:
1632 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
1633 if self._int[prec] >= 5:
1634 tmp = tmp._increment(round=0, context=context)
1635 if len(tmp._int) > prec:
1636 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1637 return tmp
1638
1639 def _round_half_even(self, prec, expdiff, context):
1640 """Round 5 to even, rest to nearest."""
1641
1642 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1643 half = (self._int[prec] == 5)
1644 if half:
1645 for digit in self._int[prec+1:]:
1646 if digit != 0:
1647 half = 0
1648 break
1649 if half:
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001650 if self._int[prec-1] & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001651 return tmp
1652 return self._round_half_up(prec, expdiff, context, tmp)
1653
1654 def _round_half_down(self, prec, expdiff, context):
1655 """Round 5 down"""
1656
1657 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1658 half = (self._int[prec] == 5)
1659 if half:
1660 for digit in self._int[prec+1:]:
1661 if digit != 0:
1662 half = 0
1663 break
1664 if half:
1665 return tmp
1666 return self._round_half_up(prec, expdiff, context, tmp)
1667
1668 def _round_up(self, prec, expdiff, context):
1669 """Rounds away from 0."""
1670 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1671 for digit in self._int[prec:]:
1672 if digit != 0:
1673 tmp = tmp._increment(round=1, context=context)
1674 if len(tmp._int) > prec:
1675 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1676 else:
1677 return tmp
1678 return tmp
1679
1680 def _round_ceiling(self, prec, expdiff, context):
1681 """Rounds up (not away from 0 if negative.)"""
1682 if self._sign:
1683 return self._round_down(prec, expdiff, context)
1684 else:
1685 return self._round_up(prec, expdiff, context)
1686
1687 def _round_floor(self, prec, expdiff, context):
1688 """Rounds down (not towards 0 if negative)"""
1689 if not self._sign:
1690 return self._round_down(prec, expdiff, context)
1691 else:
1692 return self._round_up(prec, expdiff, context)
1693
1694 def __pow__(self, n, modulo = None, context=None):
1695 """Return self ** n (mod modulo)
1696
1697 If modulo is None (default), don't take it mod modulo.
1698 """
1699 if context is None:
1700 context = getcontext()
1701 n = self._convert_other(n)
1702
1703 #Because the spot << doesn't work with really big exponents
1704 if n._isinfinity() or n.adjusted() > 8:
1705 return context._raise_error(InvalidOperation, 'x ** INF')
1706
1707 ans = self._check_nans(n, context)
1708 if ans:
1709 return ans
1710
1711 if not n._isinfinity() and not n._isinteger():
1712 return context._raise_error(InvalidOperation, 'x ** (non-integer)')
1713
1714 if not self and not n:
1715 return context._raise_error(InvalidOperation, '0 ** 0')
1716
1717 if not n:
1718 return Decimal(1)
1719
1720 if self == Decimal(1):
1721 return Decimal(1)
1722
1723 sign = self._sign and not n._iseven()
1724 n = int(n)
1725
1726 if self._isinfinity():
1727 if modulo:
1728 return context._raise_error(InvalidOperation, 'INF % x')
1729 if n > 0:
1730 return Infsign[sign]
1731 return Decimal( (sign, (0,), 0) )
1732
1733 #with ludicrously large exponent, just raise an overflow and return inf.
1734 if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
1735 and self:
1736
1737 tmp = Decimal('inf')
1738 tmp._sign = sign
1739 context._raise_error(Rounded)
1740 context._raise_error(Inexact)
1741 context._raise_error(Overflow, 'Big power', sign)
1742 return tmp
1743
1744 elength = len(str(abs(n)))
1745 firstprec = context.prec
1746
Raymond Hettinger99148e72004-07-14 19:56:56 +00001747 if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001748 return context._raise_error(Overflow, 'Too much precision.', sign)
1749
1750 mul = Decimal(self)
1751 val = Decimal(1)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001752 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001753 context.prec = firstprec + elength + 1
1754 rounding = context.rounding
1755 if n < 0:
1756 #n is a long now, not Decimal instance
1757 n = -n
1758 mul = Decimal(1).__div__(mul, context=context)
1759
1760 shouldround = context._rounding_decision == ALWAYS_ROUND
1761
1762 spot = 1
1763 while spot <= n:
1764 spot <<= 1
1765
1766 spot >>= 1
1767 #Spot is the highest power of 2 less than n
1768 while spot:
1769 val = val.__mul__(val, context=context)
1770 if val._isinfinity():
1771 val = Infsign[sign]
1772 break
1773 if spot & n:
1774 val = val.__mul__(mul, context=context)
1775 if modulo is not None:
1776 val = val.__mod__(modulo, context=context)
1777 spot >>= 1
1778 context.prec = firstprec
1779
1780 if shouldround:
1781 return val._fix(context=context)
1782 return val
1783
1784 def __rpow__(self, other, context=None):
1785 """Swaps self/other and returns __pow__."""
1786 other = self._convert_other(other)
1787 return other.__pow__(self, context=context)
1788
1789 def normalize(self, context=None):
1790 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
1791 if context is None:
1792 context = getcontext()
1793
1794 ans = self._check_nans(context=context)
1795 if ans:
1796 return ans
1797
1798 dup = self._fix(context=context)
1799 if dup._isinfinity():
1800 return dup
1801
1802 if not dup:
1803 return Decimal( (dup._sign, (0,), 0) )
1804 end = len(dup._int)
1805 exp = dup._exp
1806 while dup._int[end-1] == 0:
1807 exp += 1
1808 end -= 1
1809 return Decimal( (dup._sign, dup._int[:end], exp) )
1810
1811
1812 def quantize(self, exp, rounding = None, context=None, watchexp = 1):
1813 """Quantize self so its exponent is the same as that of exp.
1814
1815 Similar to self._rescale(exp._exp) but with error checking.
1816 """
1817 if context is None:
1818 context = getcontext()
1819
1820 ans = self._check_nans(exp, context)
1821 if ans:
1822 return ans
1823
1824 if exp._isinfinity() or self._isinfinity():
1825 if exp._isinfinity() and self._isinfinity():
1826 return self #if both are inf, it is OK
1827 return context._raise_error(InvalidOperation,
1828 'quantize with one INF')
1829 return self._rescale(exp._exp, rounding, context, watchexp)
1830
1831 def same_quantum(self, other):
1832 """Test whether self and other have the same exponent.
1833
1834 same as self._exp == other._exp, except NaN == sNaN
1835 """
1836 if self._isnan() or other._isnan():
1837 return self._isnan() and other._isnan() and True
1838 if self._isinfinity() or other._isinfinity():
1839 return self._isinfinity() and other._isinfinity() and True
1840 return self._exp == other._exp
1841
1842 def _rescale(self, exp, rounding = None, context=None, watchexp = 1):
1843 """Rescales so that the exponent is exp.
1844
1845 exp = exp to scale to (an integer)
1846 rounding = rounding version
1847 watchexp: if set (default) an error is returned if exp is greater
1848 than Emax or less than Etiny.
1849 """
1850 if context is None:
1851 context = getcontext()
1852
1853 if self._isinfinity():
1854 return context._raise_error(InvalidOperation, 'rescale with an INF')
1855
1856 ans = self._check_nans(context=context)
1857 if ans:
1858 return ans
1859
1860 out = 0
1861
1862 if watchexp and (context.Emax < exp or context.Etiny() > exp):
1863 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1864
1865 if not self:
1866 ans = Decimal(self)
1867 ans._int = (0,)
1868 ans._exp = exp
1869 return ans
1870
1871 diff = self._exp - exp
1872 digits = len(self._int)+diff
1873
1874 if watchexp and digits > context.prec:
1875 return context._raise_error(InvalidOperation, 'Rescale > prec')
1876
1877 tmp = Decimal(self)
1878 tmp._int = (0,)+tmp._int
1879 digits += 1
1880
1881 prevexact = context.flags[Inexact]
1882 if digits < 0:
1883 tmp._exp = -digits + tmp._exp
1884 tmp._int = (0,1)
1885 digits = 1
1886 tmp = tmp._round(digits, rounding, context=context)
1887
1888 if tmp._int[0] == 0 and len(tmp._int) > 1:
1889 tmp._int = tmp._int[1:]
1890 tmp._exp = exp
1891
1892 if tmp and tmp.adjusted() < context.Emin:
1893 context._raise_error(Subnormal)
1894 elif tmp and tmp.adjusted() > context.Emax:
1895 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1896 return tmp
1897
1898 def to_integral(self, rounding = None, context=None):
1899 """Rounds to the nearest integer, without raising inexact, rounded."""
1900 if context is None:
1901 context = getcontext()
1902 ans = self._check_nans(context=context)
1903 if ans:
1904 return ans
1905 if self._exp >= 0:
1906 return self
1907 flags = context._ignore_flags(Rounded, Inexact)
1908 ans = self._rescale(0, rounding, context=context)
1909 context._regard_flags(flags)
1910 return ans
1911
1912 def sqrt(self, context=None):
1913 """Return the square root of self.
1914
1915 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
1916 Should quadratically approach the right answer.
1917 """
1918 if context is None:
1919 context = getcontext()
1920
1921 ans = self._check_nans(context=context)
1922 if ans:
1923 return ans
1924
1925 if not self:
1926 #exponent = self._exp / 2, using round_down.
1927 #if self._exp < 0:
1928 # exp = (self._exp+1) // 2
1929 #else:
1930 exp = (self._exp) // 2
1931 if self._sign == 1:
1932 #sqrt(-0) = -0
1933 return Decimal( (1, (0,), exp))
1934 else:
1935 return Decimal( (0, (0,), exp))
1936
1937 if self._sign == 1:
1938 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
1939
1940 if self._isinfinity():
1941 return Decimal(self)
1942
1943 tmp = Decimal(self)
1944
1945 expadd = tmp._exp / 2
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001946 if tmp._exp & 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001947 tmp._int += (0,)
1948 tmp._exp = 0
1949 else:
1950 tmp._exp = 0
1951
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001952 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001953 flags = context._ignore_all_flags()
1954 firstprec = context.prec
1955 context.prec = 3
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001956 if tmp.adjusted() & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001957 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) )
1958 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
1959 context=context), context=context)
1960 ans._exp -= 1 + tmp.adjusted()/2
1961 else:
1962 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
1963 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
1964 context=context), context=context)
1965 ans._exp -= 1 + tmp.adjusted()/2
1966
1967 #ans is now a linear approximation.
1968
1969 Emax, Emin = context.Emax, context.Emin
Raymond Hettinger99148e72004-07-14 19:56:56 +00001970 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001971
1972 half = Decimal('0.5')
1973
1974 count = 1
1975 maxp = firstprec + 2
1976 rounding = context._set_rounding(ROUND_HALF_EVEN)
1977 while 1:
1978 context.prec = min(2*context.prec - 2, maxp)
1979 ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
1980 context=context), context=context)
1981 if context.prec == maxp:
1982 break
1983
1984 #round to the answer's precision-- the only error can be 1 ulp.
1985 context.prec = firstprec
1986 prevexp = ans.adjusted()
1987 ans = ans._round(context=context)
1988
1989 #Now, check if the other last digits are better.
1990 context.prec = firstprec + 1
1991 # In case we rounded up another digit and we should actually go lower.
1992 if prevexp != ans.adjusted():
1993 ans._int += (0,)
1994 ans._exp -= 1
1995
1996
1997 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
1998 context._set_rounding(ROUND_UP)
1999 if lower.__mul__(lower, context=context) > (tmp):
2000 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
2001
2002 else:
2003 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
2004 context._set_rounding(ROUND_DOWN)
2005 if upper.__mul__(upper, context=context) < tmp:
2006 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
2007
2008 ans._exp += expadd
2009
2010 context.prec = firstprec
2011 context.rounding = rounding
2012 ans = ans._fix(context=context)
2013
2014 rounding = context._set_rounding_decision(NEVER_ROUND)
2015 if not ans.__mul__(ans, context=context) == self:
2016 # Only rounded/inexact if here.
2017 context._regard_flags(flags)
2018 context._raise_error(Rounded)
2019 context._raise_error(Inexact)
2020 else:
2021 #Exact answer, so let's set the exponent right.
2022 #if self._exp < 0:
2023 # exp = (self._exp +1)// 2
2024 #else:
2025 exp = self._exp // 2
2026 context.prec += ans._exp - exp
2027 ans = ans._rescale(exp, context=context)
2028 context.prec = firstprec
2029 context._regard_flags(flags)
2030 context.Emax, context.Emin = Emax, Emin
2031
2032 return ans._fix(context=context)
2033
2034 def max(self, other, context=None):
2035 """Returns the larger value.
2036
2037 like max(self, other) except if one is not a number, returns
2038 NaN (and signals if one is sNaN). Also rounds.
2039 """
2040 if context is None:
2041 context = getcontext()
2042 other = self._convert_other(other)
2043
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002044 # if one operand is a quiet NaN and the other is number, then the
2045 # number is always returned
2046 sn = self._isnan()
2047 on = other._isnan()
2048 if sn or on:
2049 if on == 1 and sn != 2:
2050 return self
2051 if sn == 1 and on != 2:
2052 return other
2053 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002054
2055 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002056 c = self.__cmp__(other)
2057 if c == 0:
2058 # if both operands are finite and equal in numerical value
2059 # then an ordering is applied:
2060 #
2061 # if the signs differ then max returns the operand with the
2062 # positive sign and min returns the operand with the negative sign
2063 #
2064 # if the signs are the same then the exponent is used to select
2065 # the result.
2066 if self._sign != other._sign:
2067 if self._sign:
2068 ans = other
2069 elif self._exp < other._exp and not self._sign:
2070 ans = other
2071 elif self._exp > other._exp and self._sign:
2072 ans = other
2073 elif c == -1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002074 ans = other
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002075 context._rounding_decision == ALWAYS_ROUND
2076 return ans._fix(context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002077
2078 def min(self, other, context=None):
2079 """Returns the smaller value.
2080
2081 like min(self, other) except if one is not a number, returns
2082 NaN (and signals if one is sNaN). Also rounds.
2083 """
2084 if context is None:
2085 context = getcontext()
2086 other = self._convert_other(other)
2087
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002088 # if one operand is a quiet NaN and the other is number, then the
2089 # number is always returned
2090 sn = self._isnan()
2091 on = other._isnan()
2092 if sn or on:
2093 if on == 1 and sn != 2:
2094 return self
2095 if sn == 1 and on != 2:
2096 return other
2097 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002098
2099 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002100 c = self.__cmp__(other)
2101 if c == 0:
2102 # if both operands are finite and equal in numerical value
2103 # then an ordering is applied:
2104 #
2105 # if the signs differ then max returns the operand with the
2106 # positive sign and min returns the operand with the negative sign
2107 #
2108 # if the signs are the same then the exponent is used to select
2109 # the result.
2110 if self._sign != other._sign:
2111 if other._sign:
2112 ans = other
2113 elif self._exp > other._exp and not self._sign:
2114 ans = other
2115 elif self._exp < other._exp and self._sign:
2116 ans = other
2117 elif c == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002118 ans = other
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002119 context._rounding_decision == ALWAYS_ROUND
2120 return ans._fix(context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002121
2122 def _isinteger(self):
2123 """Returns whether self is an integer"""
2124 if self._exp >= 0:
2125 return True
2126 rest = self._int[self._exp:]
2127 return rest == (0,)*len(rest)
2128
2129 def _iseven(self):
2130 """Returns 1 if self is even. Assumes self is an integer."""
2131 if self._exp > 0:
2132 return 1
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002133 return self._int[-1+self._exp] & 1 == 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002134
2135 def adjusted(self):
2136 """Return the adjusted exponent of self"""
2137 try:
2138 return self._exp + len(self._int) - 1
2139 #If NaN or Infinity, self._exp is string
2140 except TypeError:
2141 return 0
2142
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002143 # support for pickling, copy, and deepcopy
2144 def __reduce__(self):
2145 return (self.__class__, (str(self),))
2146
2147 def __copy__(self):
2148 if type(self) == Decimal:
2149 return self # I'm immutable; therefore I am my own clone
2150 return self.__class__(str(self))
2151
2152 def __deepcopy__(self, memo):
2153 if type(self) == Decimal:
2154 return self # My components are also immutable
2155 return self.__class__(str(self))
2156
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002157##### Context class ###########################################
2158
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002159
2160# get rounding method function:
2161rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
2162for name in rounding_functions:
2163 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
2164 globalname = name[1:].upper()
2165 val = globals()[globalname]
2166 Decimal._pick_rounding_function[val] = name
2167
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002168del name, val, globalname, rounding_functions
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002169
2170class Context(object):
2171 """Contains the context for a Decimal instance.
2172
2173 Contains:
2174 prec - precision (for use in rounding, division, square roots..)
2175 rounding - rounding type. (how you round)
2176 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
Raymond Hettingerbf440692004-07-10 14:14:37 +00002177 traps - If traps[exception] = 1, then the exception is
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002178 raised when it is caused. Otherwise, a value is
2179 substituted in.
2180 flags - When an exception is caused, flags[exception] is incremented.
2181 (Whether or not the trap_enabler is set)
2182 Should be reset by user of Decimal instance.
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002183 Emin - Minimum exponent
2184 Emax - Maximum exponent
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002185 capitals - If 1, 1*10^1 is printed as 1E+1.
2186 If 0, printed as 1e1
Raymond Hettingere0f15812004-07-05 05:36:39 +00002187 _clamp - If 1, change exponents if too high (Default 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002188 """
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002189
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002190 def __init__(self, prec=None, rounding=None,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002191 traps=None, flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002192 _rounding_decision=None,
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002193 Emin=None, Emax=None,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002194 capitals=None, _clamp=0,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002195 _ignored_flags=[]):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002196 if not isinstance(flags, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002197 flags = dict([(s,s in flags) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002198 del s
Raymond Hettingerbf440692004-07-10 14:14:37 +00002199 if traps is not None and not isinstance(traps, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002200 traps = dict([(s,s in traps) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002201 del s
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002202 for name, val in locals().items():
2203 if val is None:
2204 setattr(self, name, copy.copy(getattr(DefaultContext, name)))
2205 else:
2206 setattr(self, name, val)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002207 del self.self
2208
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002209 def __repr__(self):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002210 """Show the current context."""
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002211 s = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002212 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
2213 s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
2214 s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002215 return ', '.join(s) + ')'
2216
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002217 def clear_flags(self):
2218 """Reset all flags to zero"""
2219 for flag in self.flags:
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002220 self.flags[flag] = 0
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002221
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002222 def _shallow_copy(self):
2223 """Returns a shallow copy from self."""
Raymond Hettingerbf440692004-07-10 14:14:37 +00002224 nc = Context(self.prec, self.rounding, self.traps, self.flags,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002225 self._rounding_decision, self.Emin, self.Emax,
2226 self.capitals, self._clamp, self._ignored_flags)
2227 return nc
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002228
2229 def copy(self):
2230 """Returns a deep copy from self."""
2231 nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
2232 self._rounding_decision, self.Emin, self.Emax,
2233 self.capitals, self._clamp, self._ignored_flags)
2234 return nc
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002235 __copy__ = copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002236
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002237 def _raise_error(self, condition, explanation = None, *args):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002238 """Handles an error
2239
2240 If the flag is in _ignored_flags, returns the default response.
2241 Otherwise, it increments the flag, then, if the corresponding
2242 trap_enabler is set, it reaises the exception. Otherwise, it returns
2243 the default value after incrementing the flag.
2244 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002245 error = _condition_map.get(condition, condition)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002246 if error in self._ignored_flags:
2247 #Don't touch the flag
2248 return error().handle(self, *args)
2249
2250 self.flags[error] += 1
Raymond Hettingerbf440692004-07-10 14:14:37 +00002251 if not self.traps[error]:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002252 #The errors define how to handle themselves.
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002253 return condition().handle(self, *args)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002254
2255 # Errors should only be risked on copies of the context
2256 #self._ignored_flags = []
2257 raise error, explanation
2258
2259 def _ignore_all_flags(self):
2260 """Ignore all flags, if they are raised"""
Raymond Hettingerfed52962004-07-14 15:41:57 +00002261 return self._ignore_flags(*_signals)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002262
2263 def _ignore_flags(self, *flags):
2264 """Ignore the flags, if they are raised"""
2265 # Do not mutate-- This way, copies of a context leave the original
2266 # alone.
2267 self._ignored_flags = (self._ignored_flags + list(flags))
2268 return list(flags)
2269
2270 def _regard_flags(self, *flags):
2271 """Stop ignoring the flags, if they are raised"""
2272 if flags and isinstance(flags[0], (tuple,list)):
2273 flags = flags[0]
2274 for flag in flags:
2275 self._ignored_flags.remove(flag)
2276
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002277 def __hash__(self):
2278 """A Context cannot be hashed."""
2279 # We inherit object.__hash__, so we must deny this explicitly
2280 raise TypeError, "Cannot hash a Context."
2281
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002282 def Etiny(self):
2283 """Returns Etiny (= Emin - prec + 1)"""
2284 return int(self.Emin - self.prec + 1)
2285
2286 def Etop(self):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002287 """Returns maximum exponent (= Emax - prec + 1)"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002288 return int(self.Emax - self.prec + 1)
2289
2290 def _set_rounding_decision(self, type):
2291 """Sets the rounding decision.
2292
2293 Sets the rounding decision, and returns the current (previous)
2294 rounding decision. Often used like:
2295
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002296 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002297 # That so you don't change the calling context
2298 # if an error occurs in the middle (say DivisionImpossible is raised).
2299
2300 rounding = context._set_rounding_decision(NEVER_ROUND)
2301 instance = instance / Decimal(2)
2302 context._set_rounding_decision(rounding)
2303
2304 This will make it not round for that operation.
2305 """
2306
2307 rounding = self._rounding_decision
2308 self._rounding_decision = type
2309 return rounding
2310
2311 def _set_rounding(self, type):
2312 """Sets the rounding type.
2313
2314 Sets the rounding type, and returns the current (previous)
2315 rounding type. Often used like:
2316
2317 context = context.copy()
2318 # so you don't change the calling context
2319 # if an error occurs in the middle.
2320 rounding = context._set_rounding(ROUND_UP)
2321 val = self.__sub__(other, context=context)
2322 context._set_rounding(rounding)
2323
2324 This will make it round up for that operation.
2325 """
2326 rounding = self.rounding
2327 self.rounding= type
2328 return rounding
2329
Raymond Hettingerfed52962004-07-14 15:41:57 +00002330 def create_decimal(self, num='0'):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002331 """Creates a new Decimal instance but using self as context."""
2332 d = Decimal(num, context=self)
2333 return d._fix(context=self)
2334
2335 #Methods
2336 def abs(self, a):
2337 """Returns the absolute value of the operand.
2338
2339 If the operand is negative, the result is the same as using the minus
2340 operation on the operand. Otherwise, the result is the same as using
2341 the plus operation on the operand.
2342
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002343 >>> ExtendedContext.abs(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002344 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002345 >>> ExtendedContext.abs(Decimal('-100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002346 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002347 >>> ExtendedContext.abs(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002348 Decimal("101.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002349 >>> ExtendedContext.abs(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002350 Decimal("101.5")
2351 """
2352 return a.__abs__(context=self)
2353
2354 def add(self, a, b):
2355 """Return the sum of the two operands.
2356
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002357 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002358 Decimal("19.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002359 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002360 Decimal("1.02E+4")
2361 """
2362 return a.__add__(b, context=self)
2363
2364 def _apply(self, a):
2365 return str(a._fix(context=self))
2366
2367 def compare(self, a, b):
2368 """Compares values numerically.
2369
2370 If the signs of the operands differ, a value representing each operand
2371 ('-1' if the operand is less than zero, '0' if the operand is zero or
2372 negative zero, or '1' if the operand is greater than zero) is used in
2373 place of that operand for the comparison instead of the actual
2374 operand.
2375
2376 The comparison is then effected by subtracting the second operand from
2377 the first and then returning a value according to the result of the
2378 subtraction: '-1' if the result is less than zero, '0' if the result is
2379 zero or negative zero, or '1' if the result is greater than zero.
2380
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002381 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002382 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002383 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002384 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002385 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002386 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002387 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002388 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002389 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002390 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002391 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002392 Decimal("-1")
2393 """
2394 return a.compare(b, context=self)
2395
2396 def divide(self, a, b):
2397 """Decimal division in a specified context.
2398
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002399 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002400 Decimal("0.333333333")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002401 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002402 Decimal("0.666666667")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002403 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002404 Decimal("2.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002405 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002406 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002407 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002408 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002409 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002410 Decimal("4.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002411 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002412 Decimal("1.20")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002413 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002414 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002415 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002416 Decimal("1000")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002417 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002418 Decimal("1.20E+6")
2419 """
2420 return a.__div__(b, context=self)
2421
2422 def divide_int(self, a, b):
2423 """Divides two numbers and returns the integer part of the result.
2424
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002425 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002426 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002427 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002428 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002429 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002430 Decimal("3")
2431 """
2432 return a.__floordiv__(b, context=self)
2433
2434 def divmod(self, a, b):
2435 return a.__divmod__(b, context=self)
2436
2437 def max(self, a,b):
2438 """max compares two values numerically and returns the maximum.
2439
2440 If either operand is a NaN then the general rules apply.
2441 Otherwise, the operands are compared as as though by the compare
2442 operation. If they are numerically equal then the left-hand operand
2443 is chosen as the result. Otherwise the maximum (closer to positive
2444 infinity) of the two operands is chosen as the result.
2445
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002446 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002447 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002448 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002449 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002450 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002451 Decimal("1")
2452 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
2453 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002454 """
2455 return a.max(b, context=self)
2456
2457 def min(self, a,b):
2458 """min compares two values numerically and returns the minimum.
2459
2460 If either operand is a NaN then the general rules apply.
2461 Otherwise, the operands are compared as as though by the compare
2462 operation. If they are numerically equal then the left-hand operand
2463 is chosen as the result. Otherwise the minimum (closer to negative
2464 infinity) of the two operands is chosen as the result.
2465
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002466 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002467 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002468 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002469 Decimal("-10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002470 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002471 Decimal("1.0")
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002472 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
2473 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002474 """
2475 return a.min(b, context=self)
2476
2477 def minus(self, a):
2478 """Minus corresponds to unary prefix minus in Python.
2479
2480 The operation is evaluated using the same rules as subtract; the
2481 operation minus(a) is calculated as subtract('0', a) where the '0'
2482 has the same exponent as the operand.
2483
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002484 >>> ExtendedContext.minus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002485 Decimal("-1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002486 >>> ExtendedContext.minus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002487 Decimal("1.3")
2488 """
2489 return a.__neg__(context=self)
2490
2491 def multiply(self, a, b):
2492 """multiply multiplies two operands.
2493
2494 If either operand is a special value then the general rules apply.
2495 Otherwise, the operands are multiplied together ('long multiplication'),
2496 resulting in a number which may be as long as the sum of the lengths
2497 of the two operands.
2498
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002499 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002500 Decimal("3.60")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002501 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002502 Decimal("21")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002503 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002504 Decimal("0.72")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002505 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002506 Decimal("-0.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002507 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002508 Decimal("4.28135971E+11")
2509 """
2510 return a.__mul__(b, context=self)
2511
2512 def normalize(self, a):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002513 """normalize reduces an operand to its simplest form.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002514
2515 Essentially a plus operation with all trailing zeros removed from the
2516 result.
2517
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002518 >>> ExtendedContext.normalize(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002519 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002520 >>> ExtendedContext.normalize(Decimal('-2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002521 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002522 >>> ExtendedContext.normalize(Decimal('1.200'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002523 Decimal("1.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002524 >>> ExtendedContext.normalize(Decimal('-120'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002525 Decimal("-1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002526 >>> ExtendedContext.normalize(Decimal('120.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002527 Decimal("1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002528 >>> ExtendedContext.normalize(Decimal('0.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002529 Decimal("0")
2530 """
2531 return a.normalize(context=self)
2532
2533 def plus(self, a):
2534 """Plus corresponds to unary prefix plus in Python.
2535
2536 The operation is evaluated using the same rules as add; the
2537 operation plus(a) is calculated as add('0', a) where the '0'
2538 has the same exponent as the operand.
2539
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002540 >>> ExtendedContext.plus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002541 Decimal("1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002542 >>> ExtendedContext.plus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002543 Decimal("-1.3")
2544 """
2545 return a.__pos__(context=self)
2546
2547 def power(self, a, b, modulo=None):
2548 """Raises a to the power of b, to modulo if given.
2549
2550 The right-hand operand must be a whole number whose integer part (after
2551 any exponent has been applied) has no more than 9 digits and whose
2552 fractional part (if any) is all zeros before any rounding. The operand
2553 may be positive, negative, or zero; if negative, the absolute value of
2554 the power is used, and the left-hand operand is inverted (divided into
2555 1) before use.
2556
2557 If the increased precision needed for the intermediate calculations
2558 exceeds the capabilities of the implementation then an Invalid operation
2559 condition is raised.
2560
2561 If, when raising to a negative power, an underflow occurs during the
2562 division into 1, the operation is not halted at that point but
2563 continues.
2564
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002565 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002566 Decimal("8")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002567 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002568 Decimal("0.125")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002569 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002570 Decimal("69.7575744")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002571 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002572 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002573 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002574 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002575 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002576 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002577 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002578 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002579 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002580 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002581 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002582 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002583 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002584 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002585 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002586 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002587 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002588 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002589 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002590 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002591 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002592 Decimal("NaN")
2593 """
2594 return a.__pow__(b, modulo, context=self)
2595
2596 def quantize(self, a, b):
2597 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
2598
2599 The coefficient of the result is derived from that of the left-hand
2600 operand. It may be rounded using the current rounding setting (if the
2601 exponent is being increased), multiplied by a positive power of ten (if
2602 the exponent is being decreased), or is unchanged (if the exponent is
2603 already equal to that of the right-hand operand).
2604
2605 Unlike other operations, if the length of the coefficient after the
2606 quantize operation would be greater than precision then an Invalid
2607 operation condition is raised. This guarantees that, unless there is an
2608 error condition, the exponent of the result of a quantize is always
2609 equal to that of the right-hand operand.
2610
2611 Also unlike other operations, quantize will never raise Underflow, even
2612 if the result is subnormal and inexact.
2613
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002614 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002615 Decimal("2.170")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002616 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002617 Decimal("2.17")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002618 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002619 Decimal("2.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002620 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002621 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002622 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002623 Decimal("0E+1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002624 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002625 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002626 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002627 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002628 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002629 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002630 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002631 Decimal("-0E+5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002632 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002633 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002634 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002635 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002636 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002637 Decimal("217.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002638 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002639 Decimal("217")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002640 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002641 Decimal("2.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002642 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002643 Decimal("2E+2")
2644 """
2645 return a.quantize(b, context=self)
2646
2647 def remainder(self, a, b):
2648 """Returns the remainder from integer division.
2649
2650 The result is the residue of the dividend after the operation of
2651 calculating integer division as described for divide-integer, rounded to
2652 precision digits if necessary. The sign of the result, if non-zero, is
2653 the same as that of the original dividend.
2654
2655 This operation will fail under the same conditions as integer division
2656 (that is, if integer division on the same two operands would fail, the
2657 remainder cannot be calculated).
2658
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002659 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002660 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002661 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002662 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002663 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002664 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002665 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002666 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002667 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002668 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002669 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002670 Decimal("1.0")
2671 """
2672 return a.__mod__(b, context=self)
2673
2674 def remainder_near(self, a, b):
2675 """Returns to be "a - b * n", where n is the integer nearest the exact
2676 value of "x / b" (if two integers are equally near then the even one
2677 is chosen). If the result is equal to 0 then its sign will be the
2678 sign of a.
2679
2680 This operation will fail under the same conditions as integer division
2681 (that is, if integer division on the same two operands would fail, the
2682 remainder cannot be calculated).
2683
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002684 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002685 Decimal("-0.9")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002686 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002687 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002688 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002689 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002690 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002691 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002692 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002693 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002694 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002695 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002696 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002697 Decimal("-0.3")
2698 """
2699 return a.remainder_near(b, context=self)
2700
2701 def same_quantum(self, a, b):
2702 """Returns True if the two operands have the same exponent.
2703
2704 The result is never affected by either the sign or the coefficient of
2705 either operand.
2706
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002707 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002708 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002709 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002710 True
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002711 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002712 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002713 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002714 True
2715 """
2716 return a.same_quantum(b)
2717
2718 def sqrt(self, a):
2719 """Returns the square root of a non-negative number to context precision.
2720
2721 If the result must be inexact, it is rounded using the round-half-even
2722 algorithm.
2723
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002724 >>> ExtendedContext.sqrt(Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002725 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002726 >>> ExtendedContext.sqrt(Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002727 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002728 >>> ExtendedContext.sqrt(Decimal('0.39'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002729 Decimal("0.624499800")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002730 >>> ExtendedContext.sqrt(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002731 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002732 >>> ExtendedContext.sqrt(Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002733 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002734 >>> ExtendedContext.sqrt(Decimal('1.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002735 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002736 >>> ExtendedContext.sqrt(Decimal('1.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002737 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002738 >>> ExtendedContext.sqrt(Decimal('7'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002739 Decimal("2.64575131")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002740 >>> ExtendedContext.sqrt(Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002741 Decimal("3.16227766")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002742 >>> ExtendedContext.prec
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002743 9
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002744 """
2745 return a.sqrt(context=self)
2746
2747 def subtract(self, a, b):
2748 """Return the sum of the two operands.
2749
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002750 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002751 Decimal("0.23")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002752 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002753 Decimal("0.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002754 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002755 Decimal("-0.77")
2756 """
2757 return a.__sub__(b, context=self)
2758
2759 def to_eng_string(self, a):
2760 """Converts a number to a string, using scientific notation.
2761
2762 The operation is not affected by the context.
2763 """
2764 return a.to_eng_string(context=self)
2765
2766 def to_sci_string(self, a):
2767 """Converts a number to a string, using scientific notation.
2768
2769 The operation is not affected by the context.
2770 """
2771 return a.__str__(context=self)
2772
2773 def to_integral(self, a):
2774 """Rounds to an integer.
2775
2776 When the operand has a negative exponent, the result is the same
2777 as using the quantize() operation using the given operand as the
2778 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2779 of the operand as the precision setting, except that no flags will
2780 be set. The rounding mode is taken from the context.
2781
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002782 >>> ExtendedContext.to_integral(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002783 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002784 >>> ExtendedContext.to_integral(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002785 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002786 >>> ExtendedContext.to_integral(Decimal('100.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002787 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002788 >>> ExtendedContext.to_integral(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002789 Decimal("102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002790 >>> ExtendedContext.to_integral(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002791 Decimal("-102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002792 >>> ExtendedContext.to_integral(Decimal('10E+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002793 Decimal("1.0E+6")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002794 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002795 Decimal("7.89E+77")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002796 >>> ExtendedContext.to_integral(Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002797 Decimal("-Infinity")
2798 """
2799 return a.to_integral(context=self)
2800
2801class _WorkRep(object):
2802 __slots__ = ('sign','int','exp')
2803 # sign: -1 None 1
2804 # int: list
2805 # exp: None, int, or string
2806
2807 def __init__(self, value=None):
2808 if value is None:
2809 self.sign = None
2810 self.int = []
2811 self.exp = None
2812 if isinstance(value, Decimal):
2813 if value._sign:
2814 self.sign = -1
2815 else:
2816 self.sign = 1
2817 self.int = list(value._int)
2818 self.exp = value._exp
2819 if isinstance(value, tuple):
2820 self.sign = value[0]
2821 self.int = value[1]
2822 self.exp = value[2]
2823
2824 def __repr__(self):
2825 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2826
2827 __str__ = __repr__
2828
2829 def __neg__(self):
2830 if self.sign == 1:
2831 return _WorkRep( (-1, self.int, self.exp) )
2832 else:
2833 return _WorkRep( (1, self.int, self.exp) )
2834
2835 def __abs__(self):
2836 if self.sign == -1:
2837 return -self
2838 else:
2839 return self
2840
2841 def __cmp__(self, other):
2842 if self.exp != other.exp:
2843 raise ValueError("Operands not normalized: %r, %r" % (self, other))
2844 if self.sign != other.sign:
2845 if self.sign == -1:
2846 return -1
2847 else:
2848 return 1
2849 if self.sign == -1:
2850 direction = -1
2851 else:
2852 direction = 1
2853 int1 = self.int
2854 int2 = other.int
2855 if len(int1) > len(int2):
2856 return direction * 1
2857 if len(int1) < len(int2):
2858 return direction * -1
2859 for i in xrange(len(int1)):
2860 if int1[i] > int2[i]:
2861 return direction * 1
2862 if int1[i] < int2[i]:
2863 return direction * -1
2864 return 0
2865
2866 def _increment(self):
2867 curspot = len(self.int) - 1
2868 self.int[curspot]+= 1
2869 while (self.int[curspot] >= 10):
2870 self.int[curspot] -= 10
2871 if curspot == 0:
2872 self.int[0:0] = [1]
2873 break
2874 self.int[curspot-1] += 1
2875 curspot -= 1
2876
2877 def subtract(self, alist):
2878 """Subtract a list from the current int (in place).
2879
2880 It is assured that (len(list) = len(self.int) and list < self.int) or
2881 len(list) = len(self.int)-1
2882 (i.e. that int(join(list)) < int(join(self.int)))
2883 """
2884
2885 selfint = self.int
2886 selfint.reverse()
2887 alist.reverse()
2888
2889 carry = 0
2890 for x in xrange(len(alist)):
2891 selfint[x] -= alist[x] + carry
2892 if selfint[x] < 0:
2893 carry = 1
2894 selfint[x] += 10
2895 else:
Tim Peters4e0e1b62004-07-07 20:54:48 +00002896 carry = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002897 if carry:
2898 selfint[x+1] -= 1
2899 last = len(selfint)-1
2900 while len(selfint) > 1 and selfint[last] == 0:
2901 last -= 1
2902 if last == 0:
2903 break
2904 selfint[last+1:]=[]
2905 selfint.reverse()
2906 alist.reverse()
2907 return
2908
2909
2910def _normalize(op1, op2, shouldround = 0, prec = 0):
2911 """Normalizes op1, op2 to have the same exp and length of coefficient.
2912
2913 Done during addition.
2914 """
2915 # Yes, the exponent is a long, but the difference between exponents
2916 # must be an int-- otherwise you'd get a big memory problem.
2917 numdigits = int(op1.exp - op2.exp)
2918 if numdigits < 0:
2919 numdigits = -numdigits
2920 tmp = op2
2921 other = op1
2922 else:
2923 tmp = op1
2924 other = op2
2925
2926 if shouldround and numdigits > len(other.int) + prec + 1 -len(tmp.int):
2927 # If the difference in adjusted exps is > prec+1, we know
2928 # other is insignificant, so might as well put a 1 after the precision.
2929 # (since this is only for addition.) Also stops MemoryErrors.
2930
2931 extend = prec + 2 -len(tmp.int)
2932 if extend <= 0:
2933 extend = 1
2934 tmp.int.extend([0]*extend)
2935 tmp.exp -= extend
2936 other.int[:] = [0]*(len(tmp.int)-1)+[1]
2937 other.exp = tmp.exp
2938 return op1, op2
2939
2940 tmp.int.extend([0] * numdigits)
2941 tmp.exp = tmp.exp - numdigits
2942 numdigits = len(op1.int) - len(op2.int)
2943 # numdigits != 0 => They have the same exponent, but not the same length
2944 # of the coefficient.
2945 if numdigits < 0:
2946 numdigits = -numdigits
2947 tmp = op1
2948 else:
2949 tmp = op2
2950 tmp.int[0:0] = [0] * numdigits
2951 return op1, op2
2952
2953def _adjust_coefficients(op1, op2):
2954 """Adjust op1, op2 so that op2.int+[0] > op1.int >= op2.int.
2955
2956 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2957
2958 Used on _WorkRep instances during division.
2959 """
2960 adjust = 0
2961 #If op1 is smaller, get it to same size
2962 if len(op2.int) > len(op1.int):
2963 diff = len(op2.int) - len(op1.int)
2964 op1.int.extend([0]*diff)
2965 op1.exp -= diff
2966 adjust = diff
2967
2968 #Same length, wrong order
2969 if len(op1.int) == len(op2.int) and op1.int < op2.int:
2970 op1.int.append(0)
2971 op1.exp -= 1
2972 adjust+= 1
2973 return op1, op2, adjust
2974
2975 if len(op1.int) > len(op2.int) + 1:
2976 diff = len(op1.int) - len(op2.int) - 1
2977 op2.int.extend([0]*diff)
2978 op2.exp -= diff
2979 adjust -= diff
2980
2981 if len(op1.int) == len(op2.int)+1 and op1.int > op2.int:
2982
2983 op2.int.append(0)
2984 op2.exp -= 1
2985 adjust -= 1
2986 return op1, op2, adjust
2987
2988##### Helper Functions ########################################
2989
2990_infinity_map = {
2991 'inf' : 1,
2992 'infinity' : 1,
2993 '+inf' : 1,
2994 '+infinity' : 1,
2995 '-inf' : -1,
2996 '-infinity' : -1
2997}
2998
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002999def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003000 """Determines whether a string or float is infinity.
3001
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00003002 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003003 """
3004 num = str(num).lower()
3005 return _infinity_map.get(num, 0)
3006
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00003007def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003008 """Determines whether a string or float is NaN
3009
3010 (1, sign, diagnostic info as string) => NaN
3011 (2, sign, diagnostic info as string) => sNaN
3012 0 => not a NaN
3013 """
3014 num = str(num).lower()
3015 if not num:
3016 return 0
3017
3018 #get the sign, get rid of trailing [+-]
3019 sign = 0
3020 if num[0] == '+':
3021 num = num[1:]
3022 elif num[0] == '-': #elif avoids '+-nan'
3023 num = num[1:]
3024 sign = 1
3025
3026 if num.startswith('nan'):
3027 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
3028 return 0
3029 return (1, sign, num[3:].lstrip('0'))
3030 if num.startswith('snan'):
3031 if len(num) > 4 and not num[4:].isdigit():
3032 return 0
3033 return (2, sign, num[4:].lstrip('0'))
3034 return 0
3035
3036
3037##### Setup Specific Contexts ################################
3038
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003039# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00003040# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003041
3042DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003043 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003044 traps=[DivisionByZero, Overflow, InvalidOperation],
3045 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003046 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00003047 Emax=999999999,
3048 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00003049 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003050)
3051
3052# Pre-made alternate contexts offered by the specification
3053# Don't change these; the user should be able to select these
3054# contexts and be able to reproduce results from other implementations
3055# of the spec.
3056
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003057BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003058 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003059 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
3060 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003061)
3062
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003063ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003064 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003065 traps=[],
3066 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003067)
3068
3069
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00003070##### Useful Constants (internal use only) ####################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003071
3072#Reusable defaults
3073Inf = Decimal('Inf')
3074negInf = Decimal('-Inf')
3075
3076#Infsign[sign] is infinity w/ that sign
3077Infsign = (Inf, negInf)
3078
3079NaN = Decimal('NaN')
3080
3081
3082##### crud for parsing strings #################################
3083import re
3084
3085# There's an optional sign at the start, and an optional exponent
3086# at the end. The exponent has an optional sign and at least one
3087# digit. In between, must have either at least one digit followed
3088# by an optional fraction, or a decimal point followed by at least
3089# one digit. Yuck.
3090
3091_parser = re.compile(r"""
3092# \s*
3093 (?P<sign>[-+])?
3094 (
3095 (?P<int>\d+) (\. (?P<frac>\d*))?
3096 |
3097 \. (?P<onlyfrac>\d+)
3098 )
3099 ([eE](?P<exp>[-+]? \d+))?
3100# \s*
3101 $
3102""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
3103
3104del re
3105
3106# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
3107
3108def _string2exact(s):
3109 m = _parser(s)
3110 if m is None:
3111 raise ValueError("invalid literal for Decimal: %r" % s)
3112
3113 if m.group('sign') == "-":
3114 sign = 1
3115 else:
3116 sign = 0
3117
3118 exp = m.group('exp')
3119 if exp is None:
3120 exp = 0
3121 else:
3122 exp = int(exp)
3123
3124 intpart = m.group('int')
3125 if intpart is None:
3126 intpart = ""
3127 fracpart = m.group('onlyfrac')
3128 else:
3129 fracpart = m.group('frac')
3130 if fracpart is None:
3131 fracpart = ""
3132
3133 exp -= len(fracpart)
3134
3135 mantissa = intpart + fracpart
3136 tmp = map(int, mantissa)
3137 backup = tmp
3138 while tmp and tmp[0] == 0:
3139 del tmp[0]
3140
3141 # It's a zero
3142 if not tmp:
3143 if backup:
3144 return (sign, tuple(backup), exp)
3145 return (sign, (0,), exp)
3146 mantissa = tuple(tmp)
3147
3148 return (sign, mantissa, exp)
3149
3150
3151if __name__ == '__main__':
3152 import doctest, sys
3153 doctest.testmod(sys.modules[__name__])