blob: 967f101c61b553ba69cd503c604b7a718edf1dd2 [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
734 # Normalization assures that hast(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
1138 def __div__(self, other, context=None):
1139 """Return self / other."""
1140 return self._divide(other, context=context)
1141 __truediv__ = __div__
1142
1143 def _divide(self, other, divmod = 0, context=None):
1144 """Return a / b, to context.prec precision.
1145
1146 divmod:
1147 0 => true division
1148 1 => (a //b, a%b)
1149 2 => a //b
1150 3 => a%b
1151
1152 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1153 computing the other value are not raised.
1154 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001155 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001156 if other is NotImplemented:
1157 if divmod in (0, 1):
1158 return NotImplemented
1159 return (NotImplemented, NotImplemented)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001160
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001161 if context is None:
1162 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001163
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001164 sign = self._sign ^ other._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001165
1166 if self._is_special or other._is_special:
1167 ans = self._check_nans(other, context)
1168 if ans:
1169 if divmod:
1170 return (ans, ans)
1171 return ans
1172
1173 if self._isinfinity() and other._isinfinity():
1174 if divmod:
1175 return (context._raise_error(InvalidOperation,
1176 '(+-)INF // (+-)INF'),
1177 context._raise_error(InvalidOperation,
1178 '(+-)INF % (+-)INF'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001179 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001180
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001181 if self._isinfinity():
1182 if divmod == 1:
1183 return (Infsign[sign],
1184 context._raise_error(InvalidOperation, 'INF % x'))
1185 elif divmod == 2:
1186 return (Infsign[sign], NaN)
1187 elif divmod == 3:
1188 return (Infsign[sign],
1189 context._raise_error(InvalidOperation, 'INF % x'))
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001190 return Infsign[sign]
1191
1192 if other._isinfinity():
1193 if divmod:
1194 return (Decimal((sign, (0,), 0)), Decimal(self))
1195 context._raise_error(Clamped, 'Division by infinity')
1196 return Decimal((sign, (0,), context.Etiny()))
1197
1198 # Special cases for zeroes
1199 if not self and not other:
1200 if divmod:
1201 return context._raise_error(DivisionUndefined, '0 / 0', 1)
1202 return context._raise_error(DivisionUndefined, '0 / 0')
1203
1204 if not self:
1205 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001206 otherside = Decimal(self)
1207 otherside._exp = min(self._exp, other._exp)
1208 return (Decimal((sign, (0,), 0)), otherside)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001209 exp = self._exp - other._exp
1210 if exp < context.Etiny():
1211 exp = context.Etiny()
1212 context._raise_error(Clamped, '0e-x / y')
1213 if exp > context.Emax:
1214 exp = context.Emax
1215 context._raise_error(Clamped, '0e+x / y')
1216 return Decimal( (sign, (0,), exp) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001217
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001218 if not other:
1219 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001220 return context._raise_error(DivisionByZero, 'divmod(x,0)',
1221 sign, 1)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001222 return context._raise_error(DivisionByZero, 'x / 0', sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001223
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001224 #OK, so neither = 0, INF or NaN
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001225
1226 shouldround = context._rounding_decision == ALWAYS_ROUND
1227
1228 #If we're dividing into ints, and self < other, stop.
1229 #self.__abs__(0) does not round.
1230 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
1231
1232 if divmod == 1 or divmod == 3:
1233 exp = min(self._exp, other._exp)
1234 ans2 = self._rescale(exp, context=context, watchexp=0)
1235 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001236 ans2 = ans2._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001237 return (Decimal( (sign, (0,), 0) ),
1238 ans2)
1239
1240 elif divmod == 2:
1241 #Don't round the mod part, if we don't need it.
1242 return (Decimal( (sign, (0,), 0) ), Decimal(self))
1243
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001244 op1 = _WorkRep(self)
1245 op2 = _WorkRep(other)
1246 op1, op2, adjust = _adjust_coefficients(op1, op2)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001247 res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001248 if divmod and res.exp > context.prec + 1:
1249 return context._raise_error(DivisionImpossible)
1250
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001251 prec_limit = 10 ** context.prec
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001252 while 1:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001253 while op2.int <= op1.int:
1254 res.int += 1
1255 op1.int -= op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001256 if res.exp == 0 and divmod:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001257 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001258 return context._raise_error(DivisionImpossible)
1259 otherside = Decimal(op1)
1260 frozen = context._ignore_all_flags()
1261
1262 exp = min(self._exp, other._exp)
Raymond Hettinger17931de2004-10-27 06:21:46 +00001263 otherside = otherside._rescale(exp, context=context, watchexp=0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001264 context._regard_flags(*frozen)
1265 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001266 otherside = otherside._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001267 return (Decimal(res), otherside)
1268
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001269 if op1.int == 0 and adjust >= 0 and not divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001270 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001271 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001272 if divmod:
1273 return context._raise_error(DivisionImpossible)
1274 shouldround=1
1275 # Really, the answer is a bit higher, so adding a one to
1276 # the end will make sure the rounding is right.
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001277 if op1.int != 0:
1278 res.int *= 10
1279 res.int += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001280 res.exp -= 1
1281
1282 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001283 res.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001284 res.exp -= 1
1285 adjust += 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001286 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001287 op1.exp -= 1
1288
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001289 if res.exp == 0 and divmod and op2.int > op1.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001290 #Solves an error in precision. Same as a previous block.
1291
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001292 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001293 return context._raise_error(DivisionImpossible)
1294 otherside = Decimal(op1)
1295 frozen = context._ignore_all_flags()
1296
1297 exp = min(self._exp, other._exp)
1298 otherside = otherside._rescale(exp, context=context)
1299
1300 context._regard_flags(*frozen)
1301
1302 return (Decimal(res), otherside)
1303
1304 ans = Decimal(res)
1305 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001306 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001307 return ans
1308
1309 def __rdiv__(self, other, context=None):
1310 """Swaps self/other and returns __div__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001311 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001312 if other is NotImplemented:
1313 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001314 return other.__div__(self, context=context)
1315 __rtruediv__ = __rdiv__
1316
1317 def __divmod__(self, other, context=None):
1318 """
1319 (self // other, self % other)
1320 """
1321 return self._divide(other, 1, context)
1322
1323 def __rdivmod__(self, other, context=None):
1324 """Swaps self/other and returns __divmod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001325 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001326 if other is NotImplemented:
1327 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001328 return other.__divmod__(self, context=context)
1329
1330 def __mod__(self, other, context=None):
1331 """
1332 self % other
1333 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001334 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001335 if other is NotImplemented:
1336 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001337
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001338 if self._is_special or other._is_special:
1339 ans = self._check_nans(other, context)
1340 if ans:
1341 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001342
1343 if self and not other:
1344 return context._raise_error(InvalidOperation, 'x % 0')
1345
1346 return self._divide(other, 3, context)[1]
1347
1348 def __rmod__(self, other, context=None):
1349 """Swaps self/other and returns __mod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001350 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001351 if other is NotImplemented:
1352 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001353 return other.__mod__(self, context=context)
1354
1355 def remainder_near(self, other, context=None):
1356 """
1357 Remainder nearest to 0- abs(remainder-near) <= other/2
1358 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001359 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001360 if other is NotImplemented:
1361 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001362
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001363 if self._is_special or other._is_special:
1364 ans = self._check_nans(other, context)
1365 if ans:
1366 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001367 if self and not other:
1368 return context._raise_error(InvalidOperation, 'x % 0')
1369
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001370 if context is None:
1371 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001372 # If DivisionImpossible causes an error, do not leave Rounded/Inexact
1373 # ignored in the calling function.
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001374 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001375 flags = context._ignore_flags(Rounded, Inexact)
1376 #keep DivisionImpossible flags
1377 (side, r) = self.__divmod__(other, context=context)
1378
1379 if r._isnan():
1380 context._regard_flags(*flags)
1381 return r
1382
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001383 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001384 rounding = context._set_rounding_decision(NEVER_ROUND)
1385
1386 if other._sign:
1387 comparison = other.__div__(Decimal(-2), context=context)
1388 else:
1389 comparison = other.__div__(Decimal(2), context=context)
1390
1391 context._set_rounding_decision(rounding)
1392 context._regard_flags(*flags)
1393
1394 s1, s2 = r._sign, comparison._sign
1395 r._sign, comparison._sign = 0, 0
1396
1397 if r < comparison:
1398 r._sign, comparison._sign = s1, s2
1399 #Get flags now
1400 self.__divmod__(other, context=context)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001401 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001402 r._sign, comparison._sign = s1, s2
1403
1404 rounding = context._set_rounding_decision(NEVER_ROUND)
1405
1406 (side, r) = self.__divmod__(other, context=context)
1407 context._set_rounding_decision(rounding)
1408 if r._isnan():
1409 return r
1410
1411 decrease = not side._iseven()
1412 rounding = context._set_rounding_decision(NEVER_ROUND)
1413 side = side.__abs__(context=context)
1414 context._set_rounding_decision(rounding)
1415
1416 s1, s2 = r._sign, comparison._sign
1417 r._sign, comparison._sign = 0, 0
1418 if r > comparison or decrease and r == comparison:
1419 r._sign, comparison._sign = s1, s2
1420 context.prec += 1
1421 if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
1422 context.prec -= 1
1423 return context._raise_error(DivisionImpossible)[1]
1424 context.prec -= 1
1425 if self._sign == other._sign:
1426 r = r.__sub__(other, context=context)
1427 else:
1428 r = r.__add__(other, context=context)
1429 else:
1430 r._sign, comparison._sign = s1, s2
1431
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001432 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001433
1434 def __floordiv__(self, other, context=None):
1435 """self // other"""
1436 return self._divide(other, 2, context)[0]
1437
1438 def __rfloordiv__(self, other, context=None):
1439 """Swaps self/other and returns __floordiv__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001440 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001441 if other is NotImplemented:
1442 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001443 return other.__floordiv__(self, context=context)
1444
1445 def __float__(self):
1446 """Float representation."""
1447 return float(str(self))
1448
1449 def __int__(self):
Brett Cannon46b08022005-03-01 03:12:26 +00001450 """Converts self to an int, truncating if necessary."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001451 if self._is_special:
1452 if self._isnan():
1453 context = getcontext()
1454 return context._raise_error(InvalidContext)
1455 elif self._isinfinity():
1456 raise OverflowError, "Cannot convert infinity to long"
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001457 if self._exp >= 0:
Raymond Hettinger605ed022004-11-24 07:28:48 +00001458 s = ''.join(map(str, self._int)) + '0'*self._exp
1459 else:
1460 s = ''.join(map(str, self._int))[:self._exp]
1461 if s == '':
1462 s = '0'
1463 sign = '-'*self._sign
1464 return int(sign + s)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001465
1466 def __long__(self):
1467 """Converts to a long.
1468
1469 Equivalent to long(int(self))
1470 """
1471 return long(self.__int__())
1472
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001473 def _fix(self, context):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001474 """Round if it is necessary to keep self within prec precision.
1475
1476 Rounds and fixes the exponent. Does not raise on a sNaN.
1477
1478 Arguments:
1479 self - Decimal instance
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001480 context - context used.
1481 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001482 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001483 return self
1484 if context is None:
1485 context = getcontext()
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001486 prec = context.prec
Facundo Batista99b55482004-10-26 23:38:46 +00001487 ans = self._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001488 if len(ans._int) > prec:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001489 ans = ans._round(prec, context=context)
Facundo Batista99b55482004-10-26 23:38:46 +00001490 ans = ans._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001491 return ans
1492
Facundo Batista99b55482004-10-26 23:38:46 +00001493 def _fixexponents(self, context):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001494 """Fix the exponents and return a copy with the exponent in bounds.
1495 Only call if known to not be a special value.
1496 """
1497 folddown = context._clamp
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001498 Emin = context.Emin
Facundo Batista99b55482004-10-26 23:38:46 +00001499 ans = self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001500 ans_adjusted = ans.adjusted()
1501 if ans_adjusted < Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001502 Etiny = context.Etiny()
1503 if ans._exp < Etiny:
1504 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001505 ans = Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001506 ans._exp = Etiny
1507 context._raise_error(Clamped)
1508 return ans
1509 ans = ans._rescale(Etiny, context=context)
1510 #It isn't zero, and exp < Emin => subnormal
1511 context._raise_error(Subnormal)
1512 if context.flags[Inexact]:
1513 context._raise_error(Underflow)
1514 else:
1515 if ans:
1516 #Only raise subnormal if non-zero.
1517 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001518 else:
1519 Etop = context.Etop()
1520 if folddown and ans._exp > Etop:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001521 context._raise_error(Clamped)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001522 ans = ans._rescale(Etop, context=context)
1523 else:
1524 Emax = context.Emax
1525 if ans_adjusted > Emax:
1526 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001527 ans = Decimal(self)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001528 ans._exp = Emax
1529 context._raise_error(Clamped)
1530 return ans
1531 context._raise_error(Inexact)
1532 context._raise_error(Rounded)
1533 return context._raise_error(Overflow, 'above Emax', ans._sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001534 return ans
1535
1536 def _round(self, prec=None, rounding=None, context=None):
1537 """Returns a rounded version of self.
1538
1539 You can specify the precision or rounding method. Otherwise, the
1540 context determines it.
1541 """
1542
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001543 if self._is_special:
1544 ans = self._check_nans(context=context)
1545 if ans:
1546 return ans
1547
1548 if self._isinfinity():
1549 return Decimal(self)
1550
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001551 if context is None:
1552 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001553
1554 if rounding is None:
1555 rounding = context.rounding
1556 if prec is None:
1557 prec = context.prec
1558
1559 if not self:
1560 if prec <= 0:
1561 dig = (0,)
1562 exp = len(self._int) - prec + self._exp
1563 else:
1564 dig = (0,) * prec
1565 exp = len(self._int) + self._exp - prec
1566 ans = Decimal((self._sign, dig, exp))
1567 context._raise_error(Rounded)
1568 return ans
1569
1570 if prec == 0:
1571 temp = Decimal(self)
1572 temp._int = (0,)+temp._int
1573 prec = 1
1574 elif prec < 0:
1575 exp = self._exp + len(self._int) - prec - 1
1576 temp = Decimal( (self._sign, (0, 1), exp))
1577 prec = 1
1578 else:
1579 temp = Decimal(self)
1580
1581 numdigits = len(temp._int)
1582 if prec == numdigits:
1583 return temp
1584
1585 # See if we need to extend precision
1586 expdiff = prec - numdigits
1587 if expdiff > 0:
1588 tmp = list(temp._int)
1589 tmp.extend([0] * expdiff)
1590 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff))
1591 return ans
1592
1593 #OK, but maybe all the lost digits are 0.
1594 lostdigits = self._int[expdiff:]
1595 if lostdigits == (0,) * len(lostdigits):
1596 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
1597 #Rounded, but not Inexact
1598 context._raise_error(Rounded)
1599 return ans
1600
1601 # Okay, let's round and lose data
1602
1603 this_function = getattr(temp, self._pick_rounding_function[rounding])
1604 #Now we've got the rounding function
1605
1606 if prec != context.prec:
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001607 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001608 context.prec = prec
1609 ans = this_function(prec, expdiff, context)
1610 context._raise_error(Rounded)
1611 context._raise_error(Inexact, 'Changed in rounding')
1612
1613 return ans
1614
1615 _pick_rounding_function = {}
1616
1617 def _round_down(self, prec, expdiff, context):
1618 """Also known as round-towards-0, truncate."""
1619 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1620
1621 def _round_half_up(self, prec, expdiff, context, tmp = None):
1622 """Rounds 5 up (away from 0)"""
1623
1624 if tmp is None:
1625 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
1626 if self._int[prec] >= 5:
1627 tmp = tmp._increment(round=0, context=context)
1628 if len(tmp._int) > prec:
1629 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1630 return tmp
1631
1632 def _round_half_even(self, prec, expdiff, context):
1633 """Round 5 to even, rest to nearest."""
1634
1635 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1636 half = (self._int[prec] == 5)
1637 if half:
1638 for digit in self._int[prec+1:]:
1639 if digit != 0:
1640 half = 0
1641 break
1642 if half:
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001643 if self._int[prec-1] & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001644 return tmp
1645 return self._round_half_up(prec, expdiff, context, tmp)
1646
1647 def _round_half_down(self, prec, expdiff, context):
1648 """Round 5 down"""
1649
1650 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1651 half = (self._int[prec] == 5)
1652 if half:
1653 for digit in self._int[prec+1:]:
1654 if digit != 0:
1655 half = 0
1656 break
1657 if half:
1658 return tmp
1659 return self._round_half_up(prec, expdiff, context, tmp)
1660
1661 def _round_up(self, prec, expdiff, context):
1662 """Rounds away from 0."""
1663 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1664 for digit in self._int[prec:]:
1665 if digit != 0:
1666 tmp = tmp._increment(round=1, context=context)
1667 if len(tmp._int) > prec:
1668 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1669 else:
1670 return tmp
1671 return tmp
1672
1673 def _round_ceiling(self, prec, expdiff, context):
1674 """Rounds up (not away from 0 if negative.)"""
1675 if self._sign:
1676 return self._round_down(prec, expdiff, context)
1677 else:
1678 return self._round_up(prec, expdiff, context)
1679
1680 def _round_floor(self, prec, expdiff, context):
1681 """Rounds down (not towards 0 if negative)"""
1682 if not self._sign:
1683 return self._round_down(prec, expdiff, context)
1684 else:
1685 return self._round_up(prec, expdiff, context)
1686
1687 def __pow__(self, n, modulo = None, context=None):
1688 """Return self ** n (mod modulo)
1689
1690 If modulo is None (default), don't take it mod modulo.
1691 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001692 n = _convert_other(n)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001693 if n is NotImplemented:
1694 return n
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001695
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001696 if context is None:
1697 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001698
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001699 if self._is_special or n._is_special or n.adjusted() > 8:
1700 #Because the spot << doesn't work with really big exponents
1701 if n._isinfinity() or n.adjusted() > 8:
1702 return context._raise_error(InvalidOperation, 'x ** INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001703
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001704 ans = self._check_nans(n, context)
1705 if ans:
1706 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001707
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001708 if not n._isinteger():
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001709 return context._raise_error(InvalidOperation, 'x ** (non-integer)')
1710
1711 if not self and not n:
1712 return context._raise_error(InvalidOperation, '0 ** 0')
1713
1714 if not n:
1715 return Decimal(1)
1716
1717 if self == Decimal(1):
1718 return Decimal(1)
1719
1720 sign = self._sign and not n._iseven()
1721 n = int(n)
1722
1723 if self._isinfinity():
1724 if modulo:
1725 return context._raise_error(InvalidOperation, 'INF % x')
1726 if n > 0:
1727 return Infsign[sign]
1728 return Decimal( (sign, (0,), 0) )
1729
1730 #with ludicrously large exponent, just raise an overflow and return inf.
1731 if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
1732 and self:
1733
1734 tmp = Decimal('inf')
1735 tmp._sign = sign
1736 context._raise_error(Rounded)
1737 context._raise_error(Inexact)
1738 context._raise_error(Overflow, 'Big power', sign)
1739 return tmp
1740
1741 elength = len(str(abs(n)))
1742 firstprec = context.prec
1743
Raymond Hettinger99148e72004-07-14 19:56:56 +00001744 if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001745 return context._raise_error(Overflow, 'Too much precision.', sign)
1746
1747 mul = Decimal(self)
1748 val = Decimal(1)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001749 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001750 context.prec = firstprec + elength + 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001751 if n < 0:
1752 #n is a long now, not Decimal instance
1753 n = -n
1754 mul = Decimal(1).__div__(mul, context=context)
1755
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001756 spot = 1
1757 while spot <= n:
1758 spot <<= 1
1759
1760 spot >>= 1
1761 #Spot is the highest power of 2 less than n
1762 while spot:
1763 val = val.__mul__(val, context=context)
1764 if val._isinfinity():
1765 val = Infsign[sign]
1766 break
1767 if spot & n:
1768 val = val.__mul__(mul, context=context)
1769 if modulo is not None:
1770 val = val.__mod__(modulo, context=context)
1771 spot >>= 1
1772 context.prec = firstprec
1773
Raymond Hettinger76e60d62004-10-20 06:58:28 +00001774 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001775 return val._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001776 return val
1777
1778 def __rpow__(self, other, context=None):
1779 """Swaps self/other and returns __pow__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001780 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001781 if other is NotImplemented:
1782 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001783 return other.__pow__(self, context=context)
1784
1785 def normalize(self, context=None):
1786 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001787
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001788 if self._is_special:
1789 ans = self._check_nans(context=context)
1790 if ans:
1791 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001792
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001793 dup = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001794 if dup._isinfinity():
1795 return dup
1796
1797 if not dup:
1798 return Decimal( (dup._sign, (0,), 0) )
1799 end = len(dup._int)
1800 exp = dup._exp
1801 while dup._int[end-1] == 0:
1802 exp += 1
1803 end -= 1
1804 return Decimal( (dup._sign, dup._int[:end], exp) )
1805
1806
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001807 def quantize(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001808 """Quantize self so its exponent is the same as that of exp.
1809
1810 Similar to self._rescale(exp._exp) but with error checking.
1811 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001812 if self._is_special or exp._is_special:
1813 ans = self._check_nans(exp, context)
1814 if ans:
1815 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001816
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001817 if exp._isinfinity() or self._isinfinity():
1818 if exp._isinfinity() and self._isinfinity():
1819 return self #if both are inf, it is OK
1820 if context is None:
1821 context = getcontext()
1822 return context._raise_error(InvalidOperation,
1823 'quantize with one INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001824 return self._rescale(exp._exp, rounding, context, watchexp)
1825
1826 def same_quantum(self, other):
1827 """Test whether self and other have the same exponent.
1828
1829 same as self._exp == other._exp, except NaN == sNaN
1830 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001831 if self._is_special or other._is_special:
1832 if self._isnan() or other._isnan():
1833 return self._isnan() and other._isnan() and True
1834 if self._isinfinity() or other._isinfinity():
1835 return self._isinfinity() and other._isinfinity() and True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001836 return self._exp == other._exp
1837
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001838 def _rescale(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001839 """Rescales so that the exponent is exp.
1840
1841 exp = exp to scale to (an integer)
1842 rounding = rounding version
1843 watchexp: if set (default) an error is returned if exp is greater
1844 than Emax or less than Etiny.
1845 """
1846 if context is None:
1847 context = getcontext()
1848
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001849 if self._is_special:
1850 if self._isinfinity():
1851 return context._raise_error(InvalidOperation, 'rescale with an INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001852
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001853 ans = self._check_nans(context=context)
1854 if ans:
1855 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001856
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001857 if watchexp and (context.Emax < exp or context.Etiny() > exp):
1858 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1859
1860 if not self:
1861 ans = Decimal(self)
1862 ans._int = (0,)
1863 ans._exp = exp
1864 return ans
1865
1866 diff = self._exp - exp
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001867 digits = len(self._int) + diff
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001868
1869 if watchexp and digits > context.prec:
1870 return context._raise_error(InvalidOperation, 'Rescale > prec')
1871
1872 tmp = Decimal(self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001873 tmp._int = (0,) + tmp._int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001874 digits += 1
1875
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001876 if digits < 0:
1877 tmp._exp = -digits + tmp._exp
1878 tmp._int = (0,1)
1879 digits = 1
1880 tmp = tmp._round(digits, rounding, context=context)
1881
1882 if tmp._int[0] == 0 and len(tmp._int) > 1:
1883 tmp._int = tmp._int[1:]
1884 tmp._exp = exp
1885
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001886 tmp_adjusted = tmp.adjusted()
1887 if tmp and tmp_adjusted < context.Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001888 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001889 elif tmp and tmp_adjusted > context.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001890 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1891 return tmp
1892
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001893 def to_integral(self, rounding=None, context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001894 """Rounds to the nearest integer, without raising inexact, rounded."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001895 if self._is_special:
1896 ans = self._check_nans(context=context)
1897 if ans:
1898 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001899 if self._exp >= 0:
1900 return self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001901 if context is None:
1902 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001903 flags = context._ignore_flags(Rounded, Inexact)
1904 ans = self._rescale(0, rounding, context=context)
1905 context._regard_flags(flags)
1906 return ans
1907
1908 def sqrt(self, context=None):
1909 """Return the square root of self.
1910
1911 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
1912 Should quadratically approach the right answer.
1913 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001914 if self._is_special:
1915 ans = self._check_nans(context=context)
1916 if ans:
1917 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001918
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001919 if self._isinfinity() and self._sign == 0:
1920 return Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001921
1922 if not self:
1923 #exponent = self._exp / 2, using round_down.
1924 #if self._exp < 0:
1925 # exp = (self._exp+1) // 2
1926 #else:
1927 exp = (self._exp) // 2
1928 if self._sign == 1:
1929 #sqrt(-0) = -0
1930 return Decimal( (1, (0,), exp))
1931 else:
1932 return Decimal( (0, (0,), exp))
1933
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001934 if context is None:
1935 context = getcontext()
1936
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001937 if self._sign == 1:
1938 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
1939
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001940 tmp = Decimal(self)
1941
Raymond Hettinger4837a222004-09-27 14:23:40 +00001942 expadd = tmp._exp // 2
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001943 if tmp._exp & 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001944 tmp._int += (0,)
1945 tmp._exp = 0
1946 else:
1947 tmp._exp = 0
1948
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001949 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001950 flags = context._ignore_all_flags()
1951 firstprec = context.prec
1952 context.prec = 3
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001953 if tmp.adjusted() & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001954 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) )
1955 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
1956 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00001957 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001958 else:
1959 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
1960 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
1961 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00001962 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001963
1964 #ans is now a linear approximation.
1965
1966 Emax, Emin = context.Emax, context.Emin
Raymond Hettinger99148e72004-07-14 19:56:56 +00001967 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001968
1969 half = Decimal('0.5')
1970
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001971 maxp = firstprec + 2
1972 rounding = context._set_rounding(ROUND_HALF_EVEN)
1973 while 1:
1974 context.prec = min(2*context.prec - 2, maxp)
1975 ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
1976 context=context), context=context)
1977 if context.prec == maxp:
1978 break
1979
1980 #round to the answer's precision-- the only error can be 1 ulp.
1981 context.prec = firstprec
1982 prevexp = ans.adjusted()
1983 ans = ans._round(context=context)
1984
1985 #Now, check if the other last digits are better.
1986 context.prec = firstprec + 1
1987 # In case we rounded up another digit and we should actually go lower.
1988 if prevexp != ans.adjusted():
1989 ans._int += (0,)
1990 ans._exp -= 1
1991
1992
1993 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
1994 context._set_rounding(ROUND_UP)
1995 if lower.__mul__(lower, context=context) > (tmp):
1996 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
1997
1998 else:
1999 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
2000 context._set_rounding(ROUND_DOWN)
2001 if upper.__mul__(upper, context=context) < tmp:
2002 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
2003
2004 ans._exp += expadd
2005
2006 context.prec = firstprec
2007 context.rounding = rounding
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002008 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002009
2010 rounding = context._set_rounding_decision(NEVER_ROUND)
2011 if not ans.__mul__(ans, context=context) == self:
2012 # Only rounded/inexact if here.
2013 context._regard_flags(flags)
2014 context._raise_error(Rounded)
2015 context._raise_error(Inexact)
2016 else:
2017 #Exact answer, so let's set the exponent right.
2018 #if self._exp < 0:
2019 # exp = (self._exp +1)// 2
2020 #else:
2021 exp = self._exp // 2
2022 context.prec += ans._exp - exp
2023 ans = ans._rescale(exp, context=context)
2024 context.prec = firstprec
2025 context._regard_flags(flags)
2026 context.Emax, context.Emin = Emax, Emin
2027
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002028 return ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002029
2030 def max(self, other, context=None):
2031 """Returns the larger value.
2032
2033 like max(self, other) except if one is not a number, returns
2034 NaN (and signals if one is sNaN). Also rounds.
2035 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002036 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002037 if other is NotImplemented:
2038 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002039
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002040 if self._is_special or other._is_special:
2041 # if one operand is a quiet NaN and the other is number, then the
2042 # number is always returned
2043 sn = self._isnan()
2044 on = other._isnan()
2045 if sn or on:
2046 if on == 1 and sn != 2:
2047 return self
2048 if sn == 1 and on != 2:
2049 return other
2050 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002051
2052 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002053 c = self.__cmp__(other)
2054 if c == 0:
2055 # if both operands are finite and equal in numerical value
2056 # then an ordering is applied:
2057 #
2058 # if the signs differ then max returns the operand with the
2059 # positive sign and min returns the operand with the negative sign
2060 #
2061 # if the signs are the same then the exponent is used to select
2062 # the result.
2063 if self._sign != other._sign:
2064 if self._sign:
2065 ans = other
2066 elif self._exp < other._exp and not self._sign:
2067 ans = other
2068 elif self._exp > other._exp and self._sign:
2069 ans = other
2070 elif c == -1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002071 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002072
2073 if context is None:
2074 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002075 if context._rounding_decision == ALWAYS_ROUND:
2076 return ans._fix(context)
2077 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002078
2079 def min(self, other, context=None):
2080 """Returns the smaller value.
2081
2082 like min(self, other) except if one is not a number, returns
2083 NaN (and signals if one is sNaN). Also rounds.
2084 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002085 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002086 if other is NotImplemented:
2087 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002088
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002089 if self._is_special or other._is_special:
2090 # if one operand is a quiet NaN and the other is number, then the
2091 # number is always returned
2092 sn = self._isnan()
2093 on = other._isnan()
2094 if sn or on:
2095 if on == 1 and sn != 2:
2096 return self
2097 if sn == 1 and on != 2:
2098 return other
2099 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002100
2101 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002102 c = self.__cmp__(other)
2103 if c == 0:
2104 # if both operands are finite and equal in numerical value
2105 # then an ordering is applied:
2106 #
2107 # if the signs differ then max returns the operand with the
2108 # positive sign and min returns the operand with the negative sign
2109 #
2110 # if the signs are the same then the exponent is used to select
2111 # the result.
2112 if self._sign != other._sign:
2113 if other._sign:
2114 ans = other
2115 elif self._exp > other._exp and not self._sign:
2116 ans = other
2117 elif self._exp < other._exp and self._sign:
2118 ans = other
2119 elif c == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002120 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002121
2122 if context is None:
2123 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002124 if context._rounding_decision == ALWAYS_ROUND:
2125 return ans._fix(context)
2126 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002127
2128 def _isinteger(self):
2129 """Returns whether self is an integer"""
2130 if self._exp >= 0:
2131 return True
2132 rest = self._int[self._exp:]
2133 return rest == (0,)*len(rest)
2134
2135 def _iseven(self):
2136 """Returns 1 if self is even. Assumes self is an integer."""
2137 if self._exp > 0:
2138 return 1
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002139 return self._int[-1+self._exp] & 1 == 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002140
2141 def adjusted(self):
2142 """Return the adjusted exponent of self"""
2143 try:
2144 return self._exp + len(self._int) - 1
2145 #If NaN or Infinity, self._exp is string
2146 except TypeError:
2147 return 0
2148
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002149 # support for pickling, copy, and deepcopy
2150 def __reduce__(self):
2151 return (self.__class__, (str(self),))
2152
2153 def __copy__(self):
2154 if type(self) == Decimal:
2155 return self # I'm immutable; therefore I am my own clone
2156 return self.__class__(str(self))
2157
2158 def __deepcopy__(self, memo):
2159 if type(self) == Decimal:
2160 return self # My components are also immutable
2161 return self.__class__(str(self))
2162
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002163##### Context class ###########################################
2164
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002165
2166# get rounding method function:
2167rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
2168for name in rounding_functions:
2169 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
2170 globalname = name[1:].upper()
2171 val = globals()[globalname]
2172 Decimal._pick_rounding_function[val] = name
2173
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002174del name, val, globalname, rounding_functions
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002175
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002176class ContextManager(object):
2177 """Helper class to simplify Context management.
2178
2179 Sample usage:
2180
2181 with decimal.ExtendedContext:
2182 s = ...
2183 return +s # Convert result to normal precision
2184
2185 with decimal.getcontext() as ctx:
2186 ctx.prec += 2
2187 s = ...
2188 return +s
2189
2190 """
2191 def __init__(self, new_context):
2192 self.new_context = new_context
2193 def __enter__(self):
2194 self.saved_context = getcontext()
2195 setcontext(self.new_context)
2196 return self.new_context
2197 def __exit__(self, t, v, tb):
2198 setcontext(self.saved_context)
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002199
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002200class Context(object):
2201 """Contains the context for a Decimal instance.
2202
2203 Contains:
2204 prec - precision (for use in rounding, division, square roots..)
2205 rounding - rounding type. (how you round)
2206 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
Raymond Hettingerbf440692004-07-10 14:14:37 +00002207 traps - If traps[exception] = 1, then the exception is
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002208 raised when it is caused. Otherwise, a value is
2209 substituted in.
2210 flags - When an exception is caused, flags[exception] is incremented.
2211 (Whether or not the trap_enabler is set)
2212 Should be reset by user of Decimal instance.
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002213 Emin - Minimum exponent
2214 Emax - Maximum exponent
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002215 capitals - If 1, 1*10^1 is printed as 1E+1.
2216 If 0, printed as 1e1
Raymond Hettingere0f15812004-07-05 05:36:39 +00002217 _clamp - If 1, change exponents if too high (Default 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002218 """
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002219
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002220 def __init__(self, prec=None, rounding=None,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002221 traps=None, flags=None,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002222 _rounding_decision=None,
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002223 Emin=None, Emax=None,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002224 capitals=None, _clamp=0,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002225 _ignored_flags=None):
2226 if flags is None:
2227 flags = []
2228 if _ignored_flags is None:
2229 _ignored_flags = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002230 if not isinstance(flags, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002231 flags = dict([(s,s in flags) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002232 del s
Raymond Hettingerbf440692004-07-10 14:14:37 +00002233 if traps is not None and not isinstance(traps, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002234 traps = dict([(s,s in traps) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002235 del s
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002236 for name, val in locals().items():
2237 if val is None:
Raymond Hettingereb260842005-06-07 18:52:34 +00002238 setattr(self, name, _copy.copy(getattr(DefaultContext, name)))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002239 else:
2240 setattr(self, name, val)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002241 del self.self
2242
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002243 def __repr__(self):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002244 """Show the current context."""
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002245 s = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002246 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
2247 s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
2248 s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002249 return ', '.join(s) + ')'
2250
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002251 def __context__(self):
2252 return ContextManager(self.copy())
2253
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002254 def clear_flags(self):
2255 """Reset all flags to zero"""
2256 for flag in self.flags:
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002257 self.flags[flag] = 0
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002258
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002259 def _shallow_copy(self):
2260 """Returns a shallow copy from self."""
Raymond Hettingerbf440692004-07-10 14:14:37 +00002261 nc = Context(self.prec, self.rounding, self.traps, self.flags,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002262 self._rounding_decision, self.Emin, self.Emax,
2263 self.capitals, self._clamp, self._ignored_flags)
2264 return nc
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002265
2266 def copy(self):
2267 """Returns a deep copy from self."""
2268 nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
2269 self._rounding_decision, self.Emin, self.Emax,
2270 self.capitals, self._clamp, self._ignored_flags)
2271 return nc
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002272 __copy__ = copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002273
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002274 def _raise_error(self, condition, explanation = None, *args):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002275 """Handles an error
2276
2277 If the flag is in _ignored_flags, returns the default response.
2278 Otherwise, it increments the flag, then, if the corresponding
2279 trap_enabler is set, it reaises the exception. Otherwise, it returns
2280 the default value after incrementing the flag.
2281 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002282 error = _condition_map.get(condition, condition)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002283 if error in self._ignored_flags:
2284 #Don't touch the flag
2285 return error().handle(self, *args)
2286
2287 self.flags[error] += 1
Raymond Hettingerbf440692004-07-10 14:14:37 +00002288 if not self.traps[error]:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002289 #The errors define how to handle themselves.
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002290 return condition().handle(self, *args)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002291
2292 # Errors should only be risked on copies of the context
2293 #self._ignored_flags = []
2294 raise error, explanation
2295
2296 def _ignore_all_flags(self):
2297 """Ignore all flags, if they are raised"""
Raymond Hettingerfed52962004-07-14 15:41:57 +00002298 return self._ignore_flags(*_signals)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002299
2300 def _ignore_flags(self, *flags):
2301 """Ignore the flags, if they are raised"""
2302 # Do not mutate-- This way, copies of a context leave the original
2303 # alone.
2304 self._ignored_flags = (self._ignored_flags + list(flags))
2305 return list(flags)
2306
2307 def _regard_flags(self, *flags):
2308 """Stop ignoring the flags, if they are raised"""
2309 if flags and isinstance(flags[0], (tuple,list)):
2310 flags = flags[0]
2311 for flag in flags:
2312 self._ignored_flags.remove(flag)
2313
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002314 def __hash__(self):
2315 """A Context cannot be hashed."""
2316 # We inherit object.__hash__, so we must deny this explicitly
2317 raise TypeError, "Cannot hash a Context."
2318
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002319 def Etiny(self):
2320 """Returns Etiny (= Emin - prec + 1)"""
2321 return int(self.Emin - self.prec + 1)
2322
2323 def Etop(self):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002324 """Returns maximum exponent (= Emax - prec + 1)"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002325 return int(self.Emax - self.prec + 1)
2326
2327 def _set_rounding_decision(self, type):
2328 """Sets the rounding decision.
2329
2330 Sets the rounding decision, and returns the current (previous)
2331 rounding decision. Often used like:
2332
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002333 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002334 # That so you don't change the calling context
2335 # if an error occurs in the middle (say DivisionImpossible is raised).
2336
2337 rounding = context._set_rounding_decision(NEVER_ROUND)
2338 instance = instance / Decimal(2)
2339 context._set_rounding_decision(rounding)
2340
2341 This will make it not round for that operation.
2342 """
2343
2344 rounding = self._rounding_decision
2345 self._rounding_decision = type
2346 return rounding
2347
2348 def _set_rounding(self, type):
2349 """Sets the rounding type.
2350
2351 Sets the rounding type, and returns the current (previous)
2352 rounding type. Often used like:
2353
2354 context = context.copy()
2355 # so you don't change the calling context
2356 # if an error occurs in the middle.
2357 rounding = context._set_rounding(ROUND_UP)
2358 val = self.__sub__(other, context=context)
2359 context._set_rounding(rounding)
2360
2361 This will make it round up for that operation.
2362 """
2363 rounding = self.rounding
2364 self.rounding= type
2365 return rounding
2366
Raymond Hettingerfed52962004-07-14 15:41:57 +00002367 def create_decimal(self, num='0'):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002368 """Creates a new Decimal instance but using self as context."""
2369 d = Decimal(num, context=self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002370 return d._fix(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002371
2372 #Methods
2373 def abs(self, a):
2374 """Returns the absolute value of the operand.
2375
2376 If the operand is negative, the result is the same as using the minus
2377 operation on the operand. Otherwise, the result is the same as using
2378 the plus operation on the operand.
2379
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002380 >>> ExtendedContext.abs(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002381 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002382 >>> ExtendedContext.abs(Decimal('-100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002383 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002384 >>> ExtendedContext.abs(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002385 Decimal("101.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002386 >>> ExtendedContext.abs(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002387 Decimal("101.5")
2388 """
2389 return a.__abs__(context=self)
2390
2391 def add(self, a, b):
2392 """Return the sum of the two operands.
2393
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002394 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002395 Decimal("19.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002396 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002397 Decimal("1.02E+4")
2398 """
2399 return a.__add__(b, context=self)
2400
2401 def _apply(self, a):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002402 return str(a._fix(self))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002403
2404 def compare(self, a, b):
2405 """Compares values numerically.
2406
2407 If the signs of the operands differ, a value representing each operand
2408 ('-1' if the operand is less than zero, '0' if the operand is zero or
2409 negative zero, or '1' if the operand is greater than zero) is used in
2410 place of that operand for the comparison instead of the actual
2411 operand.
2412
2413 The comparison is then effected by subtracting the second operand from
2414 the first and then returning a value according to the result of the
2415 subtraction: '-1' if the result is less than zero, '0' if the result is
2416 zero or negative zero, or '1' if the result is greater than zero.
2417
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002418 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002419 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002420 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002421 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002422 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002423 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002424 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002425 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002426 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002427 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002428 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002429 Decimal("-1")
2430 """
2431 return a.compare(b, context=self)
2432
2433 def divide(self, a, b):
2434 """Decimal division in a specified context.
2435
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002436 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002437 Decimal("0.333333333")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002438 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002439 Decimal("0.666666667")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002440 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002441 Decimal("2.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002442 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002443 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002444 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002445 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002446 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002447 Decimal("4.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002448 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002449 Decimal("1.20")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002450 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002451 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002452 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002453 Decimal("1000")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002454 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002455 Decimal("1.20E+6")
2456 """
2457 return a.__div__(b, context=self)
2458
2459 def divide_int(self, a, b):
2460 """Divides two numbers and returns the integer part of the result.
2461
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002462 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002463 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002464 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002465 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002466 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002467 Decimal("3")
2468 """
2469 return a.__floordiv__(b, context=self)
2470
2471 def divmod(self, a, b):
2472 return a.__divmod__(b, context=self)
2473
2474 def max(self, a,b):
2475 """max compares two values numerically and returns the maximum.
2476
2477 If either operand is a NaN then the general rules apply.
2478 Otherwise, the operands are compared as as though by the compare
2479 operation. If they are numerically equal then the left-hand operand
2480 is chosen as the result. Otherwise the maximum (closer to positive
2481 infinity) of the two operands is chosen as the result.
2482
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002483 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002484 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002485 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002486 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002487 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002488 Decimal("1")
2489 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
2490 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002491 """
2492 return a.max(b, context=self)
2493
2494 def min(self, a,b):
2495 """min compares two values numerically and returns the minimum.
2496
2497 If either operand is a NaN then the general rules apply.
2498 Otherwise, the operands are compared as as though by the compare
2499 operation. If they are numerically equal then the left-hand operand
2500 is chosen as the result. Otherwise the minimum (closer to negative
2501 infinity) of the two operands is chosen as the result.
2502
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002503 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002504 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002505 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002506 Decimal("-10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002507 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002508 Decimal("1.0")
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002509 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
2510 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002511 """
2512 return a.min(b, context=self)
2513
2514 def minus(self, a):
2515 """Minus corresponds to unary prefix minus in Python.
2516
2517 The operation is evaluated using the same rules as subtract; the
2518 operation minus(a) is calculated as subtract('0', a) where the '0'
2519 has the same exponent as the operand.
2520
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002521 >>> ExtendedContext.minus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002522 Decimal("-1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002523 >>> ExtendedContext.minus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002524 Decimal("1.3")
2525 """
2526 return a.__neg__(context=self)
2527
2528 def multiply(self, a, b):
2529 """multiply multiplies two operands.
2530
2531 If either operand is a special value then the general rules apply.
2532 Otherwise, the operands are multiplied together ('long multiplication'),
2533 resulting in a number which may be as long as the sum of the lengths
2534 of the two operands.
2535
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002536 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002537 Decimal("3.60")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002538 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002539 Decimal("21")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002540 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002541 Decimal("0.72")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002542 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002543 Decimal("-0.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002544 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002545 Decimal("4.28135971E+11")
2546 """
2547 return a.__mul__(b, context=self)
2548
2549 def normalize(self, a):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002550 """normalize reduces an operand to its simplest form.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002551
2552 Essentially a plus operation with all trailing zeros removed from the
2553 result.
2554
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002555 >>> ExtendedContext.normalize(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002556 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002557 >>> ExtendedContext.normalize(Decimal('-2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002558 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002559 >>> ExtendedContext.normalize(Decimal('1.200'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002560 Decimal("1.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002561 >>> ExtendedContext.normalize(Decimal('-120'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002562 Decimal("-1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002563 >>> ExtendedContext.normalize(Decimal('120.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002564 Decimal("1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002565 >>> ExtendedContext.normalize(Decimal('0.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002566 Decimal("0")
2567 """
2568 return a.normalize(context=self)
2569
2570 def plus(self, a):
2571 """Plus corresponds to unary prefix plus in Python.
2572
2573 The operation is evaluated using the same rules as add; the
2574 operation plus(a) is calculated as add('0', a) where the '0'
2575 has the same exponent as the operand.
2576
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002577 >>> ExtendedContext.plus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002578 Decimal("1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002579 >>> ExtendedContext.plus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002580 Decimal("-1.3")
2581 """
2582 return a.__pos__(context=self)
2583
2584 def power(self, a, b, modulo=None):
2585 """Raises a to the power of b, to modulo if given.
2586
2587 The right-hand operand must be a whole number whose integer part (after
2588 any exponent has been applied) has no more than 9 digits and whose
2589 fractional part (if any) is all zeros before any rounding. The operand
2590 may be positive, negative, or zero; if negative, the absolute value of
2591 the power is used, and the left-hand operand is inverted (divided into
2592 1) before use.
2593
2594 If the increased precision needed for the intermediate calculations
2595 exceeds the capabilities of the implementation then an Invalid operation
2596 condition is raised.
2597
2598 If, when raising to a negative power, an underflow occurs during the
2599 division into 1, the operation is not halted at that point but
2600 continues.
2601
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002602 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002603 Decimal("8")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002604 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002605 Decimal("0.125")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002606 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002607 Decimal("69.7575744")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002608 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002609 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002610 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002611 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002612 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002613 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002614 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
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("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002618 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002619 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002620 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002621 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002622 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002623 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002624 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002625 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002626 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002627 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002628 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002629 Decimal("NaN")
2630 """
2631 return a.__pow__(b, modulo, context=self)
2632
2633 def quantize(self, a, b):
2634 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
2635
2636 The coefficient of the result is derived from that of the left-hand
2637 operand. It may be rounded using the current rounding setting (if the
2638 exponent is being increased), multiplied by a positive power of ten (if
2639 the exponent is being decreased), or is unchanged (if the exponent is
2640 already equal to that of the right-hand operand).
2641
2642 Unlike other operations, if the length of the coefficient after the
2643 quantize operation would be greater than precision then an Invalid
2644 operation condition is raised. This guarantees that, unless there is an
2645 error condition, the exponent of the result of a quantize is always
2646 equal to that of the right-hand operand.
2647
2648 Also unlike other operations, quantize will never raise Underflow, even
2649 if the result is subnormal and inexact.
2650
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002651 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002652 Decimal("2.170")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002653 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002654 Decimal("2.17")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002655 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002656 Decimal("2.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002657 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002658 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002659 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002660 Decimal("0E+1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002661 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002662 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002663 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002664 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002665 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002666 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002667 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002668 Decimal("-0E+5")
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('-35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002672 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002673 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002674 Decimal("217.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002675 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002676 Decimal("217")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002677 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002678 Decimal("2.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002679 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002680 Decimal("2E+2")
2681 """
2682 return a.quantize(b, context=self)
2683
2684 def remainder(self, a, b):
2685 """Returns the remainder from integer division.
2686
2687 The result is the residue of the dividend after the operation of
2688 calculating integer division as described for divide-integer, rounded to
2689 precision digits if necessary. The sign of the result, if non-zero, is
2690 the same as that of the original dividend.
2691
2692 This operation will fail under the same conditions as integer division
2693 (that is, if integer division on the same two operands would fail, the
2694 remainder cannot be calculated).
2695
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002696 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002697 Decimal("2.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'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002701 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002702 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002703 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002704 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002705 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002706 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002707 Decimal("1.0")
2708 """
2709 return a.__mod__(b, context=self)
2710
2711 def remainder_near(self, a, b):
2712 """Returns to be "a - b * n", where n is the integer nearest the exact
2713 value of "x / b" (if two integers are equally near then the even one
2714 is chosen). If the result is equal to 0 then its sign will be the
2715 sign of a.
2716
2717 This operation will fail under the same conditions as integer division
2718 (that is, if integer division on the same two operands would fail, the
2719 remainder cannot be calculated).
2720
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002721 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002722 Decimal("-0.9")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002723 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002724 Decimal("-2")
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'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002728 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002729 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002730 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002731 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002732 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002733 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002734 Decimal("-0.3")
2735 """
2736 return a.remainder_near(b, context=self)
2737
2738 def same_quantum(self, a, b):
2739 """Returns True if the two operands have the same exponent.
2740
2741 The result is never affected by either the sign or the coefficient of
2742 either operand.
2743
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002744 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002745 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002746 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002747 True
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002748 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002749 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002750 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002751 True
2752 """
2753 return a.same_quantum(b)
2754
2755 def sqrt(self, a):
2756 """Returns the square root of a non-negative number to context precision.
2757
2758 If the result must be inexact, it is rounded using the round-half-even
2759 algorithm.
2760
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'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002764 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002765 >>> ExtendedContext.sqrt(Decimal('0.39'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002766 Decimal("0.624499800")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002767 >>> ExtendedContext.sqrt(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002768 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002769 >>> ExtendedContext.sqrt(Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002770 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002771 >>> ExtendedContext.sqrt(Decimal('1.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002772 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002773 >>> ExtendedContext.sqrt(Decimal('1.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002774 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002775 >>> ExtendedContext.sqrt(Decimal('7'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002776 Decimal("2.64575131")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002777 >>> ExtendedContext.sqrt(Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002778 Decimal("3.16227766")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002779 >>> ExtendedContext.prec
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002780 9
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002781 """
2782 return a.sqrt(context=self)
2783
2784 def subtract(self, a, b):
Georg Brandlf33d01d2005-08-22 19:35:18 +00002785 """Return the difference between the two operands.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002786
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002787 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002788 Decimal("0.23")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002789 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002790 Decimal("0.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002791 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002792 Decimal("-0.77")
2793 """
2794 return a.__sub__(b, context=self)
2795
2796 def to_eng_string(self, a):
2797 """Converts a number to a string, using scientific notation.
2798
2799 The operation is not affected by the context.
2800 """
2801 return a.to_eng_string(context=self)
2802
2803 def to_sci_string(self, a):
2804 """Converts a number to a string, using scientific notation.
2805
2806 The operation is not affected by the context.
2807 """
2808 return a.__str__(context=self)
2809
2810 def to_integral(self, a):
2811 """Rounds to an integer.
2812
2813 When the operand has a negative exponent, the result is the same
2814 as using the quantize() operation using the given operand as the
2815 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2816 of the operand as the precision setting, except that no flags will
2817 be set. The rounding mode is taken from the context.
2818
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002819 >>> ExtendedContext.to_integral(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002820 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002821 >>> ExtendedContext.to_integral(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002822 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002823 >>> ExtendedContext.to_integral(Decimal('100.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002824 Decimal("100")
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('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002828 Decimal("-102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002829 >>> ExtendedContext.to_integral(Decimal('10E+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002830 Decimal("1.0E+6")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002831 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002832 Decimal("7.89E+77")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002833 >>> ExtendedContext.to_integral(Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002834 Decimal("-Infinity")
2835 """
2836 return a.to_integral(context=self)
2837
2838class _WorkRep(object):
2839 __slots__ = ('sign','int','exp')
Raymond Hettinger17931de2004-10-27 06:21:46 +00002840 # sign: 0 or 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002841 # int: int or long
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002842 # exp: None, int, or string
2843
2844 def __init__(self, value=None):
2845 if value is None:
2846 self.sign = None
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002847 self.int = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002848 self.exp = None
Raymond Hettinger17931de2004-10-27 06:21:46 +00002849 elif isinstance(value, Decimal):
2850 self.sign = value._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002851 cum = 0
Raymond Hettinger17931de2004-10-27 06:21:46 +00002852 for digit in value._int:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002853 cum = cum * 10 + digit
2854 self.int = cum
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002855 self.exp = value._exp
Raymond Hettinger17931de2004-10-27 06:21:46 +00002856 else:
2857 # assert isinstance(value, tuple)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002858 self.sign = value[0]
2859 self.int = value[1]
2860 self.exp = value[2]
2861
2862 def __repr__(self):
2863 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2864
2865 __str__ = __repr__
2866
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002867
2868
2869def _normalize(op1, op2, shouldround = 0, prec = 0):
2870 """Normalizes op1, op2 to have the same exp and length of coefficient.
2871
2872 Done during addition.
2873 """
2874 # Yes, the exponent is a long, but the difference between exponents
2875 # must be an int-- otherwise you'd get a big memory problem.
2876 numdigits = int(op1.exp - op2.exp)
2877 if numdigits < 0:
2878 numdigits = -numdigits
2879 tmp = op2
2880 other = op1
2881 else:
2882 tmp = op1
2883 other = op2
2884
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002885
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002886 if shouldround and numdigits > prec + 1:
2887 # Big difference in exponents - check the adjusted exponents
2888 tmp_len = len(str(tmp.int))
2889 other_len = len(str(other.int))
2890 if numdigits > (other_len + prec + 1 - tmp_len):
2891 # If the difference in adjusted exps is > prec+1, we know
2892 # other is insignificant, so might as well put a 1 after the precision.
2893 # (since this is only for addition.) Also stops use of massive longs.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002894
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002895 extend = prec + 2 - tmp_len
2896 if extend <= 0:
2897 extend = 1
2898 tmp.int *= 10 ** extend
2899 tmp.exp -= extend
2900 other.int = 1
2901 other.exp = tmp.exp
2902 return op1, op2
2903
2904 tmp.int *= 10 ** numdigits
2905 tmp.exp -= numdigits
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002906 return op1, op2
2907
2908def _adjust_coefficients(op1, op2):
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002909 """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002910
2911 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2912
2913 Used on _WorkRep instances during division.
2914 """
2915 adjust = 0
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002916 #If op1 is smaller, make it larger
2917 while op2.int > op1.int:
2918 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002919 op1.exp -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002920 adjust += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002921
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002922 #If op2 is too small, make it larger
2923 while op1.int >= (10 * op2.int):
2924 op2.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002925 op2.exp -= 1
2926 adjust -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002927
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002928 return op1, op2, adjust
2929
2930##### Helper Functions ########################################
2931
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002932def _convert_other(other):
2933 """Convert other to Decimal.
2934
2935 Verifies that it's ok to use in an implicit construction.
2936 """
2937 if isinstance(other, Decimal):
2938 return other
2939 if isinstance(other, (int, long)):
2940 return Decimal(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002941 return NotImplemented
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002942
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002943_infinity_map = {
2944 'inf' : 1,
2945 'infinity' : 1,
2946 '+inf' : 1,
2947 '+infinity' : 1,
2948 '-inf' : -1,
2949 '-infinity' : -1
2950}
2951
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002952def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002953 """Determines whether a string or float is infinity.
2954
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002955 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002956 """
2957 num = str(num).lower()
2958 return _infinity_map.get(num, 0)
2959
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002960def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002961 """Determines whether a string or float is NaN
2962
2963 (1, sign, diagnostic info as string) => NaN
2964 (2, sign, diagnostic info as string) => sNaN
2965 0 => not a NaN
2966 """
2967 num = str(num).lower()
2968 if not num:
2969 return 0
2970
2971 #get the sign, get rid of trailing [+-]
2972 sign = 0
2973 if num[0] == '+':
2974 num = num[1:]
2975 elif num[0] == '-': #elif avoids '+-nan'
2976 num = num[1:]
2977 sign = 1
2978
2979 if num.startswith('nan'):
2980 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
2981 return 0
2982 return (1, sign, num[3:].lstrip('0'))
2983 if num.startswith('snan'):
2984 if len(num) > 4 and not num[4:].isdigit():
2985 return 0
2986 return (2, sign, num[4:].lstrip('0'))
2987 return 0
2988
2989
2990##### Setup Specific Contexts ################################
2991
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002992# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00002993# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002994
2995DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002996 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002997 traps=[DivisionByZero, Overflow, InvalidOperation],
2998 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002999 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00003000 Emax=999999999,
3001 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00003002 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003003)
3004
3005# Pre-made alternate contexts offered by the specification
3006# Don't change these; the user should be able to select these
3007# contexts and be able to reproduce results from other implementations
3008# of the spec.
3009
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003010BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003011 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003012 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
3013 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003014)
3015
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003016ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003017 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003018 traps=[],
3019 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003020)
3021
3022
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00003023##### Useful Constants (internal use only) ####################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003024
3025#Reusable defaults
3026Inf = Decimal('Inf')
3027negInf = Decimal('-Inf')
3028
3029#Infsign[sign] is infinity w/ that sign
3030Infsign = (Inf, negInf)
3031
3032NaN = Decimal('NaN')
3033
3034
3035##### crud for parsing strings #################################
3036import re
3037
3038# There's an optional sign at the start, and an optional exponent
3039# at the end. The exponent has an optional sign and at least one
3040# digit. In between, must have either at least one digit followed
3041# by an optional fraction, or a decimal point followed by at least
3042# one digit. Yuck.
3043
3044_parser = re.compile(r"""
3045# \s*
3046 (?P<sign>[-+])?
3047 (
3048 (?P<int>\d+) (\. (?P<frac>\d*))?
3049 |
3050 \. (?P<onlyfrac>\d+)
3051 )
3052 ([eE](?P<exp>[-+]? \d+))?
3053# \s*
3054 $
3055""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
3056
3057del re
3058
3059# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
3060
3061def _string2exact(s):
3062 m = _parser(s)
3063 if m is None:
3064 raise ValueError("invalid literal for Decimal: %r" % s)
3065
3066 if m.group('sign') == "-":
3067 sign = 1
3068 else:
3069 sign = 0
3070
3071 exp = m.group('exp')
3072 if exp is None:
3073 exp = 0
3074 else:
3075 exp = int(exp)
3076
3077 intpart = m.group('int')
3078 if intpart is None:
3079 intpart = ""
3080 fracpart = m.group('onlyfrac')
3081 else:
3082 fracpart = m.group('frac')
3083 if fracpart is None:
3084 fracpart = ""
3085
3086 exp -= len(fracpart)
3087
3088 mantissa = intpart + fracpart
3089 tmp = map(int, mantissa)
3090 backup = tmp
3091 while tmp and tmp[0] == 0:
3092 del tmp[0]
3093
3094 # It's a zero
3095 if not tmp:
3096 if backup:
3097 return (sign, tuple(backup), exp)
3098 return (sign, (0,), exp)
3099 mantissa = tuple(tmp)
3100
3101 return (sign, mantissa, exp)
3102
3103
3104if __name__ == '__main__':
3105 import doctest, sys
3106 doctest.testmod(sys.modules[__name__])