blob: 90e2dccefaf8d245dc1618aaab911fa8b5e110ba [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 Hettinger7c85fa42004-07-01 11:01:35 +0000648
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000649 if self._is_special or other._is_special:
650 ans = self._check_nans(other, context)
651 if ans:
652 return 1 # Comparison involving NaN's always reports self > other
653
654 # INF = INF
655 return cmp(self._isinfinity(), other._isinfinity())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000656
657 if not self and not other:
658 return 0 #If both 0, sign comparison isn't certain.
659
660 #If different signs, neg one is less
661 if other._sign < self._sign:
662 return -1
663 if self._sign < other._sign:
664 return 1
665
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000666 self_adjusted = self.adjusted()
667 other_adjusted = other.adjusted()
668 if self_adjusted == other_adjusted and \
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000669 self._int + (0,)*(self._exp - other._exp) == \
670 other._int + (0,)*(other._exp - self._exp):
671 return 0 #equal, except in precision. ([0]*(-x) = [])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000672 elif self_adjusted > other_adjusted and self._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000673 return (-1)**self._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000674 elif self_adjusted < other_adjusted and other._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000675 return -((-1)**self._sign)
676
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000677 # Need to round, so make sure we have a valid context
678 if context is None:
679 context = getcontext()
680
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000681 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000682 rounding = context._set_rounding(ROUND_UP) #round away from 0
683
684 flags = context._ignore_all_flags()
685 res = self.__sub__(other, context=context)
686
687 context._regard_flags(*flags)
688
689 context.rounding = rounding
690
691 if not res:
692 return 0
693 elif res._sign:
694 return -1
695 return 1
696
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000697 def __eq__(self, other):
698 if not isinstance(other, (Decimal, int, long)):
699 return False
700 return self.__cmp__(other) == 0
701
702 def __ne__(self, other):
703 if not isinstance(other, (Decimal, int, long)):
704 return True
705 return self.__cmp__(other) != 0
706
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000707 def compare(self, other, context=None):
708 """Compares one to another.
709
710 -1 => a < b
711 0 => a = b
712 1 => a > b
713 NaN => one is NaN
714 Like __cmp__, but returns Decimal instances.
715 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000716 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000717
718 #compare(NaN, NaN) = NaN
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000719 if (self._is_special or other and other._is_special):
720 ans = self._check_nans(other, context)
721 if ans:
722 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000723
724 return Decimal(self.__cmp__(other, context))
725
726 def __hash__(self):
727 """x.__hash__() <==> hash(x)"""
728 # Decimal integers must hash the same as the ints
729 # Non-integer decimals are normalized and hashed as strings
730 # Normalization assures that hast(100E-1) == hash(10)
731 i = int(self)
732 if self == Decimal(i):
733 return hash(i)
734 assert self.__nonzero__() # '-0' handled by integer case
735 return hash(str(self.normalize()))
736
737 def as_tuple(self):
738 """Represents the number as a triple tuple.
739
740 To show the internals exactly as they are.
741 """
742 return (self._sign, self._int, self._exp)
743
744 def __repr__(self):
745 """Represents the number as an instance of Decimal."""
746 # Invariant: eval(repr(d)) == d
747 return 'Decimal("%s")' % str(self)
748
749 def __str__(self, eng = 0, context=None):
750 """Return string representation of the number in scientific notation.
751
752 Captures all of the information in the underlying representation.
753 """
754
755 if self._isnan():
756 minus = '-'*self._sign
757 if self._int == (0,):
758 info = ''
759 else:
760 info = ''.join(map(str, self._int))
761 if self._isnan() == 2:
762 return minus + 'sNaN' + info
763 return minus + 'NaN' + info
764 if self._isinfinity():
765 minus = '-'*self._sign
766 return minus + 'Infinity'
767
768 if context is None:
769 context = getcontext()
770
771 tmp = map(str, self._int)
772 numdigits = len(self._int)
773 leftdigits = self._exp + numdigits
774 if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
775 if self._exp < 0 and self._exp >= -6: #short, no need for e/E
776 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
777 return s
778 #exp is closest mult. of 3 >= self._exp
779 exp = ((self._exp - 1)// 3 + 1) * 3
780 if exp != self._exp:
781 s = '0.'+'0'*(exp - self._exp)
782 else:
783 s = '0'
784 if exp != 0:
785 if context.capitals:
786 s += 'E'
787 else:
788 s += 'e'
789 if exp > 0:
790 s += '+' #0.0e+3, not 0.0e3
791 s += str(exp)
792 s = '-'*self._sign + s
793 return s
794 if eng:
795 dotplace = (leftdigits-1)%3+1
796 adjexp = leftdigits -1 - (leftdigits-1)%3
797 else:
798 adjexp = leftdigits-1
799 dotplace = 1
800 if self._exp == 0:
801 pass
802 elif self._exp < 0 and adjexp >= 0:
803 tmp.insert(leftdigits, '.')
804 elif self._exp < 0 and adjexp >= -6:
805 tmp[0:0] = ['0'] * int(-leftdigits)
806 tmp.insert(0, '0.')
807 else:
808 if numdigits > dotplace:
809 tmp.insert(dotplace, '.')
810 elif numdigits < dotplace:
811 tmp.extend(['0']*(dotplace-numdigits))
812 if adjexp:
813 if not context.capitals:
814 tmp.append('e')
815 else:
816 tmp.append('E')
817 if adjexp > 0:
818 tmp.append('+')
819 tmp.append(str(adjexp))
820 if eng:
821 while tmp[0:1] == ['0']:
822 tmp[0:1] = []
823 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
824 tmp[0:0] = ['0']
825 if self._sign:
826 tmp.insert(0, '-')
827
828 return ''.join(tmp)
829
830 def to_eng_string(self, context=None):
831 """Convert to engineering-type string.
832
833 Engineering notation has an exponent which is a multiple of 3, so there
834 are up to 3 digits left of the decimal place.
835
836 Same rules for when in exponential and when as a value as in __str__.
837 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000838 return self.__str__(eng=1, context=context)
839
840 def __neg__(self, context=None):
841 """Returns a copy with the sign switched.
842
843 Rounds, if it has reason.
844 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000845 if self._is_special:
846 ans = self._check_nans(context=context)
847 if ans:
848 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000849
850 if not self:
851 # -Decimal('0') is Decimal('0'), not Decimal('-0')
852 sign = 0
853 elif self._sign:
854 sign = 0
855 else:
856 sign = 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000857
858 if context is None:
859 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000860 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000861 return Decimal((sign, self._int, self._exp))._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000862 return Decimal( (sign, self._int, self._exp))
863
864 def __pos__(self, context=None):
865 """Returns a copy, unless it is a sNaN.
866
867 Rounds the number (if more then precision digits)
868 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000869 if self._is_special:
870 ans = self._check_nans(context=context)
871 if ans:
872 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000873
874 sign = self._sign
875 if not self:
876 # + (-0) = 0
877 sign = 0
878
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000879 if context is None:
880 context = getcontext()
881
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000882 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000883 ans = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000884 else:
885 ans = Decimal(self)
886 ans._sign = sign
887 return ans
888
889 def __abs__(self, round=1, context=None):
890 """Returns the absolute value of self.
891
892 If the second argument is 0, do not round.
893 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000894 if self._is_special:
895 ans = self._check_nans(context=context)
896 if ans:
897 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000898
899 if not round:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000900 if context is None:
901 context = getcontext()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000902 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000903 context._set_rounding_decision(NEVER_ROUND)
904
905 if self._sign:
906 ans = self.__neg__(context=context)
907 else:
908 ans = self.__pos__(context=context)
909
910 return ans
911
912 def __add__(self, other, context=None):
913 """Returns self + other.
914
915 -INF + INF (or the reverse) cause InvalidOperation errors.
916 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000917 other = _convert_other(other)
918
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000919 if context is None:
920 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000921
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000922 if self._is_special or other._is_special:
923 ans = self._check_nans(other, context)
924 if ans:
925 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000926
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000927 if self._isinfinity():
928 #If both INF, same sign => same as both, opposite => error.
929 if self._sign != other._sign and other._isinfinity():
930 return context._raise_error(InvalidOperation, '-INF + INF')
931 return Decimal(self)
932 if other._isinfinity():
933 return Decimal(other) #Can't both be infinity here
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000934
935 shouldround = context._rounding_decision == ALWAYS_ROUND
936
937 exp = min(self._exp, other._exp)
938 negativezero = 0
939 if context.rounding == ROUND_FLOOR and self._sign != other._sign:
940 #If the answer is 0, the sign should be negative, in this case.
941 negativezero = 1
942
943 if not self and not other:
944 sign = min(self._sign, other._sign)
945 if negativezero:
946 sign = 1
947 return Decimal( (sign, (0,), exp))
948 if not self:
Facundo Batista99b55482004-10-26 23:38:46 +0000949 exp = max(exp, other._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000950 ans = other._rescale(exp, watchexp=0, context=context)
951 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000952 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000953 return ans
954 if not other:
Facundo Batista99b55482004-10-26 23:38:46 +0000955 exp = max(exp, self._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000956 ans = self._rescale(exp, watchexp=0, context=context)
957 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000958 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000959 return ans
960
961 op1 = _WorkRep(self)
962 op2 = _WorkRep(other)
963 op1, op2 = _normalize(op1, op2, shouldround, context.prec)
964
965 result = _WorkRep()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000966 if op1.sign != op2.sign:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000967 # Equal and opposite
Raymond Hettinger17931de2004-10-27 06:21:46 +0000968 if op1.int == op2.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000969 if exp < context.Etiny():
970 exp = context.Etiny()
971 context._raise_error(Clamped)
972 return Decimal((negativezero, (0,), exp))
Raymond Hettinger17931de2004-10-27 06:21:46 +0000973 if op1.int < op2.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000974 op1, op2 = op2, op1
975 #OK, now abs(op1) > abs(op2)
Raymond Hettinger17931de2004-10-27 06:21:46 +0000976 if op1.sign == 1:
977 result.sign = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000978 op1.sign, op2.sign = op2.sign, op1.sign
979 else:
Raymond Hettinger17931de2004-10-27 06:21:46 +0000980 result.sign = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000981 #So we know the sign, and op1 > 0.
Raymond Hettinger17931de2004-10-27 06:21:46 +0000982 elif op1.sign == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000983 result.sign = 1
Raymond Hettinger17931de2004-10-27 06:21:46 +0000984 op1.sign, op2.sign = (0, 0)
985 else:
986 result.sign = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000987 #Now, op1 > abs(op2) > 0
988
Raymond Hettinger17931de2004-10-27 06:21:46 +0000989 if op2.sign == 0:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000990 result.int = op1.int + op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000991 else:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000992 result.int = op1.int - op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000993
994 result.exp = op1.exp
995 ans = Decimal(result)
996 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000997 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000998 return ans
999
1000 __radd__ = __add__
1001
1002 def __sub__(self, other, context=None):
1003 """Return self + (-other)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001004 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001005
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001006 if self._is_special or other._is_special:
1007 ans = self._check_nans(other, context=context)
1008 if ans:
1009 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001010
1011 # -Decimal(0) = Decimal(0), which we don't want since
1012 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
1013 # so we change the sign directly to a copy
1014 tmp = Decimal(other)
1015 tmp._sign = 1-tmp._sign
1016
1017 return self.__add__(tmp, context=context)
1018
1019 def __rsub__(self, other, context=None):
1020 """Return other + (-self)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001021 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001022
1023 tmp = Decimal(self)
1024 tmp._sign = 1 - tmp._sign
1025 return other.__add__(tmp, context=context)
1026
1027 def _increment(self, round=1, context=None):
1028 """Special case of add, adding 1eExponent
1029
1030 Since it is common, (rounding, for example) this adds
1031 (sign)*one E self._exp to the number more efficiently than add.
1032
1033 For example:
1034 Decimal('5.624e10')._increment() == Decimal('5.625e10')
1035 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001036 if self._is_special:
1037 ans = self._check_nans(context=context)
1038 if ans:
1039 return ans
1040
1041 return Decimal(self) # Must be infinite, and incrementing makes no difference
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001042
1043 L = list(self._int)
1044 L[-1] += 1
1045 spot = len(L)-1
1046 while L[spot] == 10:
1047 L[spot] = 0
1048 if spot == 0:
1049 L[0:0] = [1]
1050 break
1051 L[spot-1] += 1
1052 spot -= 1
1053 ans = Decimal((self._sign, L, self._exp))
1054
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001055 if context is None:
1056 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001057 if round and context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001058 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001059 return ans
1060
1061 def __mul__(self, other, context=None):
1062 """Return self * other.
1063
1064 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1065 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001066 other = _convert_other(other)
1067
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001068 if context is None:
1069 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001070
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001071 resultsign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001072
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001073 if self._is_special or other._is_special:
1074 ans = self._check_nans(other, context)
1075 if ans:
1076 return ans
1077
1078 if self._isinfinity():
1079 if not other:
1080 return context._raise_error(InvalidOperation, '(+-)INF * 0')
1081 return Infsign[resultsign]
1082
1083 if other._isinfinity():
1084 if not self:
1085 return context._raise_error(InvalidOperation, '0 * (+-)INF')
1086 return Infsign[resultsign]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001087
1088 resultexp = self._exp + other._exp
1089 shouldround = context._rounding_decision == ALWAYS_ROUND
1090
1091 # Special case for multiplying by zero
1092 if not self or not other:
1093 ans = Decimal((resultsign, (0,), resultexp))
1094 if shouldround:
1095 #Fixing in case the exponent is out of bounds
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001096 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001097 return ans
1098
1099 # Special case for multiplying by power of 10
1100 if self._int == (1,):
1101 ans = Decimal((resultsign, other._int, resultexp))
1102 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001103 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001104 return ans
1105 if other._int == (1,):
1106 ans = Decimal((resultsign, self._int, resultexp))
1107 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001108 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001109 return ans
1110
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001111 op1 = _WorkRep(self)
1112 op2 = _WorkRep(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001113
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001114 ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001115 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001116 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001117
1118 return ans
1119 __rmul__ = __mul__
1120
1121 def __div__(self, other, context=None):
1122 """Return self / other."""
1123 return self._divide(other, context=context)
1124 __truediv__ = __div__
1125
1126 def _divide(self, other, divmod = 0, context=None):
1127 """Return a / b, to context.prec precision.
1128
1129 divmod:
1130 0 => true division
1131 1 => (a //b, a%b)
1132 2 => a //b
1133 3 => a%b
1134
1135 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1136 computing the other value are not raised.
1137 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001138 other = _convert_other(other)
1139
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001140 if context is None:
1141 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001142
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001143 sign = self._sign ^ other._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001144
1145 if self._is_special or other._is_special:
1146 ans = self._check_nans(other, context)
1147 if ans:
1148 if divmod:
1149 return (ans, ans)
1150 return ans
1151
1152 if self._isinfinity() and other._isinfinity():
1153 if divmod:
1154 return (context._raise_error(InvalidOperation,
1155 '(+-)INF // (+-)INF'),
1156 context._raise_error(InvalidOperation,
1157 '(+-)INF % (+-)INF'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001158 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001159
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001160 if self._isinfinity():
1161 if divmod == 1:
1162 return (Infsign[sign],
1163 context._raise_error(InvalidOperation, 'INF % x'))
1164 elif divmod == 2:
1165 return (Infsign[sign], NaN)
1166 elif divmod == 3:
1167 return (Infsign[sign],
1168 context._raise_error(InvalidOperation, 'INF % x'))
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001169 return Infsign[sign]
1170
1171 if other._isinfinity():
1172 if divmod:
1173 return (Decimal((sign, (0,), 0)), Decimal(self))
1174 context._raise_error(Clamped, 'Division by infinity')
1175 return Decimal((sign, (0,), context.Etiny()))
1176
1177 # Special cases for zeroes
1178 if not self and not other:
1179 if divmod:
1180 return context._raise_error(DivisionUndefined, '0 / 0', 1)
1181 return context._raise_error(DivisionUndefined, '0 / 0')
1182
1183 if not self:
1184 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001185 otherside = Decimal(self)
1186 otherside._exp = min(self._exp, other._exp)
1187 return (Decimal((sign, (0,), 0)), otherside)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001188 exp = self._exp - other._exp
1189 if exp < context.Etiny():
1190 exp = context.Etiny()
1191 context._raise_error(Clamped, '0e-x / y')
1192 if exp > context.Emax:
1193 exp = context.Emax
1194 context._raise_error(Clamped, '0e+x / y')
1195 return Decimal( (sign, (0,), exp) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001196
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001197 if not other:
1198 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001199 return context._raise_error(DivisionByZero, 'divmod(x,0)',
1200 sign, 1)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001201 return context._raise_error(DivisionByZero, 'x / 0', sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001202
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001203 #OK, so neither = 0, INF or NaN
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001204
1205 shouldround = context._rounding_decision == ALWAYS_ROUND
1206
1207 #If we're dividing into ints, and self < other, stop.
1208 #self.__abs__(0) does not round.
1209 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
1210
1211 if divmod == 1 or divmod == 3:
1212 exp = min(self._exp, other._exp)
1213 ans2 = self._rescale(exp, context=context, watchexp=0)
1214 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001215 ans2 = ans2._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001216 return (Decimal( (sign, (0,), 0) ),
1217 ans2)
1218
1219 elif divmod == 2:
1220 #Don't round the mod part, if we don't need it.
1221 return (Decimal( (sign, (0,), 0) ), Decimal(self))
1222
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001223 op1 = _WorkRep(self)
1224 op2 = _WorkRep(other)
1225 op1, op2, adjust = _adjust_coefficients(op1, op2)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001226 res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001227 if divmod and res.exp > context.prec + 1:
1228 return context._raise_error(DivisionImpossible)
1229
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001230 prec_limit = 10 ** context.prec
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001231 while 1:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001232 while op2.int <= op1.int:
1233 res.int += 1
1234 op1.int -= op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001235 if res.exp == 0 and divmod:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001236 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001237 return context._raise_error(DivisionImpossible)
1238 otherside = Decimal(op1)
1239 frozen = context._ignore_all_flags()
1240
1241 exp = min(self._exp, other._exp)
Raymond Hettinger17931de2004-10-27 06:21:46 +00001242 otherside = otherside._rescale(exp, context=context, watchexp=0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001243 context._regard_flags(*frozen)
1244 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001245 otherside = otherside._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001246 return (Decimal(res), otherside)
1247
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001248 if op1.int == 0 and adjust >= 0 and not divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001249 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001250 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001251 if divmod:
1252 return context._raise_error(DivisionImpossible)
1253 shouldround=1
1254 # Really, the answer is a bit higher, so adding a one to
1255 # the end will make sure the rounding is right.
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001256 if op1.int != 0:
1257 res.int *= 10
1258 res.int += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001259 res.exp -= 1
1260
1261 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001262 res.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001263 res.exp -= 1
1264 adjust += 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001265 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001266 op1.exp -= 1
1267
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001268 if res.exp == 0 and divmod and op2.int > op1.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001269 #Solves an error in precision. Same as a previous block.
1270
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001271 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001272 return context._raise_error(DivisionImpossible)
1273 otherside = Decimal(op1)
1274 frozen = context._ignore_all_flags()
1275
1276 exp = min(self._exp, other._exp)
1277 otherside = otherside._rescale(exp, context=context)
1278
1279 context._regard_flags(*frozen)
1280
1281 return (Decimal(res), otherside)
1282
1283 ans = Decimal(res)
1284 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001285 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001286 return ans
1287
1288 def __rdiv__(self, other, context=None):
1289 """Swaps self/other and returns __div__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001290 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001291 return other.__div__(self, context=context)
1292 __rtruediv__ = __rdiv__
1293
1294 def __divmod__(self, other, context=None):
1295 """
1296 (self // other, self % other)
1297 """
1298 return self._divide(other, 1, context)
1299
1300 def __rdivmod__(self, other, context=None):
1301 """Swaps self/other and returns __divmod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001302 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001303 return other.__divmod__(self, context=context)
1304
1305 def __mod__(self, other, context=None):
1306 """
1307 self % other
1308 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001309 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001310
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001311 if self._is_special or other._is_special:
1312 ans = self._check_nans(other, context)
1313 if ans:
1314 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001315
1316 if self and not other:
1317 return context._raise_error(InvalidOperation, 'x % 0')
1318
1319 return self._divide(other, 3, context)[1]
1320
1321 def __rmod__(self, other, context=None):
1322 """Swaps self/other and returns __mod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001323 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001324 return other.__mod__(self, context=context)
1325
1326 def remainder_near(self, other, context=None):
1327 """
1328 Remainder nearest to 0- abs(remainder-near) <= other/2
1329 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001330 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001331
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001332 if self._is_special or other._is_special:
1333 ans = self._check_nans(other, context)
1334 if ans:
1335 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001336 if self and not other:
1337 return context._raise_error(InvalidOperation, 'x % 0')
1338
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001339 if context is None:
1340 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001341 # If DivisionImpossible causes an error, do not leave Rounded/Inexact
1342 # ignored in the calling function.
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001343 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001344 flags = context._ignore_flags(Rounded, Inexact)
1345 #keep DivisionImpossible flags
1346 (side, r) = self.__divmod__(other, context=context)
1347
1348 if r._isnan():
1349 context._regard_flags(*flags)
1350 return r
1351
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001352 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001353 rounding = context._set_rounding_decision(NEVER_ROUND)
1354
1355 if other._sign:
1356 comparison = other.__div__(Decimal(-2), context=context)
1357 else:
1358 comparison = other.__div__(Decimal(2), context=context)
1359
1360 context._set_rounding_decision(rounding)
1361 context._regard_flags(*flags)
1362
1363 s1, s2 = r._sign, comparison._sign
1364 r._sign, comparison._sign = 0, 0
1365
1366 if r < comparison:
1367 r._sign, comparison._sign = s1, s2
1368 #Get flags now
1369 self.__divmod__(other, context=context)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001370 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001371 r._sign, comparison._sign = s1, s2
1372
1373 rounding = context._set_rounding_decision(NEVER_ROUND)
1374
1375 (side, r) = self.__divmod__(other, context=context)
1376 context._set_rounding_decision(rounding)
1377 if r._isnan():
1378 return r
1379
1380 decrease = not side._iseven()
1381 rounding = context._set_rounding_decision(NEVER_ROUND)
1382 side = side.__abs__(context=context)
1383 context._set_rounding_decision(rounding)
1384
1385 s1, s2 = r._sign, comparison._sign
1386 r._sign, comparison._sign = 0, 0
1387 if r > comparison or decrease and r == comparison:
1388 r._sign, comparison._sign = s1, s2
1389 context.prec += 1
1390 if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
1391 context.prec -= 1
1392 return context._raise_error(DivisionImpossible)[1]
1393 context.prec -= 1
1394 if self._sign == other._sign:
1395 r = r.__sub__(other, context=context)
1396 else:
1397 r = r.__add__(other, context=context)
1398 else:
1399 r._sign, comparison._sign = s1, s2
1400
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001401 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001402
1403 def __floordiv__(self, other, context=None):
1404 """self // other"""
1405 return self._divide(other, 2, context)[0]
1406
1407 def __rfloordiv__(self, other, context=None):
1408 """Swaps self/other and returns __floordiv__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001409 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001410 return other.__floordiv__(self, context=context)
1411
1412 def __float__(self):
1413 """Float representation."""
1414 return float(str(self))
1415
1416 def __int__(self):
1417 """Converts self to a int, truncating if necessary."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001418 if self._is_special:
1419 if self._isnan():
1420 context = getcontext()
1421 return context._raise_error(InvalidContext)
1422 elif self._isinfinity():
1423 raise OverflowError, "Cannot convert infinity to long"
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001424 if self._exp >= 0:
Raymond Hettinger605ed022004-11-24 07:28:48 +00001425 s = ''.join(map(str, self._int)) + '0'*self._exp
1426 else:
1427 s = ''.join(map(str, self._int))[:self._exp]
1428 if s == '':
1429 s = '0'
1430 sign = '-'*self._sign
1431 return int(sign + s)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001432
1433 def __long__(self):
1434 """Converts to a long.
1435
1436 Equivalent to long(int(self))
1437 """
1438 return long(self.__int__())
1439
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001440 def _fix(self, context):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001441 """Round if it is necessary to keep self within prec precision.
1442
1443 Rounds and fixes the exponent. Does not raise on a sNaN.
1444
1445 Arguments:
1446 self - Decimal instance
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001447 context - context used.
1448 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001449 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001450 return self
1451 if context is None:
1452 context = getcontext()
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001453 prec = context.prec
Facundo Batista99b55482004-10-26 23:38:46 +00001454 ans = self._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001455 if len(ans._int) > prec:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001456 ans = ans._round(prec, context=context)
Facundo Batista99b55482004-10-26 23:38:46 +00001457 ans = ans._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001458 return ans
1459
Facundo Batista99b55482004-10-26 23:38:46 +00001460 def _fixexponents(self, context):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001461 """Fix the exponents and return a copy with the exponent in bounds.
1462 Only call if known to not be a special value.
1463 """
1464 folddown = context._clamp
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001465 Emin = context.Emin
Facundo Batista99b55482004-10-26 23:38:46 +00001466 ans = self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001467 ans_adjusted = ans.adjusted()
1468 if ans_adjusted < Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001469 Etiny = context.Etiny()
1470 if ans._exp < Etiny:
1471 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001472 ans = Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001473 ans._exp = Etiny
1474 context._raise_error(Clamped)
1475 return ans
1476 ans = ans._rescale(Etiny, context=context)
1477 #It isn't zero, and exp < Emin => subnormal
1478 context._raise_error(Subnormal)
1479 if context.flags[Inexact]:
1480 context._raise_error(Underflow)
1481 else:
1482 if ans:
1483 #Only raise subnormal if non-zero.
1484 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001485 else:
1486 Etop = context.Etop()
1487 if folddown and ans._exp > Etop:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001488 context._raise_error(Clamped)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001489 ans = ans._rescale(Etop, context=context)
1490 else:
1491 Emax = context.Emax
1492 if ans_adjusted > Emax:
1493 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001494 ans = Decimal(self)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001495 ans._exp = Emax
1496 context._raise_error(Clamped)
1497 return ans
1498 context._raise_error(Inexact)
1499 context._raise_error(Rounded)
1500 return context._raise_error(Overflow, 'above Emax', ans._sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001501 return ans
1502
1503 def _round(self, prec=None, rounding=None, context=None):
1504 """Returns a rounded version of self.
1505
1506 You can specify the precision or rounding method. Otherwise, the
1507 context determines it.
1508 """
1509
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001510 if self._is_special:
1511 ans = self._check_nans(context=context)
1512 if ans:
1513 return ans
1514
1515 if self._isinfinity():
1516 return Decimal(self)
1517
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001518 if context is None:
1519 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001520
1521 if rounding is None:
1522 rounding = context.rounding
1523 if prec is None:
1524 prec = context.prec
1525
1526 if not self:
1527 if prec <= 0:
1528 dig = (0,)
1529 exp = len(self._int) - prec + self._exp
1530 else:
1531 dig = (0,) * prec
1532 exp = len(self._int) + self._exp - prec
1533 ans = Decimal((self._sign, dig, exp))
1534 context._raise_error(Rounded)
1535 return ans
1536
1537 if prec == 0:
1538 temp = Decimal(self)
1539 temp._int = (0,)+temp._int
1540 prec = 1
1541 elif prec < 0:
1542 exp = self._exp + len(self._int) - prec - 1
1543 temp = Decimal( (self._sign, (0, 1), exp))
1544 prec = 1
1545 else:
1546 temp = Decimal(self)
1547
1548 numdigits = len(temp._int)
1549 if prec == numdigits:
1550 return temp
1551
1552 # See if we need to extend precision
1553 expdiff = prec - numdigits
1554 if expdiff > 0:
1555 tmp = list(temp._int)
1556 tmp.extend([0] * expdiff)
1557 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff))
1558 return ans
1559
1560 #OK, but maybe all the lost digits are 0.
1561 lostdigits = self._int[expdiff:]
1562 if lostdigits == (0,) * len(lostdigits):
1563 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
1564 #Rounded, but not Inexact
1565 context._raise_error(Rounded)
1566 return ans
1567
1568 # Okay, let's round and lose data
1569
1570 this_function = getattr(temp, self._pick_rounding_function[rounding])
1571 #Now we've got the rounding function
1572
1573 if prec != context.prec:
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001574 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001575 context.prec = prec
1576 ans = this_function(prec, expdiff, context)
1577 context._raise_error(Rounded)
1578 context._raise_error(Inexact, 'Changed in rounding')
1579
1580 return ans
1581
1582 _pick_rounding_function = {}
1583
1584 def _round_down(self, prec, expdiff, context):
1585 """Also known as round-towards-0, truncate."""
1586 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1587
1588 def _round_half_up(self, prec, expdiff, context, tmp = None):
1589 """Rounds 5 up (away from 0)"""
1590
1591 if tmp is None:
1592 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
1593 if self._int[prec] >= 5:
1594 tmp = tmp._increment(round=0, context=context)
1595 if len(tmp._int) > prec:
1596 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1597 return tmp
1598
1599 def _round_half_even(self, prec, expdiff, context):
1600 """Round 5 to even, rest to nearest."""
1601
1602 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1603 half = (self._int[prec] == 5)
1604 if half:
1605 for digit in self._int[prec+1:]:
1606 if digit != 0:
1607 half = 0
1608 break
1609 if half:
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001610 if self._int[prec-1] & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001611 return tmp
1612 return self._round_half_up(prec, expdiff, context, tmp)
1613
1614 def _round_half_down(self, prec, expdiff, context):
1615 """Round 5 down"""
1616
1617 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1618 half = (self._int[prec] == 5)
1619 if half:
1620 for digit in self._int[prec+1:]:
1621 if digit != 0:
1622 half = 0
1623 break
1624 if half:
1625 return tmp
1626 return self._round_half_up(prec, expdiff, context, tmp)
1627
1628 def _round_up(self, prec, expdiff, context):
1629 """Rounds away from 0."""
1630 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1631 for digit in self._int[prec:]:
1632 if digit != 0:
1633 tmp = tmp._increment(round=1, context=context)
1634 if len(tmp._int) > prec:
1635 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1636 else:
1637 return tmp
1638 return tmp
1639
1640 def _round_ceiling(self, prec, expdiff, context):
1641 """Rounds up (not away from 0 if negative.)"""
1642 if self._sign:
1643 return self._round_down(prec, expdiff, context)
1644 else:
1645 return self._round_up(prec, expdiff, context)
1646
1647 def _round_floor(self, prec, expdiff, context):
1648 """Rounds down (not towards 0 if negative)"""
1649 if not self._sign:
1650 return self._round_down(prec, expdiff, context)
1651 else:
1652 return self._round_up(prec, expdiff, context)
1653
1654 def __pow__(self, n, modulo = None, context=None):
1655 """Return self ** n (mod modulo)
1656
1657 If modulo is None (default), don't take it mod modulo.
1658 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001659 n = _convert_other(n)
1660
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001661 if context is None:
1662 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001663
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001664 if self._is_special or n._is_special or n.adjusted() > 8:
1665 #Because the spot << doesn't work with really big exponents
1666 if n._isinfinity() or n.adjusted() > 8:
1667 return context._raise_error(InvalidOperation, 'x ** INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001668
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001669 ans = self._check_nans(n, context)
1670 if ans:
1671 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001672
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001673 if not n._isinteger():
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001674 return context._raise_error(InvalidOperation, 'x ** (non-integer)')
1675
1676 if not self and not n:
1677 return context._raise_error(InvalidOperation, '0 ** 0')
1678
1679 if not n:
1680 return Decimal(1)
1681
1682 if self == Decimal(1):
1683 return Decimal(1)
1684
1685 sign = self._sign and not n._iseven()
1686 n = int(n)
1687
1688 if self._isinfinity():
1689 if modulo:
1690 return context._raise_error(InvalidOperation, 'INF % x')
1691 if n > 0:
1692 return Infsign[sign]
1693 return Decimal( (sign, (0,), 0) )
1694
1695 #with ludicrously large exponent, just raise an overflow and return inf.
1696 if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
1697 and self:
1698
1699 tmp = Decimal('inf')
1700 tmp._sign = sign
1701 context._raise_error(Rounded)
1702 context._raise_error(Inexact)
1703 context._raise_error(Overflow, 'Big power', sign)
1704 return tmp
1705
1706 elength = len(str(abs(n)))
1707 firstprec = context.prec
1708
Raymond Hettinger99148e72004-07-14 19:56:56 +00001709 if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001710 return context._raise_error(Overflow, 'Too much precision.', sign)
1711
1712 mul = Decimal(self)
1713 val = Decimal(1)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001714 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001715 context.prec = firstprec + elength + 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001716 if n < 0:
1717 #n is a long now, not Decimal instance
1718 n = -n
1719 mul = Decimal(1).__div__(mul, context=context)
1720
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001721 spot = 1
1722 while spot <= n:
1723 spot <<= 1
1724
1725 spot >>= 1
1726 #Spot is the highest power of 2 less than n
1727 while spot:
1728 val = val.__mul__(val, context=context)
1729 if val._isinfinity():
1730 val = Infsign[sign]
1731 break
1732 if spot & n:
1733 val = val.__mul__(mul, context=context)
1734 if modulo is not None:
1735 val = val.__mod__(modulo, context=context)
1736 spot >>= 1
1737 context.prec = firstprec
1738
Raymond Hettinger76e60d62004-10-20 06:58:28 +00001739 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001740 return val._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001741 return val
1742
1743 def __rpow__(self, other, context=None):
1744 """Swaps self/other and returns __pow__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001745 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001746 return other.__pow__(self, context=context)
1747
1748 def normalize(self, context=None):
1749 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001750
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001751 if self._is_special:
1752 ans = self._check_nans(context=context)
1753 if ans:
1754 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001755
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001756 dup = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001757 if dup._isinfinity():
1758 return dup
1759
1760 if not dup:
1761 return Decimal( (dup._sign, (0,), 0) )
1762 end = len(dup._int)
1763 exp = dup._exp
1764 while dup._int[end-1] == 0:
1765 exp += 1
1766 end -= 1
1767 return Decimal( (dup._sign, dup._int[:end], exp) )
1768
1769
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001770 def quantize(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001771 """Quantize self so its exponent is the same as that of exp.
1772
1773 Similar to self._rescale(exp._exp) but with error checking.
1774 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001775 if self._is_special or exp._is_special:
1776 ans = self._check_nans(exp, context)
1777 if ans:
1778 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001779
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001780 if exp._isinfinity() or self._isinfinity():
1781 if exp._isinfinity() and self._isinfinity():
1782 return self #if both are inf, it is OK
1783 if context is None:
1784 context = getcontext()
1785 return context._raise_error(InvalidOperation,
1786 'quantize with one INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001787 return self._rescale(exp._exp, rounding, context, watchexp)
1788
1789 def same_quantum(self, other):
1790 """Test whether self and other have the same exponent.
1791
1792 same as self._exp == other._exp, except NaN == sNaN
1793 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001794 if self._is_special or other._is_special:
1795 if self._isnan() or other._isnan():
1796 return self._isnan() and other._isnan() and True
1797 if self._isinfinity() or other._isinfinity():
1798 return self._isinfinity() and other._isinfinity() and True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001799 return self._exp == other._exp
1800
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001801 def _rescale(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001802 """Rescales so that the exponent is exp.
1803
1804 exp = exp to scale to (an integer)
1805 rounding = rounding version
1806 watchexp: if set (default) an error is returned if exp is greater
1807 than Emax or less than Etiny.
1808 """
1809 if context is None:
1810 context = getcontext()
1811
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001812 if self._is_special:
1813 if self._isinfinity():
1814 return context._raise_error(InvalidOperation, 'rescale with an INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001815
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001816 ans = self._check_nans(context=context)
1817 if ans:
1818 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001819
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001820 if watchexp and (context.Emax < exp or context.Etiny() > exp):
1821 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1822
1823 if not self:
1824 ans = Decimal(self)
1825 ans._int = (0,)
1826 ans._exp = exp
1827 return ans
1828
1829 diff = self._exp - exp
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001830 digits = len(self._int) + diff
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001831
1832 if watchexp and digits > context.prec:
1833 return context._raise_error(InvalidOperation, 'Rescale > prec')
1834
1835 tmp = Decimal(self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001836 tmp._int = (0,) + tmp._int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001837 digits += 1
1838
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001839 if digits < 0:
1840 tmp._exp = -digits + tmp._exp
1841 tmp._int = (0,1)
1842 digits = 1
1843 tmp = tmp._round(digits, rounding, context=context)
1844
1845 if tmp._int[0] == 0 and len(tmp._int) > 1:
1846 tmp._int = tmp._int[1:]
1847 tmp._exp = exp
1848
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001849 tmp_adjusted = tmp.adjusted()
1850 if tmp and tmp_adjusted < context.Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001851 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001852 elif tmp and tmp_adjusted > context.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001853 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1854 return tmp
1855
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001856 def to_integral(self, rounding=None, context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001857 """Rounds to the nearest integer, without raising inexact, rounded."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001858 if self._is_special:
1859 ans = self._check_nans(context=context)
1860 if ans:
1861 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001862 if self._exp >= 0:
1863 return self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001864 if context is None:
1865 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001866 flags = context._ignore_flags(Rounded, Inexact)
1867 ans = self._rescale(0, rounding, context=context)
1868 context._regard_flags(flags)
1869 return ans
1870
1871 def sqrt(self, context=None):
1872 """Return the square root of self.
1873
1874 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
1875 Should quadratically approach the right answer.
1876 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001877 if self._is_special:
1878 ans = self._check_nans(context=context)
1879 if ans:
1880 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001881
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001882 if self._isinfinity() and self._sign == 0:
1883 return Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001884
1885 if not self:
1886 #exponent = self._exp / 2, using round_down.
1887 #if self._exp < 0:
1888 # exp = (self._exp+1) // 2
1889 #else:
1890 exp = (self._exp) // 2
1891 if self._sign == 1:
1892 #sqrt(-0) = -0
1893 return Decimal( (1, (0,), exp))
1894 else:
1895 return Decimal( (0, (0,), exp))
1896
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001897 if context is None:
1898 context = getcontext()
1899
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001900 if self._sign == 1:
1901 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
1902
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001903 tmp = Decimal(self)
1904
Raymond Hettinger4837a222004-09-27 14:23:40 +00001905 expadd = tmp._exp // 2
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001906 if tmp._exp & 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001907 tmp._int += (0,)
1908 tmp._exp = 0
1909 else:
1910 tmp._exp = 0
1911
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001912 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001913 flags = context._ignore_all_flags()
1914 firstprec = context.prec
1915 context.prec = 3
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001916 if tmp.adjusted() & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001917 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) )
1918 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
1919 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00001920 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001921 else:
1922 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
1923 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
1924 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00001925 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001926
1927 #ans is now a linear approximation.
1928
1929 Emax, Emin = context.Emax, context.Emin
Raymond Hettinger99148e72004-07-14 19:56:56 +00001930 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001931
1932 half = Decimal('0.5')
1933
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001934 maxp = firstprec + 2
1935 rounding = context._set_rounding(ROUND_HALF_EVEN)
1936 while 1:
1937 context.prec = min(2*context.prec - 2, maxp)
1938 ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
1939 context=context), context=context)
1940 if context.prec == maxp:
1941 break
1942
1943 #round to the answer's precision-- the only error can be 1 ulp.
1944 context.prec = firstprec
1945 prevexp = ans.adjusted()
1946 ans = ans._round(context=context)
1947
1948 #Now, check if the other last digits are better.
1949 context.prec = firstprec + 1
1950 # In case we rounded up another digit and we should actually go lower.
1951 if prevexp != ans.adjusted():
1952 ans._int += (0,)
1953 ans._exp -= 1
1954
1955
1956 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
1957 context._set_rounding(ROUND_UP)
1958 if lower.__mul__(lower, context=context) > (tmp):
1959 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
1960
1961 else:
1962 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
1963 context._set_rounding(ROUND_DOWN)
1964 if upper.__mul__(upper, context=context) < tmp:
1965 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
1966
1967 ans._exp += expadd
1968
1969 context.prec = firstprec
1970 context.rounding = rounding
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001971 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001972
1973 rounding = context._set_rounding_decision(NEVER_ROUND)
1974 if not ans.__mul__(ans, context=context) == self:
1975 # Only rounded/inexact if here.
1976 context._regard_flags(flags)
1977 context._raise_error(Rounded)
1978 context._raise_error(Inexact)
1979 else:
1980 #Exact answer, so let's set the exponent right.
1981 #if self._exp < 0:
1982 # exp = (self._exp +1)// 2
1983 #else:
1984 exp = self._exp // 2
1985 context.prec += ans._exp - exp
1986 ans = ans._rescale(exp, context=context)
1987 context.prec = firstprec
1988 context._regard_flags(flags)
1989 context.Emax, context.Emin = Emax, Emin
1990
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001991 return ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001992
1993 def max(self, other, context=None):
1994 """Returns the larger value.
1995
1996 like max(self, other) except if one is not a number, returns
1997 NaN (and signals if one is sNaN). Also rounds.
1998 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001999 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002000
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002001 if self._is_special or other._is_special:
2002 # if one operand is a quiet NaN and the other is number, then the
2003 # number is always returned
2004 sn = self._isnan()
2005 on = other._isnan()
2006 if sn or on:
2007 if on == 1 and sn != 2:
2008 return self
2009 if sn == 1 and on != 2:
2010 return other
2011 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002012
2013 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002014 c = self.__cmp__(other)
2015 if c == 0:
2016 # if both operands are finite and equal in numerical value
2017 # then an ordering is applied:
2018 #
2019 # if the signs differ then max returns the operand with the
2020 # positive sign and min returns the operand with the negative sign
2021 #
2022 # if the signs are the same then the exponent is used to select
2023 # the result.
2024 if self._sign != other._sign:
2025 if self._sign:
2026 ans = other
2027 elif self._exp < other._exp and not self._sign:
2028 ans = other
2029 elif self._exp > other._exp and self._sign:
2030 ans = other
2031 elif c == -1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002032 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002033
2034 if context is None:
2035 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002036 if context._rounding_decision == ALWAYS_ROUND:
2037 return ans._fix(context)
2038 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002039
2040 def min(self, other, context=None):
2041 """Returns the smaller value.
2042
2043 like min(self, other) except if one is not a number, returns
2044 NaN (and signals if one is sNaN). Also rounds.
2045 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002046 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002047
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002048 if self._is_special or other._is_special:
2049 # if one operand is a quiet NaN and the other is number, then the
2050 # number is always returned
2051 sn = self._isnan()
2052 on = other._isnan()
2053 if sn or on:
2054 if on == 1 and sn != 2:
2055 return self
2056 if sn == 1 and on != 2:
2057 return other
2058 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002059
2060 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002061 c = self.__cmp__(other)
2062 if c == 0:
2063 # if both operands are finite and equal in numerical value
2064 # then an ordering is applied:
2065 #
2066 # if the signs differ then max returns the operand with the
2067 # positive sign and min returns the operand with the negative sign
2068 #
2069 # if the signs are the same then the exponent is used to select
2070 # the result.
2071 if self._sign != other._sign:
2072 if other._sign:
2073 ans = other
2074 elif self._exp > other._exp and not self._sign:
2075 ans = other
2076 elif self._exp < other._exp and self._sign:
2077 ans = other
2078 elif c == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002079 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002080
2081 if context is None:
2082 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002083 if context._rounding_decision == ALWAYS_ROUND:
2084 return ans._fix(context)
2085 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002086
2087 def _isinteger(self):
2088 """Returns whether self is an integer"""
2089 if self._exp >= 0:
2090 return True
2091 rest = self._int[self._exp:]
2092 return rest == (0,)*len(rest)
2093
2094 def _iseven(self):
2095 """Returns 1 if self is even. Assumes self is an integer."""
2096 if self._exp > 0:
2097 return 1
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002098 return self._int[-1+self._exp] & 1 == 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002099
2100 def adjusted(self):
2101 """Return the adjusted exponent of self"""
2102 try:
2103 return self._exp + len(self._int) - 1
2104 #If NaN or Infinity, self._exp is string
2105 except TypeError:
2106 return 0
2107
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002108 # support for pickling, copy, and deepcopy
2109 def __reduce__(self):
2110 return (self.__class__, (str(self),))
2111
2112 def __copy__(self):
2113 if type(self) == Decimal:
2114 return self # I'm immutable; therefore I am my own clone
2115 return self.__class__(str(self))
2116
2117 def __deepcopy__(self, memo):
2118 if type(self) == Decimal:
2119 return self # My components are also immutable
2120 return self.__class__(str(self))
2121
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002122##### Context class ###########################################
2123
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002124
2125# get rounding method function:
2126rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
2127for name in rounding_functions:
2128 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
2129 globalname = name[1:].upper()
2130 val = globals()[globalname]
2131 Decimal._pick_rounding_function[val] = name
2132
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002133del name, val, globalname, rounding_functions
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002134
2135class Context(object):
2136 """Contains the context for a Decimal instance.
2137
2138 Contains:
2139 prec - precision (for use in rounding, division, square roots..)
2140 rounding - rounding type. (how you round)
2141 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
Raymond Hettingerbf440692004-07-10 14:14:37 +00002142 traps - If traps[exception] = 1, then the exception is
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002143 raised when it is caused. Otherwise, a value is
2144 substituted in.
2145 flags - When an exception is caused, flags[exception] is incremented.
2146 (Whether or not the trap_enabler is set)
2147 Should be reset by user of Decimal instance.
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002148 Emin - Minimum exponent
2149 Emax - Maximum exponent
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002150 capitals - If 1, 1*10^1 is printed as 1E+1.
2151 If 0, printed as 1e1
Raymond Hettingere0f15812004-07-05 05:36:39 +00002152 _clamp - If 1, change exponents if too high (Default 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002153 """
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002154
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002155 def __init__(self, prec=None, rounding=None,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002156 traps=None, flags=None,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002157 _rounding_decision=None,
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002158 Emin=None, Emax=None,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002159 capitals=None, _clamp=0,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002160 _ignored_flags=None):
2161 if flags is None:
2162 flags = []
2163 if _ignored_flags is None:
2164 _ignored_flags = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002165 if not isinstance(flags, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002166 flags = dict([(s,s in flags) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002167 del s
Raymond Hettingerbf440692004-07-10 14:14:37 +00002168 if traps is not None and not isinstance(traps, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002169 traps = dict([(s,s in traps) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002170 del s
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002171 for name, val in locals().items():
2172 if val is None:
2173 setattr(self, name, copy.copy(getattr(DefaultContext, name)))
2174 else:
2175 setattr(self, name, val)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002176 del self.self
2177
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002178 def __repr__(self):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002179 """Show the current context."""
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002180 s = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002181 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
2182 s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
2183 s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002184 return ', '.join(s) + ')'
2185
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002186 def clear_flags(self):
2187 """Reset all flags to zero"""
2188 for flag in self.flags:
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002189 self.flags[flag] = 0
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002190
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002191 def _shallow_copy(self):
2192 """Returns a shallow copy from self."""
Raymond Hettingerbf440692004-07-10 14:14:37 +00002193 nc = Context(self.prec, self.rounding, self.traps, self.flags,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002194 self._rounding_decision, self.Emin, self.Emax,
2195 self.capitals, self._clamp, self._ignored_flags)
2196 return nc
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002197
2198 def copy(self):
2199 """Returns a deep copy from self."""
2200 nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
2201 self._rounding_decision, self.Emin, self.Emax,
2202 self.capitals, self._clamp, self._ignored_flags)
2203 return nc
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002204 __copy__ = copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002205
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002206 def _raise_error(self, condition, explanation = None, *args):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002207 """Handles an error
2208
2209 If the flag is in _ignored_flags, returns the default response.
2210 Otherwise, it increments the flag, then, if the corresponding
2211 trap_enabler is set, it reaises the exception. Otherwise, it returns
2212 the default value after incrementing the flag.
2213 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002214 error = _condition_map.get(condition, condition)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002215 if error in self._ignored_flags:
2216 #Don't touch the flag
2217 return error().handle(self, *args)
2218
2219 self.flags[error] += 1
Raymond Hettingerbf440692004-07-10 14:14:37 +00002220 if not self.traps[error]:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002221 #The errors define how to handle themselves.
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002222 return condition().handle(self, *args)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002223
2224 # Errors should only be risked on copies of the context
2225 #self._ignored_flags = []
2226 raise error, explanation
2227
2228 def _ignore_all_flags(self):
2229 """Ignore all flags, if they are raised"""
Raymond Hettingerfed52962004-07-14 15:41:57 +00002230 return self._ignore_flags(*_signals)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002231
2232 def _ignore_flags(self, *flags):
2233 """Ignore the flags, if they are raised"""
2234 # Do not mutate-- This way, copies of a context leave the original
2235 # alone.
2236 self._ignored_flags = (self._ignored_flags + list(flags))
2237 return list(flags)
2238
2239 def _regard_flags(self, *flags):
2240 """Stop ignoring the flags, if they are raised"""
2241 if flags and isinstance(flags[0], (tuple,list)):
2242 flags = flags[0]
2243 for flag in flags:
2244 self._ignored_flags.remove(flag)
2245
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002246 def __hash__(self):
2247 """A Context cannot be hashed."""
2248 # We inherit object.__hash__, so we must deny this explicitly
2249 raise TypeError, "Cannot hash a Context."
2250
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002251 def Etiny(self):
2252 """Returns Etiny (= Emin - prec + 1)"""
2253 return int(self.Emin - self.prec + 1)
2254
2255 def Etop(self):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002256 """Returns maximum exponent (= Emax - prec + 1)"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002257 return int(self.Emax - self.prec + 1)
2258
2259 def _set_rounding_decision(self, type):
2260 """Sets the rounding decision.
2261
2262 Sets the rounding decision, and returns the current (previous)
2263 rounding decision. Often used like:
2264
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002265 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002266 # That so you don't change the calling context
2267 # if an error occurs in the middle (say DivisionImpossible is raised).
2268
2269 rounding = context._set_rounding_decision(NEVER_ROUND)
2270 instance = instance / Decimal(2)
2271 context._set_rounding_decision(rounding)
2272
2273 This will make it not round for that operation.
2274 """
2275
2276 rounding = self._rounding_decision
2277 self._rounding_decision = type
2278 return rounding
2279
2280 def _set_rounding(self, type):
2281 """Sets the rounding type.
2282
2283 Sets the rounding type, and returns the current (previous)
2284 rounding type. Often used like:
2285
2286 context = context.copy()
2287 # so you don't change the calling context
2288 # if an error occurs in the middle.
2289 rounding = context._set_rounding(ROUND_UP)
2290 val = self.__sub__(other, context=context)
2291 context._set_rounding(rounding)
2292
2293 This will make it round up for that operation.
2294 """
2295 rounding = self.rounding
2296 self.rounding= type
2297 return rounding
2298
Raymond Hettingerfed52962004-07-14 15:41:57 +00002299 def create_decimal(self, num='0'):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002300 """Creates a new Decimal instance but using self as context."""
2301 d = Decimal(num, context=self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002302 return d._fix(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002303
2304 #Methods
2305 def abs(self, a):
2306 """Returns the absolute value of the operand.
2307
2308 If the operand is negative, the result is the same as using the minus
2309 operation on the operand. Otherwise, the result is the same as using
2310 the plus operation on the operand.
2311
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002312 >>> ExtendedContext.abs(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002313 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002314 >>> ExtendedContext.abs(Decimal('-100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002315 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002316 >>> ExtendedContext.abs(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002317 Decimal("101.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002318 >>> ExtendedContext.abs(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002319 Decimal("101.5")
2320 """
2321 return a.__abs__(context=self)
2322
2323 def add(self, a, b):
2324 """Return the sum of the two operands.
2325
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002326 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002327 Decimal("19.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002328 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002329 Decimal("1.02E+4")
2330 """
2331 return a.__add__(b, context=self)
2332
2333 def _apply(self, a):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002334 return str(a._fix(self))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002335
2336 def compare(self, a, b):
2337 """Compares values numerically.
2338
2339 If the signs of the operands differ, a value representing each operand
2340 ('-1' if the operand is less than zero, '0' if the operand is zero or
2341 negative zero, or '1' if the operand is greater than zero) is used in
2342 place of that operand for the comparison instead of the actual
2343 operand.
2344
2345 The comparison is then effected by subtracting the second operand from
2346 the first and then returning a value according to the result of the
2347 subtraction: '-1' if the result is less than zero, '0' if the result is
2348 zero or negative zero, or '1' if the result is greater than zero.
2349
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002350 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002351 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002352 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002353 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002354 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002355 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002356 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002357 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002358 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002359 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002360 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002361 Decimal("-1")
2362 """
2363 return a.compare(b, context=self)
2364
2365 def divide(self, a, b):
2366 """Decimal division in a specified context.
2367
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002368 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002369 Decimal("0.333333333")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002370 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002371 Decimal("0.666666667")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002372 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002373 Decimal("2.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002374 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002375 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002376 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002377 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002378 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002379 Decimal("4.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002380 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002381 Decimal("1.20")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002382 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002383 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002384 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002385 Decimal("1000")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002386 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002387 Decimal("1.20E+6")
2388 """
2389 return a.__div__(b, context=self)
2390
2391 def divide_int(self, a, b):
2392 """Divides two numbers and returns the integer part of the result.
2393
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002394 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002395 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002396 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002397 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002398 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002399 Decimal("3")
2400 """
2401 return a.__floordiv__(b, context=self)
2402
2403 def divmod(self, a, b):
2404 return a.__divmod__(b, context=self)
2405
2406 def max(self, a,b):
2407 """max compares two values numerically and returns the maximum.
2408
2409 If either operand is a NaN then the general rules apply.
2410 Otherwise, the operands are compared as as though by the compare
2411 operation. If they are numerically equal then the left-hand operand
2412 is chosen as the result. Otherwise the maximum (closer to positive
2413 infinity) of the two operands is chosen as the result.
2414
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002415 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002416 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002417 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002418 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002419 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002420 Decimal("1")
2421 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
2422 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002423 """
2424 return a.max(b, context=self)
2425
2426 def min(self, a,b):
2427 """min compares two values numerically and returns the minimum.
2428
2429 If either operand is a NaN then the general rules apply.
2430 Otherwise, the operands are compared as as though by the compare
2431 operation. If they are numerically equal then the left-hand operand
2432 is chosen as the result. Otherwise the minimum (closer to negative
2433 infinity) of the two operands is chosen as the result.
2434
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002435 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002436 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002437 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002438 Decimal("-10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002439 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002440 Decimal("1.0")
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002441 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
2442 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002443 """
2444 return a.min(b, context=self)
2445
2446 def minus(self, a):
2447 """Minus corresponds to unary prefix minus in Python.
2448
2449 The operation is evaluated using the same rules as subtract; the
2450 operation minus(a) is calculated as subtract('0', a) where the '0'
2451 has the same exponent as the operand.
2452
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002453 >>> ExtendedContext.minus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002454 Decimal("-1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002455 >>> ExtendedContext.minus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002456 Decimal("1.3")
2457 """
2458 return a.__neg__(context=self)
2459
2460 def multiply(self, a, b):
2461 """multiply multiplies two operands.
2462
2463 If either operand is a special value then the general rules apply.
2464 Otherwise, the operands are multiplied together ('long multiplication'),
2465 resulting in a number which may be as long as the sum of the lengths
2466 of the two operands.
2467
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002468 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002469 Decimal("3.60")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002470 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002471 Decimal("21")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002472 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002473 Decimal("0.72")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002474 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002475 Decimal("-0.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002476 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002477 Decimal("4.28135971E+11")
2478 """
2479 return a.__mul__(b, context=self)
2480
2481 def normalize(self, a):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002482 """normalize reduces an operand to its simplest form.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002483
2484 Essentially a plus operation with all trailing zeros removed from the
2485 result.
2486
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002487 >>> ExtendedContext.normalize(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002488 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002489 >>> ExtendedContext.normalize(Decimal('-2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002490 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002491 >>> ExtendedContext.normalize(Decimal('1.200'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002492 Decimal("1.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002493 >>> ExtendedContext.normalize(Decimal('-120'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002494 Decimal("-1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002495 >>> ExtendedContext.normalize(Decimal('120.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002496 Decimal("1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002497 >>> ExtendedContext.normalize(Decimal('0.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002498 Decimal("0")
2499 """
2500 return a.normalize(context=self)
2501
2502 def plus(self, a):
2503 """Plus corresponds to unary prefix plus in Python.
2504
2505 The operation is evaluated using the same rules as add; the
2506 operation plus(a) is calculated as add('0', a) where the '0'
2507 has the same exponent as the operand.
2508
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002509 >>> ExtendedContext.plus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002510 Decimal("1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002511 >>> ExtendedContext.plus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002512 Decimal("-1.3")
2513 """
2514 return a.__pos__(context=self)
2515
2516 def power(self, a, b, modulo=None):
2517 """Raises a to the power of b, to modulo if given.
2518
2519 The right-hand operand must be a whole number whose integer part (after
2520 any exponent has been applied) has no more than 9 digits and whose
2521 fractional part (if any) is all zeros before any rounding. The operand
2522 may be positive, negative, or zero; if negative, the absolute value of
2523 the power is used, and the left-hand operand is inverted (divided into
2524 1) before use.
2525
2526 If the increased precision needed for the intermediate calculations
2527 exceeds the capabilities of the implementation then an Invalid operation
2528 condition is raised.
2529
2530 If, when raising to a negative power, an underflow occurs during the
2531 division into 1, the operation is not halted at that point but
2532 continues.
2533
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002534 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002535 Decimal("8")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002536 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002537 Decimal("0.125")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002538 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002539 Decimal("69.7575744")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002540 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002541 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002542 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002543 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002544 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002545 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002546 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002547 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002548 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002549 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002550 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002551 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002552 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002553 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002554 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002555 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002556 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002557 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002558 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002559 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002560 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002561 Decimal("NaN")
2562 """
2563 return a.__pow__(b, modulo, context=self)
2564
2565 def quantize(self, a, b):
2566 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
2567
2568 The coefficient of the result is derived from that of the left-hand
2569 operand. It may be rounded using the current rounding setting (if the
2570 exponent is being increased), multiplied by a positive power of ten (if
2571 the exponent is being decreased), or is unchanged (if the exponent is
2572 already equal to that of the right-hand operand).
2573
2574 Unlike other operations, if the length of the coefficient after the
2575 quantize operation would be greater than precision then an Invalid
2576 operation condition is raised. This guarantees that, unless there is an
2577 error condition, the exponent of the result of a quantize is always
2578 equal to that of the right-hand operand.
2579
2580 Also unlike other operations, quantize will never raise Underflow, even
2581 if the result is subnormal and inexact.
2582
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002583 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002584 Decimal("2.170")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002585 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002586 Decimal("2.17")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002587 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002588 Decimal("2.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002589 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002590 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002591 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002592 Decimal("0E+1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002593 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002594 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002595 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002596 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002597 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002598 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002599 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002600 Decimal("-0E+5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002601 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002602 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002603 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002604 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002605 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002606 Decimal("217.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002607 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002608 Decimal("217")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002609 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002610 Decimal("2.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002611 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002612 Decimal("2E+2")
2613 """
2614 return a.quantize(b, context=self)
2615
2616 def remainder(self, a, b):
2617 """Returns the remainder from integer division.
2618
2619 The result is the residue of the dividend after the operation of
2620 calculating integer division as described for divide-integer, rounded to
2621 precision digits if necessary. The sign of the result, if non-zero, is
2622 the same as that of the original dividend.
2623
2624 This operation will fail under the same conditions as integer division
2625 (that is, if integer division on the same two operands would fail, the
2626 remainder cannot be calculated).
2627
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002628 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002629 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002630 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002631 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002632 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002633 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002634 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002635 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002636 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002637 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002638 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002639 Decimal("1.0")
2640 """
2641 return a.__mod__(b, context=self)
2642
2643 def remainder_near(self, a, b):
2644 """Returns to be "a - b * n", where n is the integer nearest the exact
2645 value of "x / b" (if two integers are equally near then the even one
2646 is chosen). If the result is equal to 0 then its sign will be the
2647 sign of a.
2648
2649 This operation will fail under the same conditions as integer division
2650 (that is, if integer division on the same two operands would fail, the
2651 remainder cannot be calculated).
2652
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002653 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002654 Decimal("-0.9")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002655 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002656 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002657 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002658 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002659 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002660 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002661 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002662 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002663 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002664 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002665 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002666 Decimal("-0.3")
2667 """
2668 return a.remainder_near(b, context=self)
2669
2670 def same_quantum(self, a, b):
2671 """Returns True if the two operands have the same exponent.
2672
2673 The result is never affected by either the sign or the coefficient of
2674 either operand.
2675
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002676 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002677 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002678 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002679 True
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002680 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002681 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002682 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002683 True
2684 """
2685 return a.same_quantum(b)
2686
2687 def sqrt(self, a):
2688 """Returns the square root of a non-negative number to context precision.
2689
2690 If the result must be inexact, it is rounded using the round-half-even
2691 algorithm.
2692
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002693 >>> ExtendedContext.sqrt(Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002694 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002695 >>> ExtendedContext.sqrt(Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002696 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002697 >>> ExtendedContext.sqrt(Decimal('0.39'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002698 Decimal("0.624499800")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002699 >>> ExtendedContext.sqrt(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002700 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002701 >>> ExtendedContext.sqrt(Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002702 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002703 >>> ExtendedContext.sqrt(Decimal('1.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002704 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002705 >>> ExtendedContext.sqrt(Decimal('1.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002706 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002707 >>> ExtendedContext.sqrt(Decimal('7'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002708 Decimal("2.64575131")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002709 >>> ExtendedContext.sqrt(Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002710 Decimal("3.16227766")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002711 >>> ExtendedContext.prec
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002712 9
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002713 """
2714 return a.sqrt(context=self)
2715
2716 def subtract(self, a, b):
2717 """Return the sum of the two operands.
2718
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002719 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002720 Decimal("0.23")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002721 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002722 Decimal("0.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002723 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002724 Decimal("-0.77")
2725 """
2726 return a.__sub__(b, context=self)
2727
2728 def to_eng_string(self, a):
2729 """Converts a number to a string, using scientific notation.
2730
2731 The operation is not affected by the context.
2732 """
2733 return a.to_eng_string(context=self)
2734
2735 def to_sci_string(self, a):
2736 """Converts a number to a string, using scientific notation.
2737
2738 The operation is not affected by the context.
2739 """
2740 return a.__str__(context=self)
2741
2742 def to_integral(self, a):
2743 """Rounds to an integer.
2744
2745 When the operand has a negative exponent, the result is the same
2746 as using the quantize() operation using the given operand as the
2747 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2748 of the operand as the precision setting, except that no flags will
2749 be set. The rounding mode is taken from the context.
2750
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002751 >>> ExtendedContext.to_integral(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002752 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002753 >>> ExtendedContext.to_integral(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002754 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002755 >>> ExtendedContext.to_integral(Decimal('100.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002756 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002757 >>> ExtendedContext.to_integral(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002758 Decimal("102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002759 >>> ExtendedContext.to_integral(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002760 Decimal("-102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002761 >>> ExtendedContext.to_integral(Decimal('10E+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002762 Decimal("1.0E+6")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002763 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002764 Decimal("7.89E+77")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002765 >>> ExtendedContext.to_integral(Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002766 Decimal("-Infinity")
2767 """
2768 return a.to_integral(context=self)
2769
2770class _WorkRep(object):
2771 __slots__ = ('sign','int','exp')
Raymond Hettinger17931de2004-10-27 06:21:46 +00002772 # sign: 0 or 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002773 # int: int or long
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002774 # exp: None, int, or string
2775
2776 def __init__(self, value=None):
2777 if value is None:
2778 self.sign = None
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002779 self.int = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002780 self.exp = None
Raymond Hettinger17931de2004-10-27 06:21:46 +00002781 elif isinstance(value, Decimal):
2782 self.sign = value._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002783 cum = 0
Raymond Hettinger17931de2004-10-27 06:21:46 +00002784 for digit in value._int:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002785 cum = cum * 10 + digit
2786 self.int = cum
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002787 self.exp = value._exp
Raymond Hettinger17931de2004-10-27 06:21:46 +00002788 else:
2789 # assert isinstance(value, tuple)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002790 self.sign = value[0]
2791 self.int = value[1]
2792 self.exp = value[2]
2793
2794 def __repr__(self):
2795 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2796
2797 __str__ = __repr__
2798
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002799
2800
2801def _normalize(op1, op2, shouldround = 0, prec = 0):
2802 """Normalizes op1, op2 to have the same exp and length of coefficient.
2803
2804 Done during addition.
2805 """
2806 # Yes, the exponent is a long, but the difference between exponents
2807 # must be an int-- otherwise you'd get a big memory problem.
2808 numdigits = int(op1.exp - op2.exp)
2809 if numdigits < 0:
2810 numdigits = -numdigits
2811 tmp = op2
2812 other = op1
2813 else:
2814 tmp = op1
2815 other = op2
2816
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002817
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002818 if shouldround and numdigits > prec + 1:
2819 # Big difference in exponents - check the adjusted exponents
2820 tmp_len = len(str(tmp.int))
2821 other_len = len(str(other.int))
2822 if numdigits > (other_len + prec + 1 - tmp_len):
2823 # If the difference in adjusted exps is > prec+1, we know
2824 # other is insignificant, so might as well put a 1 after the precision.
2825 # (since this is only for addition.) Also stops use of massive longs.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002826
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002827 extend = prec + 2 - tmp_len
2828 if extend <= 0:
2829 extend = 1
2830 tmp.int *= 10 ** extend
2831 tmp.exp -= extend
2832 other.int = 1
2833 other.exp = tmp.exp
2834 return op1, op2
2835
2836 tmp.int *= 10 ** numdigits
2837 tmp.exp -= numdigits
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002838 return op1, op2
2839
2840def _adjust_coefficients(op1, op2):
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002841 """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002842
2843 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2844
2845 Used on _WorkRep instances during division.
2846 """
2847 adjust = 0
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002848 #If op1 is smaller, make it larger
2849 while op2.int > op1.int:
2850 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002851 op1.exp -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002852 adjust += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002853
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002854 #If op2 is too small, make it larger
2855 while op1.int >= (10 * op2.int):
2856 op2.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002857 op2.exp -= 1
2858 adjust -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002859
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002860 return op1, op2, adjust
2861
2862##### Helper Functions ########################################
2863
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002864def _convert_other(other):
2865 """Convert other to Decimal.
2866
2867 Verifies that it's ok to use in an implicit construction.
2868 """
2869 if isinstance(other, Decimal):
2870 return other
2871 if isinstance(other, (int, long)):
2872 return Decimal(other)
2873
2874 raise TypeError, "You can interact Decimal only with int, long or Decimal data types."
2875
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002876_infinity_map = {
2877 'inf' : 1,
2878 'infinity' : 1,
2879 '+inf' : 1,
2880 '+infinity' : 1,
2881 '-inf' : -1,
2882 '-infinity' : -1
2883}
2884
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002885def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002886 """Determines whether a string or float is infinity.
2887
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002888 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002889 """
2890 num = str(num).lower()
2891 return _infinity_map.get(num, 0)
2892
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002893def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002894 """Determines whether a string or float is NaN
2895
2896 (1, sign, diagnostic info as string) => NaN
2897 (2, sign, diagnostic info as string) => sNaN
2898 0 => not a NaN
2899 """
2900 num = str(num).lower()
2901 if not num:
2902 return 0
2903
2904 #get the sign, get rid of trailing [+-]
2905 sign = 0
2906 if num[0] == '+':
2907 num = num[1:]
2908 elif num[0] == '-': #elif avoids '+-nan'
2909 num = num[1:]
2910 sign = 1
2911
2912 if num.startswith('nan'):
2913 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
2914 return 0
2915 return (1, sign, num[3:].lstrip('0'))
2916 if num.startswith('snan'):
2917 if len(num) > 4 and not num[4:].isdigit():
2918 return 0
2919 return (2, sign, num[4:].lstrip('0'))
2920 return 0
2921
2922
2923##### Setup Specific Contexts ################################
2924
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002925# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00002926# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002927
2928DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002929 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002930 traps=[DivisionByZero, Overflow, InvalidOperation],
2931 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002932 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00002933 Emax=999999999,
2934 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002935 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002936)
2937
2938# Pre-made alternate contexts offered by the specification
2939# Don't change these; the user should be able to select these
2940# contexts and be able to reproduce results from other implementations
2941# of the spec.
2942
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002943BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002944 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002945 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
2946 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002947)
2948
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002949ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002950 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002951 traps=[],
2952 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002953)
2954
2955
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002956##### Useful Constants (internal use only) ####################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002957
2958#Reusable defaults
2959Inf = Decimal('Inf')
2960negInf = Decimal('-Inf')
2961
2962#Infsign[sign] is infinity w/ that sign
2963Infsign = (Inf, negInf)
2964
2965NaN = Decimal('NaN')
2966
2967
2968##### crud for parsing strings #################################
2969import re
2970
2971# There's an optional sign at the start, and an optional exponent
2972# at the end. The exponent has an optional sign and at least one
2973# digit. In between, must have either at least one digit followed
2974# by an optional fraction, or a decimal point followed by at least
2975# one digit. Yuck.
2976
2977_parser = re.compile(r"""
2978# \s*
2979 (?P<sign>[-+])?
2980 (
2981 (?P<int>\d+) (\. (?P<frac>\d*))?
2982 |
2983 \. (?P<onlyfrac>\d+)
2984 )
2985 ([eE](?P<exp>[-+]? \d+))?
2986# \s*
2987 $
2988""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
2989
2990del re
2991
2992# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
2993
2994def _string2exact(s):
2995 m = _parser(s)
2996 if m is None:
2997 raise ValueError("invalid literal for Decimal: %r" % s)
2998
2999 if m.group('sign') == "-":
3000 sign = 1
3001 else:
3002 sign = 0
3003
3004 exp = m.group('exp')
3005 if exp is None:
3006 exp = 0
3007 else:
3008 exp = int(exp)
3009
3010 intpart = m.group('int')
3011 if intpart is None:
3012 intpart = ""
3013 fracpart = m.group('onlyfrac')
3014 else:
3015 fracpart = m.group('frac')
3016 if fracpart is None:
3017 fracpart = ""
3018
3019 exp -= len(fracpart)
3020
3021 mantissa = intpart + fracpart
3022 tmp = map(int, mantissa)
3023 backup = tmp
3024 while tmp and tmp[0] == 0:
3025 del tmp[0]
3026
3027 # It's a zero
3028 if not tmp:
3029 if backup:
3030 return (sign, tuple(backup), exp)
3031 return (sign, (0,), exp)
3032 mantissa = tuple(tmp)
3033
3034 return (sign, mantissa, exp)
3035
3036
3037if __name__ == '__main__':
3038 import doctest, sys
3039 doctest.testmod(sys.modules[__name__])