blob: 210db523f9bd3e96fbb60855024e251b4b584ab1 [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
Raymond Hettingereb260842005-06-07 18:52:34 +0000137import copy as _copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000138
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000139#Rounding
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000140ROUND_DOWN = 'ROUND_DOWN'
141ROUND_HALF_UP = 'ROUND_HALF_UP'
142ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
143ROUND_CEILING = 'ROUND_CEILING'
144ROUND_FLOOR = 'ROUND_FLOOR'
145ROUND_UP = 'ROUND_UP'
146ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000147
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +0000148#Rounding decision (not part of the public API)
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000149NEVER_ROUND = 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY
150ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000151
152#Errors
153
154class DecimalException(ArithmeticError):
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000155 """Base exception class.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000156
157 Used exceptions derive from this.
158 If an exception derives from another exception besides this (such as
159 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
160 called if the others are present. This isn't actually used for
161 anything, though.
162
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000163 handle -- Called when context._raise_error is called and the
164 trap_enabler is set. First argument is self, second is the
165 context. More arguments can be given, those being after
166 the explanation in _raise_error (For example,
167 context._raise_error(NewError, '(-x)!', self._sign) would
168 call NewError().handle(context, self._sign).)
169
170 To define a new exception, it should be sufficient to have it derive
171 from DecimalException.
172 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000173 def handle(self, context, *args):
174 pass
175
176
177class Clamped(DecimalException):
178 """Exponent of a 0 changed to fit bounds.
179
180 This occurs and signals clamped if the exponent of a result has been
181 altered in order to fit the constraints of a specific concrete
182 representation. This may occur when the exponent of a zero result would
183 be outside the bounds of a representation, or when a large normal
184 number would have an encoded exponent that cannot be represented. In
185 this latter case, the exponent is reduced to fit and the corresponding
186 number of zero digits are appended to the coefficient ("fold-down").
187 """
188
189
190class InvalidOperation(DecimalException):
191 """An invalid operation was performed.
192
193 Various bad things cause this:
194
195 Something creates a signaling NaN
196 -INF + INF
197 0 * (+-)INF
198 (+-)INF / (+-)INF
199 x % 0
200 (+-)INF % x
201 x._rescale( non-integer )
202 sqrt(-x) , x > 0
203 0 ** 0
204 x ** (non-integer)
205 x ** (+-)INF
206 An operand is invalid
207 """
208 def handle(self, context, *args):
209 if args:
210 if args[0] == 1: #sNaN, must drop 's' but keep diagnostics
211 return Decimal( (args[1]._sign, args[1]._int, 'n') )
212 return NaN
213
214class ConversionSyntax(InvalidOperation):
215 """Trying to convert badly formed string.
216
217 This occurs and signals invalid-operation if an string is being
218 converted to a number and it does not conform to the numeric string
219 syntax. The result is [0,qNaN].
220 """
221
222 def handle(self, context, *args):
223 return (0, (0,), 'n') #Passed to something which uses a tuple.
224
225class DivisionByZero(DecimalException, ZeroDivisionError):
226 """Division by 0.
227
228 This occurs and signals division-by-zero if division of a finite number
229 by zero was attempted (during a divide-integer or divide operation, or a
230 power operation with negative right-hand operand), and the dividend was
231 not zero.
232
233 The result of the operation is [sign,inf], where sign is the exclusive
234 or of the signs of the operands for divide, or is 1 for an odd power of
235 -0, for power.
236 """
237
238 def handle(self, context, sign, double = None, *args):
239 if double is not None:
240 return (Infsign[sign],)*2
241 return Infsign[sign]
242
243class DivisionImpossible(InvalidOperation):
244 """Cannot perform the division adequately.
245
246 This occurs and signals invalid-operation if the integer result of a
247 divide-integer or remainder operation had too many digits (would be
248 longer than precision). The result is [0,qNaN].
249 """
250
251 def handle(self, context, *args):
252 return (NaN, NaN)
253
254class DivisionUndefined(InvalidOperation, ZeroDivisionError):
255 """Undefined result of division.
256
257 This occurs and signals invalid-operation if division by zero was
258 attempted (during a divide-integer, divide, or remainder operation), and
259 the dividend is also zero. The result is [0,qNaN].
260 """
261
262 def handle(self, context, tup=None, *args):
263 if tup is not None:
264 return (NaN, NaN) #for 0 %0, 0 // 0
265 return NaN
266
267class Inexact(DecimalException):
268 """Had to round, losing information.
269
270 This occurs and signals inexact whenever the result of an operation is
271 not exact (that is, it needed to be rounded and any discarded digits
272 were non-zero), or if an overflow or underflow condition occurs. The
273 result in all cases is unchanged.
274
275 The inexact signal may be tested (or trapped) to determine if a given
276 operation (or sequence of operations) was inexact.
277 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000278 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000279
280class InvalidContext(InvalidOperation):
281 """Invalid context. Unknown rounding, for example.
282
283 This occurs and signals invalid-operation if an invalid context was
284 detected during an operation. This can occur if contexts are not checked
285 on creation and either the precision exceeds the capability of the
286 underlying concrete representation or an unknown or unsupported rounding
287 was specified. These aspects of the context need only be checked when
288 the values are required to be used. The result is [0,qNaN].
289 """
290
291 def handle(self, context, *args):
292 return NaN
293
294class Rounded(DecimalException):
295 """Number got rounded (not necessarily changed during rounding).
296
297 This occurs and signals rounded whenever the result of an operation is
298 rounded (that is, some zero or non-zero digits were discarded from the
299 coefficient), or if an overflow or underflow condition occurs. The
300 result in all cases is unchanged.
301
302 The rounded signal may be tested (or trapped) to determine if a given
303 operation (or sequence of operations) caused a loss of precision.
304 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000305 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000306
307class Subnormal(DecimalException):
308 """Exponent < Emin before rounding.
309
310 This occurs and signals subnormal whenever the result of a conversion or
311 operation is subnormal (that is, its adjusted exponent is less than
312 Emin, before any rounding). The result in all cases is unchanged.
313
314 The subnormal signal may be tested (or trapped) to determine if a given
315 or operation (or sequence of operations) yielded a subnormal result.
316 """
317 pass
318
319class Overflow(Inexact, Rounded):
320 """Numerical overflow.
321
322 This occurs and signals overflow if the adjusted exponent of a result
323 (from a conversion or from an operation that is not an attempt to divide
324 by zero), after rounding, would be greater than the largest value that
325 can be handled by the implementation (the value Emax).
326
327 The result depends on the rounding mode:
328
329 For round-half-up and round-half-even (and for round-half-down and
330 round-up, if implemented), the result of the operation is [sign,inf],
331 where sign is the sign of the intermediate result. For round-down, the
332 result is the largest finite number that can be represented in the
333 current precision, with the sign of the intermediate result. For
334 round-ceiling, the result is the same as for round-down if the sign of
335 the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
336 the result is the same as for round-down if the sign of the intermediate
337 result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
338 will also be raised.
339 """
340
341 def handle(self, context, sign, *args):
342 if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
343 ROUND_HALF_DOWN, ROUND_UP):
344 return Infsign[sign]
345 if sign == 0:
346 if context.rounding == ROUND_CEILING:
347 return Infsign[sign]
348 return Decimal((sign, (9,)*context.prec,
349 context.Emax-context.prec+1))
350 if sign == 1:
351 if context.rounding == ROUND_FLOOR:
352 return Infsign[sign]
353 return Decimal( (sign, (9,)*context.prec,
354 context.Emax-context.prec+1))
355
356
357class Underflow(Inexact, Rounded, Subnormal):
358 """Numerical underflow with result rounded to 0.
359
360 This occurs and signals underflow if a result is inexact and the
361 adjusted exponent of the result would be smaller (more negative) than
362 the smallest value that can be handled by the implementation (the value
363 Emin). That is, the result is both inexact and subnormal.
364
365 The result after an underflow will be a subnormal number rounded, if
366 necessary, so that its exponent is not less than Etiny. This may result
367 in 0 with the sign of the intermediate result and an exponent of Etiny.
368
369 In all cases, Inexact, Rounded, and Subnormal will also be raised.
370 """
371
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000372# List of public traps and flags
Raymond Hettingerfed52962004-07-14 15:41:57 +0000373_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000374 Underflow, InvalidOperation, Subnormal]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000375
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000376# Map conditions (per the spec) to signals
377_condition_map = {ConversionSyntax:InvalidOperation,
378 DivisionImpossible:InvalidOperation,
379 DivisionUndefined:InvalidOperation,
380 InvalidContext:InvalidOperation}
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000381
382##### Context Functions #######################################
383
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000384# The getcontext() and setcontext() function manage access to a thread-local
385# current context. Py2.4 offers direct support for thread locals. If that
386# is not available, use threading.currentThread() which is slower but will
Raymond Hettinger7e71fa52004-12-18 19:07:19 +0000387# work for older Pythons. If threads are not part of the build, create a
388# mock threading object with threading.local() returning the module namespace.
389
390try:
391 import threading
392except ImportError:
393 # Python was compiled without threads; create a mock object instead
394 import sys
395 class MockThreading:
396 def local(self, sys=sys):
397 return sys.modules[__name__]
398 threading = MockThreading()
399 del sys, MockThreading
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000400
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000401try:
402 threading.local
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000403
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000404except AttributeError:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000405
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000406 #To fix reloading, force it to create a new context
407 #Old contexts have different exceptions in their dicts, making problems.
408 if hasattr(threading.currentThread(), '__decimal_context__'):
409 del threading.currentThread().__decimal_context__
410
411 def setcontext(context):
412 """Set this thread's context to context."""
413 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000414 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000415 context.clear_flags()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000416 threading.currentThread().__decimal_context__ = context
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000417
418 def getcontext():
419 """Returns this thread's context.
420
421 If this thread does not yet have a context, returns
422 a new context and sets this thread's context.
423 New contexts are copies of DefaultContext.
424 """
425 try:
426 return threading.currentThread().__decimal_context__
427 except AttributeError:
428 context = Context()
429 threading.currentThread().__decimal_context__ = context
430 return context
431
432else:
433
434 local = threading.local()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000435 if hasattr(local, '__decimal_context__'):
436 del local.__decimal_context__
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000437
438 def getcontext(_local=local):
439 """Returns this thread's context.
440
441 If this thread does not yet have a context, returns
442 a new context and sets this thread's context.
443 New contexts are copies of DefaultContext.
444 """
445 try:
446 return _local.__decimal_context__
447 except AttributeError:
448 context = Context()
449 _local.__decimal_context__ = context
450 return context
451
452 def setcontext(context, _local=local):
453 """Set this thread's context to context."""
454 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000455 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000456 context.clear_flags()
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000457 _local.__decimal_context__ = context
458
459 del threading, local # Don't contaminate the namespace
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000460
461
462##### Decimal class ###########################################
463
464class Decimal(object):
465 """Floating point class for decimal arithmetic."""
466
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000467 __slots__ = ('_exp','_int','_sign', '_is_special')
468 # Generally, the value of the Decimal instance is given by
469 # (-1)**_sign * _int * 10**_exp
470 # Special values are signified by _is_special == True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000471
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000472 # We're immutable, so use __new__ not __init__
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000473 def __new__(cls, value="0", context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000474 """Create a decimal point instance.
475
476 >>> Decimal('3.14') # string input
477 Decimal("3.14")
478 >>> Decimal((0, (3, 1, 4), -2)) # tuple input (sign, digit_tuple, exponent)
479 Decimal("3.14")
480 >>> Decimal(314) # int or long
481 Decimal("314")
482 >>> Decimal(Decimal(314)) # another decimal instance
483 Decimal("314")
484 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000485
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000486 self = object.__new__(cls)
487 self._is_special = False
488
489 # From an internal working value
490 if isinstance(value, _WorkRep):
Raymond Hettinger17931de2004-10-27 06:21:46 +0000491 self._sign = value.sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000492 self._int = tuple(map(int, str(value.int)))
493 self._exp = int(value.exp)
494 return self
495
496 # From another decimal
497 if isinstance(value, Decimal):
498 self._exp = value._exp
499 self._sign = value._sign
500 self._int = value._int
501 self._is_special = value._is_special
502 return self
503
504 # From an integer
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000505 if isinstance(value, (int,long)):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000506 if value >= 0:
507 self._sign = 0
508 else:
509 self._sign = 1
510 self._exp = 0
511 self._int = tuple(map(int, str(abs(value))))
512 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000513
514 # tuple/list conversion (possibly from as_tuple())
515 if isinstance(value, (list,tuple)):
516 if len(value) != 3:
517 raise ValueError, 'Invalid arguments'
Raymond Hettingerdbecd932005-02-06 06:57:08 +0000518 if value[0] not in (0,1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000519 raise ValueError, 'Invalid sign'
520 for digit in value[1]:
521 if not isinstance(digit, (int,long)) or digit < 0:
522 raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
523
524 self._sign = value[0]
525 self._int = tuple(value[1])
526 if value[2] in ('F','n','N'):
527 self._exp = value[2]
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000528 self._is_special = True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000529 else:
530 self._exp = int(value[2])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000531 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000532
Raymond Hettingerbf440692004-07-10 14:14:37 +0000533 if isinstance(value, float):
534 raise TypeError("Cannot convert float to Decimal. " +
535 "First convert the float to a string")
536
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000537 # Other argument types may require the context during interpretation
538 if context is None:
539 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000540
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000541 # From a string
542 # REs insist on real strings, so we can too.
543 if isinstance(value, basestring):
544 if _isinfinity(value):
545 self._exp = 'F'
546 self._int = (0,)
547 self._is_special = True
548 if _isinfinity(value) == 1:
549 self._sign = 0
550 else:
551 self._sign = 1
552 return self
553 if _isnan(value):
554 sig, sign, diag = _isnan(value)
555 self._is_special = True
556 if len(diag) > context.prec: #Diagnostic info too long
557 self._sign, self._int, self._exp = \
558 context._raise_error(ConversionSyntax)
559 return self
560 if sig == 1:
561 self._exp = 'n' #qNaN
562 else: #sig == 2
563 self._exp = 'N' #sNaN
564 self._sign = sign
565 self._int = tuple(map(int, diag)) #Diagnostic info
566 return self
567 try:
568 self._sign, self._int, self._exp = _string2exact(value)
569 except ValueError:
570 self._is_special = True
571 self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
572 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000573
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000574 raise TypeError("Cannot convert %r to Decimal" % value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000575
576 def _isnan(self):
577 """Returns whether the number is not actually one.
578
579 0 if a number
580 1 if NaN
581 2 if sNaN
582 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000583 if self._is_special:
584 exp = self._exp
585 if exp == 'n':
586 return 1
587 elif exp == 'N':
588 return 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000589 return 0
590
591 def _isinfinity(self):
592 """Returns whether the number is infinite
593
594 0 if finite or not a number
595 1 if +INF
596 -1 if -INF
597 """
598 if self._exp == 'F':
599 if self._sign:
600 return -1
601 return 1
602 return 0
603
604 def _check_nans(self, other = None, context=None):
605 """Returns whether the number is not actually one.
606
607 if self, other are sNaN, signal
608 if self, other are NaN return nan
609 return 0
610
611 Done before operations.
612 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000613
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000614 self_is_nan = self._isnan()
615 if other is None:
616 other_is_nan = False
617 else:
618 other_is_nan = other._isnan()
619
620 if self_is_nan or other_is_nan:
621 if context is None:
622 context = getcontext()
623
624 if self_is_nan == 2:
625 return context._raise_error(InvalidOperation, 'sNaN',
626 1, self)
627 if other_is_nan == 2:
628 return context._raise_error(InvalidOperation, 'sNaN',
629 1, other)
630 if self_is_nan:
631 return self
632
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000633 return other
634 return 0
635
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000636 def __nonzero__(self):
637 """Is the number non-zero?
638
639 0 if self == 0
640 1 if self != 0
641 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000642 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000643 return 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000644 return sum(self._int) != 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000645
646 def __cmp__(self, other, context=None):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000647 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +0000648 if other is NotImplemented:
649 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000650
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000651 if self._is_special or other._is_special:
652 ans = self._check_nans(other, context)
653 if ans:
654 return 1 # Comparison involving NaN's always reports self > other
655
656 # INF = INF
657 return cmp(self._isinfinity(), other._isinfinity())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000658
659 if not self and not other:
660 return 0 #If both 0, sign comparison isn't certain.
661
662 #If different signs, neg one is less
663 if other._sign < self._sign:
664 return -1
665 if self._sign < other._sign:
666 return 1
667
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000668 self_adjusted = self.adjusted()
669 other_adjusted = other.adjusted()
670 if self_adjusted == other_adjusted and \
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000671 self._int + (0,)*(self._exp - other._exp) == \
672 other._int + (0,)*(other._exp - self._exp):
673 return 0 #equal, except in precision. ([0]*(-x) = [])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000674 elif self_adjusted > other_adjusted and self._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000675 return (-1)**self._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000676 elif self_adjusted < other_adjusted and other._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000677 return -((-1)**self._sign)
678
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000679 # Need to round, so make sure we have a valid context
680 if context is None:
681 context = getcontext()
682
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000683 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000684 rounding = context._set_rounding(ROUND_UP) #round away from 0
685
686 flags = context._ignore_all_flags()
687 res = self.__sub__(other, context=context)
688
689 context._regard_flags(*flags)
690
691 context.rounding = rounding
692
693 if not res:
694 return 0
695 elif res._sign:
696 return -1
697 return 1
698
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000699 def __eq__(self, other):
700 if not isinstance(other, (Decimal, int, long)):
Raymond Hettinger267b8682005-03-27 10:47:39 +0000701 return NotImplemented
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000702 return self.__cmp__(other) == 0
703
704 def __ne__(self, other):
705 if not isinstance(other, (Decimal, int, long)):
Raymond Hettinger267b8682005-03-27 10:47:39 +0000706 return NotImplemented
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000707 return self.__cmp__(other) != 0
708
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000709 def compare(self, other, context=None):
710 """Compares one to another.
711
712 -1 => a < b
713 0 => a = b
714 1 => a > b
715 NaN => one is NaN
716 Like __cmp__, but returns Decimal instances.
717 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000718 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +0000719 if other is NotImplemented:
720 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000721
722 #compare(NaN, NaN) = NaN
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000723 if (self._is_special or other and other._is_special):
724 ans = self._check_nans(other, context)
725 if ans:
726 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000727
728 return Decimal(self.__cmp__(other, context))
729
730 def __hash__(self):
731 """x.__hash__() <==> hash(x)"""
732 # Decimal integers must hash the same as the ints
733 # Non-integer decimals are normalized and hashed as strings
Thomas Wouters477c8d52006-05-27 19:21:47 +0000734 # Normalization assures that hash(100E-1) == hash(10)
Raymond Hettingerbea3f6f2005-03-15 04:59:17 +0000735 if self._is_special:
736 if self._isnan():
737 raise TypeError('Cannot hash a NaN value.')
738 return hash(str(self))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000739 i = int(self)
740 if self == Decimal(i):
741 return hash(i)
742 assert self.__nonzero__() # '-0' handled by integer case
743 return hash(str(self.normalize()))
744
745 def as_tuple(self):
746 """Represents the number as a triple tuple.
747
748 To show the internals exactly as they are.
749 """
750 return (self._sign, self._int, self._exp)
751
752 def __repr__(self):
753 """Represents the number as an instance of Decimal."""
754 # Invariant: eval(repr(d)) == d
755 return 'Decimal("%s")' % str(self)
756
757 def __str__(self, eng = 0, context=None):
758 """Return string representation of the number in scientific notation.
759
760 Captures all of the information in the underlying representation.
761 """
762
Raymond Hettingere5a0a962005-06-20 09:49:42 +0000763 if self._is_special:
764 if self._isnan():
765 minus = '-'*self._sign
766 if self._int == (0,):
767 info = ''
768 else:
769 info = ''.join(map(str, self._int))
770 if self._isnan() == 2:
771 return minus + 'sNaN' + info
772 return minus + 'NaN' + info
773 if self._isinfinity():
774 minus = '-'*self._sign
775 return minus + 'Infinity'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000776
777 if context is None:
778 context = getcontext()
779
780 tmp = map(str, self._int)
781 numdigits = len(self._int)
782 leftdigits = self._exp + numdigits
783 if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
784 if self._exp < 0 and self._exp >= -6: #short, no need for e/E
785 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
786 return s
787 #exp is closest mult. of 3 >= self._exp
788 exp = ((self._exp - 1)// 3 + 1) * 3
789 if exp != self._exp:
790 s = '0.'+'0'*(exp - self._exp)
791 else:
792 s = '0'
793 if exp != 0:
794 if context.capitals:
795 s += 'E'
796 else:
797 s += 'e'
798 if exp > 0:
799 s += '+' #0.0e+3, not 0.0e3
800 s += str(exp)
801 s = '-'*self._sign + s
802 return s
803 if eng:
804 dotplace = (leftdigits-1)%3+1
805 adjexp = leftdigits -1 - (leftdigits-1)%3
806 else:
807 adjexp = leftdigits-1
808 dotplace = 1
809 if self._exp == 0:
810 pass
811 elif self._exp < 0 and adjexp >= 0:
812 tmp.insert(leftdigits, '.')
813 elif self._exp < 0 and adjexp >= -6:
814 tmp[0:0] = ['0'] * int(-leftdigits)
815 tmp.insert(0, '0.')
816 else:
817 if numdigits > dotplace:
818 tmp.insert(dotplace, '.')
819 elif numdigits < dotplace:
820 tmp.extend(['0']*(dotplace-numdigits))
821 if adjexp:
822 if not context.capitals:
823 tmp.append('e')
824 else:
825 tmp.append('E')
826 if adjexp > 0:
827 tmp.append('+')
828 tmp.append(str(adjexp))
829 if eng:
830 while tmp[0:1] == ['0']:
831 tmp[0:1] = []
832 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
833 tmp[0:0] = ['0']
834 if self._sign:
835 tmp.insert(0, '-')
836
837 return ''.join(tmp)
838
839 def to_eng_string(self, context=None):
840 """Convert to engineering-type string.
841
842 Engineering notation has an exponent which is a multiple of 3, so there
843 are up to 3 digits left of the decimal place.
844
845 Same rules for when in exponential and when as a value as in __str__.
846 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000847 return self.__str__(eng=1, context=context)
848
849 def __neg__(self, context=None):
850 """Returns a copy with the sign switched.
851
852 Rounds, if it has reason.
853 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000854 if self._is_special:
855 ans = self._check_nans(context=context)
856 if ans:
857 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000858
859 if not self:
860 # -Decimal('0') is Decimal('0'), not Decimal('-0')
861 sign = 0
862 elif self._sign:
863 sign = 0
864 else:
865 sign = 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000866
867 if context is None:
868 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000869 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000870 return Decimal((sign, self._int, self._exp))._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000871 return Decimal( (sign, self._int, self._exp))
872
873 def __pos__(self, context=None):
874 """Returns a copy, unless it is a sNaN.
875
876 Rounds the number (if more then precision digits)
877 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000878 if self._is_special:
879 ans = self._check_nans(context=context)
880 if ans:
881 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000882
883 sign = self._sign
884 if not self:
885 # + (-0) = 0
886 sign = 0
887
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000888 if context is None:
889 context = getcontext()
890
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000891 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000892 ans = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000893 else:
894 ans = Decimal(self)
895 ans._sign = sign
896 return ans
897
898 def __abs__(self, round=1, context=None):
899 """Returns the absolute value of self.
900
901 If the second argument is 0, do not round.
902 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000903 if self._is_special:
904 ans = self._check_nans(context=context)
905 if ans:
906 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000907
908 if not round:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000909 if context is None:
910 context = getcontext()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000911 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000912 context._set_rounding_decision(NEVER_ROUND)
913
914 if self._sign:
915 ans = self.__neg__(context=context)
916 else:
917 ans = self.__pos__(context=context)
918
919 return ans
920
921 def __add__(self, other, context=None):
922 """Returns self + other.
923
924 -INF + INF (or the reverse) cause InvalidOperation errors.
925 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000926 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +0000927 if other is NotImplemented:
928 return other
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000929
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000930 if context is None:
931 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000932
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000933 if self._is_special or other._is_special:
934 ans = self._check_nans(other, context)
935 if ans:
936 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000937
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000938 if self._isinfinity():
939 #If both INF, same sign => same as both, opposite => error.
940 if self._sign != other._sign and other._isinfinity():
941 return context._raise_error(InvalidOperation, '-INF + INF')
942 return Decimal(self)
943 if other._isinfinity():
944 return Decimal(other) #Can't both be infinity here
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000945
946 shouldround = context._rounding_decision == ALWAYS_ROUND
947
948 exp = min(self._exp, other._exp)
949 negativezero = 0
950 if context.rounding == ROUND_FLOOR and self._sign != other._sign:
951 #If the answer is 0, the sign should be negative, in this case.
952 negativezero = 1
953
954 if not self and not other:
955 sign = min(self._sign, other._sign)
956 if negativezero:
957 sign = 1
958 return Decimal( (sign, (0,), exp))
959 if not self:
Facundo Batista99b55482004-10-26 23:38:46 +0000960 exp = max(exp, other._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000961 ans = other._rescale(exp, watchexp=0, context=context)
962 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000963 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000964 return ans
965 if not other:
Facundo Batista99b55482004-10-26 23:38:46 +0000966 exp = max(exp, self._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000967 ans = self._rescale(exp, watchexp=0, context=context)
968 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000969 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000970 return ans
971
972 op1 = _WorkRep(self)
973 op2 = _WorkRep(other)
974 op1, op2 = _normalize(op1, op2, shouldround, context.prec)
975
976 result = _WorkRep()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000977 if op1.sign != op2.sign:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000978 # Equal and opposite
Raymond Hettinger17931de2004-10-27 06:21:46 +0000979 if op1.int == op2.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000980 if exp < context.Etiny():
981 exp = context.Etiny()
982 context._raise_error(Clamped)
983 return Decimal((negativezero, (0,), exp))
Raymond Hettinger17931de2004-10-27 06:21:46 +0000984 if op1.int < op2.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000985 op1, op2 = op2, op1
986 #OK, now abs(op1) > abs(op2)
Raymond Hettinger17931de2004-10-27 06:21:46 +0000987 if op1.sign == 1:
988 result.sign = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000989 op1.sign, op2.sign = op2.sign, op1.sign
990 else:
Raymond Hettinger17931de2004-10-27 06:21:46 +0000991 result.sign = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000992 #So we know the sign, and op1 > 0.
Raymond Hettinger17931de2004-10-27 06:21:46 +0000993 elif op1.sign == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000994 result.sign = 1
Raymond Hettinger17931de2004-10-27 06:21:46 +0000995 op1.sign, op2.sign = (0, 0)
996 else:
997 result.sign = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000998 #Now, op1 > abs(op2) > 0
999
Raymond Hettinger17931de2004-10-27 06:21:46 +00001000 if op2.sign == 0:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001001 result.int = op1.int + op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001002 else:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001003 result.int = op1.int - op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001004
1005 result.exp = op1.exp
1006 ans = Decimal(result)
1007 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001008 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001009 return ans
1010
1011 __radd__ = __add__
1012
1013 def __sub__(self, other, context=None):
1014 """Return self + (-other)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001015 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001016 if other is NotImplemented:
1017 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001018
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001019 if self._is_special or other._is_special:
1020 ans = self._check_nans(other, context=context)
1021 if ans:
1022 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001023
1024 # -Decimal(0) = Decimal(0), which we don't want since
1025 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
1026 # so we change the sign directly to a copy
1027 tmp = Decimal(other)
1028 tmp._sign = 1-tmp._sign
1029
1030 return self.__add__(tmp, context=context)
1031
1032 def __rsub__(self, other, context=None):
1033 """Return other + (-self)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001034 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001035 if other is NotImplemented:
1036 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001037
1038 tmp = Decimal(self)
1039 tmp._sign = 1 - tmp._sign
1040 return other.__add__(tmp, context=context)
1041
1042 def _increment(self, round=1, context=None):
1043 """Special case of add, adding 1eExponent
1044
1045 Since it is common, (rounding, for example) this adds
1046 (sign)*one E self._exp to the number more efficiently than add.
1047
1048 For example:
1049 Decimal('5.624e10')._increment() == Decimal('5.625e10')
1050 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001051 if self._is_special:
1052 ans = self._check_nans(context=context)
1053 if ans:
1054 return ans
1055
1056 return Decimal(self) # Must be infinite, and incrementing makes no difference
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001057
1058 L = list(self._int)
1059 L[-1] += 1
1060 spot = len(L)-1
1061 while L[spot] == 10:
1062 L[spot] = 0
1063 if spot == 0:
1064 L[0:0] = [1]
1065 break
1066 L[spot-1] += 1
1067 spot -= 1
1068 ans = Decimal((self._sign, L, self._exp))
1069
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001070 if context is None:
1071 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001072 if round and context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001073 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001074 return ans
1075
1076 def __mul__(self, other, context=None):
1077 """Return self * other.
1078
1079 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1080 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001081 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001082 if other is NotImplemented:
1083 return other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001084
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001085 if context is None:
1086 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001087
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001088 resultsign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001089
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001090 if self._is_special or other._is_special:
1091 ans = self._check_nans(other, context)
1092 if ans:
1093 return ans
1094
1095 if self._isinfinity():
1096 if not other:
1097 return context._raise_error(InvalidOperation, '(+-)INF * 0')
1098 return Infsign[resultsign]
1099
1100 if other._isinfinity():
1101 if not self:
1102 return context._raise_error(InvalidOperation, '0 * (+-)INF')
1103 return Infsign[resultsign]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001104
1105 resultexp = self._exp + other._exp
1106 shouldround = context._rounding_decision == ALWAYS_ROUND
1107
1108 # Special case for multiplying by zero
1109 if not self or not other:
1110 ans = Decimal((resultsign, (0,), resultexp))
1111 if shouldround:
1112 #Fixing in case the exponent is out of bounds
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001113 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001114 return ans
1115
1116 # Special case for multiplying by power of 10
1117 if self._int == (1,):
1118 ans = Decimal((resultsign, other._int, resultexp))
1119 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001120 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001121 return ans
1122 if other._int == (1,):
1123 ans = Decimal((resultsign, self._int, resultexp))
1124 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001125 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001126 return ans
1127
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001128 op1 = _WorkRep(self)
1129 op2 = _WorkRep(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001130
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001131 ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001132 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001133 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001134
1135 return ans
1136 __rmul__ = __mul__
1137
Neal Norwitzbcc0db82006-03-24 08:14:36 +00001138 def __truediv__(self, other, context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001139 """Return self / other."""
1140 return self._divide(other, context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001141
1142 def _divide(self, other, divmod = 0, context=None):
1143 """Return a / b, to context.prec precision.
1144
1145 divmod:
1146 0 => true division
1147 1 => (a //b, a%b)
1148 2 => a //b
1149 3 => a%b
1150
1151 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1152 computing the other value are not raised.
1153 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001154 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001155 if other is NotImplemented:
1156 if divmod in (0, 1):
1157 return NotImplemented
1158 return (NotImplemented, NotImplemented)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001159
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001160 if context is None:
1161 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001162
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001163 sign = self._sign ^ other._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001164
1165 if self._is_special or other._is_special:
1166 ans = self._check_nans(other, context)
1167 if ans:
1168 if divmod:
1169 return (ans, ans)
1170 return ans
1171
1172 if self._isinfinity() and other._isinfinity():
1173 if divmod:
1174 return (context._raise_error(InvalidOperation,
1175 '(+-)INF // (+-)INF'),
1176 context._raise_error(InvalidOperation,
1177 '(+-)INF % (+-)INF'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001178 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001179
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001180 if self._isinfinity():
1181 if divmod == 1:
1182 return (Infsign[sign],
1183 context._raise_error(InvalidOperation, 'INF % x'))
1184 elif divmod == 2:
1185 return (Infsign[sign], NaN)
1186 elif divmod == 3:
1187 return (Infsign[sign],
1188 context._raise_error(InvalidOperation, 'INF % x'))
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001189 return Infsign[sign]
1190
1191 if other._isinfinity():
1192 if divmod:
1193 return (Decimal((sign, (0,), 0)), Decimal(self))
1194 context._raise_error(Clamped, 'Division by infinity')
1195 return Decimal((sign, (0,), context.Etiny()))
1196
1197 # Special cases for zeroes
1198 if not self and not other:
1199 if divmod:
1200 return context._raise_error(DivisionUndefined, '0 / 0', 1)
1201 return context._raise_error(DivisionUndefined, '0 / 0')
1202
1203 if not self:
1204 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001205 otherside = Decimal(self)
1206 otherside._exp = min(self._exp, other._exp)
1207 return (Decimal((sign, (0,), 0)), otherside)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001208 exp = self._exp - other._exp
1209 if exp < context.Etiny():
1210 exp = context.Etiny()
1211 context._raise_error(Clamped, '0e-x / y')
1212 if exp > context.Emax:
1213 exp = context.Emax
1214 context._raise_error(Clamped, '0e+x / y')
1215 return Decimal( (sign, (0,), exp) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001216
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001217 if not other:
1218 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001219 return context._raise_error(DivisionByZero, 'divmod(x,0)',
1220 sign, 1)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001221 return context._raise_error(DivisionByZero, 'x / 0', sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001222
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001223 #OK, so neither = 0, INF or NaN
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001224
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:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001235 ans2 = ans2._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001236 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
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001243 op1 = _WorkRep(self)
1244 op2 = _WorkRep(other)
1245 op1, op2, adjust = _adjust_coefficients(op1, op2)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001246 res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001247 if divmod and res.exp > context.prec + 1:
1248 return context._raise_error(DivisionImpossible)
1249
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001250 prec_limit = 10 ** context.prec
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001251 while 1:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001252 while op2.int <= op1.int:
1253 res.int += 1
1254 op1.int -= op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001255 if res.exp == 0 and divmod:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001256 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001257 return context._raise_error(DivisionImpossible)
1258 otherside = Decimal(op1)
1259 frozen = context._ignore_all_flags()
1260
1261 exp = min(self._exp, other._exp)
Raymond Hettinger17931de2004-10-27 06:21:46 +00001262 otherside = otherside._rescale(exp, context=context, watchexp=0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001263 context._regard_flags(*frozen)
1264 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001265 otherside = otherside._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001266 return (Decimal(res), otherside)
1267
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001268 if op1.int == 0 and adjust >= 0 and not divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001269 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001270 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001271 if divmod:
1272 return context._raise_error(DivisionImpossible)
1273 shouldround=1
1274 # Really, the answer is a bit higher, so adding a one to
1275 # the end will make sure the rounding is right.
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001276 if op1.int != 0:
1277 res.int *= 10
1278 res.int += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001279 res.exp -= 1
1280
1281 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001282 res.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001283 res.exp -= 1
1284 adjust += 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001285 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001286 op1.exp -= 1
1287
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001288 if res.exp == 0 and divmod and op2.int > op1.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001289 #Solves an error in precision. Same as a previous block.
1290
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001291 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001292 return context._raise_error(DivisionImpossible)
1293 otherside = Decimal(op1)
1294 frozen = context._ignore_all_flags()
1295
1296 exp = min(self._exp, other._exp)
1297 otherside = otherside._rescale(exp, context=context)
1298
1299 context._regard_flags(*frozen)
1300
1301 return (Decimal(res), otherside)
1302
1303 ans = Decimal(res)
1304 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001305 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001306 return ans
1307
Neal Norwitzbcc0db82006-03-24 08:14:36 +00001308 def __rtruediv__(self, other, context=None):
1309 """Swaps self/other and returns __truediv__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001310 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001311 if other is NotImplemented:
1312 return other
Neal Norwitzbcc0db82006-03-24 08:14:36 +00001313 return other.__truediv__(self, context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001314
1315 def __divmod__(self, other, context=None):
1316 """
1317 (self // other, self % other)
1318 """
1319 return self._divide(other, 1, context)
1320
1321 def __rdivmod__(self, other, context=None):
1322 """Swaps self/other and returns __divmod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001323 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001324 if other is NotImplemented:
1325 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001326 return other.__divmod__(self, context=context)
1327
1328 def __mod__(self, other, context=None):
1329 """
1330 self % other
1331 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001332 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001333 if other is NotImplemented:
1334 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001335
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001336 if self._is_special or other._is_special:
1337 ans = self._check_nans(other, context)
1338 if ans:
1339 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001340
1341 if self and not other:
1342 return context._raise_error(InvalidOperation, 'x % 0')
1343
1344 return self._divide(other, 3, context)[1]
1345
1346 def __rmod__(self, other, context=None):
1347 """Swaps self/other and returns __mod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001348 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001349 if other is NotImplemented:
1350 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001351 return other.__mod__(self, context=context)
1352
1353 def remainder_near(self, other, context=None):
1354 """
1355 Remainder nearest to 0- abs(remainder-near) <= other/2
1356 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001357 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001358 if other is NotImplemented:
1359 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001360
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001361 if self._is_special or other._is_special:
1362 ans = self._check_nans(other, context)
1363 if ans:
1364 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001365 if self and not other:
1366 return context._raise_error(InvalidOperation, 'x % 0')
1367
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001368 if context is None:
1369 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001370 # 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:
Neal Norwitzbcc0db82006-03-24 08:14:36 +00001385 comparison = other.__truediv__(Decimal(-2), context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001386 else:
Neal Norwitzbcc0db82006-03-24 08:14:36 +00001387 comparison = other.__truediv__(Decimal(2), context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001388
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)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001399 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001400 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
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001430 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001431
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__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001438 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001439 if other is NotImplemented:
1440 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001441 return other.__floordiv__(self, context=context)
1442
1443 def __float__(self):
1444 """Float representation."""
1445 return float(str(self))
1446
1447 def __int__(self):
Brett Cannon46b08022005-03-01 03:12:26 +00001448 """Converts self to an int, truncating if necessary."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001449 if self._is_special:
1450 if self._isnan():
1451 context = getcontext()
1452 return context._raise_error(InvalidContext)
1453 elif self._isinfinity():
1454 raise OverflowError, "Cannot convert infinity to long"
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001455 if self._exp >= 0:
Raymond Hettinger605ed022004-11-24 07:28:48 +00001456 s = ''.join(map(str, self._int)) + '0'*self._exp
1457 else:
1458 s = ''.join(map(str, self._int))[:self._exp]
1459 if s == '':
1460 s = '0'
1461 sign = '-'*self._sign
1462 return int(sign + s)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001463
1464 def __long__(self):
1465 """Converts to a long.
1466
1467 Equivalent to long(int(self))
1468 """
1469 return long(self.__int__())
1470
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001471 def _fix(self, context):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001472 """Round if it is necessary to keep self within prec precision.
1473
1474 Rounds and fixes the exponent. Does not raise on a sNaN.
1475
1476 Arguments:
1477 self - Decimal instance
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001478 context - context used.
1479 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001480 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001481 return self
1482 if context is None:
1483 context = getcontext()
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001484 prec = context.prec
Facundo Batista99b55482004-10-26 23:38:46 +00001485 ans = self._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001486 if len(ans._int) > prec:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001487 ans = ans._round(prec, context=context)
Facundo Batista99b55482004-10-26 23:38:46 +00001488 ans = ans._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001489 return ans
1490
Facundo Batista99b55482004-10-26 23:38:46 +00001491 def _fixexponents(self, context):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001492 """Fix the exponents and return a copy with the exponent in bounds.
1493 Only call if known to not be a special value.
1494 """
1495 folddown = context._clamp
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001496 Emin = context.Emin
Facundo Batista99b55482004-10-26 23:38:46 +00001497 ans = self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001498 ans_adjusted = ans.adjusted()
1499 if ans_adjusted < Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001500 Etiny = context.Etiny()
1501 if ans._exp < Etiny:
1502 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001503 ans = Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001504 ans._exp = Etiny
1505 context._raise_error(Clamped)
1506 return ans
1507 ans = ans._rescale(Etiny, context=context)
1508 #It isn't zero, and exp < Emin => subnormal
1509 context._raise_error(Subnormal)
1510 if context.flags[Inexact]:
1511 context._raise_error(Underflow)
1512 else:
1513 if ans:
1514 #Only raise subnormal if non-zero.
1515 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001516 else:
1517 Etop = context.Etop()
1518 if folddown and ans._exp > Etop:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001519 context._raise_error(Clamped)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001520 ans = ans._rescale(Etop, context=context)
1521 else:
1522 Emax = context.Emax
1523 if ans_adjusted > Emax:
1524 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001525 ans = Decimal(self)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001526 ans._exp = Emax
1527 context._raise_error(Clamped)
1528 return ans
1529 context._raise_error(Inexact)
1530 context._raise_error(Rounded)
1531 return context._raise_error(Overflow, 'above Emax', ans._sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001532 return ans
1533
1534 def _round(self, prec=None, rounding=None, context=None):
1535 """Returns a rounded version of self.
1536
1537 You can specify the precision or rounding method. Otherwise, the
1538 context determines it.
1539 """
1540
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001541 if self._is_special:
1542 ans = self._check_nans(context=context)
1543 if ans:
1544 return ans
1545
1546 if self._isinfinity():
1547 return Decimal(self)
1548
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001549 if context is None:
1550 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001551
1552 if rounding is None:
1553 rounding = context.rounding
1554 if prec is None:
1555 prec = context.prec
1556
1557 if not self:
1558 if prec <= 0:
1559 dig = (0,)
1560 exp = len(self._int) - prec + self._exp
1561 else:
1562 dig = (0,) * prec
1563 exp = len(self._int) + self._exp - prec
1564 ans = Decimal((self._sign, dig, exp))
1565 context._raise_error(Rounded)
1566 return ans
1567
1568 if prec == 0:
1569 temp = Decimal(self)
1570 temp._int = (0,)+temp._int
1571 prec = 1
1572 elif prec < 0:
1573 exp = self._exp + len(self._int) - prec - 1
1574 temp = Decimal( (self._sign, (0, 1), exp))
1575 prec = 1
1576 else:
1577 temp = Decimal(self)
1578
1579 numdigits = len(temp._int)
1580 if prec == numdigits:
1581 return temp
1582
1583 # See if we need to extend precision
1584 expdiff = prec - numdigits
1585 if expdiff > 0:
1586 tmp = list(temp._int)
1587 tmp.extend([0] * expdiff)
1588 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff))
1589 return ans
1590
1591 #OK, but maybe all the lost digits are 0.
1592 lostdigits = self._int[expdiff:]
1593 if lostdigits == (0,) * len(lostdigits):
1594 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
1595 #Rounded, but not Inexact
1596 context._raise_error(Rounded)
1597 return ans
1598
1599 # Okay, let's round and lose data
1600
1601 this_function = getattr(temp, self._pick_rounding_function[rounding])
1602 #Now we've got the rounding function
1603
1604 if prec != context.prec:
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001605 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001606 context.prec = prec
1607 ans = this_function(prec, expdiff, context)
1608 context._raise_error(Rounded)
1609 context._raise_error(Inexact, 'Changed in rounding')
1610
1611 return ans
1612
1613 _pick_rounding_function = {}
1614
1615 def _round_down(self, prec, expdiff, context):
1616 """Also known as round-towards-0, truncate."""
1617 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1618
1619 def _round_half_up(self, prec, expdiff, context, tmp = None):
1620 """Rounds 5 up (away from 0)"""
1621
1622 if tmp is None:
1623 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
1624 if self._int[prec] >= 5:
1625 tmp = tmp._increment(round=0, context=context)
1626 if len(tmp._int) > prec:
1627 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1628 return tmp
1629
1630 def _round_half_even(self, prec, expdiff, context):
1631 """Round 5 to even, rest to nearest."""
1632
1633 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1634 half = (self._int[prec] == 5)
1635 if half:
1636 for digit in self._int[prec+1:]:
1637 if digit != 0:
1638 half = 0
1639 break
1640 if half:
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001641 if self._int[prec-1] & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001642 return tmp
1643 return self._round_half_up(prec, expdiff, context, tmp)
1644
1645 def _round_half_down(self, prec, expdiff, context):
1646 """Round 5 down"""
1647
1648 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1649 half = (self._int[prec] == 5)
1650 if half:
1651 for digit in self._int[prec+1:]:
1652 if digit != 0:
1653 half = 0
1654 break
1655 if half:
1656 return tmp
1657 return self._round_half_up(prec, expdiff, context, tmp)
1658
1659 def _round_up(self, prec, expdiff, context):
1660 """Rounds away from 0."""
1661 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1662 for digit in self._int[prec:]:
1663 if digit != 0:
1664 tmp = tmp._increment(round=1, context=context)
1665 if len(tmp._int) > prec:
1666 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1667 else:
1668 return tmp
1669 return tmp
1670
1671 def _round_ceiling(self, prec, expdiff, context):
1672 """Rounds up (not away from 0 if negative.)"""
1673 if self._sign:
1674 return self._round_down(prec, expdiff, context)
1675 else:
1676 return self._round_up(prec, expdiff, context)
1677
1678 def _round_floor(self, prec, expdiff, context):
1679 """Rounds down (not towards 0 if negative)"""
1680 if not self._sign:
1681 return self._round_down(prec, expdiff, context)
1682 else:
1683 return self._round_up(prec, expdiff, context)
1684
1685 def __pow__(self, n, modulo = None, context=None):
1686 """Return self ** n (mod modulo)
1687
1688 If modulo is None (default), don't take it mod modulo.
1689 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001690 n = _convert_other(n)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001691 if n is NotImplemented:
1692 return n
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001693
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001694 if context is None:
1695 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001696
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001697 if self._is_special or n._is_special or n.adjusted() > 8:
1698 #Because the spot << doesn't work with really big exponents
1699 if n._isinfinity() or n.adjusted() > 8:
1700 return context._raise_error(InvalidOperation, 'x ** INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001701
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001702 ans = self._check_nans(n, context)
1703 if ans:
1704 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001705
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001706 if not n._isinteger():
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001707 return context._raise_error(InvalidOperation, 'x ** (non-integer)')
1708
1709 if not self and not n:
1710 return context._raise_error(InvalidOperation, '0 ** 0')
1711
1712 if not n:
1713 return Decimal(1)
1714
1715 if self == Decimal(1):
1716 return Decimal(1)
1717
1718 sign = self._sign and not n._iseven()
1719 n = int(n)
1720
1721 if self._isinfinity():
1722 if modulo:
1723 return context._raise_error(InvalidOperation, 'INF % x')
1724 if n > 0:
1725 return Infsign[sign]
1726 return Decimal( (sign, (0,), 0) )
1727
1728 #with ludicrously large exponent, just raise an overflow and return inf.
1729 if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
1730 and self:
1731
1732 tmp = Decimal('inf')
1733 tmp._sign = sign
1734 context._raise_error(Rounded)
1735 context._raise_error(Inexact)
1736 context._raise_error(Overflow, 'Big power', sign)
1737 return tmp
1738
1739 elength = len(str(abs(n)))
1740 firstprec = context.prec
1741
Raymond Hettinger99148e72004-07-14 19:56:56 +00001742 if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001743 return context._raise_error(Overflow, 'Too much precision.', sign)
1744
1745 mul = Decimal(self)
1746 val = Decimal(1)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001747 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001748 context.prec = firstprec + elength + 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001749 if n < 0:
1750 #n is a long now, not Decimal instance
1751 n = -n
Neal Norwitzbcc0db82006-03-24 08:14:36 +00001752 mul = Decimal(1).__truediv__(mul, context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001753
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001754 spot = 1
1755 while spot <= n:
1756 spot <<= 1
1757
1758 spot >>= 1
1759 #Spot is the highest power of 2 less than n
1760 while spot:
1761 val = val.__mul__(val, context=context)
1762 if val._isinfinity():
1763 val = Infsign[sign]
1764 break
1765 if spot & n:
1766 val = val.__mul__(mul, context=context)
1767 if modulo is not None:
1768 val = val.__mod__(modulo, context=context)
1769 spot >>= 1
1770 context.prec = firstprec
1771
Raymond Hettinger76e60d62004-10-20 06:58:28 +00001772 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001773 return val._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001774 return val
1775
1776 def __rpow__(self, other, context=None):
1777 """Swaps self/other and returns __pow__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001778 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001779 if other is NotImplemented:
1780 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001781 return other.__pow__(self, context=context)
1782
1783 def normalize(self, context=None):
1784 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001785
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001786 if self._is_special:
1787 ans = self._check_nans(context=context)
1788 if ans:
1789 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001790
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001791 dup = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001792 if dup._isinfinity():
1793 return dup
1794
1795 if not dup:
1796 return Decimal( (dup._sign, (0,), 0) )
1797 end = len(dup._int)
1798 exp = dup._exp
1799 while dup._int[end-1] == 0:
1800 exp += 1
1801 end -= 1
1802 return Decimal( (dup._sign, dup._int[:end], exp) )
1803
1804
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001805 def quantize(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001806 """Quantize self so its exponent is the same as that of exp.
1807
1808 Similar to self._rescale(exp._exp) but with error checking.
1809 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001810 if self._is_special or exp._is_special:
1811 ans = self._check_nans(exp, context)
1812 if ans:
1813 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001814
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001815 if exp._isinfinity() or self._isinfinity():
1816 if exp._isinfinity() and self._isinfinity():
1817 return self #if both are inf, it is OK
1818 if context is None:
1819 context = getcontext()
1820 return context._raise_error(InvalidOperation,
1821 'quantize with one INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001822 return self._rescale(exp._exp, rounding, context, watchexp)
1823
1824 def same_quantum(self, other):
1825 """Test whether self and other have the same exponent.
1826
1827 same as self._exp == other._exp, except NaN == sNaN
1828 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001829 if self._is_special or other._is_special:
1830 if self._isnan() or other._isnan():
1831 return self._isnan() and other._isnan() and True
1832 if self._isinfinity() or other._isinfinity():
1833 return self._isinfinity() and other._isinfinity() and True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001834 return self._exp == other._exp
1835
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001836 def _rescale(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001837 """Rescales so that the exponent is exp.
1838
1839 exp = exp to scale to (an integer)
1840 rounding = rounding version
1841 watchexp: if set (default) an error is returned if exp is greater
1842 than Emax or less than Etiny.
1843 """
1844 if context is None:
1845 context = getcontext()
1846
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001847 if self._is_special:
1848 if self._isinfinity():
1849 return context._raise_error(InvalidOperation, 'rescale with an INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001850
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001851 ans = self._check_nans(context=context)
1852 if ans:
1853 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001854
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001855 if watchexp and (context.Emax < exp or context.Etiny() > exp):
1856 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1857
1858 if not self:
1859 ans = Decimal(self)
1860 ans._int = (0,)
1861 ans._exp = exp
1862 return ans
1863
1864 diff = self._exp - exp
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001865 digits = len(self._int) + diff
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001866
1867 if watchexp and digits > context.prec:
1868 return context._raise_error(InvalidOperation, 'Rescale > prec')
1869
1870 tmp = Decimal(self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001871 tmp._int = (0,) + tmp._int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001872 digits += 1
1873
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001874 if digits < 0:
1875 tmp._exp = -digits + tmp._exp
1876 tmp._int = (0,1)
1877 digits = 1
1878 tmp = tmp._round(digits, rounding, context=context)
1879
1880 if tmp._int[0] == 0 and len(tmp._int) > 1:
1881 tmp._int = tmp._int[1:]
1882 tmp._exp = exp
1883
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001884 tmp_adjusted = tmp.adjusted()
1885 if tmp and tmp_adjusted < context.Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001886 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001887 elif tmp and tmp_adjusted > context.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001888 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1889 return tmp
1890
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001891 def to_integral(self, rounding=None, context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001892 """Rounds to the nearest integer, without raising inexact, rounded."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001893 if self._is_special:
1894 ans = self._check_nans(context=context)
1895 if ans:
1896 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001897 if self._exp >= 0:
1898 return self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001899 if context is None:
1900 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001901 flags = context._ignore_flags(Rounded, Inexact)
1902 ans = self._rescale(0, rounding, context=context)
1903 context._regard_flags(flags)
1904 return ans
1905
1906 def sqrt(self, context=None):
1907 """Return the square root of self.
1908
1909 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
1910 Should quadratically approach the right answer.
1911 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001912 if self._is_special:
1913 ans = self._check_nans(context=context)
1914 if ans:
1915 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001916
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001917 if self._isinfinity() and self._sign == 0:
1918 return Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001919
1920 if not self:
1921 #exponent = self._exp / 2, using round_down.
1922 #if self._exp < 0:
1923 # exp = (self._exp+1) // 2
1924 #else:
1925 exp = (self._exp) // 2
1926 if self._sign == 1:
1927 #sqrt(-0) = -0
1928 return Decimal( (1, (0,), exp))
1929 else:
1930 return Decimal( (0, (0,), exp))
1931
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001932 if context is None:
1933 context = getcontext()
1934
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001935 if self._sign == 1:
1936 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
1937
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001938 tmp = Decimal(self)
1939
Raymond Hettinger4837a222004-09-27 14:23:40 +00001940 expadd = tmp._exp // 2
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001941 if tmp._exp & 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001942 tmp._int += (0,)
1943 tmp._exp = 0
1944 else:
1945 tmp._exp = 0
1946
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001947 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001948 flags = context._ignore_all_flags()
1949 firstprec = context.prec
1950 context.prec = 3
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001951 if tmp.adjusted() & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001952 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) )
1953 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
1954 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00001955 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001956 else:
1957 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
1958 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
1959 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00001960 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001961
1962 #ans is now a linear approximation.
1963
1964 Emax, Emin = context.Emax, context.Emin
Raymond Hettinger99148e72004-07-14 19:56:56 +00001965 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001966
1967 half = Decimal('0.5')
1968
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001969 maxp = firstprec + 2
1970 rounding = context._set_rounding(ROUND_HALF_EVEN)
1971 while 1:
1972 context.prec = min(2*context.prec - 2, maxp)
Neal Norwitzbcc0db82006-03-24 08:14:36 +00001973 ans = half.__mul__(ans.__add__(tmp.__truediv__(ans, context=context),
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001974 context=context), context=context)
1975 if context.prec == maxp:
1976 break
1977
1978 #round to the answer's precision-- the only error can be 1 ulp.
1979 context.prec = firstprec
1980 prevexp = ans.adjusted()
1981 ans = ans._round(context=context)
1982
1983 #Now, check if the other last digits are better.
1984 context.prec = firstprec + 1
1985 # In case we rounded up another digit and we should actually go lower.
1986 if prevexp != ans.adjusted():
1987 ans._int += (0,)
1988 ans._exp -= 1
1989
1990
1991 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
1992 context._set_rounding(ROUND_UP)
1993 if lower.__mul__(lower, context=context) > (tmp):
1994 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
1995
1996 else:
1997 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
1998 context._set_rounding(ROUND_DOWN)
1999 if upper.__mul__(upper, context=context) < tmp:
2000 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
2001
2002 ans._exp += expadd
2003
2004 context.prec = firstprec
2005 context.rounding = rounding
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002006 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002007
2008 rounding = context._set_rounding_decision(NEVER_ROUND)
2009 if not ans.__mul__(ans, context=context) == self:
2010 # Only rounded/inexact if here.
2011 context._regard_flags(flags)
2012 context._raise_error(Rounded)
2013 context._raise_error(Inexact)
2014 else:
2015 #Exact answer, so let's set the exponent right.
2016 #if self._exp < 0:
2017 # exp = (self._exp +1)// 2
2018 #else:
2019 exp = self._exp // 2
2020 context.prec += ans._exp - exp
2021 ans = ans._rescale(exp, context=context)
2022 context.prec = firstprec
2023 context._regard_flags(flags)
2024 context.Emax, context.Emin = Emax, Emin
2025
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002026 return ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002027
2028 def max(self, other, context=None):
2029 """Returns the larger value.
2030
2031 like max(self, other) except if one is not a number, returns
2032 NaN (and signals if one is sNaN). Also rounds.
2033 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002034 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002035 if other is NotImplemented:
2036 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002037
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002038 if self._is_special or other._is_special:
2039 # if one operand is a quiet NaN and the other is number, then the
2040 # number is always returned
2041 sn = self._isnan()
2042 on = other._isnan()
2043 if sn or on:
2044 if on == 1 and sn != 2:
2045 return self
2046 if sn == 1 and on != 2:
2047 return other
2048 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002049
2050 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002051 c = self.__cmp__(other)
2052 if c == 0:
2053 # if both operands are finite and equal in numerical value
2054 # then an ordering is applied:
2055 #
2056 # if the signs differ then max returns the operand with the
2057 # positive sign and min returns the operand with the negative sign
2058 #
2059 # if the signs are the same then the exponent is used to select
2060 # the result.
2061 if self._sign != other._sign:
2062 if self._sign:
2063 ans = other
2064 elif self._exp < other._exp and not self._sign:
2065 ans = other
2066 elif self._exp > other._exp and self._sign:
2067 ans = other
2068 elif c == -1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002069 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002070
2071 if context is None:
2072 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002073 if context._rounding_decision == ALWAYS_ROUND:
2074 return ans._fix(context)
2075 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002076
2077 def min(self, other, context=None):
2078 """Returns the smaller value.
2079
2080 like min(self, other) except if one is not a number, returns
2081 NaN (and signals if one is sNaN). Also rounds.
2082 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002083 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002084 if other is NotImplemented:
2085 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002086
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002087 if self._is_special or other._is_special:
2088 # 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 Hettinger636a6b12004-09-19 01:54:09 +00002119
2120 if context is None:
2121 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002122 if context._rounding_decision == ALWAYS_ROUND:
2123 return ans._fix(context)
2124 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002125
2126 def _isinteger(self):
2127 """Returns whether self is an integer"""
2128 if self._exp >= 0:
2129 return True
2130 rest = self._int[self._exp:]
2131 return rest == (0,)*len(rest)
2132
2133 def _iseven(self):
2134 """Returns 1 if self is even. Assumes self is an integer."""
2135 if self._exp > 0:
2136 return 1
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002137 return self._int[-1+self._exp] & 1 == 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002138
2139 def adjusted(self):
2140 """Return the adjusted exponent of self"""
2141 try:
2142 return self._exp + len(self._int) - 1
2143 #If NaN or Infinity, self._exp is string
2144 except TypeError:
2145 return 0
2146
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002147 # support for pickling, copy, and deepcopy
2148 def __reduce__(self):
2149 return (self.__class__, (str(self),))
2150
2151 def __copy__(self):
2152 if type(self) == Decimal:
2153 return self # I'm immutable; therefore I am my own clone
2154 return self.__class__(str(self))
2155
2156 def __deepcopy__(self, memo):
2157 if type(self) == Decimal:
2158 return self # My components are also immutable
2159 return self.__class__(str(self))
2160
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002161##### Context class ###########################################
2162
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002163
2164# get rounding method function:
2165rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
2166for name in rounding_functions:
2167 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
2168 globalname = name[1:].upper()
2169 val = globals()[globalname]
2170 Decimal._pick_rounding_function[val] = name
2171
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002172del name, val, globalname, rounding_functions
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002173
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002174class ContextManager(object):
2175 """Helper class to simplify Context management.
2176
2177 Sample usage:
2178
2179 with decimal.ExtendedContext:
2180 s = ...
2181 return +s # Convert result to normal precision
2182
2183 with decimal.getcontext() as ctx:
2184 ctx.prec += 2
2185 s = ...
2186 return +s
2187
2188 """
2189 def __init__(self, new_context):
2190 self.new_context = new_context
2191 def __enter__(self):
2192 self.saved_context = getcontext()
2193 setcontext(self.new_context)
2194 return self.new_context
2195 def __exit__(self, t, v, tb):
2196 setcontext(self.saved_context)
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002197
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002198class Context(object):
2199 """Contains the context for a Decimal instance.
2200
2201 Contains:
2202 prec - precision (for use in rounding, division, square roots..)
2203 rounding - rounding type. (how you round)
2204 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
Raymond Hettingerbf440692004-07-10 14:14:37 +00002205 traps - If traps[exception] = 1, then the exception is
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002206 raised when it is caused. Otherwise, a value is
2207 substituted in.
2208 flags - When an exception is caused, flags[exception] is incremented.
2209 (Whether or not the trap_enabler is set)
2210 Should be reset by user of Decimal instance.
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002211 Emin - Minimum exponent
2212 Emax - Maximum exponent
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002213 capitals - If 1, 1*10^1 is printed as 1E+1.
2214 If 0, printed as 1e1
Raymond Hettingere0f15812004-07-05 05:36:39 +00002215 _clamp - If 1, change exponents if too high (Default 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002216 """
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002217
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002218 def __init__(self, prec=None, rounding=None,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002219 traps=None, flags=None,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002220 _rounding_decision=None,
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002221 Emin=None, Emax=None,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002222 capitals=None, _clamp=0,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002223 _ignored_flags=None):
2224 if flags is None:
2225 flags = []
2226 if _ignored_flags is None:
2227 _ignored_flags = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002228 if not isinstance(flags, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002229 flags = dict([(s,s in flags) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002230 del s
Raymond Hettingerbf440692004-07-10 14:14:37 +00002231 if traps is not None and not isinstance(traps, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002232 traps = dict([(s,s in traps) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002233 del s
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002234 for name, val in locals().items():
2235 if val is None:
Raymond Hettingereb260842005-06-07 18:52:34 +00002236 setattr(self, name, _copy.copy(getattr(DefaultContext, name)))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002237 else:
2238 setattr(self, name, val)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002239 del self.self
2240
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002241 def __repr__(self):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002242 """Show the current context."""
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002243 s = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002244 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
2245 s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
2246 s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002247 return ', '.join(s) + ')'
2248
Thomas Wouters477c8d52006-05-27 19:21:47 +00002249 def get_manager(self):
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002250 return ContextManager(self.copy())
2251
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002252 def clear_flags(self):
2253 """Reset all flags to zero"""
2254 for flag in self.flags:
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002255 self.flags[flag] = 0
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002256
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002257 def _shallow_copy(self):
2258 """Returns a shallow copy from self."""
Raymond Hettingerbf440692004-07-10 14:14:37 +00002259 nc = Context(self.prec, self.rounding, self.traps, self.flags,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002260 self._rounding_decision, self.Emin, self.Emax,
2261 self.capitals, self._clamp, self._ignored_flags)
2262 return nc
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002263
2264 def copy(self):
2265 """Returns a deep copy from self."""
2266 nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
2267 self._rounding_decision, self.Emin, self.Emax,
2268 self.capitals, self._clamp, self._ignored_flags)
2269 return nc
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002270 __copy__ = copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002271
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002272 def _raise_error(self, condition, explanation = None, *args):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002273 """Handles an error
2274
2275 If the flag is in _ignored_flags, returns the default response.
2276 Otherwise, it increments the flag, then, if the corresponding
2277 trap_enabler is set, it reaises the exception. Otherwise, it returns
2278 the default value after incrementing the flag.
2279 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002280 error = _condition_map.get(condition, condition)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002281 if error in self._ignored_flags:
2282 #Don't touch the flag
2283 return error().handle(self, *args)
2284
2285 self.flags[error] += 1
Raymond Hettingerbf440692004-07-10 14:14:37 +00002286 if not self.traps[error]:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002287 #The errors define how to handle themselves.
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002288 return condition().handle(self, *args)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002289
2290 # Errors should only be risked on copies of the context
2291 #self._ignored_flags = []
2292 raise error, explanation
2293
2294 def _ignore_all_flags(self):
2295 """Ignore all flags, if they are raised"""
Raymond Hettingerfed52962004-07-14 15:41:57 +00002296 return self._ignore_flags(*_signals)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002297
2298 def _ignore_flags(self, *flags):
2299 """Ignore the flags, if they are raised"""
2300 # Do not mutate-- This way, copies of a context leave the original
2301 # alone.
2302 self._ignored_flags = (self._ignored_flags + list(flags))
2303 return list(flags)
2304
2305 def _regard_flags(self, *flags):
2306 """Stop ignoring the flags, if they are raised"""
2307 if flags and isinstance(flags[0], (tuple,list)):
2308 flags = flags[0]
2309 for flag in flags:
2310 self._ignored_flags.remove(flag)
2311
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002312 def __hash__(self):
2313 """A Context cannot be hashed."""
2314 # We inherit object.__hash__, so we must deny this explicitly
2315 raise TypeError, "Cannot hash a Context."
2316
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002317 def Etiny(self):
2318 """Returns Etiny (= Emin - prec + 1)"""
2319 return int(self.Emin - self.prec + 1)
2320
2321 def Etop(self):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002322 """Returns maximum exponent (= Emax - prec + 1)"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002323 return int(self.Emax - self.prec + 1)
2324
2325 def _set_rounding_decision(self, type):
2326 """Sets the rounding decision.
2327
2328 Sets the rounding decision, and returns the current (previous)
2329 rounding decision. Often used like:
2330
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002331 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002332 # That so you don't change the calling context
2333 # if an error occurs in the middle (say DivisionImpossible is raised).
2334
2335 rounding = context._set_rounding_decision(NEVER_ROUND)
2336 instance = instance / Decimal(2)
2337 context._set_rounding_decision(rounding)
2338
2339 This will make it not round for that operation.
2340 """
2341
2342 rounding = self._rounding_decision
2343 self._rounding_decision = type
2344 return rounding
2345
2346 def _set_rounding(self, type):
2347 """Sets the rounding type.
2348
2349 Sets the rounding type, and returns the current (previous)
2350 rounding type. Often used like:
2351
2352 context = context.copy()
2353 # so you don't change the calling context
2354 # if an error occurs in the middle.
2355 rounding = context._set_rounding(ROUND_UP)
2356 val = self.__sub__(other, context=context)
2357 context._set_rounding(rounding)
2358
2359 This will make it round up for that operation.
2360 """
2361 rounding = self.rounding
2362 self.rounding= type
2363 return rounding
2364
Raymond Hettingerfed52962004-07-14 15:41:57 +00002365 def create_decimal(self, num='0'):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002366 """Creates a new Decimal instance but using self as context."""
2367 d = Decimal(num, context=self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002368 return d._fix(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002369
2370 #Methods
2371 def abs(self, a):
2372 """Returns the absolute value of the operand.
2373
2374 If the operand is negative, the result is the same as using the minus
2375 operation on the operand. Otherwise, the result is the same as using
2376 the plus operation on the operand.
2377
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002378 >>> ExtendedContext.abs(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002379 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002380 >>> ExtendedContext.abs(Decimal('-100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002381 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002382 >>> ExtendedContext.abs(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002383 Decimal("101.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002384 >>> ExtendedContext.abs(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002385 Decimal("101.5")
2386 """
2387 return a.__abs__(context=self)
2388
2389 def add(self, a, b):
2390 """Return the sum of the two operands.
2391
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002392 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002393 Decimal("19.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002394 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002395 Decimal("1.02E+4")
2396 """
2397 return a.__add__(b, context=self)
2398
2399 def _apply(self, a):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002400 return str(a._fix(self))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002401
2402 def compare(self, a, b):
2403 """Compares values numerically.
2404
2405 If the signs of the operands differ, a value representing each operand
2406 ('-1' if the operand is less than zero, '0' if the operand is zero or
2407 negative zero, or '1' if the operand is greater than zero) is used in
2408 place of that operand for the comparison instead of the actual
2409 operand.
2410
2411 The comparison is then effected by subtracting the second operand from
2412 the first and then returning a value according to the result of the
2413 subtraction: '-1' if the result is less than zero, '0' if the result is
2414 zero or negative zero, or '1' if the result is greater than zero.
2415
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002416 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002417 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002418 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002419 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002420 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002421 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002422 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002423 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002424 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002425 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002426 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002427 Decimal("-1")
2428 """
2429 return a.compare(b, context=self)
2430
2431 def divide(self, a, b):
2432 """Decimal division in a specified context.
2433
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002434 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002435 Decimal("0.333333333")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002436 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002437 Decimal("0.666666667")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002438 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002439 Decimal("2.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002440 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002441 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002442 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002443 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002444 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002445 Decimal("4.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002446 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002447 Decimal("1.20")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002448 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002449 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002450 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002451 Decimal("1000")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002452 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002453 Decimal("1.20E+6")
2454 """
Neal Norwitzbcc0db82006-03-24 08:14:36 +00002455 return a.__truediv__(b, context=self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002456
2457 def divide_int(self, a, b):
2458 """Divides two numbers and returns the integer part of the result.
2459
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002460 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002461 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002462 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002463 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002464 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002465 Decimal("3")
2466 """
2467 return a.__floordiv__(b, context=self)
2468
2469 def divmod(self, a, b):
2470 return a.__divmod__(b, context=self)
2471
2472 def max(self, a,b):
2473 """max compares two values numerically and returns the maximum.
2474
2475 If either operand is a NaN then the general rules apply.
2476 Otherwise, the operands are compared as as though by the compare
2477 operation. If they are numerically equal then the left-hand operand
2478 is chosen as the result. Otherwise the maximum (closer to positive
2479 infinity) of the two operands is chosen as the result.
2480
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002481 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002482 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002483 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002484 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002485 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002486 Decimal("1")
2487 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
2488 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002489 """
2490 return a.max(b, context=self)
2491
2492 def min(self, a,b):
2493 """min compares two values numerically and returns the minimum.
2494
2495 If either operand is a NaN then the general rules apply.
2496 Otherwise, the operands are compared as as though by the compare
2497 operation. If they are numerically equal then the left-hand operand
2498 is chosen as the result. Otherwise the minimum (closer to negative
2499 infinity) of the two operands is chosen as the result.
2500
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002501 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002502 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002503 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002504 Decimal("-10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002505 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002506 Decimal("1.0")
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002507 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
2508 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002509 """
2510 return a.min(b, context=self)
2511
2512 def minus(self, a):
2513 """Minus corresponds to unary prefix minus in Python.
2514
2515 The operation is evaluated using the same rules as subtract; the
2516 operation minus(a) is calculated as subtract('0', a) where the '0'
2517 has the same exponent as the operand.
2518
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002519 >>> ExtendedContext.minus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002520 Decimal("-1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002521 >>> ExtendedContext.minus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002522 Decimal("1.3")
2523 """
2524 return a.__neg__(context=self)
2525
2526 def multiply(self, a, b):
2527 """multiply multiplies two operands.
2528
2529 If either operand is a special value then the general rules apply.
2530 Otherwise, the operands are multiplied together ('long multiplication'),
2531 resulting in a number which may be as long as the sum of the lengths
2532 of the two operands.
2533
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002534 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002535 Decimal("3.60")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002536 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002537 Decimal("21")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002538 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002539 Decimal("0.72")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002540 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002541 Decimal("-0.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002542 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002543 Decimal("4.28135971E+11")
2544 """
2545 return a.__mul__(b, context=self)
2546
2547 def normalize(self, a):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002548 """normalize reduces an operand to its simplest form.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002549
2550 Essentially a plus operation with all trailing zeros removed from the
2551 result.
2552
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002553 >>> ExtendedContext.normalize(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002554 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002555 >>> ExtendedContext.normalize(Decimal('-2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002556 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002557 >>> ExtendedContext.normalize(Decimal('1.200'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002558 Decimal("1.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002559 >>> ExtendedContext.normalize(Decimal('-120'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002560 Decimal("-1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002561 >>> ExtendedContext.normalize(Decimal('120.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002562 Decimal("1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002563 >>> ExtendedContext.normalize(Decimal('0.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002564 Decimal("0")
2565 """
2566 return a.normalize(context=self)
2567
2568 def plus(self, a):
2569 """Plus corresponds to unary prefix plus in Python.
2570
2571 The operation is evaluated using the same rules as add; the
2572 operation plus(a) is calculated as add('0', a) where the '0'
2573 has the same exponent as the operand.
2574
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002575 >>> ExtendedContext.plus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002576 Decimal("1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002577 >>> ExtendedContext.plus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002578 Decimal("-1.3")
2579 """
2580 return a.__pos__(context=self)
2581
2582 def power(self, a, b, modulo=None):
2583 """Raises a to the power of b, to modulo if given.
2584
2585 The right-hand operand must be a whole number whose integer part (after
2586 any exponent has been applied) has no more than 9 digits and whose
2587 fractional part (if any) is all zeros before any rounding. The operand
2588 may be positive, negative, or zero; if negative, the absolute value of
2589 the power is used, and the left-hand operand is inverted (divided into
2590 1) before use.
2591
2592 If the increased precision needed for the intermediate calculations
2593 exceeds the capabilities of the implementation then an Invalid operation
2594 condition is raised.
2595
2596 If, when raising to a negative power, an underflow occurs during the
2597 division into 1, the operation is not halted at that point but
2598 continues.
2599
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002600 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002601 Decimal("8")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002602 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002603 Decimal("0.125")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002604 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002605 Decimal("69.7575744")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002606 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002607 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002608 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002609 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002610 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002611 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002612 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002613 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002614 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002615 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002616 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002617 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002618 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002619 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002620 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002621 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002622 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002623 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002624 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002625 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002626 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002627 Decimal("NaN")
2628 """
2629 return a.__pow__(b, modulo, context=self)
2630
2631 def quantize(self, a, b):
2632 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
2633
2634 The coefficient of the result is derived from that of the left-hand
2635 operand. It may be rounded using the current rounding setting (if the
2636 exponent is being increased), multiplied by a positive power of ten (if
2637 the exponent is being decreased), or is unchanged (if the exponent is
2638 already equal to that of the right-hand operand).
2639
2640 Unlike other operations, if the length of the coefficient after the
2641 quantize operation would be greater than precision then an Invalid
2642 operation condition is raised. This guarantees that, unless there is an
2643 error condition, the exponent of the result of a quantize is always
2644 equal to that of the right-hand operand.
2645
2646 Also unlike other operations, quantize will never raise Underflow, even
2647 if the result is subnormal and inexact.
2648
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002649 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002650 Decimal("2.170")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002651 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002652 Decimal("2.17")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002653 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002654 Decimal("2.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002655 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002656 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002657 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002658 Decimal("0E+1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002659 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002660 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002661 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002662 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002663 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002664 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002665 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002666 Decimal("-0E+5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002667 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002668 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002669 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002670 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002671 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002672 Decimal("217.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002673 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002674 Decimal("217")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002675 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002676 Decimal("2.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002677 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002678 Decimal("2E+2")
2679 """
2680 return a.quantize(b, context=self)
2681
2682 def remainder(self, a, b):
2683 """Returns the remainder from integer division.
2684
2685 The result is the residue of the dividend after the operation of
2686 calculating integer division as described for divide-integer, rounded to
2687 precision digits if necessary. The sign of the result, if non-zero, is
2688 the same as that of the original dividend.
2689
2690 This operation will fail under the same conditions as integer division
2691 (that is, if integer division on the same two operands would fail, the
2692 remainder cannot be calculated).
2693
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002694 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002695 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002696 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002697 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002698 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002699 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002700 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002701 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002702 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002703 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002704 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002705 Decimal("1.0")
2706 """
2707 return a.__mod__(b, context=self)
2708
2709 def remainder_near(self, a, b):
2710 """Returns to be "a - b * n", where n is the integer nearest the exact
2711 value of "x / b" (if two integers are equally near then the even one
2712 is chosen). If the result is equal to 0 then its sign will be the
2713 sign of a.
2714
2715 This operation will fail under the same conditions as integer division
2716 (that is, if integer division on the same two operands would fail, the
2717 remainder cannot be calculated).
2718
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002719 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002720 Decimal("-0.9")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002721 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002722 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002723 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002724 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002725 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002726 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002727 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002728 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002729 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002730 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002731 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002732 Decimal("-0.3")
2733 """
2734 return a.remainder_near(b, context=self)
2735
2736 def same_quantum(self, a, b):
2737 """Returns True if the two operands have the same exponent.
2738
2739 The result is never affected by either the sign or the coefficient of
2740 either operand.
2741
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002742 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002743 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002744 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002745 True
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002746 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002747 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002748 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002749 True
2750 """
2751 return a.same_quantum(b)
2752
2753 def sqrt(self, a):
2754 """Returns the square root of a non-negative number to context precision.
2755
2756 If the result must be inexact, it is rounded using the round-half-even
2757 algorithm.
2758
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002759 >>> ExtendedContext.sqrt(Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002760 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002761 >>> ExtendedContext.sqrt(Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002762 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002763 >>> ExtendedContext.sqrt(Decimal('0.39'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002764 Decimal("0.624499800")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002765 >>> ExtendedContext.sqrt(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002766 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002767 >>> ExtendedContext.sqrt(Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002768 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002769 >>> ExtendedContext.sqrt(Decimal('1.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002770 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002771 >>> ExtendedContext.sqrt(Decimal('1.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002772 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002773 >>> ExtendedContext.sqrt(Decimal('7'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002774 Decimal("2.64575131")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002775 >>> ExtendedContext.sqrt(Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002776 Decimal("3.16227766")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002777 >>> ExtendedContext.prec
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002778 9
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002779 """
2780 return a.sqrt(context=self)
2781
2782 def subtract(self, a, b):
Georg Brandlf33d01d2005-08-22 19:35:18 +00002783 """Return the difference between the two operands.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002784
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002785 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002786 Decimal("0.23")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002787 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002788 Decimal("0.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002789 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002790 Decimal("-0.77")
2791 """
2792 return a.__sub__(b, context=self)
2793
2794 def to_eng_string(self, a):
2795 """Converts a number to a string, using scientific notation.
2796
2797 The operation is not affected by the context.
2798 """
2799 return a.to_eng_string(context=self)
2800
2801 def to_sci_string(self, a):
2802 """Converts a number to a string, using scientific notation.
2803
2804 The operation is not affected by the context.
2805 """
2806 return a.__str__(context=self)
2807
2808 def to_integral(self, a):
2809 """Rounds to an integer.
2810
2811 When the operand has a negative exponent, the result is the same
2812 as using the quantize() operation using the given operand as the
2813 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2814 of the operand as the precision setting, except that no flags will
2815 be set. The rounding mode is taken from the context.
2816
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002817 >>> ExtendedContext.to_integral(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002818 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002819 >>> ExtendedContext.to_integral(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002820 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002821 >>> ExtendedContext.to_integral(Decimal('100.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002822 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002823 >>> ExtendedContext.to_integral(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002824 Decimal("102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002825 >>> ExtendedContext.to_integral(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002826 Decimal("-102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002827 >>> ExtendedContext.to_integral(Decimal('10E+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002828 Decimal("1.0E+6")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002829 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002830 Decimal("7.89E+77")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002831 >>> ExtendedContext.to_integral(Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002832 Decimal("-Infinity")
2833 """
2834 return a.to_integral(context=self)
2835
2836class _WorkRep(object):
2837 __slots__ = ('sign','int','exp')
Raymond Hettinger17931de2004-10-27 06:21:46 +00002838 # sign: 0 or 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002839 # int: int or long
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002840 # exp: None, int, or string
2841
2842 def __init__(self, value=None):
2843 if value is None:
2844 self.sign = None
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002845 self.int = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002846 self.exp = None
Raymond Hettinger17931de2004-10-27 06:21:46 +00002847 elif isinstance(value, Decimal):
2848 self.sign = value._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002849 cum = 0
Raymond Hettinger17931de2004-10-27 06:21:46 +00002850 for digit in value._int:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002851 cum = cum * 10 + digit
2852 self.int = cum
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002853 self.exp = value._exp
Raymond Hettinger17931de2004-10-27 06:21:46 +00002854 else:
2855 # assert isinstance(value, tuple)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002856 self.sign = value[0]
2857 self.int = value[1]
2858 self.exp = value[2]
2859
2860 def __repr__(self):
2861 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2862
2863 __str__ = __repr__
2864
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002865
2866
2867def _normalize(op1, op2, shouldround = 0, prec = 0):
2868 """Normalizes op1, op2 to have the same exp and length of coefficient.
2869
2870 Done during addition.
2871 """
2872 # Yes, the exponent is a long, but the difference between exponents
2873 # must be an int-- otherwise you'd get a big memory problem.
2874 numdigits = int(op1.exp - op2.exp)
2875 if numdigits < 0:
2876 numdigits = -numdigits
2877 tmp = op2
2878 other = op1
2879 else:
2880 tmp = op1
2881 other = op2
2882
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002883
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002884 if shouldround and numdigits > prec + 1:
2885 # Big difference in exponents - check the adjusted exponents
2886 tmp_len = len(str(tmp.int))
2887 other_len = len(str(other.int))
2888 if numdigits > (other_len + prec + 1 - tmp_len):
2889 # If the difference in adjusted exps is > prec+1, we know
2890 # other is insignificant, so might as well put a 1 after the precision.
2891 # (since this is only for addition.) Also stops use of massive longs.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002892
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002893 extend = prec + 2 - tmp_len
2894 if extend <= 0:
2895 extend = 1
2896 tmp.int *= 10 ** extend
2897 tmp.exp -= extend
2898 other.int = 1
2899 other.exp = tmp.exp
2900 return op1, op2
2901
2902 tmp.int *= 10 ** numdigits
2903 tmp.exp -= numdigits
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002904 return op1, op2
2905
2906def _adjust_coefficients(op1, op2):
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002907 """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002908
2909 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2910
2911 Used on _WorkRep instances during division.
2912 """
2913 adjust = 0
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002914 #If op1 is smaller, make it larger
2915 while op2.int > op1.int:
2916 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002917 op1.exp -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002918 adjust += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002919
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002920 #If op2 is too small, make it larger
2921 while op1.int >= (10 * op2.int):
2922 op2.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002923 op2.exp -= 1
2924 adjust -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002925
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002926 return op1, op2, adjust
2927
2928##### Helper Functions ########################################
2929
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002930def _convert_other(other):
2931 """Convert other to Decimal.
2932
2933 Verifies that it's ok to use in an implicit construction.
2934 """
2935 if isinstance(other, Decimal):
2936 return other
2937 if isinstance(other, (int, long)):
2938 return Decimal(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002939 return NotImplemented
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002940
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002941_infinity_map = {
2942 'inf' : 1,
2943 'infinity' : 1,
2944 '+inf' : 1,
2945 '+infinity' : 1,
2946 '-inf' : -1,
2947 '-infinity' : -1
2948}
2949
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002950def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002951 """Determines whether a string or float is infinity.
2952
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002953 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002954 """
2955 num = str(num).lower()
2956 return _infinity_map.get(num, 0)
2957
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002958def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002959 """Determines whether a string or float is NaN
2960
2961 (1, sign, diagnostic info as string) => NaN
2962 (2, sign, diagnostic info as string) => sNaN
2963 0 => not a NaN
2964 """
2965 num = str(num).lower()
2966 if not num:
2967 return 0
2968
2969 #get the sign, get rid of trailing [+-]
2970 sign = 0
2971 if num[0] == '+':
2972 num = num[1:]
2973 elif num[0] == '-': #elif avoids '+-nan'
2974 num = num[1:]
2975 sign = 1
2976
2977 if num.startswith('nan'):
2978 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
2979 return 0
2980 return (1, sign, num[3:].lstrip('0'))
2981 if num.startswith('snan'):
2982 if len(num) > 4 and not num[4:].isdigit():
2983 return 0
2984 return (2, sign, num[4:].lstrip('0'))
2985 return 0
2986
2987
2988##### Setup Specific Contexts ################################
2989
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002990# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00002991# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002992
2993DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002994 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002995 traps=[DivisionByZero, Overflow, InvalidOperation],
2996 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002997 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00002998 Emax=999999999,
2999 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00003000 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003001)
3002
3003# Pre-made alternate contexts offered by the specification
3004# Don't change these; the user should be able to select these
3005# contexts and be able to reproduce results from other implementations
3006# of the spec.
3007
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003008BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003009 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003010 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
3011 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003012)
3013
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003014ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003015 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003016 traps=[],
3017 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003018)
3019
3020
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00003021##### Useful Constants (internal use only) ####################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003022
3023#Reusable defaults
3024Inf = Decimal('Inf')
3025negInf = Decimal('-Inf')
3026
3027#Infsign[sign] is infinity w/ that sign
3028Infsign = (Inf, negInf)
3029
3030NaN = Decimal('NaN')
3031
3032
3033##### crud for parsing strings #################################
3034import re
3035
3036# There's an optional sign at the start, and an optional exponent
3037# at the end. The exponent has an optional sign and at least one
3038# digit. In between, must have either at least one digit followed
3039# by an optional fraction, or a decimal point followed by at least
3040# one digit. Yuck.
3041
3042_parser = re.compile(r"""
3043# \s*
3044 (?P<sign>[-+])?
3045 (
3046 (?P<int>\d+) (\. (?P<frac>\d*))?
3047 |
3048 \. (?P<onlyfrac>\d+)
3049 )
3050 ([eE](?P<exp>[-+]? \d+))?
3051# \s*
3052 $
3053""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
3054
3055del re
3056
3057# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
3058
3059def _string2exact(s):
3060 m = _parser(s)
3061 if m is None:
3062 raise ValueError("invalid literal for Decimal: %r" % s)
3063
3064 if m.group('sign') == "-":
3065 sign = 1
3066 else:
3067 sign = 0
3068
3069 exp = m.group('exp')
3070 if exp is None:
3071 exp = 0
3072 else:
3073 exp = int(exp)
3074
3075 intpart = m.group('int')
3076 if intpart is None:
3077 intpart = ""
3078 fracpart = m.group('onlyfrac')
3079 else:
3080 fracpart = m.group('frac')
3081 if fracpart is None:
3082 fracpart = ""
3083
3084 exp -= len(fracpart)
3085
3086 mantissa = intpart + fracpart
3087 tmp = map(int, mantissa)
3088 backup = tmp
3089 while tmp and tmp[0] == 0:
3090 del tmp[0]
3091
3092 # It's a zero
3093 if not tmp:
3094 if backup:
3095 return (sign, tuple(backup), exp)
3096 return (sign, (0,), exp)
3097 mantissa = tuple(tmp)
3098
3099 return (sign, mantissa, exp)
3100
3101
3102if __name__ == '__main__':
3103 import doctest, sys
3104 doctest.testmod(sys.modules[__name__])