blob: e3e7fd5c11c081b1efd11f748669ce38cb12cf14 [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 Hettinger7c85fa42004-07-01 11:01:35 +0000137import 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
763 if self._isnan():
764 minus = '-'*self._sign
765 if self._int == (0,):
766 info = ''
767 else:
768 info = ''.join(map(str, self._int))
769 if self._isnan() == 2:
770 return minus + 'sNaN' + info
771 return minus + 'NaN' + info
772 if self._isinfinity():
773 minus = '-'*self._sign
774 return minus + 'Infinity'
775
776 if context is None:
777 context = getcontext()
778
779 tmp = map(str, self._int)
780 numdigits = len(self._int)
781 leftdigits = self._exp + numdigits
782 if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
783 if self._exp < 0 and self._exp >= -6: #short, no need for e/E
784 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
785 return s
786 #exp is closest mult. of 3 >= self._exp
787 exp = ((self._exp - 1)// 3 + 1) * 3
788 if exp != self._exp:
789 s = '0.'+'0'*(exp - self._exp)
790 else:
791 s = '0'
792 if exp != 0:
793 if context.capitals:
794 s += 'E'
795 else:
796 s += 'e'
797 if exp > 0:
798 s += '+' #0.0e+3, not 0.0e3
799 s += str(exp)
800 s = '-'*self._sign + s
801 return s
802 if eng:
803 dotplace = (leftdigits-1)%3+1
804 adjexp = leftdigits -1 - (leftdigits-1)%3
805 else:
806 adjexp = leftdigits-1
807 dotplace = 1
808 if self._exp == 0:
809 pass
810 elif self._exp < 0 and adjexp >= 0:
811 tmp.insert(leftdigits, '.')
812 elif self._exp < 0 and adjexp >= -6:
813 tmp[0:0] = ['0'] * int(-leftdigits)
814 tmp.insert(0, '0.')
815 else:
816 if numdigits > dotplace:
817 tmp.insert(dotplace, '.')
818 elif numdigits < dotplace:
819 tmp.extend(['0']*(dotplace-numdigits))
820 if adjexp:
821 if not context.capitals:
822 tmp.append('e')
823 else:
824 tmp.append('E')
825 if adjexp > 0:
826 tmp.append('+')
827 tmp.append(str(adjexp))
828 if eng:
829 while tmp[0:1] == ['0']:
830 tmp[0:1] = []
831 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
832 tmp[0:0] = ['0']
833 if self._sign:
834 tmp.insert(0, '-')
835
836 return ''.join(tmp)
837
838 def to_eng_string(self, context=None):
839 """Convert to engineering-type string.
840
841 Engineering notation has an exponent which is a multiple of 3, so there
842 are up to 3 digits left of the decimal place.
843
844 Same rules for when in exponential and when as a value as in __str__.
845 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000846 return self.__str__(eng=1, context=context)
847
848 def __neg__(self, context=None):
849 """Returns a copy with the sign switched.
850
851 Rounds, if it has reason.
852 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000853 if self._is_special:
854 ans = self._check_nans(context=context)
855 if ans:
856 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000857
858 if not self:
859 # -Decimal('0') is Decimal('0'), not Decimal('-0')
860 sign = 0
861 elif self._sign:
862 sign = 0
863 else:
864 sign = 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000865
866 if context is None:
867 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000868 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000869 return Decimal((sign, self._int, self._exp))._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000870 return Decimal( (sign, self._int, self._exp))
871
872 def __pos__(self, context=None):
873 """Returns a copy, unless it is a sNaN.
874
875 Rounds the number (if more then precision digits)
876 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000877 if self._is_special:
878 ans = self._check_nans(context=context)
879 if ans:
880 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000881
882 sign = self._sign
883 if not self:
884 # + (-0) = 0
885 sign = 0
886
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000887 if context is None:
888 context = getcontext()
889
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000890 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000891 ans = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000892 else:
893 ans = Decimal(self)
894 ans._sign = sign
895 return ans
896
897 def __abs__(self, round=1, context=None):
898 """Returns the absolute value of self.
899
900 If the second argument is 0, do not round.
901 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000902 if self._is_special:
903 ans = self._check_nans(context=context)
904 if ans:
905 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000906
907 if not round:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000908 if context is None:
909 context = getcontext()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000910 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000911 context._set_rounding_decision(NEVER_ROUND)
912
913 if self._sign:
914 ans = self.__neg__(context=context)
915 else:
916 ans = self.__pos__(context=context)
917
918 return ans
919
920 def __add__(self, other, context=None):
921 """Returns self + other.
922
923 -INF + INF (or the reverse) cause InvalidOperation errors.
924 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000925 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +0000926 if other is NotImplemented:
927 return other
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000928
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000929 if context is None:
930 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000931
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000932 if self._is_special or other._is_special:
933 ans = self._check_nans(other, context)
934 if ans:
935 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000936
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000937 if self._isinfinity():
938 #If both INF, same sign => same as both, opposite => error.
939 if self._sign != other._sign and other._isinfinity():
940 return context._raise_error(InvalidOperation, '-INF + INF')
941 return Decimal(self)
942 if other._isinfinity():
943 return Decimal(other) #Can't both be infinity here
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000944
945 shouldround = context._rounding_decision == ALWAYS_ROUND
946
947 exp = min(self._exp, other._exp)
948 negativezero = 0
949 if context.rounding == ROUND_FLOOR and self._sign != other._sign:
950 #If the answer is 0, the sign should be negative, in this case.
951 negativezero = 1
952
953 if not self and not other:
954 sign = min(self._sign, other._sign)
955 if negativezero:
956 sign = 1
957 return Decimal( (sign, (0,), exp))
958 if not self:
Facundo Batista99b55482004-10-26 23:38:46 +0000959 exp = max(exp, other._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000960 ans = other._rescale(exp, watchexp=0, context=context)
961 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000962 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000963 return ans
964 if not other:
Facundo Batista99b55482004-10-26 23:38:46 +0000965 exp = max(exp, self._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000966 ans = self._rescale(exp, watchexp=0, context=context)
967 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000968 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000969 return ans
970
971 op1 = _WorkRep(self)
972 op2 = _WorkRep(other)
973 op1, op2 = _normalize(op1, op2, shouldround, context.prec)
974
975 result = _WorkRep()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000976 if op1.sign != op2.sign:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000977 # Equal and opposite
Raymond Hettinger17931de2004-10-27 06:21:46 +0000978 if op1.int == op2.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000979 if exp < context.Etiny():
980 exp = context.Etiny()
981 context._raise_error(Clamped)
982 return Decimal((negativezero, (0,), exp))
Raymond Hettinger17931de2004-10-27 06:21:46 +0000983 if op1.int < op2.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000984 op1, op2 = op2, op1
985 #OK, now abs(op1) > abs(op2)
Raymond Hettinger17931de2004-10-27 06:21:46 +0000986 if op1.sign == 1:
987 result.sign = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000988 op1.sign, op2.sign = op2.sign, op1.sign
989 else:
Raymond Hettinger17931de2004-10-27 06:21:46 +0000990 result.sign = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000991 #So we know the sign, and op1 > 0.
Raymond Hettinger17931de2004-10-27 06:21:46 +0000992 elif op1.sign == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000993 result.sign = 1
Raymond Hettinger17931de2004-10-27 06:21:46 +0000994 op1.sign, op2.sign = (0, 0)
995 else:
996 result.sign = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000997 #Now, op1 > abs(op2) > 0
998
Raymond Hettinger17931de2004-10-27 06:21:46 +0000999 if op2.sign == 0:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001000 result.int = op1.int + op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001001 else:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001002 result.int = op1.int - op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001003
1004 result.exp = op1.exp
1005 ans = Decimal(result)
1006 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001007 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001008 return ans
1009
1010 __radd__ = __add__
1011
1012 def __sub__(self, other, context=None):
1013 """Return self + (-other)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001014 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001015 if other is NotImplemented:
1016 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001017
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001018 if self._is_special or other._is_special:
1019 ans = self._check_nans(other, context=context)
1020 if ans:
1021 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001022
1023 # -Decimal(0) = Decimal(0), which we don't want since
1024 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
1025 # so we change the sign directly to a copy
1026 tmp = Decimal(other)
1027 tmp._sign = 1-tmp._sign
1028
1029 return self.__add__(tmp, context=context)
1030
1031 def __rsub__(self, other, context=None):
1032 """Return other + (-self)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001033 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001034 if other is NotImplemented:
1035 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001036
1037 tmp = Decimal(self)
1038 tmp._sign = 1 - tmp._sign
1039 return other.__add__(tmp, context=context)
1040
1041 def _increment(self, round=1, context=None):
1042 """Special case of add, adding 1eExponent
1043
1044 Since it is common, (rounding, for example) this adds
1045 (sign)*one E self._exp to the number more efficiently than add.
1046
1047 For example:
1048 Decimal('5.624e10')._increment() == Decimal('5.625e10')
1049 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001050 if self._is_special:
1051 ans = self._check_nans(context=context)
1052 if ans:
1053 return ans
1054
1055 return Decimal(self) # Must be infinite, and incrementing makes no difference
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001056
1057 L = list(self._int)
1058 L[-1] += 1
1059 spot = len(L)-1
1060 while L[spot] == 10:
1061 L[spot] = 0
1062 if spot == 0:
1063 L[0:0] = [1]
1064 break
1065 L[spot-1] += 1
1066 spot -= 1
1067 ans = Decimal((self._sign, L, self._exp))
1068
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001069 if context is None:
1070 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001071 if round and context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001072 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001073 return ans
1074
1075 def __mul__(self, other, context=None):
1076 """Return self * other.
1077
1078 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1079 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001080 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001081 if other is NotImplemented:
1082 return other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001083
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001084 if context is None:
1085 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001086
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001087 resultsign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001088
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001089 if self._is_special or other._is_special:
1090 ans = self._check_nans(other, context)
1091 if ans:
1092 return ans
1093
1094 if self._isinfinity():
1095 if not other:
1096 return context._raise_error(InvalidOperation, '(+-)INF * 0')
1097 return Infsign[resultsign]
1098
1099 if other._isinfinity():
1100 if not self:
1101 return context._raise_error(InvalidOperation, '0 * (+-)INF')
1102 return Infsign[resultsign]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001103
1104 resultexp = self._exp + other._exp
1105 shouldround = context._rounding_decision == ALWAYS_ROUND
1106
1107 # Special case for multiplying by zero
1108 if not self or not other:
1109 ans = Decimal((resultsign, (0,), resultexp))
1110 if shouldround:
1111 #Fixing in case the exponent is out of bounds
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001112 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001113 return ans
1114
1115 # Special case for multiplying by power of 10
1116 if self._int == (1,):
1117 ans = Decimal((resultsign, other._int, resultexp))
1118 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001119 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001120 return ans
1121 if other._int == (1,):
1122 ans = Decimal((resultsign, self._int, resultexp))
1123 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001124 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001125 return ans
1126
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001127 op1 = _WorkRep(self)
1128 op2 = _WorkRep(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001129
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001130 ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001131 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001132 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001133
1134 return ans
1135 __rmul__ = __mul__
1136
1137 def __div__(self, other, context=None):
1138 """Return self / other."""
1139 return self._divide(other, context=context)
1140 __truediv__ = __div__
1141
1142 def _divide(self, other, divmod = 0, context=None):
1143 """Return a / b, to context.prec precision.
1144
1145 divmod:
1146 0 => true division
1147 1 => (a //b, a%b)
1148 2 => a //b
1149 3 => a%b
1150
1151 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1152 computing the other value are not raised.
1153 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001154 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001155 if other is NotImplemented:
1156 if divmod in (0, 1):
1157 return NotImplemented
1158 return (NotImplemented, NotImplemented)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001159
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001160 if context is None:
1161 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001162
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001163 sign = self._sign ^ other._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001164
1165 if self._is_special or other._is_special:
1166 ans = self._check_nans(other, context)
1167 if ans:
1168 if divmod:
1169 return (ans, ans)
1170 return ans
1171
1172 if self._isinfinity() and other._isinfinity():
1173 if divmod:
1174 return (context._raise_error(InvalidOperation,
1175 '(+-)INF // (+-)INF'),
1176 context._raise_error(InvalidOperation,
1177 '(+-)INF % (+-)INF'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001178 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001179
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001180 if self._isinfinity():
1181 if divmod == 1:
1182 return (Infsign[sign],
1183 context._raise_error(InvalidOperation, 'INF % x'))
1184 elif divmod == 2:
1185 return (Infsign[sign], NaN)
1186 elif divmod == 3:
1187 return (Infsign[sign],
1188 context._raise_error(InvalidOperation, 'INF % x'))
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001189 return Infsign[sign]
1190
1191 if other._isinfinity():
1192 if divmod:
1193 return (Decimal((sign, (0,), 0)), Decimal(self))
1194 context._raise_error(Clamped, 'Division by infinity')
1195 return Decimal((sign, (0,), context.Etiny()))
1196
1197 # Special cases for zeroes
1198 if not self and not other:
1199 if divmod:
1200 return context._raise_error(DivisionUndefined, '0 / 0', 1)
1201 return context._raise_error(DivisionUndefined, '0 / 0')
1202
1203 if not self:
1204 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001205 otherside = Decimal(self)
1206 otherside._exp = min(self._exp, other._exp)
1207 return (Decimal((sign, (0,), 0)), otherside)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001208 exp = self._exp - other._exp
1209 if exp < context.Etiny():
1210 exp = context.Etiny()
1211 context._raise_error(Clamped, '0e-x / y')
1212 if exp > context.Emax:
1213 exp = context.Emax
1214 context._raise_error(Clamped, '0e+x / y')
1215 return Decimal( (sign, (0,), exp) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001216
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001217 if not other:
1218 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001219 return context._raise_error(DivisionByZero, 'divmod(x,0)',
1220 sign, 1)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001221 return context._raise_error(DivisionByZero, 'x / 0', sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001222
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001223 #OK, so neither = 0, INF or NaN
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001224
1225 shouldround = context._rounding_decision == ALWAYS_ROUND
1226
1227 #If we're dividing into ints, and self < other, stop.
1228 #self.__abs__(0) does not round.
1229 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
1230
1231 if divmod == 1 or divmod == 3:
1232 exp = min(self._exp, other._exp)
1233 ans2 = self._rescale(exp, context=context, watchexp=0)
1234 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001235 ans2 = ans2._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001236 return (Decimal( (sign, (0,), 0) ),
1237 ans2)
1238
1239 elif divmod == 2:
1240 #Don't round the mod part, if we don't need it.
1241 return (Decimal( (sign, (0,), 0) ), Decimal(self))
1242
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001243 op1 = _WorkRep(self)
1244 op2 = _WorkRep(other)
1245 op1, op2, adjust = _adjust_coefficients(op1, op2)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001246 res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001247 if divmod and res.exp > context.prec + 1:
1248 return context._raise_error(DivisionImpossible)
1249
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001250 prec_limit = 10 ** context.prec
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001251 while 1:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001252 while op2.int <= op1.int:
1253 res.int += 1
1254 op1.int -= op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001255 if res.exp == 0 and divmod:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001256 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001257 return context._raise_error(DivisionImpossible)
1258 otherside = Decimal(op1)
1259 frozen = context._ignore_all_flags()
1260
1261 exp = min(self._exp, other._exp)
Raymond Hettinger17931de2004-10-27 06:21:46 +00001262 otherside = otherside._rescale(exp, context=context, watchexp=0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001263 context._regard_flags(*frozen)
1264 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001265 otherside = otherside._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001266 return (Decimal(res), otherside)
1267
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001268 if op1.int == 0 and adjust >= 0 and not divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001269 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001270 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001271 if divmod:
1272 return context._raise_error(DivisionImpossible)
1273 shouldround=1
1274 # Really, the answer is a bit higher, so adding a one to
1275 # the end will make sure the rounding is right.
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001276 if op1.int != 0:
1277 res.int *= 10
1278 res.int += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001279 res.exp -= 1
1280
1281 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001282 res.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001283 res.exp -= 1
1284 adjust += 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001285 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001286 op1.exp -= 1
1287
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001288 if res.exp == 0 and divmod and op2.int > op1.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001289 #Solves an error in precision. Same as a previous block.
1290
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001291 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001292 return context._raise_error(DivisionImpossible)
1293 otherside = Decimal(op1)
1294 frozen = context._ignore_all_flags()
1295
1296 exp = min(self._exp, other._exp)
1297 otherside = otherside._rescale(exp, context=context)
1298
1299 context._regard_flags(*frozen)
1300
1301 return (Decimal(res), otherside)
1302
1303 ans = Decimal(res)
1304 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001305 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001306 return ans
1307
1308 def __rdiv__(self, other, context=None):
1309 """Swaps self/other and returns __div__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001310 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001311 if other is NotImplemented:
1312 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001313 return other.__div__(self, context=context)
1314 __rtruediv__ = __rdiv__
1315
1316 def __divmod__(self, other, context=None):
1317 """
1318 (self // other, self % other)
1319 """
1320 return self._divide(other, 1, context)
1321
1322 def __rdivmod__(self, other, context=None):
1323 """Swaps self/other and returns __divmod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001324 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001325 if other is NotImplemented:
1326 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001327 return other.__divmod__(self, context=context)
1328
1329 def __mod__(self, other, context=None):
1330 """
1331 self % other
1332 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001333 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001334 if other is NotImplemented:
1335 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001336
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001337 if self._is_special or other._is_special:
1338 ans = self._check_nans(other, context)
1339 if ans:
1340 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001341
1342 if self and not other:
1343 return context._raise_error(InvalidOperation, 'x % 0')
1344
1345 return self._divide(other, 3, context)[1]
1346
1347 def __rmod__(self, other, context=None):
1348 """Swaps self/other and returns __mod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001349 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001350 if other is NotImplemented:
1351 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001352 return other.__mod__(self, context=context)
1353
1354 def remainder_near(self, other, context=None):
1355 """
1356 Remainder nearest to 0- abs(remainder-near) <= other/2
1357 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001358 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001359 if other is NotImplemented:
1360 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001361
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001362 if self._is_special or other._is_special:
1363 ans = self._check_nans(other, context)
1364 if ans:
1365 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001366 if self and not other:
1367 return context._raise_error(InvalidOperation, 'x % 0')
1368
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001369 if context is None:
1370 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001371 # If DivisionImpossible causes an error, do not leave Rounded/Inexact
1372 # ignored in the calling function.
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001373 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001374 flags = context._ignore_flags(Rounded, Inexact)
1375 #keep DivisionImpossible flags
1376 (side, r) = self.__divmod__(other, context=context)
1377
1378 if r._isnan():
1379 context._regard_flags(*flags)
1380 return r
1381
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001382 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001383 rounding = context._set_rounding_decision(NEVER_ROUND)
1384
1385 if other._sign:
1386 comparison = other.__div__(Decimal(-2), context=context)
1387 else:
1388 comparison = other.__div__(Decimal(2), context=context)
1389
1390 context._set_rounding_decision(rounding)
1391 context._regard_flags(*flags)
1392
1393 s1, s2 = r._sign, comparison._sign
1394 r._sign, comparison._sign = 0, 0
1395
1396 if r < comparison:
1397 r._sign, comparison._sign = s1, s2
1398 #Get flags now
1399 self.__divmod__(other, context=context)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001400 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001401 r._sign, comparison._sign = s1, s2
1402
1403 rounding = context._set_rounding_decision(NEVER_ROUND)
1404
1405 (side, r) = self.__divmod__(other, context=context)
1406 context._set_rounding_decision(rounding)
1407 if r._isnan():
1408 return r
1409
1410 decrease = not side._iseven()
1411 rounding = context._set_rounding_decision(NEVER_ROUND)
1412 side = side.__abs__(context=context)
1413 context._set_rounding_decision(rounding)
1414
1415 s1, s2 = r._sign, comparison._sign
1416 r._sign, comparison._sign = 0, 0
1417 if r > comparison or decrease and r == comparison:
1418 r._sign, comparison._sign = s1, s2
1419 context.prec += 1
1420 if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
1421 context.prec -= 1
1422 return context._raise_error(DivisionImpossible)[1]
1423 context.prec -= 1
1424 if self._sign == other._sign:
1425 r = r.__sub__(other, context=context)
1426 else:
1427 r = r.__add__(other, context=context)
1428 else:
1429 r._sign, comparison._sign = s1, s2
1430
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001431 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001432
1433 def __floordiv__(self, other, context=None):
1434 """self // other"""
1435 return self._divide(other, 2, context)[0]
1436
1437 def __rfloordiv__(self, other, context=None):
1438 """Swaps self/other and returns __floordiv__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001439 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001440 if other is NotImplemented:
1441 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001442 return other.__floordiv__(self, context=context)
1443
1444 def __float__(self):
1445 """Float representation."""
1446 return float(str(self))
1447
1448 def __int__(self):
Brett Cannon46b08022005-03-01 03:12:26 +00001449 """Converts self to an int, truncating if necessary."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001450 if self._is_special:
1451 if self._isnan():
1452 context = getcontext()
1453 return context._raise_error(InvalidContext)
1454 elif self._isinfinity():
1455 raise OverflowError, "Cannot convert infinity to long"
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001456 if self._exp >= 0:
Raymond Hettinger605ed022004-11-24 07:28:48 +00001457 s = ''.join(map(str, self._int)) + '0'*self._exp
1458 else:
1459 s = ''.join(map(str, self._int))[:self._exp]
1460 if s == '':
1461 s = '0'
1462 sign = '-'*self._sign
1463 return int(sign + s)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001464
1465 def __long__(self):
1466 """Converts to a long.
1467
1468 Equivalent to long(int(self))
1469 """
1470 return long(self.__int__())
1471
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001472 def _fix(self, context):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001473 """Round if it is necessary to keep self within prec precision.
1474
1475 Rounds and fixes the exponent. Does not raise on a sNaN.
1476
1477 Arguments:
1478 self - Decimal instance
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001479 context - context used.
1480 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001481 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001482 return self
1483 if context is None:
1484 context = getcontext()
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001485 prec = context.prec
Facundo Batista99b55482004-10-26 23:38:46 +00001486 ans = self._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001487 if len(ans._int) > prec:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001488 ans = ans._round(prec, context=context)
Facundo Batista99b55482004-10-26 23:38:46 +00001489 ans = ans._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001490 return ans
1491
Facundo Batista99b55482004-10-26 23:38:46 +00001492 def _fixexponents(self, context):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001493 """Fix the exponents and return a copy with the exponent in bounds.
1494 Only call if known to not be a special value.
1495 """
1496 folddown = context._clamp
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001497 Emin = context.Emin
Facundo Batista99b55482004-10-26 23:38:46 +00001498 ans = self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001499 ans_adjusted = ans.adjusted()
1500 if ans_adjusted < Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001501 Etiny = context.Etiny()
1502 if ans._exp < Etiny:
1503 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001504 ans = Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001505 ans._exp = Etiny
1506 context._raise_error(Clamped)
1507 return ans
1508 ans = ans._rescale(Etiny, context=context)
1509 #It isn't zero, and exp < Emin => subnormal
1510 context._raise_error(Subnormal)
1511 if context.flags[Inexact]:
1512 context._raise_error(Underflow)
1513 else:
1514 if ans:
1515 #Only raise subnormal if non-zero.
1516 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001517 else:
1518 Etop = context.Etop()
1519 if folddown and ans._exp > Etop:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001520 context._raise_error(Clamped)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001521 ans = ans._rescale(Etop, context=context)
1522 else:
1523 Emax = context.Emax
1524 if ans_adjusted > Emax:
1525 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001526 ans = Decimal(self)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001527 ans._exp = Emax
1528 context._raise_error(Clamped)
1529 return ans
1530 context._raise_error(Inexact)
1531 context._raise_error(Rounded)
1532 return context._raise_error(Overflow, 'above Emax', ans._sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001533 return ans
1534
1535 def _round(self, prec=None, rounding=None, context=None):
1536 """Returns a rounded version of self.
1537
1538 You can specify the precision or rounding method. Otherwise, the
1539 context determines it.
1540 """
1541
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001542 if self._is_special:
1543 ans = self._check_nans(context=context)
1544 if ans:
1545 return ans
1546
1547 if self._isinfinity():
1548 return Decimal(self)
1549
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001550 if context is None:
1551 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001552
1553 if rounding is None:
1554 rounding = context.rounding
1555 if prec is None:
1556 prec = context.prec
1557
1558 if not self:
1559 if prec <= 0:
1560 dig = (0,)
1561 exp = len(self._int) - prec + self._exp
1562 else:
1563 dig = (0,) * prec
1564 exp = len(self._int) + self._exp - prec
1565 ans = Decimal((self._sign, dig, exp))
1566 context._raise_error(Rounded)
1567 return ans
1568
1569 if prec == 0:
1570 temp = Decimal(self)
1571 temp._int = (0,)+temp._int
1572 prec = 1
1573 elif prec < 0:
1574 exp = self._exp + len(self._int) - prec - 1
1575 temp = Decimal( (self._sign, (0, 1), exp))
1576 prec = 1
1577 else:
1578 temp = Decimal(self)
1579
1580 numdigits = len(temp._int)
1581 if prec == numdigits:
1582 return temp
1583
1584 # See if we need to extend precision
1585 expdiff = prec - numdigits
1586 if expdiff > 0:
1587 tmp = list(temp._int)
1588 tmp.extend([0] * expdiff)
1589 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff))
1590 return ans
1591
1592 #OK, but maybe all the lost digits are 0.
1593 lostdigits = self._int[expdiff:]
1594 if lostdigits == (0,) * len(lostdigits):
1595 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
1596 #Rounded, but not Inexact
1597 context._raise_error(Rounded)
1598 return ans
1599
1600 # Okay, let's round and lose data
1601
1602 this_function = getattr(temp, self._pick_rounding_function[rounding])
1603 #Now we've got the rounding function
1604
1605 if prec != context.prec:
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001606 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001607 context.prec = prec
1608 ans = this_function(prec, expdiff, context)
1609 context._raise_error(Rounded)
1610 context._raise_error(Inexact, 'Changed in rounding')
1611
1612 return ans
1613
1614 _pick_rounding_function = {}
1615
1616 def _round_down(self, prec, expdiff, context):
1617 """Also known as round-towards-0, truncate."""
1618 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1619
1620 def _round_half_up(self, prec, expdiff, context, tmp = None):
1621 """Rounds 5 up (away from 0)"""
1622
1623 if tmp is None:
1624 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
1625 if self._int[prec] >= 5:
1626 tmp = tmp._increment(round=0, context=context)
1627 if len(tmp._int) > prec:
1628 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1629 return tmp
1630
1631 def _round_half_even(self, prec, expdiff, context):
1632 """Round 5 to even, rest to nearest."""
1633
1634 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1635 half = (self._int[prec] == 5)
1636 if half:
1637 for digit in self._int[prec+1:]:
1638 if digit != 0:
1639 half = 0
1640 break
1641 if half:
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001642 if self._int[prec-1] & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001643 return tmp
1644 return self._round_half_up(prec, expdiff, context, tmp)
1645
1646 def _round_half_down(self, prec, expdiff, context):
1647 """Round 5 down"""
1648
1649 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1650 half = (self._int[prec] == 5)
1651 if half:
1652 for digit in self._int[prec+1:]:
1653 if digit != 0:
1654 half = 0
1655 break
1656 if half:
1657 return tmp
1658 return self._round_half_up(prec, expdiff, context, tmp)
1659
1660 def _round_up(self, prec, expdiff, context):
1661 """Rounds away from 0."""
1662 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1663 for digit in self._int[prec:]:
1664 if digit != 0:
1665 tmp = tmp._increment(round=1, context=context)
1666 if len(tmp._int) > prec:
1667 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1668 else:
1669 return tmp
1670 return tmp
1671
1672 def _round_ceiling(self, prec, expdiff, context):
1673 """Rounds up (not away from 0 if negative.)"""
1674 if self._sign:
1675 return self._round_down(prec, expdiff, context)
1676 else:
1677 return self._round_up(prec, expdiff, context)
1678
1679 def _round_floor(self, prec, expdiff, context):
1680 """Rounds down (not towards 0 if negative)"""
1681 if not self._sign:
1682 return self._round_down(prec, expdiff, context)
1683 else:
1684 return self._round_up(prec, expdiff, context)
1685
1686 def __pow__(self, n, modulo = None, context=None):
1687 """Return self ** n (mod modulo)
1688
1689 If modulo is None (default), don't take it mod modulo.
1690 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001691 n = _convert_other(n)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001692 if n is NotImplemented:
1693 return n
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001694
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001695 if context is None:
1696 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001697
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001698 if self._is_special or n._is_special or n.adjusted() > 8:
1699 #Because the spot << doesn't work with really big exponents
1700 if n._isinfinity() or n.adjusted() > 8:
1701 return context._raise_error(InvalidOperation, 'x ** INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001702
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001703 ans = self._check_nans(n, context)
1704 if ans:
1705 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001706
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001707 if not n._isinteger():
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001708 return context._raise_error(InvalidOperation, 'x ** (non-integer)')
1709
1710 if not self and not n:
1711 return context._raise_error(InvalidOperation, '0 ** 0')
1712
1713 if not n:
1714 return Decimal(1)
1715
1716 if self == Decimal(1):
1717 return Decimal(1)
1718
1719 sign = self._sign and not n._iseven()
1720 n = int(n)
1721
1722 if self._isinfinity():
1723 if modulo:
1724 return context._raise_error(InvalidOperation, 'INF % x')
1725 if n > 0:
1726 return Infsign[sign]
1727 return Decimal( (sign, (0,), 0) )
1728
1729 #with ludicrously large exponent, just raise an overflow and return inf.
1730 if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
1731 and self:
1732
1733 tmp = Decimal('inf')
1734 tmp._sign = sign
1735 context._raise_error(Rounded)
1736 context._raise_error(Inexact)
1737 context._raise_error(Overflow, 'Big power', sign)
1738 return tmp
1739
1740 elength = len(str(abs(n)))
1741 firstprec = context.prec
1742
Raymond Hettinger99148e72004-07-14 19:56:56 +00001743 if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001744 return context._raise_error(Overflow, 'Too much precision.', sign)
1745
1746 mul = Decimal(self)
1747 val = Decimal(1)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001748 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001749 context.prec = firstprec + elength + 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001750 if n < 0:
1751 #n is a long now, not Decimal instance
1752 n = -n
1753 mul = Decimal(1).__div__(mul, context=context)
1754
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001755 spot = 1
1756 while spot <= n:
1757 spot <<= 1
1758
1759 spot >>= 1
1760 #Spot is the highest power of 2 less than n
1761 while spot:
1762 val = val.__mul__(val, context=context)
1763 if val._isinfinity():
1764 val = Infsign[sign]
1765 break
1766 if spot & n:
1767 val = val.__mul__(mul, context=context)
1768 if modulo is not None:
1769 val = val.__mod__(modulo, context=context)
1770 spot >>= 1
1771 context.prec = firstprec
1772
Raymond Hettinger76e60d62004-10-20 06:58:28 +00001773 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001774 return val._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001775 return val
1776
1777 def __rpow__(self, other, context=None):
1778 """Swaps self/other and returns __pow__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001779 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001780 if other is NotImplemented:
1781 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001782 return other.__pow__(self, context=context)
1783
1784 def normalize(self, context=None):
1785 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001786
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001787 if self._is_special:
1788 ans = self._check_nans(context=context)
1789 if ans:
1790 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001791
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001792 dup = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001793 if dup._isinfinity():
1794 return dup
1795
1796 if not dup:
1797 return Decimal( (dup._sign, (0,), 0) )
1798 end = len(dup._int)
1799 exp = dup._exp
1800 while dup._int[end-1] == 0:
1801 exp += 1
1802 end -= 1
1803 return Decimal( (dup._sign, dup._int[:end], exp) )
1804
1805
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001806 def quantize(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001807 """Quantize self so its exponent is the same as that of exp.
1808
1809 Similar to self._rescale(exp._exp) but with error checking.
1810 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001811 if self._is_special or exp._is_special:
1812 ans = self._check_nans(exp, context)
1813 if ans:
1814 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001815
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001816 if exp._isinfinity() or self._isinfinity():
1817 if exp._isinfinity() and self._isinfinity():
1818 return self #if both are inf, it is OK
1819 if context is None:
1820 context = getcontext()
1821 return context._raise_error(InvalidOperation,
1822 'quantize with one INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001823 return self._rescale(exp._exp, rounding, context, watchexp)
1824
1825 def same_quantum(self, other):
1826 """Test whether self and other have the same exponent.
1827
1828 same as self._exp == other._exp, except NaN == sNaN
1829 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001830 if self._is_special or other._is_special:
1831 if self._isnan() or other._isnan():
1832 return self._isnan() and other._isnan() and True
1833 if self._isinfinity() or other._isinfinity():
1834 return self._isinfinity() and other._isinfinity() and True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001835 return self._exp == other._exp
1836
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001837 def _rescale(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001838 """Rescales so that the exponent is exp.
1839
1840 exp = exp to scale to (an integer)
1841 rounding = rounding version
1842 watchexp: if set (default) an error is returned if exp is greater
1843 than Emax or less than Etiny.
1844 """
1845 if context is None:
1846 context = getcontext()
1847
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001848 if self._is_special:
1849 if self._isinfinity():
1850 return context._raise_error(InvalidOperation, 'rescale with an INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001851
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001852 ans = self._check_nans(context=context)
1853 if ans:
1854 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001855
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001856 if watchexp and (context.Emax < exp or context.Etiny() > exp):
1857 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1858
1859 if not self:
1860 ans = Decimal(self)
1861 ans._int = (0,)
1862 ans._exp = exp
1863 return ans
1864
1865 diff = self._exp - exp
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001866 digits = len(self._int) + diff
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001867
1868 if watchexp and digits > context.prec:
1869 return context._raise_error(InvalidOperation, 'Rescale > prec')
1870
1871 tmp = Decimal(self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001872 tmp._int = (0,) + tmp._int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001873 digits += 1
1874
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001875 if digits < 0:
1876 tmp._exp = -digits + tmp._exp
1877 tmp._int = (0,1)
1878 digits = 1
1879 tmp = tmp._round(digits, rounding, context=context)
1880
1881 if tmp._int[0] == 0 and len(tmp._int) > 1:
1882 tmp._int = tmp._int[1:]
1883 tmp._exp = exp
1884
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001885 tmp_adjusted = tmp.adjusted()
1886 if tmp and tmp_adjusted < context.Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001887 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001888 elif tmp and tmp_adjusted > context.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001889 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1890 return tmp
1891
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001892 def to_integral(self, rounding=None, context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001893 """Rounds to the nearest integer, without raising inexact, rounded."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001894 if self._is_special:
1895 ans = self._check_nans(context=context)
1896 if ans:
1897 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001898 if self._exp >= 0:
1899 return self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001900 if context is None:
1901 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001902 flags = context._ignore_flags(Rounded, Inexact)
1903 ans = self._rescale(0, rounding, context=context)
1904 context._regard_flags(flags)
1905 return ans
1906
1907 def sqrt(self, context=None):
1908 """Return the square root of self.
1909
1910 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
1911 Should quadratically approach the right answer.
1912 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001913 if self._is_special:
1914 ans = self._check_nans(context=context)
1915 if ans:
1916 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001917
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001918 if self._isinfinity() and self._sign == 0:
1919 return Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001920
1921 if not self:
1922 #exponent = self._exp / 2, using round_down.
1923 #if self._exp < 0:
1924 # exp = (self._exp+1) // 2
1925 #else:
1926 exp = (self._exp) // 2
1927 if self._sign == 1:
1928 #sqrt(-0) = -0
1929 return Decimal( (1, (0,), exp))
1930 else:
1931 return Decimal( (0, (0,), exp))
1932
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001933 if context is None:
1934 context = getcontext()
1935
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001936 if self._sign == 1:
1937 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
1938
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001939 tmp = Decimal(self)
1940
Raymond Hettinger4837a222004-09-27 14:23:40 +00001941 expadd = tmp._exp // 2
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001942 if tmp._exp & 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001943 tmp._int += (0,)
1944 tmp._exp = 0
1945 else:
1946 tmp._exp = 0
1947
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001948 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001949 flags = context._ignore_all_flags()
1950 firstprec = context.prec
1951 context.prec = 3
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001952 if tmp.adjusted() & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001953 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) )
1954 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
1955 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00001956 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001957 else:
1958 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
1959 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
1960 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00001961 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001962
1963 #ans is now a linear approximation.
1964
1965 Emax, Emin = context.Emax, context.Emin
Raymond Hettinger99148e72004-07-14 19:56:56 +00001966 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001967
1968 half = Decimal('0.5')
1969
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001970 maxp = firstprec + 2
1971 rounding = context._set_rounding(ROUND_HALF_EVEN)
1972 while 1:
1973 context.prec = min(2*context.prec - 2, maxp)
1974 ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
1975 context=context), context=context)
1976 if context.prec == maxp:
1977 break
1978
1979 #round to the answer's precision-- the only error can be 1 ulp.
1980 context.prec = firstprec
1981 prevexp = ans.adjusted()
1982 ans = ans._round(context=context)
1983
1984 #Now, check if the other last digits are better.
1985 context.prec = firstprec + 1
1986 # In case we rounded up another digit and we should actually go lower.
1987 if prevexp != ans.adjusted():
1988 ans._int += (0,)
1989 ans._exp -= 1
1990
1991
1992 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
1993 context._set_rounding(ROUND_UP)
1994 if lower.__mul__(lower, context=context) > (tmp):
1995 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
1996
1997 else:
1998 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
1999 context._set_rounding(ROUND_DOWN)
2000 if upper.__mul__(upper, context=context) < tmp:
2001 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
2002
2003 ans._exp += expadd
2004
2005 context.prec = firstprec
2006 context.rounding = rounding
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002007 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002008
2009 rounding = context._set_rounding_decision(NEVER_ROUND)
2010 if not ans.__mul__(ans, context=context) == self:
2011 # Only rounded/inexact if here.
2012 context._regard_flags(flags)
2013 context._raise_error(Rounded)
2014 context._raise_error(Inexact)
2015 else:
2016 #Exact answer, so let's set the exponent right.
2017 #if self._exp < 0:
2018 # exp = (self._exp +1)// 2
2019 #else:
2020 exp = self._exp // 2
2021 context.prec += ans._exp - exp
2022 ans = ans._rescale(exp, context=context)
2023 context.prec = firstprec
2024 context._regard_flags(flags)
2025 context.Emax, context.Emin = Emax, Emin
2026
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002027 return ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002028
2029 def max(self, other, context=None):
2030 """Returns the larger value.
2031
2032 like max(self, other) except if one is not a number, returns
2033 NaN (and signals if one is sNaN). Also rounds.
2034 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002035 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002036 if other is NotImplemented:
2037 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002038
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002039 if self._is_special or other._is_special:
2040 # if one operand is a quiet NaN and the other is number, then the
2041 # number is always returned
2042 sn = self._isnan()
2043 on = other._isnan()
2044 if sn or on:
2045 if on == 1 and sn != 2:
2046 return self
2047 if sn == 1 and on != 2:
2048 return other
2049 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002050
2051 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002052 c = self.__cmp__(other)
2053 if c == 0:
2054 # if both operands are finite and equal in numerical value
2055 # then an ordering is applied:
2056 #
2057 # if the signs differ then max returns the operand with the
2058 # positive sign and min returns the operand with the negative sign
2059 #
2060 # if the signs are the same then the exponent is used to select
2061 # the result.
2062 if self._sign != other._sign:
2063 if self._sign:
2064 ans = other
2065 elif self._exp < other._exp and not self._sign:
2066 ans = other
2067 elif self._exp > other._exp and self._sign:
2068 ans = other
2069 elif c == -1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002070 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002071
2072 if context is None:
2073 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002074 if context._rounding_decision == ALWAYS_ROUND:
2075 return ans._fix(context)
2076 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002077
2078 def min(self, other, context=None):
2079 """Returns the smaller value.
2080
2081 like min(self, other) except if one is not a number, returns
2082 NaN (and signals if one is sNaN). Also rounds.
2083 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002084 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002085 if other is NotImplemented:
2086 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002087
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002088 if self._is_special or other._is_special:
2089 # if one operand is a quiet NaN and the other is number, then the
2090 # number is always returned
2091 sn = self._isnan()
2092 on = other._isnan()
2093 if sn or on:
2094 if on == 1 and sn != 2:
2095 return self
2096 if sn == 1 and on != 2:
2097 return other
2098 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002099
2100 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002101 c = self.__cmp__(other)
2102 if c == 0:
2103 # if both operands are finite and equal in numerical value
2104 # then an ordering is applied:
2105 #
2106 # if the signs differ then max returns the operand with the
2107 # positive sign and min returns the operand with the negative sign
2108 #
2109 # if the signs are the same then the exponent is used to select
2110 # the result.
2111 if self._sign != other._sign:
2112 if other._sign:
2113 ans = other
2114 elif self._exp > other._exp and not self._sign:
2115 ans = other
2116 elif self._exp < other._exp and self._sign:
2117 ans = other
2118 elif c == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002119 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002120
2121 if context is None:
2122 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002123 if context._rounding_decision == ALWAYS_ROUND:
2124 return ans._fix(context)
2125 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002126
2127 def _isinteger(self):
2128 """Returns whether self is an integer"""
2129 if self._exp >= 0:
2130 return True
2131 rest = self._int[self._exp:]
2132 return rest == (0,)*len(rest)
2133
2134 def _iseven(self):
2135 """Returns 1 if self is even. Assumes self is an integer."""
2136 if self._exp > 0:
2137 return 1
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002138 return self._int[-1+self._exp] & 1 == 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002139
2140 def adjusted(self):
2141 """Return the adjusted exponent of self"""
2142 try:
2143 return self._exp + len(self._int) - 1
2144 #If NaN or Infinity, self._exp is string
2145 except TypeError:
2146 return 0
2147
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002148 # support for pickling, copy, and deepcopy
2149 def __reduce__(self):
2150 return (self.__class__, (str(self),))
2151
2152 def __copy__(self):
2153 if type(self) == Decimal:
2154 return self # I'm immutable; therefore I am my own clone
2155 return self.__class__(str(self))
2156
2157 def __deepcopy__(self, memo):
2158 if type(self) == Decimal:
2159 return self # My components are also immutable
2160 return self.__class__(str(self))
2161
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002162##### Context class ###########################################
2163
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002164
2165# get rounding method function:
2166rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
2167for name in rounding_functions:
2168 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
2169 globalname = name[1:].upper()
2170 val = globals()[globalname]
2171 Decimal._pick_rounding_function[val] = name
2172
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002173del name, val, globalname, rounding_functions
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002174
2175class Context(object):
2176 """Contains the context for a Decimal instance.
2177
2178 Contains:
2179 prec - precision (for use in rounding, division, square roots..)
2180 rounding - rounding type. (how you round)
2181 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
Raymond Hettingerbf440692004-07-10 14:14:37 +00002182 traps - If traps[exception] = 1, then the exception is
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002183 raised when it is caused. Otherwise, a value is
2184 substituted in.
2185 flags - When an exception is caused, flags[exception] is incremented.
2186 (Whether or not the trap_enabler is set)
2187 Should be reset by user of Decimal instance.
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002188 Emin - Minimum exponent
2189 Emax - Maximum exponent
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002190 capitals - If 1, 1*10^1 is printed as 1E+1.
2191 If 0, printed as 1e1
Raymond Hettingere0f15812004-07-05 05:36:39 +00002192 _clamp - If 1, change exponents if too high (Default 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002193 """
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002194
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002195 def __init__(self, prec=None, rounding=None,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002196 traps=None, flags=None,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002197 _rounding_decision=None,
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002198 Emin=None, Emax=None,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002199 capitals=None, _clamp=0,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002200 _ignored_flags=None):
2201 if flags is None:
2202 flags = []
2203 if _ignored_flags is None:
2204 _ignored_flags = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002205 if not isinstance(flags, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002206 flags = dict([(s,s in flags) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002207 del s
Raymond Hettingerbf440692004-07-10 14:14:37 +00002208 if traps is not None and not isinstance(traps, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002209 traps = dict([(s,s in traps) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002210 del s
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002211 for name, val in locals().items():
2212 if val is None:
2213 setattr(self, name, copy.copy(getattr(DefaultContext, name)))
2214 else:
2215 setattr(self, name, val)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002216 del self.self
2217
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002218 def __repr__(self):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002219 """Show the current context."""
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002220 s = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002221 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
2222 s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
2223 s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002224 return ', '.join(s) + ')'
2225
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002226 def clear_flags(self):
2227 """Reset all flags to zero"""
2228 for flag in self.flags:
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002229 self.flags[flag] = 0
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002230
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002231 def _shallow_copy(self):
2232 """Returns a shallow copy from self."""
Raymond Hettingerbf440692004-07-10 14:14:37 +00002233 nc = Context(self.prec, self.rounding, self.traps, self.flags,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002234 self._rounding_decision, self.Emin, self.Emax,
2235 self.capitals, self._clamp, self._ignored_flags)
2236 return nc
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002237
2238 def copy(self):
2239 """Returns a deep copy from self."""
2240 nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
2241 self._rounding_decision, self.Emin, self.Emax,
2242 self.capitals, self._clamp, self._ignored_flags)
2243 return nc
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002244 __copy__ = copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002245
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002246 def _raise_error(self, condition, explanation = None, *args):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002247 """Handles an error
2248
2249 If the flag is in _ignored_flags, returns the default response.
2250 Otherwise, it increments the flag, then, if the corresponding
2251 trap_enabler is set, it reaises the exception. Otherwise, it returns
2252 the default value after incrementing the flag.
2253 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002254 error = _condition_map.get(condition, condition)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002255 if error in self._ignored_flags:
2256 #Don't touch the flag
2257 return error().handle(self, *args)
2258
2259 self.flags[error] += 1
Raymond Hettingerbf440692004-07-10 14:14:37 +00002260 if not self.traps[error]:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002261 #The errors define how to handle themselves.
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002262 return condition().handle(self, *args)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002263
2264 # Errors should only be risked on copies of the context
2265 #self._ignored_flags = []
2266 raise error, explanation
2267
2268 def _ignore_all_flags(self):
2269 """Ignore all flags, if they are raised"""
Raymond Hettingerfed52962004-07-14 15:41:57 +00002270 return self._ignore_flags(*_signals)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002271
2272 def _ignore_flags(self, *flags):
2273 """Ignore the flags, if they are raised"""
2274 # Do not mutate-- This way, copies of a context leave the original
2275 # alone.
2276 self._ignored_flags = (self._ignored_flags + list(flags))
2277 return list(flags)
2278
2279 def _regard_flags(self, *flags):
2280 """Stop ignoring the flags, if they are raised"""
2281 if flags and isinstance(flags[0], (tuple,list)):
2282 flags = flags[0]
2283 for flag in flags:
2284 self._ignored_flags.remove(flag)
2285
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002286 def __hash__(self):
2287 """A Context cannot be hashed."""
2288 # We inherit object.__hash__, so we must deny this explicitly
2289 raise TypeError, "Cannot hash a Context."
2290
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002291 def Etiny(self):
2292 """Returns Etiny (= Emin - prec + 1)"""
2293 return int(self.Emin - self.prec + 1)
2294
2295 def Etop(self):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002296 """Returns maximum exponent (= Emax - prec + 1)"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002297 return int(self.Emax - self.prec + 1)
2298
2299 def _set_rounding_decision(self, type):
2300 """Sets the rounding decision.
2301
2302 Sets the rounding decision, and returns the current (previous)
2303 rounding decision. Often used like:
2304
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002305 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002306 # That so you don't change the calling context
2307 # if an error occurs in the middle (say DivisionImpossible is raised).
2308
2309 rounding = context._set_rounding_decision(NEVER_ROUND)
2310 instance = instance / Decimal(2)
2311 context._set_rounding_decision(rounding)
2312
2313 This will make it not round for that operation.
2314 """
2315
2316 rounding = self._rounding_decision
2317 self._rounding_decision = type
2318 return rounding
2319
2320 def _set_rounding(self, type):
2321 """Sets the rounding type.
2322
2323 Sets the rounding type, and returns the current (previous)
2324 rounding type. Often used like:
2325
2326 context = context.copy()
2327 # so you don't change the calling context
2328 # if an error occurs in the middle.
2329 rounding = context._set_rounding(ROUND_UP)
2330 val = self.__sub__(other, context=context)
2331 context._set_rounding(rounding)
2332
2333 This will make it round up for that operation.
2334 """
2335 rounding = self.rounding
2336 self.rounding= type
2337 return rounding
2338
Raymond Hettingerfed52962004-07-14 15:41:57 +00002339 def create_decimal(self, num='0'):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002340 """Creates a new Decimal instance but using self as context."""
2341 d = Decimal(num, context=self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002342 return d._fix(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002343
2344 #Methods
2345 def abs(self, a):
2346 """Returns the absolute value of the operand.
2347
2348 If the operand is negative, the result is the same as using the minus
2349 operation on the operand. Otherwise, the result is the same as using
2350 the plus operation on the operand.
2351
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002352 >>> ExtendedContext.abs(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002353 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002354 >>> ExtendedContext.abs(Decimal('-100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002355 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002356 >>> ExtendedContext.abs(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002357 Decimal("101.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002358 >>> ExtendedContext.abs(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002359 Decimal("101.5")
2360 """
2361 return a.__abs__(context=self)
2362
2363 def add(self, a, b):
2364 """Return the sum of the two operands.
2365
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002366 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002367 Decimal("19.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002368 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002369 Decimal("1.02E+4")
2370 """
2371 return a.__add__(b, context=self)
2372
2373 def _apply(self, a):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002374 return str(a._fix(self))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002375
2376 def compare(self, a, b):
2377 """Compares values numerically.
2378
2379 If the signs of the operands differ, a value representing each operand
2380 ('-1' if the operand is less than zero, '0' if the operand is zero or
2381 negative zero, or '1' if the operand is greater than zero) is used in
2382 place of that operand for the comparison instead of the actual
2383 operand.
2384
2385 The comparison is then effected by subtracting the second operand from
2386 the first and then returning a value according to the result of the
2387 subtraction: '-1' if the result is less than zero, '0' if the result is
2388 zero or negative zero, or '1' if the result is greater than zero.
2389
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002390 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002391 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002392 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002393 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002394 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002395 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002396 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002397 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002398 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002399 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002400 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002401 Decimal("-1")
2402 """
2403 return a.compare(b, context=self)
2404
2405 def divide(self, a, b):
2406 """Decimal division in a specified context.
2407
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002408 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002409 Decimal("0.333333333")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002410 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002411 Decimal("0.666666667")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002412 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002413 Decimal("2.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002414 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002415 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002416 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002417 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002418 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002419 Decimal("4.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002420 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002421 Decimal("1.20")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002422 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002423 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002424 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002425 Decimal("1000")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002426 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002427 Decimal("1.20E+6")
2428 """
2429 return a.__div__(b, context=self)
2430
2431 def divide_int(self, a, b):
2432 """Divides two numbers and returns the integer part of the result.
2433
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002434 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002435 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002436 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002437 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002438 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002439 Decimal("3")
2440 """
2441 return a.__floordiv__(b, context=self)
2442
2443 def divmod(self, a, b):
2444 return a.__divmod__(b, context=self)
2445
2446 def max(self, a,b):
2447 """max compares two values numerically and returns the maximum.
2448
2449 If either operand is a NaN then the general rules apply.
2450 Otherwise, the operands are compared as as though by the compare
2451 operation. If they are numerically equal then the left-hand operand
2452 is chosen as the result. Otherwise the maximum (closer to positive
2453 infinity) of the two operands is chosen as the result.
2454
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002455 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002456 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002457 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002458 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002459 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002460 Decimal("1")
2461 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
2462 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002463 """
2464 return a.max(b, context=self)
2465
2466 def min(self, a,b):
2467 """min compares two values numerically and returns the minimum.
2468
2469 If either operand is a NaN then the general rules apply.
2470 Otherwise, the operands are compared as as though by the compare
2471 operation. If they are numerically equal then the left-hand operand
2472 is chosen as the result. Otherwise the minimum (closer to negative
2473 infinity) of the two operands is chosen as the result.
2474
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002475 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002476 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002477 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002478 Decimal("-10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002479 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002480 Decimal("1.0")
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002481 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
2482 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002483 """
2484 return a.min(b, context=self)
2485
2486 def minus(self, a):
2487 """Minus corresponds to unary prefix minus in Python.
2488
2489 The operation is evaluated using the same rules as subtract; the
2490 operation minus(a) is calculated as subtract('0', a) where the '0'
2491 has the same exponent as the operand.
2492
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002493 >>> ExtendedContext.minus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002494 Decimal("-1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002495 >>> ExtendedContext.minus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002496 Decimal("1.3")
2497 """
2498 return a.__neg__(context=self)
2499
2500 def multiply(self, a, b):
2501 """multiply multiplies two operands.
2502
2503 If either operand is a special value then the general rules apply.
2504 Otherwise, the operands are multiplied together ('long multiplication'),
2505 resulting in a number which may be as long as the sum of the lengths
2506 of the two operands.
2507
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002508 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002509 Decimal("3.60")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002510 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002511 Decimal("21")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002512 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002513 Decimal("0.72")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002514 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002515 Decimal("-0.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002516 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002517 Decimal("4.28135971E+11")
2518 """
2519 return a.__mul__(b, context=self)
2520
2521 def normalize(self, a):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002522 """normalize reduces an operand to its simplest form.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002523
2524 Essentially a plus operation with all trailing zeros removed from the
2525 result.
2526
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002527 >>> ExtendedContext.normalize(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002528 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002529 >>> ExtendedContext.normalize(Decimal('-2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002530 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002531 >>> ExtendedContext.normalize(Decimal('1.200'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002532 Decimal("1.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002533 >>> ExtendedContext.normalize(Decimal('-120'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002534 Decimal("-1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002535 >>> ExtendedContext.normalize(Decimal('120.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002536 Decimal("1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002537 >>> ExtendedContext.normalize(Decimal('0.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002538 Decimal("0")
2539 """
2540 return a.normalize(context=self)
2541
2542 def plus(self, a):
2543 """Plus corresponds to unary prefix plus in Python.
2544
2545 The operation is evaluated using the same rules as add; the
2546 operation plus(a) is calculated as add('0', a) where the '0'
2547 has the same exponent as the operand.
2548
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002549 >>> ExtendedContext.plus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002550 Decimal("1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002551 >>> ExtendedContext.plus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002552 Decimal("-1.3")
2553 """
2554 return a.__pos__(context=self)
2555
2556 def power(self, a, b, modulo=None):
2557 """Raises a to the power of b, to modulo if given.
2558
2559 The right-hand operand must be a whole number whose integer part (after
2560 any exponent has been applied) has no more than 9 digits and whose
2561 fractional part (if any) is all zeros before any rounding. The operand
2562 may be positive, negative, or zero; if negative, the absolute value of
2563 the power is used, and the left-hand operand is inverted (divided into
2564 1) before use.
2565
2566 If the increased precision needed for the intermediate calculations
2567 exceeds the capabilities of the implementation then an Invalid operation
2568 condition is raised.
2569
2570 If, when raising to a negative power, an underflow occurs during the
2571 division into 1, the operation is not halted at that point but
2572 continues.
2573
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002574 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002575 Decimal("8")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002576 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002577 Decimal("0.125")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002578 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002579 Decimal("69.7575744")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002580 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002581 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002582 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002583 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002584 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002585 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002586 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002587 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002588 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002589 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002590 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002591 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002592 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002593 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002594 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002595 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002596 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002597 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002598 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002599 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002600 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002601 Decimal("NaN")
2602 """
2603 return a.__pow__(b, modulo, context=self)
2604
2605 def quantize(self, a, b):
2606 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
2607
2608 The coefficient of the result is derived from that of the left-hand
2609 operand. It may be rounded using the current rounding setting (if the
2610 exponent is being increased), multiplied by a positive power of ten (if
2611 the exponent is being decreased), or is unchanged (if the exponent is
2612 already equal to that of the right-hand operand).
2613
2614 Unlike other operations, if the length of the coefficient after the
2615 quantize operation would be greater than precision then an Invalid
2616 operation condition is raised. This guarantees that, unless there is an
2617 error condition, the exponent of the result of a quantize is always
2618 equal to that of the right-hand operand.
2619
2620 Also unlike other operations, quantize will never raise Underflow, even
2621 if the result is subnormal and inexact.
2622
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002623 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002624 Decimal("2.170")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002625 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002626 Decimal("2.17")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002627 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002628 Decimal("2.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002629 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002630 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002631 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002632 Decimal("0E+1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002633 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002634 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002635 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002636 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002637 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002638 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002639 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002640 Decimal("-0E+5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002641 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002642 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002643 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002644 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002645 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002646 Decimal("217.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002647 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002648 Decimal("217")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002649 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002650 Decimal("2.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002651 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002652 Decimal("2E+2")
2653 """
2654 return a.quantize(b, context=self)
2655
2656 def remainder(self, a, b):
2657 """Returns the remainder from integer division.
2658
2659 The result is the residue of the dividend after the operation of
2660 calculating integer division as described for divide-integer, rounded to
2661 precision digits if necessary. The sign of the result, if non-zero, is
2662 the same as that of the original dividend.
2663
2664 This operation will fail under the same conditions as integer division
2665 (that is, if integer division on the same two operands would fail, the
2666 remainder cannot be calculated).
2667
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002668 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002669 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002670 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002671 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002672 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002673 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002674 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002675 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002676 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002677 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002678 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002679 Decimal("1.0")
2680 """
2681 return a.__mod__(b, context=self)
2682
2683 def remainder_near(self, a, b):
2684 """Returns to be "a - b * n", where n is the integer nearest the exact
2685 value of "x / b" (if two integers are equally near then the even one
2686 is chosen). If the result is equal to 0 then its sign will be the
2687 sign of a.
2688
2689 This operation will fail under the same conditions as integer division
2690 (that is, if integer division on the same two operands would fail, the
2691 remainder cannot be calculated).
2692
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002693 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002694 Decimal("-0.9")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002695 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002696 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002697 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002698 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002699 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002700 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002701 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002702 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002703 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002704 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002705 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002706 Decimal("-0.3")
2707 """
2708 return a.remainder_near(b, context=self)
2709
2710 def same_quantum(self, a, b):
2711 """Returns True if the two operands have the same exponent.
2712
2713 The result is never affected by either the sign or the coefficient of
2714 either operand.
2715
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002716 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002717 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002718 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002719 True
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002720 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002721 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002722 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002723 True
2724 """
2725 return a.same_quantum(b)
2726
2727 def sqrt(self, a):
2728 """Returns the square root of a non-negative number to context precision.
2729
2730 If the result must be inexact, it is rounded using the round-half-even
2731 algorithm.
2732
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002733 >>> ExtendedContext.sqrt(Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002734 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002735 >>> ExtendedContext.sqrt(Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002736 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002737 >>> ExtendedContext.sqrt(Decimal('0.39'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002738 Decimal("0.624499800")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002739 >>> ExtendedContext.sqrt(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002740 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002741 >>> ExtendedContext.sqrt(Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002742 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002743 >>> ExtendedContext.sqrt(Decimal('1.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002744 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002745 >>> ExtendedContext.sqrt(Decimal('1.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002746 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002747 >>> ExtendedContext.sqrt(Decimal('7'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002748 Decimal("2.64575131")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002749 >>> ExtendedContext.sqrt(Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002750 Decimal("3.16227766")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002751 >>> ExtendedContext.prec
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002752 9
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002753 """
2754 return a.sqrt(context=self)
2755
2756 def subtract(self, a, b):
2757 """Return the sum of the two operands.
2758
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002759 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002760 Decimal("0.23")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002761 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002762 Decimal("0.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002763 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002764 Decimal("-0.77")
2765 """
2766 return a.__sub__(b, context=self)
2767
2768 def to_eng_string(self, a):
2769 """Converts a number to a string, using scientific notation.
2770
2771 The operation is not affected by the context.
2772 """
2773 return a.to_eng_string(context=self)
2774
2775 def to_sci_string(self, a):
2776 """Converts a number to a string, using scientific notation.
2777
2778 The operation is not affected by the context.
2779 """
2780 return a.__str__(context=self)
2781
2782 def to_integral(self, a):
2783 """Rounds to an integer.
2784
2785 When the operand has a negative exponent, the result is the same
2786 as using the quantize() operation using the given operand as the
2787 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2788 of the operand as the precision setting, except that no flags will
2789 be set. The rounding mode is taken from the context.
2790
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002791 >>> ExtendedContext.to_integral(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002792 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002793 >>> ExtendedContext.to_integral(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002794 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002795 >>> ExtendedContext.to_integral(Decimal('100.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002796 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002797 >>> ExtendedContext.to_integral(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002798 Decimal("102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002799 >>> ExtendedContext.to_integral(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002800 Decimal("-102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002801 >>> ExtendedContext.to_integral(Decimal('10E+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002802 Decimal("1.0E+6")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002803 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002804 Decimal("7.89E+77")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002805 >>> ExtendedContext.to_integral(Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002806 Decimal("-Infinity")
2807 """
2808 return a.to_integral(context=self)
2809
2810class _WorkRep(object):
2811 __slots__ = ('sign','int','exp')
Raymond Hettinger17931de2004-10-27 06:21:46 +00002812 # sign: 0 or 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002813 # int: int or long
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002814 # exp: None, int, or string
2815
2816 def __init__(self, value=None):
2817 if value is None:
2818 self.sign = None
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002819 self.int = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002820 self.exp = None
Raymond Hettinger17931de2004-10-27 06:21:46 +00002821 elif isinstance(value, Decimal):
2822 self.sign = value._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002823 cum = 0
Raymond Hettinger17931de2004-10-27 06:21:46 +00002824 for digit in value._int:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002825 cum = cum * 10 + digit
2826 self.int = cum
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002827 self.exp = value._exp
Raymond Hettinger17931de2004-10-27 06:21:46 +00002828 else:
2829 # assert isinstance(value, tuple)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002830 self.sign = value[0]
2831 self.int = value[1]
2832 self.exp = value[2]
2833
2834 def __repr__(self):
2835 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2836
2837 __str__ = __repr__
2838
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002839
2840
2841def _normalize(op1, op2, shouldround = 0, prec = 0):
2842 """Normalizes op1, op2 to have the same exp and length of coefficient.
2843
2844 Done during addition.
2845 """
2846 # Yes, the exponent is a long, but the difference between exponents
2847 # must be an int-- otherwise you'd get a big memory problem.
2848 numdigits = int(op1.exp - op2.exp)
2849 if numdigits < 0:
2850 numdigits = -numdigits
2851 tmp = op2
2852 other = op1
2853 else:
2854 tmp = op1
2855 other = op2
2856
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002857
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002858 if shouldround and numdigits > prec + 1:
2859 # Big difference in exponents - check the adjusted exponents
2860 tmp_len = len(str(tmp.int))
2861 other_len = len(str(other.int))
2862 if numdigits > (other_len + prec + 1 - tmp_len):
2863 # If the difference in adjusted exps is > prec+1, we know
2864 # other is insignificant, so might as well put a 1 after the precision.
2865 # (since this is only for addition.) Also stops use of massive longs.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002866
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002867 extend = prec + 2 - tmp_len
2868 if extend <= 0:
2869 extend = 1
2870 tmp.int *= 10 ** extend
2871 tmp.exp -= extend
2872 other.int = 1
2873 other.exp = tmp.exp
2874 return op1, op2
2875
2876 tmp.int *= 10 ** numdigits
2877 tmp.exp -= numdigits
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002878 return op1, op2
2879
2880def _adjust_coefficients(op1, op2):
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002881 """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002882
2883 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2884
2885 Used on _WorkRep instances during division.
2886 """
2887 adjust = 0
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002888 #If op1 is smaller, make it larger
2889 while op2.int > op1.int:
2890 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002891 op1.exp -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002892 adjust += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002893
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002894 #If op2 is too small, make it larger
2895 while op1.int >= (10 * op2.int):
2896 op2.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002897 op2.exp -= 1
2898 adjust -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002899
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002900 return op1, op2, adjust
2901
2902##### Helper Functions ########################################
2903
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002904def _convert_other(other):
2905 """Convert other to Decimal.
2906
2907 Verifies that it's ok to use in an implicit construction.
2908 """
2909 if isinstance(other, Decimal):
2910 return other
2911 if isinstance(other, (int, long)):
2912 return Decimal(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002913 return NotImplemented
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002914
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002915_infinity_map = {
2916 'inf' : 1,
2917 'infinity' : 1,
2918 '+inf' : 1,
2919 '+infinity' : 1,
2920 '-inf' : -1,
2921 '-infinity' : -1
2922}
2923
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002924def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002925 """Determines whether a string or float is infinity.
2926
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002927 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002928 """
2929 num = str(num).lower()
2930 return _infinity_map.get(num, 0)
2931
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002932def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002933 """Determines whether a string or float is NaN
2934
2935 (1, sign, diagnostic info as string) => NaN
2936 (2, sign, diagnostic info as string) => sNaN
2937 0 => not a NaN
2938 """
2939 num = str(num).lower()
2940 if not num:
2941 return 0
2942
2943 #get the sign, get rid of trailing [+-]
2944 sign = 0
2945 if num[0] == '+':
2946 num = num[1:]
2947 elif num[0] == '-': #elif avoids '+-nan'
2948 num = num[1:]
2949 sign = 1
2950
2951 if num.startswith('nan'):
2952 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
2953 return 0
2954 return (1, sign, num[3:].lstrip('0'))
2955 if num.startswith('snan'):
2956 if len(num) > 4 and not num[4:].isdigit():
2957 return 0
2958 return (2, sign, num[4:].lstrip('0'))
2959 return 0
2960
2961
2962##### Setup Specific Contexts ################################
2963
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002964# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00002965# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002966
2967DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002968 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002969 traps=[DivisionByZero, Overflow, InvalidOperation],
2970 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002971 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00002972 Emax=999999999,
2973 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002974 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002975)
2976
2977# Pre-made alternate contexts offered by the specification
2978# Don't change these; the user should be able to select these
2979# contexts and be able to reproduce results from other implementations
2980# of the spec.
2981
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002982BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002983 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002984 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
2985 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002986)
2987
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002988ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002989 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002990 traps=[],
2991 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002992)
2993
2994
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002995##### Useful Constants (internal use only) ####################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002996
2997#Reusable defaults
2998Inf = Decimal('Inf')
2999negInf = Decimal('-Inf')
3000
3001#Infsign[sign] is infinity w/ that sign
3002Infsign = (Inf, negInf)
3003
3004NaN = Decimal('NaN')
3005
3006
3007##### crud for parsing strings #################################
3008import re
3009
3010# There's an optional sign at the start, and an optional exponent
3011# at the end. The exponent has an optional sign and at least one
3012# digit. In between, must have either at least one digit followed
3013# by an optional fraction, or a decimal point followed by at least
3014# one digit. Yuck.
3015
3016_parser = re.compile(r"""
3017# \s*
3018 (?P<sign>[-+])?
3019 (
3020 (?P<int>\d+) (\. (?P<frac>\d*))?
3021 |
3022 \. (?P<onlyfrac>\d+)
3023 )
3024 ([eE](?P<exp>[-+]? \d+))?
3025# \s*
3026 $
3027""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
3028
3029del re
3030
3031# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
3032
3033def _string2exact(s):
3034 m = _parser(s)
3035 if m is None:
3036 raise ValueError("invalid literal for Decimal: %r" % s)
3037
3038 if m.group('sign') == "-":
3039 sign = 1
3040 else:
3041 sign = 0
3042
3043 exp = m.group('exp')
3044 if exp is None:
3045 exp = 0
3046 else:
3047 exp = int(exp)
3048
3049 intpart = m.group('int')
3050 if intpart is None:
3051 intpart = ""
3052 fracpart = m.group('onlyfrac')
3053 else:
3054 fracpart = m.group('frac')
3055 if fracpart is None:
3056 fracpart = ""
3057
3058 exp -= len(fracpart)
3059
3060 mantissa = intpart + fracpart
3061 tmp = map(int, mantissa)
3062 backup = tmp
3063 while tmp and tmp[0] == 0:
3064 del tmp[0]
3065
3066 # It's a zero
3067 if not tmp:
3068 if backup:
3069 return (sign, tuple(backup), exp)
3070 return (sign, (0,), exp)
3071 mantissa = tuple(tmp)
3072
3073 return (sign, mantissa, exp)
3074
3075
3076if __name__ == '__main__':
3077 import doctest, sys
3078 doctest.testmod(sys.modules[__name__])