blob: 8870471d86686831547c3173d3d9a9187d2a1bfc [file] [log] [blame]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001# Copyright (c) 2004 Python Software Foundation.
2# All rights reserved.
3
4# Written by Eric Price <eprice at tjhsst.edu>
5# and Facundo Batista <facundo at taniquetil.com.ar>
6# and Raymond Hettinger <python at rcn.com>
Fred Drake1f34eb12004-07-01 14:28:36 +00007# and Aahz <aahz at pobox.com>
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00008# and Tim Peters
9
Raymond Hettinger27dbcf22004-08-19 22:39:55 +000010# This module is currently Py2.3 compatible and should be kept that way
11# unless a major compelling advantage arises. IOW, 2.3 compatibility is
12# strongly preferred, but not guaranteed.
13
14# Also, this module should be kept in sync with the latest updates of
15# the IBM specification as it evolves. Those updates will be treated
16# as bug fixes (deviation from the spec is a compatibility, usability
17# bug) and will be backported. At this point the spec is stabilizing
18# and the updates are becoming fewer, smaller, and less significant.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000019
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000020"""
21This is a Py2.3 implementation of decimal floating point arithmetic based on
22the General Decimal Arithmetic Specification:
23
24 www2.hursley.ibm.com/decimal/decarith.html
25
Raymond Hettinger0ea241e2004-07-04 13:53:24 +000026and IEEE standard 854-1987:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000027
28 www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html
29
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000030Decimal floating point has finite precision with arbitrarily large bounds.
31
32The purpose of the module is to support arithmetic using familiar
33"schoolhouse" rules and to avoid the some of tricky representation
34issues associated with binary floating point. The package is especially
35useful for financial applications or for contexts where users have
36expectations that are at odds with binary floating point (for instance,
37in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead
38of the expected Decimal("0.00") returned by decimal floating point).
39
40Here are some examples of using the decimal module:
41
42>>> from decimal import *
Raymond Hettingerbd7f76d2004-07-08 00:49:18 +000043>>> setcontext(ExtendedContext)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000044>>> Decimal(0)
45Decimal("0")
46>>> Decimal("1")
47Decimal("1")
48>>> Decimal("-.0123")
49Decimal("-0.0123")
50>>> Decimal(123456)
51Decimal("123456")
52>>> Decimal("123.45e12345678901234567890")
53Decimal("1.2345E+12345678901234567892")
54>>> Decimal("1.33") + Decimal("1.27")
55Decimal("2.60")
56>>> Decimal("12.34") + Decimal("3.87") - Decimal("18.41")
57Decimal("-2.20")
58>>> dig = Decimal(1)
59>>> print dig / Decimal(3)
600.333333333
61>>> getcontext().prec = 18
62>>> print dig / Decimal(3)
630.333333333333333333
64>>> print dig.sqrt()
651
66>>> print Decimal(3).sqrt()
671.73205080756887729
68>>> print Decimal(3) ** 123
694.85192780976896427E+58
70>>> inf = Decimal(1) / Decimal(0)
71>>> print inf
72Infinity
73>>> neginf = Decimal(-1) / Decimal(0)
74>>> print neginf
75-Infinity
76>>> print neginf + inf
77NaN
78>>> print neginf * inf
79-Infinity
80>>> print dig / 0
81Infinity
Raymond Hettingerbf440692004-07-10 14:14:37 +000082>>> getcontext().traps[DivisionByZero] = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000083>>> print dig / 0
84Traceback (most recent call last):
85 ...
86 ...
87 ...
88DivisionByZero: x / 0
89>>> c = Context()
Raymond Hettingerbf440692004-07-10 14:14:37 +000090>>> c.traps[InvalidOperation] = 0
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000091>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000920
93>>> c.divide(Decimal(0), Decimal(0))
94Decimal("NaN")
Raymond Hettingerbf440692004-07-10 14:14:37 +000095>>> c.traps[InvalidOperation] = 1
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000096>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000971
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000098>>> c.flags[InvalidOperation] = 0
99>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001000
101>>> print c.divide(Decimal(0), Decimal(0))
102Traceback (most recent call last):
103 ...
104 ...
105 ...
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000106InvalidOperation: 0 / 0
107>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001081
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000109>>> c.flags[InvalidOperation] = 0
Raymond Hettingerbf440692004-07-10 14:14:37 +0000110>>> c.traps[InvalidOperation] = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000111>>> print c.divide(Decimal(0), Decimal(0))
112NaN
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000113>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001141
115>>>
116"""
117
118__all__ = [
119 # Two major classes
120 'Decimal', 'Context',
121
122 # Contexts
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +0000123 'DefaultContext', 'BasicContext', 'ExtendedContext',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000124
125 # Exceptions
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +0000126 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
127 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000128
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000129 # Constants for use in setting up contexts
130 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING',
131 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000132
133 # Functions for manipulating contexts
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000134 'setcontext', 'getcontext'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000135]
136
137import threading
138import copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000139
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000140#Rounding
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000141ROUND_DOWN = 'ROUND_DOWN'
142ROUND_HALF_UP = 'ROUND_HALF_UP'
143ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
144ROUND_CEILING = 'ROUND_CEILING'
145ROUND_FLOOR = 'ROUND_FLOOR'
146ROUND_UP = 'ROUND_UP'
147ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000148
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +0000149#Rounding decision (not part of the public API)
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000150NEVER_ROUND = 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY
151ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000152
153#Errors
154
155class DecimalException(ArithmeticError):
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000156 """Base exception class.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000157
158 Used exceptions derive from this.
159 If an exception derives from another exception besides this (such as
160 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
161 called if the others are present. This isn't actually used for
162 anything, though.
163
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000164 handle -- Called when context._raise_error is called and the
165 trap_enabler is set. First argument is self, second is the
166 context. More arguments can be given, those being after
167 the explanation in _raise_error (For example,
168 context._raise_error(NewError, '(-x)!', self._sign) would
169 call NewError().handle(context, self._sign).)
170
171 To define a new exception, it should be sufficient to have it derive
172 from DecimalException.
173 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000174 def handle(self, context, *args):
175 pass
176
177
178class Clamped(DecimalException):
179 """Exponent of a 0 changed to fit bounds.
180
181 This occurs and signals clamped if the exponent of a result has been
182 altered in order to fit the constraints of a specific concrete
183 representation. This may occur when the exponent of a zero result would
184 be outside the bounds of a representation, or when a large normal
185 number would have an encoded exponent that cannot be represented. In
186 this latter case, the exponent is reduced to fit and the corresponding
187 number of zero digits are appended to the coefficient ("fold-down").
188 """
189
190
191class InvalidOperation(DecimalException):
192 """An invalid operation was performed.
193
194 Various bad things cause this:
195
196 Something creates a signaling NaN
197 -INF + INF
198 0 * (+-)INF
199 (+-)INF / (+-)INF
200 x % 0
201 (+-)INF % x
202 x._rescale( non-integer )
203 sqrt(-x) , x > 0
204 0 ** 0
205 x ** (non-integer)
206 x ** (+-)INF
207 An operand is invalid
208 """
209 def handle(self, context, *args):
210 if args:
211 if args[0] == 1: #sNaN, must drop 's' but keep diagnostics
212 return Decimal( (args[1]._sign, args[1]._int, 'n') )
213 return NaN
214
215class ConversionSyntax(InvalidOperation):
216 """Trying to convert badly formed string.
217
218 This occurs and signals invalid-operation if an string is being
219 converted to a number and it does not conform to the numeric string
220 syntax. The result is [0,qNaN].
221 """
222
223 def handle(self, context, *args):
224 return (0, (0,), 'n') #Passed to something which uses a tuple.
225
226class DivisionByZero(DecimalException, ZeroDivisionError):
227 """Division by 0.
228
229 This occurs and signals division-by-zero if division of a finite number
230 by zero was attempted (during a divide-integer or divide operation, or a
231 power operation with negative right-hand operand), and the dividend was
232 not zero.
233
234 The result of the operation is [sign,inf], where sign is the exclusive
235 or of the signs of the operands for divide, or is 1 for an odd power of
236 -0, for power.
237 """
238
239 def handle(self, context, sign, double = None, *args):
240 if double is not None:
241 return (Infsign[sign],)*2
242 return Infsign[sign]
243
244class DivisionImpossible(InvalidOperation):
245 """Cannot perform the division adequately.
246
247 This occurs and signals invalid-operation if the integer result of a
248 divide-integer or remainder operation had too many digits (would be
249 longer than precision). The result is [0,qNaN].
250 """
251
252 def handle(self, context, *args):
253 return (NaN, NaN)
254
255class DivisionUndefined(InvalidOperation, ZeroDivisionError):
256 """Undefined result of division.
257
258 This occurs and signals invalid-operation if division by zero was
259 attempted (during a divide-integer, divide, or remainder operation), and
260 the dividend is also zero. The result is [0,qNaN].
261 """
262
263 def handle(self, context, tup=None, *args):
264 if tup is not None:
265 return (NaN, NaN) #for 0 %0, 0 // 0
266 return NaN
267
268class Inexact(DecimalException):
269 """Had to round, losing information.
270
271 This occurs and signals inexact whenever the result of an operation is
272 not exact (that is, it needed to be rounded and any discarded digits
273 were non-zero), or if an overflow or underflow condition occurs. The
274 result in all cases is unchanged.
275
276 The inexact signal may be tested (or trapped) to determine if a given
277 operation (or sequence of operations) was inexact.
278 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000279 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000280
281class InvalidContext(InvalidOperation):
282 """Invalid context. Unknown rounding, for example.
283
284 This occurs and signals invalid-operation if an invalid context was
285 detected during an operation. This can occur if contexts are not checked
286 on creation and either the precision exceeds the capability of the
287 underlying concrete representation or an unknown or unsupported rounding
288 was specified. These aspects of the context need only be checked when
289 the values are required to be used. The result is [0,qNaN].
290 """
291
292 def handle(self, context, *args):
293 return NaN
294
295class Rounded(DecimalException):
296 """Number got rounded (not necessarily changed during rounding).
297
298 This occurs and signals rounded whenever the result of an operation is
299 rounded (that is, some zero or non-zero digits were discarded from the
300 coefficient), or if an overflow or underflow condition occurs. The
301 result in all cases is unchanged.
302
303 The rounded signal may be tested (or trapped) to determine if a given
304 operation (or sequence of operations) caused a loss of precision.
305 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000306 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000307
308class Subnormal(DecimalException):
309 """Exponent < Emin before rounding.
310
311 This occurs and signals subnormal whenever the result of a conversion or
312 operation is subnormal (that is, its adjusted exponent is less than
313 Emin, before any rounding). The result in all cases is unchanged.
314
315 The subnormal signal may be tested (or trapped) to determine if a given
316 or operation (or sequence of operations) yielded a subnormal result.
317 """
318 pass
319
320class Overflow(Inexact, Rounded):
321 """Numerical overflow.
322
323 This occurs and signals overflow if the adjusted exponent of a result
324 (from a conversion or from an operation that is not an attempt to divide
325 by zero), after rounding, would be greater than the largest value that
326 can be handled by the implementation (the value Emax).
327
328 The result depends on the rounding mode:
329
330 For round-half-up and round-half-even (and for round-half-down and
331 round-up, if implemented), the result of the operation is [sign,inf],
332 where sign is the sign of the intermediate result. For round-down, the
333 result is the largest finite number that can be represented in the
334 current precision, with the sign of the intermediate result. For
335 round-ceiling, the result is the same as for round-down if the sign of
336 the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
337 the result is the same as for round-down if the sign of the intermediate
338 result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
339 will also be raised.
340 """
341
342 def handle(self, context, sign, *args):
343 if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
344 ROUND_HALF_DOWN, ROUND_UP):
345 return Infsign[sign]
346 if sign == 0:
347 if context.rounding == ROUND_CEILING:
348 return Infsign[sign]
349 return Decimal((sign, (9,)*context.prec,
350 context.Emax-context.prec+1))
351 if sign == 1:
352 if context.rounding == ROUND_FLOOR:
353 return Infsign[sign]
354 return Decimal( (sign, (9,)*context.prec,
355 context.Emax-context.prec+1))
356
357
358class Underflow(Inexact, Rounded, Subnormal):
359 """Numerical underflow with result rounded to 0.
360
361 This occurs and signals underflow if a result is inexact and the
362 adjusted exponent of the result would be smaller (more negative) than
363 the smallest value that can be handled by the implementation (the value
364 Emin). That is, the result is both inexact and subnormal.
365
366 The result after an underflow will be a subnormal number rounded, if
367 necessary, so that its exponent is not less than Etiny. This may result
368 in 0 with the sign of the intermediate result and an exponent of Etiny.
369
370 In all cases, Inexact, Rounded, and Subnormal will also be raised.
371 """
372
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000373# List of public traps and flags
Raymond Hettingerfed52962004-07-14 15:41:57 +0000374_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000375 Underflow, InvalidOperation, Subnormal]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000376
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000377# Map conditions (per the spec) to signals
378_condition_map = {ConversionSyntax:InvalidOperation,
379 DivisionImpossible:InvalidOperation,
380 DivisionUndefined:InvalidOperation,
381 InvalidContext:InvalidOperation}
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000382
383##### Context Functions #######################################
384
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000385# The getcontext() and setcontext() function manage access to a thread-local
386# current context. Py2.4 offers direct support for thread locals. If that
387# is not available, use threading.currentThread() which is slower but will
388# work for older Pythons.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000389
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000390try:
391 threading.local
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000392
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000393except AttributeError:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000394
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000395 #To fix reloading, force it to create a new context
396 #Old contexts have different exceptions in their dicts, making problems.
397 if hasattr(threading.currentThread(), '__decimal_context__'):
398 del threading.currentThread().__decimal_context__
399
400 def setcontext(context):
401 """Set this thread's context to context."""
402 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000403 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000404 context.clear_flags()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000405 threading.currentThread().__decimal_context__ = context
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000406
407 def getcontext():
408 """Returns this thread's context.
409
410 If this thread does not yet have a context, returns
411 a new context and sets this thread's context.
412 New contexts are copies of DefaultContext.
413 """
414 try:
415 return threading.currentThread().__decimal_context__
416 except AttributeError:
417 context = Context()
418 threading.currentThread().__decimal_context__ = context
419 return context
420
421else:
422
423 local = threading.local()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000424 if hasattr(local, '__decimal_context__'):
425 del local.__decimal_context__
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000426
427 def getcontext(_local=local):
428 """Returns this thread's context.
429
430 If this thread does not yet have a context, returns
431 a new context and sets this thread's context.
432 New contexts are copies of DefaultContext.
433 """
434 try:
435 return _local.__decimal_context__
436 except AttributeError:
437 context = Context()
438 _local.__decimal_context__ = context
439 return context
440
441 def setcontext(context, _local=local):
442 """Set this thread's context to context."""
443 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000444 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000445 context.clear_flags()
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000446 _local.__decimal_context__ = context
447
448 del threading, local # Don't contaminate the namespace
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000449
450
451##### Decimal class ###########################################
452
453class Decimal(object):
454 """Floating point class for decimal arithmetic."""
455
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000456 __slots__ = ('_exp','_int','_sign', '_is_special')
457 # Generally, the value of the Decimal instance is given by
458 # (-1)**_sign * _int * 10**_exp
459 # Special values are signified by _is_special == True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000460
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000461 # We're immutable, so use __new__ not __init__
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000462 def __new__(cls, value="0", context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000463 """Create a decimal point instance.
464
465 >>> Decimal('3.14') # string input
466 Decimal("3.14")
467 >>> Decimal((0, (3, 1, 4), -2)) # tuple input (sign, digit_tuple, exponent)
468 Decimal("3.14")
469 >>> Decimal(314) # int or long
470 Decimal("314")
471 >>> Decimal(Decimal(314)) # another decimal instance
472 Decimal("314")
473 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000474
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000475 self = object.__new__(cls)
476 self._is_special = False
477
478 # From an internal working value
479 if isinstance(value, _WorkRep):
480 if value.sign == 1:
481 self._sign = 0
482 else:
483 self._sign = 1
484 self._int = tuple(map(int, str(value.int)))
485 self._exp = int(value.exp)
486 return self
487
488 # From another decimal
489 if isinstance(value, Decimal):
490 self._exp = value._exp
491 self._sign = value._sign
492 self._int = value._int
493 self._is_special = value._is_special
494 return self
495
496 # From an integer
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000497 if isinstance(value, (int,long)):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000498 if value >= 0:
499 self._sign = 0
500 else:
501 self._sign = 1
502 self._exp = 0
503 self._int = tuple(map(int, str(abs(value))))
504 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000505
506 # tuple/list conversion (possibly from as_tuple())
507 if isinstance(value, (list,tuple)):
508 if len(value) != 3:
509 raise ValueError, 'Invalid arguments'
510 if value[0] not in [0,1]:
511 raise ValueError, 'Invalid sign'
512 for digit in value[1]:
513 if not isinstance(digit, (int,long)) or digit < 0:
514 raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
515
516 self._sign = value[0]
517 self._int = tuple(value[1])
518 if value[2] in ('F','n','N'):
519 self._exp = value[2]
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000520 self._is_special = True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000521 else:
522 self._exp = int(value[2])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000523 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000524
Raymond Hettingerbf440692004-07-10 14:14:37 +0000525 if isinstance(value, float):
526 raise TypeError("Cannot convert float to Decimal. " +
527 "First convert the float to a string")
528
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000529 # Other argument types may require the context during interpretation
530 if context is None:
531 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000532
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000533 # From a string
534 # REs insist on real strings, so we can too.
535 if isinstance(value, basestring):
536 if _isinfinity(value):
537 self._exp = 'F'
538 self._int = (0,)
539 self._is_special = True
540 if _isinfinity(value) == 1:
541 self._sign = 0
542 else:
543 self._sign = 1
544 return self
545 if _isnan(value):
546 sig, sign, diag = _isnan(value)
547 self._is_special = True
548 if len(diag) > context.prec: #Diagnostic info too long
549 self._sign, self._int, self._exp = \
550 context._raise_error(ConversionSyntax)
551 return self
552 if sig == 1:
553 self._exp = 'n' #qNaN
554 else: #sig == 2
555 self._exp = 'N' #sNaN
556 self._sign = sign
557 self._int = tuple(map(int, diag)) #Diagnostic info
558 return self
559 try:
560 self._sign, self._int, self._exp = _string2exact(value)
561 except ValueError:
562 self._is_special = True
563 self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
564 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000565
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000566 raise TypeError("Cannot convert %r to Decimal" % value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000567
568 def _isnan(self):
569 """Returns whether the number is not actually one.
570
571 0 if a number
572 1 if NaN
573 2 if sNaN
574 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000575 if self._is_special:
576 exp = self._exp
577 if exp == 'n':
578 return 1
579 elif exp == 'N':
580 return 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000581 return 0
582
583 def _isinfinity(self):
584 """Returns whether the number is infinite
585
586 0 if finite or not a number
587 1 if +INF
588 -1 if -INF
589 """
590 if self._exp == 'F':
591 if self._sign:
592 return -1
593 return 1
594 return 0
595
596 def _check_nans(self, other = None, context=None):
597 """Returns whether the number is not actually one.
598
599 if self, other are sNaN, signal
600 if self, other are NaN return nan
601 return 0
602
603 Done before operations.
604 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000605
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000606 self_is_nan = self._isnan()
607 if other is None:
608 other_is_nan = False
609 else:
610 other_is_nan = other._isnan()
611
612 if self_is_nan or other_is_nan:
613 if context is None:
614 context = getcontext()
615
616 if self_is_nan == 2:
617 return context._raise_error(InvalidOperation, 'sNaN',
618 1, self)
619 if other_is_nan == 2:
620 return context._raise_error(InvalidOperation, 'sNaN',
621 1, other)
622 if self_is_nan:
623 return self
624
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000625 return other
626 return 0
627
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000628 def __nonzero__(self):
629 """Is the number non-zero?
630
631 0 if self == 0
632 1 if self != 0
633 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000634 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000635 return 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000636 return sum(self._int) != 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000637
638 def __cmp__(self, other, context=None):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000639 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000640
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000641 if self._is_special or other._is_special:
642 ans = self._check_nans(other, context)
643 if ans:
644 return 1 # Comparison involving NaN's always reports self > other
645
646 # INF = INF
647 return cmp(self._isinfinity(), other._isinfinity())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000648
649 if not self and not other:
650 return 0 #If both 0, sign comparison isn't certain.
651
652 #If different signs, neg one is less
653 if other._sign < self._sign:
654 return -1
655 if self._sign < other._sign:
656 return 1
657
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000658 self_adjusted = self.adjusted()
659 other_adjusted = other.adjusted()
660 if self_adjusted == other_adjusted and \
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000661 self._int + (0,)*(self._exp - other._exp) == \
662 other._int + (0,)*(other._exp - self._exp):
663 return 0 #equal, except in precision. ([0]*(-x) = [])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000664 elif self_adjusted > other_adjusted and self._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000665 return (-1)**self._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000666 elif self_adjusted < other_adjusted and other._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000667 return -((-1)**self._sign)
668
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000669 # Need to round, so make sure we have a valid context
670 if context is None:
671 context = getcontext()
672
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000673 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000674 rounding = context._set_rounding(ROUND_UP) #round away from 0
675
676 flags = context._ignore_all_flags()
677 res = self.__sub__(other, context=context)
678
679 context._regard_flags(*flags)
680
681 context.rounding = rounding
682
683 if not res:
684 return 0
685 elif res._sign:
686 return -1
687 return 1
688
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000689 def __eq__(self, other):
690 if not isinstance(other, (Decimal, int, long)):
691 return False
692 return self.__cmp__(other) == 0
693
694 def __ne__(self, other):
695 if not isinstance(other, (Decimal, int, long)):
696 return True
697 return self.__cmp__(other) != 0
698
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000699 def compare(self, other, context=None):
700 """Compares one to another.
701
702 -1 => a < b
703 0 => a = b
704 1 => a > b
705 NaN => one is NaN
706 Like __cmp__, but returns Decimal instances.
707 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000708 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000709
710 #compare(NaN, NaN) = NaN
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000711 if (self._is_special or other and other._is_special):
712 ans = self._check_nans(other, context)
713 if ans:
714 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000715
716 return Decimal(self.__cmp__(other, context))
717
718 def __hash__(self):
719 """x.__hash__() <==> hash(x)"""
720 # Decimal integers must hash the same as the ints
721 # Non-integer decimals are normalized and hashed as strings
722 # Normalization assures that hast(100E-1) == hash(10)
723 i = int(self)
724 if self == Decimal(i):
725 return hash(i)
726 assert self.__nonzero__() # '-0' handled by integer case
727 return hash(str(self.normalize()))
728
729 def as_tuple(self):
730 """Represents the number as a triple tuple.
731
732 To show the internals exactly as they are.
733 """
734 return (self._sign, self._int, self._exp)
735
736 def __repr__(self):
737 """Represents the number as an instance of Decimal."""
738 # Invariant: eval(repr(d)) == d
739 return 'Decimal("%s")' % str(self)
740
741 def __str__(self, eng = 0, context=None):
742 """Return string representation of the number in scientific notation.
743
744 Captures all of the information in the underlying representation.
745 """
746
747 if self._isnan():
748 minus = '-'*self._sign
749 if self._int == (0,):
750 info = ''
751 else:
752 info = ''.join(map(str, self._int))
753 if self._isnan() == 2:
754 return minus + 'sNaN' + info
755 return minus + 'NaN' + info
756 if self._isinfinity():
757 minus = '-'*self._sign
758 return minus + 'Infinity'
759
760 if context is None:
761 context = getcontext()
762
763 tmp = map(str, self._int)
764 numdigits = len(self._int)
765 leftdigits = self._exp + numdigits
766 if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
767 if self._exp < 0 and self._exp >= -6: #short, no need for e/E
768 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
769 return s
770 #exp is closest mult. of 3 >= self._exp
771 exp = ((self._exp - 1)// 3 + 1) * 3
772 if exp != self._exp:
773 s = '0.'+'0'*(exp - self._exp)
774 else:
775 s = '0'
776 if exp != 0:
777 if context.capitals:
778 s += 'E'
779 else:
780 s += 'e'
781 if exp > 0:
782 s += '+' #0.0e+3, not 0.0e3
783 s += str(exp)
784 s = '-'*self._sign + s
785 return s
786 if eng:
787 dotplace = (leftdigits-1)%3+1
788 adjexp = leftdigits -1 - (leftdigits-1)%3
789 else:
790 adjexp = leftdigits-1
791 dotplace = 1
792 if self._exp == 0:
793 pass
794 elif self._exp < 0 and adjexp >= 0:
795 tmp.insert(leftdigits, '.')
796 elif self._exp < 0 and adjexp >= -6:
797 tmp[0:0] = ['0'] * int(-leftdigits)
798 tmp.insert(0, '0.')
799 else:
800 if numdigits > dotplace:
801 tmp.insert(dotplace, '.')
802 elif numdigits < dotplace:
803 tmp.extend(['0']*(dotplace-numdigits))
804 if adjexp:
805 if not context.capitals:
806 tmp.append('e')
807 else:
808 tmp.append('E')
809 if adjexp > 0:
810 tmp.append('+')
811 tmp.append(str(adjexp))
812 if eng:
813 while tmp[0:1] == ['0']:
814 tmp[0:1] = []
815 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
816 tmp[0:0] = ['0']
817 if self._sign:
818 tmp.insert(0, '-')
819
820 return ''.join(tmp)
821
822 def to_eng_string(self, context=None):
823 """Convert to engineering-type string.
824
825 Engineering notation has an exponent which is a multiple of 3, so there
826 are up to 3 digits left of the decimal place.
827
828 Same rules for when in exponential and when as a value as in __str__.
829 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000830 return self.__str__(eng=1, context=context)
831
832 def __neg__(self, context=None):
833 """Returns a copy with the sign switched.
834
835 Rounds, if it has reason.
836 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000837 if self._is_special:
838 ans = self._check_nans(context=context)
839 if ans:
840 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000841
842 if not self:
843 # -Decimal('0') is Decimal('0'), not Decimal('-0')
844 sign = 0
845 elif self._sign:
846 sign = 0
847 else:
848 sign = 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000849
850 if context is None:
851 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000852 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000853 return Decimal((sign, self._int, self._exp))._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000854 return Decimal( (sign, self._int, self._exp))
855
856 def __pos__(self, context=None):
857 """Returns a copy, unless it is a sNaN.
858
859 Rounds the number (if more then precision digits)
860 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000861 if self._is_special:
862 ans = self._check_nans(context=context)
863 if ans:
864 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000865
866 sign = self._sign
867 if not self:
868 # + (-0) = 0
869 sign = 0
870
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000871 if context is None:
872 context = getcontext()
873
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000874 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000875 ans = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000876 else:
877 ans = Decimal(self)
878 ans._sign = sign
879 return ans
880
881 def __abs__(self, round=1, context=None):
882 """Returns the absolute value of self.
883
884 If the second argument is 0, do not round.
885 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000886 if self._is_special:
887 ans = self._check_nans(context=context)
888 if ans:
889 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000890
891 if not round:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000892 if context is None:
893 context = getcontext()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000894 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000895 context._set_rounding_decision(NEVER_ROUND)
896
897 if self._sign:
898 ans = self.__neg__(context=context)
899 else:
900 ans = self.__pos__(context=context)
901
902 return ans
903
904 def __add__(self, other, context=None):
905 """Returns self + other.
906
907 -INF + INF (or the reverse) cause InvalidOperation errors.
908 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000909 other = _convert_other(other)
910
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000911 if context is None:
912 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000913
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000914 if self._is_special or other._is_special:
915 ans = self._check_nans(other, context)
916 if ans:
917 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000918
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000919 if self._isinfinity():
920 #If both INF, same sign => same as both, opposite => error.
921 if self._sign != other._sign and other._isinfinity():
922 return context._raise_error(InvalidOperation, '-INF + INF')
923 return Decimal(self)
924 if other._isinfinity():
925 return Decimal(other) #Can't both be infinity here
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000926
927 shouldround = context._rounding_decision == ALWAYS_ROUND
928
929 exp = min(self._exp, other._exp)
930 negativezero = 0
931 if context.rounding == ROUND_FLOOR and self._sign != other._sign:
932 #If the answer is 0, the sign should be negative, in this case.
933 negativezero = 1
934
935 if not self and not other:
936 sign = min(self._sign, other._sign)
937 if negativezero:
938 sign = 1
939 return Decimal( (sign, (0,), exp))
940 if not self:
Facundo Batista99b55482004-10-26 23:38:46 +0000941 exp = max(exp, other._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000942 ans = other._rescale(exp, watchexp=0, context=context)
943 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000944 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000945 return ans
946 if not other:
Facundo Batista99b55482004-10-26 23:38:46 +0000947 exp = max(exp, self._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000948 ans = self._rescale(exp, watchexp=0, context=context)
949 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000950 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000951 return ans
952
953 op1 = _WorkRep(self)
954 op2 = _WorkRep(other)
955 op1, op2 = _normalize(op1, op2, shouldround, context.prec)
956
957 result = _WorkRep()
958
959 if op1.sign != op2.sign:
960 diff = cmp(abs(op1), abs(op2))
961 # Equal and opposite
962 if diff == 0:
963 if exp < context.Etiny():
964 exp = context.Etiny()
965 context._raise_error(Clamped)
966 return Decimal((negativezero, (0,), exp))
967 if diff < 0:
968 op1, op2 = op2, op1
969 #OK, now abs(op1) > abs(op2)
970 if op1.sign == -1:
971 result.sign = -1
972 op1.sign, op2.sign = op2.sign, op1.sign
973 else:
974 result.sign = 1
975 #So we know the sign, and op1 > 0.
976 elif op1.sign == -1:
977 result.sign = -1
978 op1.sign, op2.sign = (1, 1)
979 else:
980 result.sign = 1
981 #Now, op1 > abs(op2) > 0
982
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000983 if op2.sign == 1:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000984 result.int = op1.int + op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000985 else:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000986 result.int = op1.int - op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000987
988 result.exp = op1.exp
989 ans = Decimal(result)
990 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000991 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000992 return ans
993
994 __radd__ = __add__
995
996 def __sub__(self, other, context=None):
997 """Return self + (-other)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000998 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000999
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001000 if self._is_special or other._is_special:
1001 ans = self._check_nans(other, context=context)
1002 if ans:
1003 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001004
1005 # -Decimal(0) = Decimal(0), which we don't want since
1006 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
1007 # so we change the sign directly to a copy
1008 tmp = Decimal(other)
1009 tmp._sign = 1-tmp._sign
1010
1011 return self.__add__(tmp, context=context)
1012
1013 def __rsub__(self, other, context=None):
1014 """Return other + (-self)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001015 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001016
1017 tmp = Decimal(self)
1018 tmp._sign = 1 - tmp._sign
1019 return other.__add__(tmp, context=context)
1020
1021 def _increment(self, round=1, context=None):
1022 """Special case of add, adding 1eExponent
1023
1024 Since it is common, (rounding, for example) this adds
1025 (sign)*one E self._exp to the number more efficiently than add.
1026
1027 For example:
1028 Decimal('5.624e10')._increment() == Decimal('5.625e10')
1029 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001030 if self._is_special:
1031 ans = self._check_nans(context=context)
1032 if ans:
1033 return ans
1034
1035 return Decimal(self) # Must be infinite, and incrementing makes no difference
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001036
1037 L = list(self._int)
1038 L[-1] += 1
1039 spot = len(L)-1
1040 while L[spot] == 10:
1041 L[spot] = 0
1042 if spot == 0:
1043 L[0:0] = [1]
1044 break
1045 L[spot-1] += 1
1046 spot -= 1
1047 ans = Decimal((self._sign, L, self._exp))
1048
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001049 if context is None:
1050 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001051 if round and context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001052 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001053 return ans
1054
1055 def __mul__(self, other, context=None):
1056 """Return self * other.
1057
1058 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1059 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001060 other = _convert_other(other)
1061
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001062 if context is None:
1063 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001064
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001065 resultsign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001066
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001067 if self._is_special or other._is_special:
1068 ans = self._check_nans(other, context)
1069 if ans:
1070 return ans
1071
1072 if self._isinfinity():
1073 if not other:
1074 return context._raise_error(InvalidOperation, '(+-)INF * 0')
1075 return Infsign[resultsign]
1076
1077 if other._isinfinity():
1078 if not self:
1079 return context._raise_error(InvalidOperation, '0 * (+-)INF')
1080 return Infsign[resultsign]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001081
1082 resultexp = self._exp + other._exp
1083 shouldround = context._rounding_decision == ALWAYS_ROUND
1084
1085 # Special case for multiplying by zero
1086 if not self or not other:
1087 ans = Decimal((resultsign, (0,), resultexp))
1088 if shouldround:
1089 #Fixing in case the exponent is out of bounds
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001090 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001091 return ans
1092
1093 # Special case for multiplying by power of 10
1094 if self._int == (1,):
1095 ans = Decimal((resultsign, other._int, resultexp))
1096 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001097 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001098 return ans
1099 if other._int == (1,):
1100 ans = Decimal((resultsign, self._int, resultexp))
1101 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001102 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001103 return ans
1104
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001105 op1 = _WorkRep(self)
1106 op2 = _WorkRep(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001107
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001108 ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001109 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001110 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001111
1112 return ans
1113 __rmul__ = __mul__
1114
1115 def __div__(self, other, context=None):
1116 """Return self / other."""
1117 return self._divide(other, context=context)
1118 __truediv__ = __div__
1119
1120 def _divide(self, other, divmod = 0, context=None):
1121 """Return a / b, to context.prec precision.
1122
1123 divmod:
1124 0 => true division
1125 1 => (a //b, a%b)
1126 2 => a //b
1127 3 => a%b
1128
1129 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1130 computing the other value are not raised.
1131 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001132 other = _convert_other(other)
1133
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001134 if context is None:
1135 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001136
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001137 sign = self._sign ^ other._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001138
1139 if self._is_special or other._is_special:
1140 ans = self._check_nans(other, context)
1141 if ans:
1142 if divmod:
1143 return (ans, ans)
1144 return ans
1145
1146 if self._isinfinity() and other._isinfinity():
1147 if divmod:
1148 return (context._raise_error(InvalidOperation,
1149 '(+-)INF // (+-)INF'),
1150 context._raise_error(InvalidOperation,
1151 '(+-)INF % (+-)INF'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001152 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001153
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001154 if self._isinfinity():
1155 if divmod == 1:
1156 return (Infsign[sign],
1157 context._raise_error(InvalidOperation, 'INF % x'))
1158 elif divmod == 2:
1159 return (Infsign[sign], NaN)
1160 elif divmod == 3:
1161 return (Infsign[sign],
1162 context._raise_error(InvalidOperation, 'INF % x'))
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001163 return Infsign[sign]
1164
1165 if other._isinfinity():
1166 if divmod:
1167 return (Decimal((sign, (0,), 0)), Decimal(self))
1168 context._raise_error(Clamped, 'Division by infinity')
1169 return Decimal((sign, (0,), context.Etiny()))
1170
1171 # Special cases for zeroes
1172 if not self and not other:
1173 if divmod:
1174 return context._raise_error(DivisionUndefined, '0 / 0', 1)
1175 return context._raise_error(DivisionUndefined, '0 / 0')
1176
1177 if not self:
1178 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001179 otherside = Decimal(self)
1180 otherside._exp = min(self._exp, other._exp)
1181 return (Decimal((sign, (0,), 0)), otherside)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001182 exp = self._exp - other._exp
1183 if exp < context.Etiny():
1184 exp = context.Etiny()
1185 context._raise_error(Clamped, '0e-x / y')
1186 if exp > context.Emax:
1187 exp = context.Emax
1188 context._raise_error(Clamped, '0e+x / y')
1189 return Decimal( (sign, (0,), exp) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001190
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001191 if not other:
1192 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001193 return context._raise_error(DivisionByZero, 'divmod(x,0)',
1194 sign, 1)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001195 return context._raise_error(DivisionByZero, 'x / 0', sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001196
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001197 #OK, so neither = 0, INF or NaN
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001198
1199 shouldround = context._rounding_decision == ALWAYS_ROUND
1200
1201 #If we're dividing into ints, and self < other, stop.
1202 #self.__abs__(0) does not round.
1203 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
1204
1205 if divmod == 1 or divmod == 3:
1206 exp = min(self._exp, other._exp)
1207 ans2 = self._rescale(exp, context=context, watchexp=0)
1208 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001209 ans2 = ans2._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001210 return (Decimal( (sign, (0,), 0) ),
1211 ans2)
1212
1213 elif divmod == 2:
1214 #Don't round the mod part, if we don't need it.
1215 return (Decimal( (sign, (0,), 0) ), Decimal(self))
1216
1217 if sign:
1218 sign = -1
1219 else:
1220 sign = 1
1221 adjust = 0
1222 op1 = _WorkRep(self)
1223 op2 = _WorkRep(other)
1224 op1, op2, adjust = _adjust_coefficients(op1, op2)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001225 res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001226 if divmod and res.exp > context.prec + 1:
1227 return context._raise_error(DivisionImpossible)
1228
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001229 prec_limit = 10 ** context.prec
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001230 while 1:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001231 while op2.int <= op1.int:
1232 res.int += 1
1233 op1.int -= op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001234 if res.exp == 0 and divmod:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001235 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001236 return context._raise_error(DivisionImpossible)
1237 otherside = Decimal(op1)
1238 frozen = context._ignore_all_flags()
1239
1240 exp = min(self._exp, other._exp)
1241 otherside = otherside._rescale(exp, context=context,
1242 watchexp=0)
1243 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 not self:
1425 return 0
1426 sign = '-'*self._sign
1427 if self._exp >= 0:
1428 s = sign + ''.join(map(str, self._int)) + '0'*self._exp
1429 return int(s)
1430 s = sign + ''.join(map(str, self._int))[:self._exp]
1431 return int(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')
2772 # sign: -1 None 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
2781 if isinstance(value, Decimal):
2782 if value._sign:
2783 self.sign = -1
2784 else:
2785 self.sign = 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002786 cum = 0
2787 for digit in value._int:
2788 cum = cum * 10 + digit
2789 self.int = cum
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002790 self.exp = value._exp
2791 if isinstance(value, tuple):
2792 self.sign = value[0]
2793 self.int = value[1]
2794 self.exp = value[2]
2795
2796 def __repr__(self):
2797 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2798
2799 __str__ = __repr__
2800
2801 def __neg__(self):
2802 if self.sign == 1:
2803 return _WorkRep( (-1, self.int, self.exp) )
2804 else:
2805 return _WorkRep( (1, self.int, self.exp) )
2806
2807 def __abs__(self):
2808 if self.sign == -1:
2809 return -self
2810 else:
2811 return self
2812
2813 def __cmp__(self, other):
2814 if self.exp != other.exp:
2815 raise ValueError("Operands not normalized: %r, %r" % (self, other))
2816 if self.sign != other.sign:
2817 if self.sign == -1:
2818 return -1
2819 else:
2820 return 1
2821 if self.sign == -1:
2822 direction = -1
2823 else:
2824 direction = 1
2825 int1 = self.int
2826 int2 = other.int
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002827 if int1 > int2:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002828 return direction * 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002829 if int1 < int2:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002830 return direction * -1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002831 return 0
2832
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002833
2834
2835def _normalize(op1, op2, shouldround = 0, prec = 0):
2836 """Normalizes op1, op2 to have the same exp and length of coefficient.
2837
2838 Done during addition.
2839 """
2840 # Yes, the exponent is a long, but the difference between exponents
2841 # must be an int-- otherwise you'd get a big memory problem.
2842 numdigits = int(op1.exp - op2.exp)
2843 if numdigits < 0:
2844 numdigits = -numdigits
2845 tmp = op2
2846 other = op1
2847 else:
2848 tmp = op1
2849 other = op2
2850
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002851
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002852 if shouldround and numdigits > prec + 1:
2853 # Big difference in exponents - check the adjusted exponents
2854 tmp_len = len(str(tmp.int))
2855 other_len = len(str(other.int))
2856 if numdigits > (other_len + prec + 1 - tmp_len):
2857 # If the difference in adjusted exps is > prec+1, we know
2858 # other is insignificant, so might as well put a 1 after the precision.
2859 # (since this is only for addition.) Also stops use of massive longs.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002860
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002861 extend = prec + 2 - tmp_len
2862 if extend <= 0:
2863 extend = 1
2864 tmp.int *= 10 ** extend
2865 tmp.exp -= extend
2866 other.int = 1
2867 other.exp = tmp.exp
2868 return op1, op2
2869
2870 tmp.int *= 10 ** numdigits
2871 tmp.exp -= numdigits
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002872 return op1, op2
2873
2874def _adjust_coefficients(op1, op2):
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002875 """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002876
2877 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2878
2879 Used on _WorkRep instances during division.
2880 """
2881 adjust = 0
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002882 #If op1 is smaller, make it larger
2883 while op2.int > op1.int:
2884 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002885 op1.exp -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002886 adjust += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002887
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002888 #If op2 is too small, make it larger
2889 while op1.int >= (10 * op2.int):
2890 op2.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002891 op2.exp -= 1
2892 adjust -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002893
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002894 return op1, op2, adjust
2895
2896##### Helper Functions ########################################
2897
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002898def _convert_other(other):
2899 """Convert other to Decimal.
2900
2901 Verifies that it's ok to use in an implicit construction.
2902 """
2903 if isinstance(other, Decimal):
2904 return other
2905 if isinstance(other, (int, long)):
2906 return Decimal(other)
2907
2908 raise TypeError, "You can interact Decimal only with int, long or Decimal data types."
2909
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002910_infinity_map = {
2911 'inf' : 1,
2912 'infinity' : 1,
2913 '+inf' : 1,
2914 '+infinity' : 1,
2915 '-inf' : -1,
2916 '-infinity' : -1
2917}
2918
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002919def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002920 """Determines whether a string or float is infinity.
2921
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002922 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002923 """
2924 num = str(num).lower()
2925 return _infinity_map.get(num, 0)
2926
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002927def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002928 """Determines whether a string or float is NaN
2929
2930 (1, sign, diagnostic info as string) => NaN
2931 (2, sign, diagnostic info as string) => sNaN
2932 0 => not a NaN
2933 """
2934 num = str(num).lower()
2935 if not num:
2936 return 0
2937
2938 #get the sign, get rid of trailing [+-]
2939 sign = 0
2940 if num[0] == '+':
2941 num = num[1:]
2942 elif num[0] == '-': #elif avoids '+-nan'
2943 num = num[1:]
2944 sign = 1
2945
2946 if num.startswith('nan'):
2947 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
2948 return 0
2949 return (1, sign, num[3:].lstrip('0'))
2950 if num.startswith('snan'):
2951 if len(num) > 4 and not num[4:].isdigit():
2952 return 0
2953 return (2, sign, num[4:].lstrip('0'))
2954 return 0
2955
2956
2957##### Setup Specific Contexts ################################
2958
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002959# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00002960# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002961
2962DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002963 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002964 traps=[DivisionByZero, Overflow, InvalidOperation],
2965 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002966 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00002967 Emax=999999999,
2968 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002969 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002970)
2971
2972# Pre-made alternate contexts offered by the specification
2973# Don't change these; the user should be able to select these
2974# contexts and be able to reproduce results from other implementations
2975# of the spec.
2976
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002977BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002978 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002979 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
2980 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002981)
2982
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002983ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002984 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002985 traps=[],
2986 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002987)
2988
2989
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002990##### Useful Constants (internal use only) ####################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002991
2992#Reusable defaults
2993Inf = Decimal('Inf')
2994negInf = Decimal('-Inf')
2995
2996#Infsign[sign] is infinity w/ that sign
2997Infsign = (Inf, negInf)
2998
2999NaN = Decimal('NaN')
3000
3001
3002##### crud for parsing strings #################################
3003import re
3004
3005# There's an optional sign at the start, and an optional exponent
3006# at the end. The exponent has an optional sign and at least one
3007# digit. In between, must have either at least one digit followed
3008# by an optional fraction, or a decimal point followed by at least
3009# one digit. Yuck.
3010
3011_parser = re.compile(r"""
3012# \s*
3013 (?P<sign>[-+])?
3014 (
3015 (?P<int>\d+) (\. (?P<frac>\d*))?
3016 |
3017 \. (?P<onlyfrac>\d+)
3018 )
3019 ([eE](?P<exp>[-+]? \d+))?
3020# \s*
3021 $
3022""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
3023
3024del re
3025
3026# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
3027
3028def _string2exact(s):
3029 m = _parser(s)
3030 if m is None:
3031 raise ValueError("invalid literal for Decimal: %r" % s)
3032
3033 if m.group('sign') == "-":
3034 sign = 1
3035 else:
3036 sign = 0
3037
3038 exp = m.group('exp')
3039 if exp is None:
3040 exp = 0
3041 else:
3042 exp = int(exp)
3043
3044 intpart = m.group('int')
3045 if intpart is None:
3046 intpart = ""
3047 fracpart = m.group('onlyfrac')
3048 else:
3049 fracpart = m.group('frac')
3050 if fracpart is None:
3051 fracpart = ""
3052
3053 exp -= len(fracpart)
3054
3055 mantissa = intpart + fracpart
3056 tmp = map(int, mantissa)
3057 backup = tmp
3058 while tmp and tmp[0] == 0:
3059 del tmp[0]
3060
3061 # It's a zero
3062 if not tmp:
3063 if backup:
3064 return (sign, tuple(backup), exp)
3065 return (sign, (0,), exp)
3066 mantissa = tuple(tmp)
3067
3068 return (sign, mantissa, exp)
3069
3070
3071if __name__ == '__main__':
3072 import doctest, sys
3073 doctest.testmod(sys.modules[__name__])