blob: 6ffbd1847007bb62915f1ad4db951b83daac3a85 [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):
Raymond Hettinger17931de2004-10-27 06:21:46 +0000480 self._sign = value.sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000481 self._int = tuple(map(int, str(value.int)))
482 self._exp = int(value.exp)
483 return self
484
485 # From another decimal
486 if isinstance(value, Decimal):
487 self._exp = value._exp
488 self._sign = value._sign
489 self._int = value._int
490 self._is_special = value._is_special
491 return self
492
493 # From an integer
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000494 if isinstance(value, (int,long)):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000495 if value >= 0:
496 self._sign = 0
497 else:
498 self._sign = 1
499 self._exp = 0
500 self._int = tuple(map(int, str(abs(value))))
501 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000502
503 # tuple/list conversion (possibly from as_tuple())
504 if isinstance(value, (list,tuple)):
505 if len(value) != 3:
506 raise ValueError, 'Invalid arguments'
507 if value[0] not in [0,1]:
508 raise ValueError, 'Invalid sign'
509 for digit in value[1]:
510 if not isinstance(digit, (int,long)) or digit < 0:
511 raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
512
513 self._sign = value[0]
514 self._int = tuple(value[1])
515 if value[2] in ('F','n','N'):
516 self._exp = value[2]
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000517 self._is_special = True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000518 else:
519 self._exp = int(value[2])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000520 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000521
Raymond Hettingerbf440692004-07-10 14:14:37 +0000522 if isinstance(value, float):
523 raise TypeError("Cannot convert float to Decimal. " +
524 "First convert the float to a string")
525
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000526 # Other argument types may require the context during interpretation
527 if context is None:
528 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000529
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000530 # From a string
531 # REs insist on real strings, so we can too.
532 if isinstance(value, basestring):
533 if _isinfinity(value):
534 self._exp = 'F'
535 self._int = (0,)
536 self._is_special = True
537 if _isinfinity(value) == 1:
538 self._sign = 0
539 else:
540 self._sign = 1
541 return self
542 if _isnan(value):
543 sig, sign, diag = _isnan(value)
544 self._is_special = True
545 if len(diag) > context.prec: #Diagnostic info too long
546 self._sign, self._int, self._exp = \
547 context._raise_error(ConversionSyntax)
548 return self
549 if sig == 1:
550 self._exp = 'n' #qNaN
551 else: #sig == 2
552 self._exp = 'N' #sNaN
553 self._sign = sign
554 self._int = tuple(map(int, diag)) #Diagnostic info
555 return self
556 try:
557 self._sign, self._int, self._exp = _string2exact(value)
558 except ValueError:
559 self._is_special = True
560 self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
561 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000562
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000563 raise TypeError("Cannot convert %r to Decimal" % value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000564
565 def _isnan(self):
566 """Returns whether the number is not actually one.
567
568 0 if a number
569 1 if NaN
570 2 if sNaN
571 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000572 if self._is_special:
573 exp = self._exp
574 if exp == 'n':
575 return 1
576 elif exp == 'N':
577 return 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000578 return 0
579
580 def _isinfinity(self):
581 """Returns whether the number is infinite
582
583 0 if finite or not a number
584 1 if +INF
585 -1 if -INF
586 """
587 if self._exp == 'F':
588 if self._sign:
589 return -1
590 return 1
591 return 0
592
593 def _check_nans(self, other = None, context=None):
594 """Returns whether the number is not actually one.
595
596 if self, other are sNaN, signal
597 if self, other are NaN return nan
598 return 0
599
600 Done before operations.
601 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000602
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000603 self_is_nan = self._isnan()
604 if other is None:
605 other_is_nan = False
606 else:
607 other_is_nan = other._isnan()
608
609 if self_is_nan or other_is_nan:
610 if context is None:
611 context = getcontext()
612
613 if self_is_nan == 2:
614 return context._raise_error(InvalidOperation, 'sNaN',
615 1, self)
616 if other_is_nan == 2:
617 return context._raise_error(InvalidOperation, 'sNaN',
618 1, other)
619 if self_is_nan:
620 return self
621
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000622 return other
623 return 0
624
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000625 def __nonzero__(self):
626 """Is the number non-zero?
627
628 0 if self == 0
629 1 if self != 0
630 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000631 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000632 return 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000633 return sum(self._int) != 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000634
635 def __cmp__(self, other, context=None):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000636 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000637
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000638 if self._is_special or other._is_special:
639 ans = self._check_nans(other, context)
640 if ans:
641 return 1 # Comparison involving NaN's always reports self > other
642
643 # INF = INF
644 return cmp(self._isinfinity(), other._isinfinity())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000645
646 if not self and not other:
647 return 0 #If both 0, sign comparison isn't certain.
648
649 #If different signs, neg one is less
650 if other._sign < self._sign:
651 return -1
652 if self._sign < other._sign:
653 return 1
654
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000655 self_adjusted = self.adjusted()
656 other_adjusted = other.adjusted()
657 if self_adjusted == other_adjusted and \
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000658 self._int + (0,)*(self._exp - other._exp) == \
659 other._int + (0,)*(other._exp - self._exp):
660 return 0 #equal, except in precision. ([0]*(-x) = [])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000661 elif self_adjusted > other_adjusted and self._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000662 return (-1)**self._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000663 elif self_adjusted < other_adjusted and other._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000664 return -((-1)**self._sign)
665
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000666 # Need to round, so make sure we have a valid context
667 if context is None:
668 context = getcontext()
669
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000670 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000671 rounding = context._set_rounding(ROUND_UP) #round away from 0
672
673 flags = context._ignore_all_flags()
674 res = self.__sub__(other, context=context)
675
676 context._regard_flags(*flags)
677
678 context.rounding = rounding
679
680 if not res:
681 return 0
682 elif res._sign:
683 return -1
684 return 1
685
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000686 def __eq__(self, other):
687 if not isinstance(other, (Decimal, int, long)):
688 return False
689 return self.__cmp__(other) == 0
690
691 def __ne__(self, other):
692 if not isinstance(other, (Decimal, int, long)):
693 return True
694 return self.__cmp__(other) != 0
695
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000696 def compare(self, other, context=None):
697 """Compares one to another.
698
699 -1 => a < b
700 0 => a = b
701 1 => a > b
702 NaN => one is NaN
703 Like __cmp__, but returns Decimal instances.
704 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000705 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000706
707 #compare(NaN, NaN) = NaN
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000708 if (self._is_special or other and other._is_special):
709 ans = self._check_nans(other, context)
710 if ans:
711 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000712
713 return Decimal(self.__cmp__(other, context))
714
715 def __hash__(self):
716 """x.__hash__() <==> hash(x)"""
717 # Decimal integers must hash the same as the ints
718 # Non-integer decimals are normalized and hashed as strings
719 # Normalization assures that hast(100E-1) == hash(10)
720 i = int(self)
721 if self == Decimal(i):
722 return hash(i)
723 assert self.__nonzero__() # '-0' handled by integer case
724 return hash(str(self.normalize()))
725
726 def as_tuple(self):
727 """Represents the number as a triple tuple.
728
729 To show the internals exactly as they are.
730 """
731 return (self._sign, self._int, self._exp)
732
733 def __repr__(self):
734 """Represents the number as an instance of Decimal."""
735 # Invariant: eval(repr(d)) == d
736 return 'Decimal("%s")' % str(self)
737
738 def __str__(self, eng = 0, context=None):
739 """Return string representation of the number in scientific notation.
740
741 Captures all of the information in the underlying representation.
742 """
743
744 if self._isnan():
745 minus = '-'*self._sign
746 if self._int == (0,):
747 info = ''
748 else:
749 info = ''.join(map(str, self._int))
750 if self._isnan() == 2:
751 return minus + 'sNaN' + info
752 return minus + 'NaN' + info
753 if self._isinfinity():
754 minus = '-'*self._sign
755 return minus + 'Infinity'
756
757 if context is None:
758 context = getcontext()
759
760 tmp = map(str, self._int)
761 numdigits = len(self._int)
762 leftdigits = self._exp + numdigits
763 if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
764 if self._exp < 0 and self._exp >= -6: #short, no need for e/E
765 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
766 return s
767 #exp is closest mult. of 3 >= self._exp
768 exp = ((self._exp - 1)// 3 + 1) * 3
769 if exp != self._exp:
770 s = '0.'+'0'*(exp - self._exp)
771 else:
772 s = '0'
773 if exp != 0:
774 if context.capitals:
775 s += 'E'
776 else:
777 s += 'e'
778 if exp > 0:
779 s += '+' #0.0e+3, not 0.0e3
780 s += str(exp)
781 s = '-'*self._sign + s
782 return s
783 if eng:
784 dotplace = (leftdigits-1)%3+1
785 adjexp = leftdigits -1 - (leftdigits-1)%3
786 else:
787 adjexp = leftdigits-1
788 dotplace = 1
789 if self._exp == 0:
790 pass
791 elif self._exp < 0 and adjexp >= 0:
792 tmp.insert(leftdigits, '.')
793 elif self._exp < 0 and adjexp >= -6:
794 tmp[0:0] = ['0'] * int(-leftdigits)
795 tmp.insert(0, '0.')
796 else:
797 if numdigits > dotplace:
798 tmp.insert(dotplace, '.')
799 elif numdigits < dotplace:
800 tmp.extend(['0']*(dotplace-numdigits))
801 if adjexp:
802 if not context.capitals:
803 tmp.append('e')
804 else:
805 tmp.append('E')
806 if adjexp > 0:
807 tmp.append('+')
808 tmp.append(str(adjexp))
809 if eng:
810 while tmp[0:1] == ['0']:
811 tmp[0:1] = []
812 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
813 tmp[0:0] = ['0']
814 if self._sign:
815 tmp.insert(0, '-')
816
817 return ''.join(tmp)
818
819 def to_eng_string(self, context=None):
820 """Convert to engineering-type string.
821
822 Engineering notation has an exponent which is a multiple of 3, so there
823 are up to 3 digits left of the decimal place.
824
825 Same rules for when in exponential and when as a value as in __str__.
826 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000827 return self.__str__(eng=1, context=context)
828
829 def __neg__(self, context=None):
830 """Returns a copy with the sign switched.
831
832 Rounds, if it has reason.
833 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000834 if self._is_special:
835 ans = self._check_nans(context=context)
836 if ans:
837 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000838
839 if not self:
840 # -Decimal('0') is Decimal('0'), not Decimal('-0')
841 sign = 0
842 elif self._sign:
843 sign = 0
844 else:
845 sign = 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000846
847 if context is None:
848 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000849 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000850 return Decimal((sign, self._int, self._exp))._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000851 return Decimal( (sign, self._int, self._exp))
852
853 def __pos__(self, context=None):
854 """Returns a copy, unless it is a sNaN.
855
856 Rounds the number (if more then precision digits)
857 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000858 if self._is_special:
859 ans = self._check_nans(context=context)
860 if ans:
861 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000862
863 sign = self._sign
864 if not self:
865 # + (-0) = 0
866 sign = 0
867
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000868 if context is None:
869 context = getcontext()
870
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000871 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000872 ans = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000873 else:
874 ans = Decimal(self)
875 ans._sign = sign
876 return ans
877
878 def __abs__(self, round=1, context=None):
879 """Returns the absolute value of self.
880
881 If the second argument is 0, do not round.
882 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000883 if self._is_special:
884 ans = self._check_nans(context=context)
885 if ans:
886 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000887
888 if not round:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000889 if context is None:
890 context = getcontext()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000891 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000892 context._set_rounding_decision(NEVER_ROUND)
893
894 if self._sign:
895 ans = self.__neg__(context=context)
896 else:
897 ans = self.__pos__(context=context)
898
899 return ans
900
901 def __add__(self, other, context=None):
902 """Returns self + other.
903
904 -INF + INF (or the reverse) cause InvalidOperation errors.
905 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000906 other = _convert_other(other)
907
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000908 if context is None:
909 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000910
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000911 if self._is_special or other._is_special:
912 ans = self._check_nans(other, context)
913 if ans:
914 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000915
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000916 if self._isinfinity():
917 #If both INF, same sign => same as both, opposite => error.
918 if self._sign != other._sign and other._isinfinity():
919 return context._raise_error(InvalidOperation, '-INF + INF')
920 return Decimal(self)
921 if other._isinfinity():
922 return Decimal(other) #Can't both be infinity here
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000923
924 shouldround = context._rounding_decision == ALWAYS_ROUND
925
926 exp = min(self._exp, other._exp)
927 negativezero = 0
928 if context.rounding == ROUND_FLOOR and self._sign != other._sign:
929 #If the answer is 0, the sign should be negative, in this case.
930 negativezero = 1
931
932 if not self and not other:
933 sign = min(self._sign, other._sign)
934 if negativezero:
935 sign = 1
936 return Decimal( (sign, (0,), exp))
937 if not self:
Facundo Batista99b55482004-10-26 23:38:46 +0000938 exp = max(exp, other._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000939 ans = other._rescale(exp, watchexp=0, context=context)
940 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000941 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000942 return ans
943 if not other:
Facundo Batista99b55482004-10-26 23:38:46 +0000944 exp = max(exp, self._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000945 ans = self._rescale(exp, watchexp=0, context=context)
946 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000947 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000948 return ans
949
950 op1 = _WorkRep(self)
951 op2 = _WorkRep(other)
952 op1, op2 = _normalize(op1, op2, shouldround, context.prec)
953
954 result = _WorkRep()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000955 if op1.sign != op2.sign:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000956 # Equal and opposite
Raymond Hettinger17931de2004-10-27 06:21:46 +0000957 if op1.int == op2.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000958 if exp < context.Etiny():
959 exp = context.Etiny()
960 context._raise_error(Clamped)
961 return Decimal((negativezero, (0,), exp))
Raymond Hettinger17931de2004-10-27 06:21:46 +0000962 if op1.int < op2.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000963 op1, op2 = op2, op1
964 #OK, now abs(op1) > abs(op2)
Raymond Hettinger17931de2004-10-27 06:21:46 +0000965 if op1.sign == 1:
966 result.sign = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000967 op1.sign, op2.sign = op2.sign, op1.sign
968 else:
Raymond Hettinger17931de2004-10-27 06:21:46 +0000969 result.sign = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000970 #So we know the sign, and op1 > 0.
Raymond Hettinger17931de2004-10-27 06:21:46 +0000971 elif op1.sign == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000972 result.sign = 1
Raymond Hettinger17931de2004-10-27 06:21:46 +0000973 op1.sign, op2.sign = (0, 0)
974 else:
975 result.sign = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000976 #Now, op1 > abs(op2) > 0
977
Raymond Hettinger17931de2004-10-27 06:21:46 +0000978 if op2.sign == 0:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000979 result.int = op1.int + op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000980 else:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000981 result.int = op1.int - op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000982
983 result.exp = op1.exp
984 ans = Decimal(result)
985 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000986 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000987 return ans
988
989 __radd__ = __add__
990
991 def __sub__(self, other, context=None):
992 """Return self + (-other)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000993 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000994
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000995 if self._is_special or other._is_special:
996 ans = self._check_nans(other, context=context)
997 if ans:
998 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000999
1000 # -Decimal(0) = Decimal(0), which we don't want since
1001 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
1002 # so we change the sign directly to a copy
1003 tmp = Decimal(other)
1004 tmp._sign = 1-tmp._sign
1005
1006 return self.__add__(tmp, context=context)
1007
1008 def __rsub__(self, other, context=None):
1009 """Return other + (-self)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001010 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001011
1012 tmp = Decimal(self)
1013 tmp._sign = 1 - tmp._sign
1014 return other.__add__(tmp, context=context)
1015
1016 def _increment(self, round=1, context=None):
1017 """Special case of add, adding 1eExponent
1018
1019 Since it is common, (rounding, for example) this adds
1020 (sign)*one E self._exp to the number more efficiently than add.
1021
1022 For example:
1023 Decimal('5.624e10')._increment() == Decimal('5.625e10')
1024 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001025 if self._is_special:
1026 ans = self._check_nans(context=context)
1027 if ans:
1028 return ans
1029
1030 return Decimal(self) # Must be infinite, and incrementing makes no difference
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001031
1032 L = list(self._int)
1033 L[-1] += 1
1034 spot = len(L)-1
1035 while L[spot] == 10:
1036 L[spot] = 0
1037 if spot == 0:
1038 L[0:0] = [1]
1039 break
1040 L[spot-1] += 1
1041 spot -= 1
1042 ans = Decimal((self._sign, L, self._exp))
1043
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001044 if context is None:
1045 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001046 if round and context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001047 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001048 return ans
1049
1050 def __mul__(self, other, context=None):
1051 """Return self * other.
1052
1053 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1054 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001055 other = _convert_other(other)
1056
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001057 if context is None:
1058 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001059
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001060 resultsign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001061
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001062 if self._is_special or other._is_special:
1063 ans = self._check_nans(other, context)
1064 if ans:
1065 return ans
1066
1067 if self._isinfinity():
1068 if not other:
1069 return context._raise_error(InvalidOperation, '(+-)INF * 0')
1070 return Infsign[resultsign]
1071
1072 if other._isinfinity():
1073 if not self:
1074 return context._raise_error(InvalidOperation, '0 * (+-)INF')
1075 return Infsign[resultsign]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001076
1077 resultexp = self._exp + other._exp
1078 shouldround = context._rounding_decision == ALWAYS_ROUND
1079
1080 # Special case for multiplying by zero
1081 if not self or not other:
1082 ans = Decimal((resultsign, (0,), resultexp))
1083 if shouldround:
1084 #Fixing in case the exponent is out of bounds
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001085 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001086 return ans
1087
1088 # Special case for multiplying by power of 10
1089 if self._int == (1,):
1090 ans = Decimal((resultsign, other._int, resultexp))
1091 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001092 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001093 return ans
1094 if other._int == (1,):
1095 ans = Decimal((resultsign, self._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
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001100 op1 = _WorkRep(self)
1101 op2 = _WorkRep(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001102
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001103 ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001104 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001105 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001106
1107 return ans
1108 __rmul__ = __mul__
1109
1110 def __div__(self, other, context=None):
1111 """Return self / other."""
1112 return self._divide(other, context=context)
1113 __truediv__ = __div__
1114
1115 def _divide(self, other, divmod = 0, context=None):
1116 """Return a / b, to context.prec precision.
1117
1118 divmod:
1119 0 => true division
1120 1 => (a //b, a%b)
1121 2 => a //b
1122 3 => a%b
1123
1124 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1125 computing the other value are not raised.
1126 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001127 other = _convert_other(other)
1128
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001129 if context is None:
1130 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001131
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001132 sign = self._sign ^ other._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001133
1134 if self._is_special or other._is_special:
1135 ans = self._check_nans(other, context)
1136 if ans:
1137 if divmod:
1138 return (ans, ans)
1139 return ans
1140
1141 if self._isinfinity() and other._isinfinity():
1142 if divmod:
1143 return (context._raise_error(InvalidOperation,
1144 '(+-)INF // (+-)INF'),
1145 context._raise_error(InvalidOperation,
1146 '(+-)INF % (+-)INF'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001147 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001148
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001149 if self._isinfinity():
1150 if divmod == 1:
1151 return (Infsign[sign],
1152 context._raise_error(InvalidOperation, 'INF % x'))
1153 elif divmod == 2:
1154 return (Infsign[sign], NaN)
1155 elif divmod == 3:
1156 return (Infsign[sign],
1157 context._raise_error(InvalidOperation, 'INF % x'))
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001158 return Infsign[sign]
1159
1160 if other._isinfinity():
1161 if divmod:
1162 return (Decimal((sign, (0,), 0)), Decimal(self))
1163 context._raise_error(Clamped, 'Division by infinity')
1164 return Decimal((sign, (0,), context.Etiny()))
1165
1166 # Special cases for zeroes
1167 if not self and not other:
1168 if divmod:
1169 return context._raise_error(DivisionUndefined, '0 / 0', 1)
1170 return context._raise_error(DivisionUndefined, '0 / 0')
1171
1172 if not self:
1173 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001174 otherside = Decimal(self)
1175 otherside._exp = min(self._exp, other._exp)
1176 return (Decimal((sign, (0,), 0)), otherside)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001177 exp = self._exp - other._exp
1178 if exp < context.Etiny():
1179 exp = context.Etiny()
1180 context._raise_error(Clamped, '0e-x / y')
1181 if exp > context.Emax:
1182 exp = context.Emax
1183 context._raise_error(Clamped, '0e+x / y')
1184 return Decimal( (sign, (0,), exp) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001185
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001186 if not other:
1187 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001188 return context._raise_error(DivisionByZero, 'divmod(x,0)',
1189 sign, 1)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001190 return context._raise_error(DivisionByZero, 'x / 0', sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001191
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001192 #OK, so neither = 0, INF or NaN
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001193
1194 shouldround = context._rounding_decision == ALWAYS_ROUND
1195
1196 #If we're dividing into ints, and self < other, stop.
1197 #self.__abs__(0) does not round.
1198 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
1199
1200 if divmod == 1 or divmod == 3:
1201 exp = min(self._exp, other._exp)
1202 ans2 = self._rescale(exp, context=context, watchexp=0)
1203 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001204 ans2 = ans2._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001205 return (Decimal( (sign, (0,), 0) ),
1206 ans2)
1207
1208 elif divmod == 2:
1209 #Don't round the mod part, if we don't need it.
1210 return (Decimal( (sign, (0,), 0) ), Decimal(self))
1211
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001212 op1 = _WorkRep(self)
1213 op2 = _WorkRep(other)
1214 op1, op2, adjust = _adjust_coefficients(op1, op2)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001215 res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001216 if divmod and res.exp > context.prec + 1:
1217 return context._raise_error(DivisionImpossible)
1218
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001219 prec_limit = 10 ** context.prec
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001220 while 1:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001221 while op2.int <= op1.int:
1222 res.int += 1
1223 op1.int -= op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001224 if res.exp == 0 and divmod:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001225 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001226 return context._raise_error(DivisionImpossible)
1227 otherside = Decimal(op1)
1228 frozen = context._ignore_all_flags()
1229
1230 exp = min(self._exp, other._exp)
Raymond Hettinger17931de2004-10-27 06:21:46 +00001231 otherside = otherside._rescale(exp, context=context, watchexp=0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001232 context._regard_flags(*frozen)
1233 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001234 otherside = otherside._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001235 return (Decimal(res), otherside)
1236
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001237 if op1.int == 0 and adjust >= 0 and not divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001238 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001239 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001240 if divmod:
1241 return context._raise_error(DivisionImpossible)
1242 shouldround=1
1243 # Really, the answer is a bit higher, so adding a one to
1244 # the end will make sure the rounding is right.
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001245 if op1.int != 0:
1246 res.int *= 10
1247 res.int += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001248 res.exp -= 1
1249
1250 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001251 res.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001252 res.exp -= 1
1253 adjust += 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001254 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001255 op1.exp -= 1
1256
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001257 if res.exp == 0 and divmod and op2.int > op1.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001258 #Solves an error in precision. Same as a previous block.
1259
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001260 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001261 return context._raise_error(DivisionImpossible)
1262 otherside = Decimal(op1)
1263 frozen = context._ignore_all_flags()
1264
1265 exp = min(self._exp, other._exp)
1266 otherside = otherside._rescale(exp, context=context)
1267
1268 context._regard_flags(*frozen)
1269
1270 return (Decimal(res), otherside)
1271
1272 ans = Decimal(res)
1273 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001274 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001275 return ans
1276
1277 def __rdiv__(self, other, context=None):
1278 """Swaps self/other and returns __div__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001279 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001280 return other.__div__(self, context=context)
1281 __rtruediv__ = __rdiv__
1282
1283 def __divmod__(self, other, context=None):
1284 """
1285 (self // other, self % other)
1286 """
1287 return self._divide(other, 1, context)
1288
1289 def __rdivmod__(self, other, context=None):
1290 """Swaps self/other and returns __divmod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001291 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001292 return other.__divmod__(self, context=context)
1293
1294 def __mod__(self, other, context=None):
1295 """
1296 self % other
1297 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001298 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001299
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001300 if self._is_special or other._is_special:
1301 ans = self._check_nans(other, context)
1302 if ans:
1303 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001304
1305 if self and not other:
1306 return context._raise_error(InvalidOperation, 'x % 0')
1307
1308 return self._divide(other, 3, context)[1]
1309
1310 def __rmod__(self, other, context=None):
1311 """Swaps self/other and returns __mod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001312 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001313 return other.__mod__(self, context=context)
1314
1315 def remainder_near(self, other, context=None):
1316 """
1317 Remainder nearest to 0- abs(remainder-near) <= other/2
1318 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001319 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001320
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001321 if self._is_special or other._is_special:
1322 ans = self._check_nans(other, context)
1323 if ans:
1324 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001325 if self and not other:
1326 return context._raise_error(InvalidOperation, 'x % 0')
1327
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001328 if context is None:
1329 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001330 # If DivisionImpossible causes an error, do not leave Rounded/Inexact
1331 # ignored in the calling function.
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001332 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001333 flags = context._ignore_flags(Rounded, Inexact)
1334 #keep DivisionImpossible flags
1335 (side, r) = self.__divmod__(other, context=context)
1336
1337 if r._isnan():
1338 context._regard_flags(*flags)
1339 return r
1340
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001341 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001342 rounding = context._set_rounding_decision(NEVER_ROUND)
1343
1344 if other._sign:
1345 comparison = other.__div__(Decimal(-2), context=context)
1346 else:
1347 comparison = other.__div__(Decimal(2), context=context)
1348
1349 context._set_rounding_decision(rounding)
1350 context._regard_flags(*flags)
1351
1352 s1, s2 = r._sign, comparison._sign
1353 r._sign, comparison._sign = 0, 0
1354
1355 if r < comparison:
1356 r._sign, comparison._sign = s1, s2
1357 #Get flags now
1358 self.__divmod__(other, context=context)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001359 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001360 r._sign, comparison._sign = s1, s2
1361
1362 rounding = context._set_rounding_decision(NEVER_ROUND)
1363
1364 (side, r) = self.__divmod__(other, context=context)
1365 context._set_rounding_decision(rounding)
1366 if r._isnan():
1367 return r
1368
1369 decrease = not side._iseven()
1370 rounding = context._set_rounding_decision(NEVER_ROUND)
1371 side = side.__abs__(context=context)
1372 context._set_rounding_decision(rounding)
1373
1374 s1, s2 = r._sign, comparison._sign
1375 r._sign, comparison._sign = 0, 0
1376 if r > comparison or decrease and r == comparison:
1377 r._sign, comparison._sign = s1, s2
1378 context.prec += 1
1379 if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
1380 context.prec -= 1
1381 return context._raise_error(DivisionImpossible)[1]
1382 context.prec -= 1
1383 if self._sign == other._sign:
1384 r = r.__sub__(other, context=context)
1385 else:
1386 r = r.__add__(other, context=context)
1387 else:
1388 r._sign, comparison._sign = s1, s2
1389
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001390 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001391
1392 def __floordiv__(self, other, context=None):
1393 """self // other"""
1394 return self._divide(other, 2, context)[0]
1395
1396 def __rfloordiv__(self, other, context=None):
1397 """Swaps self/other and returns __floordiv__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001398 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001399 return other.__floordiv__(self, context=context)
1400
1401 def __float__(self):
1402 """Float representation."""
1403 return float(str(self))
1404
1405 def __int__(self):
1406 """Converts self to a int, truncating if necessary."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001407 if self._is_special:
1408 if self._isnan():
1409 context = getcontext()
1410 return context._raise_error(InvalidContext)
1411 elif self._isinfinity():
1412 raise OverflowError, "Cannot convert infinity to long"
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001413 if not self:
1414 return 0
1415 sign = '-'*self._sign
1416 if self._exp >= 0:
1417 s = sign + ''.join(map(str, self._int)) + '0'*self._exp
1418 return int(s)
1419 s = sign + ''.join(map(str, self._int))[:self._exp]
1420 return int(s)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001421
1422 def __long__(self):
1423 """Converts to a long.
1424
1425 Equivalent to long(int(self))
1426 """
1427 return long(self.__int__())
1428
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001429 def _fix(self, context):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001430 """Round if it is necessary to keep self within prec precision.
1431
1432 Rounds and fixes the exponent. Does not raise on a sNaN.
1433
1434 Arguments:
1435 self - Decimal instance
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001436 context - context used.
1437 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001438 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001439 return self
1440 if context is None:
1441 context = getcontext()
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001442 prec = context.prec
Facundo Batista99b55482004-10-26 23:38:46 +00001443 ans = self._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001444 if len(ans._int) > prec:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001445 ans = ans._round(prec, context=context)
Facundo Batista99b55482004-10-26 23:38:46 +00001446 ans = ans._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001447 return ans
1448
Facundo Batista99b55482004-10-26 23:38:46 +00001449 def _fixexponents(self, context):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001450 """Fix the exponents and return a copy with the exponent in bounds.
1451 Only call if known to not be a special value.
1452 """
1453 folddown = context._clamp
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001454 Emin = context.Emin
Facundo Batista99b55482004-10-26 23:38:46 +00001455 ans = self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001456 ans_adjusted = ans.adjusted()
1457 if ans_adjusted < Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001458 Etiny = context.Etiny()
1459 if ans._exp < Etiny:
1460 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001461 ans = Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001462 ans._exp = Etiny
1463 context._raise_error(Clamped)
1464 return ans
1465 ans = ans._rescale(Etiny, context=context)
1466 #It isn't zero, and exp < Emin => subnormal
1467 context._raise_error(Subnormal)
1468 if context.flags[Inexact]:
1469 context._raise_error(Underflow)
1470 else:
1471 if ans:
1472 #Only raise subnormal if non-zero.
1473 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001474 else:
1475 Etop = context.Etop()
1476 if folddown and ans._exp > Etop:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001477 context._raise_error(Clamped)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001478 ans = ans._rescale(Etop, context=context)
1479 else:
1480 Emax = context.Emax
1481 if ans_adjusted > Emax:
1482 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001483 ans = Decimal(self)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001484 ans._exp = Emax
1485 context._raise_error(Clamped)
1486 return ans
1487 context._raise_error(Inexact)
1488 context._raise_error(Rounded)
1489 return context._raise_error(Overflow, 'above Emax', ans._sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001490 return ans
1491
1492 def _round(self, prec=None, rounding=None, context=None):
1493 """Returns a rounded version of self.
1494
1495 You can specify the precision or rounding method. Otherwise, the
1496 context determines it.
1497 """
1498
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001499 if self._is_special:
1500 ans = self._check_nans(context=context)
1501 if ans:
1502 return ans
1503
1504 if self._isinfinity():
1505 return Decimal(self)
1506
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001507 if context is None:
1508 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001509
1510 if rounding is None:
1511 rounding = context.rounding
1512 if prec is None:
1513 prec = context.prec
1514
1515 if not self:
1516 if prec <= 0:
1517 dig = (0,)
1518 exp = len(self._int) - prec + self._exp
1519 else:
1520 dig = (0,) * prec
1521 exp = len(self._int) + self._exp - prec
1522 ans = Decimal((self._sign, dig, exp))
1523 context._raise_error(Rounded)
1524 return ans
1525
1526 if prec == 0:
1527 temp = Decimal(self)
1528 temp._int = (0,)+temp._int
1529 prec = 1
1530 elif prec < 0:
1531 exp = self._exp + len(self._int) - prec - 1
1532 temp = Decimal( (self._sign, (0, 1), exp))
1533 prec = 1
1534 else:
1535 temp = Decimal(self)
1536
1537 numdigits = len(temp._int)
1538 if prec == numdigits:
1539 return temp
1540
1541 # See if we need to extend precision
1542 expdiff = prec - numdigits
1543 if expdiff > 0:
1544 tmp = list(temp._int)
1545 tmp.extend([0] * expdiff)
1546 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff))
1547 return ans
1548
1549 #OK, but maybe all the lost digits are 0.
1550 lostdigits = self._int[expdiff:]
1551 if lostdigits == (0,) * len(lostdigits):
1552 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
1553 #Rounded, but not Inexact
1554 context._raise_error(Rounded)
1555 return ans
1556
1557 # Okay, let's round and lose data
1558
1559 this_function = getattr(temp, self._pick_rounding_function[rounding])
1560 #Now we've got the rounding function
1561
1562 if prec != context.prec:
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001563 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001564 context.prec = prec
1565 ans = this_function(prec, expdiff, context)
1566 context._raise_error(Rounded)
1567 context._raise_error(Inexact, 'Changed in rounding')
1568
1569 return ans
1570
1571 _pick_rounding_function = {}
1572
1573 def _round_down(self, prec, expdiff, context):
1574 """Also known as round-towards-0, truncate."""
1575 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1576
1577 def _round_half_up(self, prec, expdiff, context, tmp = None):
1578 """Rounds 5 up (away from 0)"""
1579
1580 if tmp is None:
1581 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
1582 if self._int[prec] >= 5:
1583 tmp = tmp._increment(round=0, context=context)
1584 if len(tmp._int) > prec:
1585 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1586 return tmp
1587
1588 def _round_half_even(self, prec, expdiff, context):
1589 """Round 5 to even, rest to nearest."""
1590
1591 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1592 half = (self._int[prec] == 5)
1593 if half:
1594 for digit in self._int[prec+1:]:
1595 if digit != 0:
1596 half = 0
1597 break
1598 if half:
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001599 if self._int[prec-1] & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001600 return tmp
1601 return self._round_half_up(prec, expdiff, context, tmp)
1602
1603 def _round_half_down(self, prec, expdiff, context):
1604 """Round 5 down"""
1605
1606 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1607 half = (self._int[prec] == 5)
1608 if half:
1609 for digit in self._int[prec+1:]:
1610 if digit != 0:
1611 half = 0
1612 break
1613 if half:
1614 return tmp
1615 return self._round_half_up(prec, expdiff, context, tmp)
1616
1617 def _round_up(self, prec, expdiff, context):
1618 """Rounds away from 0."""
1619 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1620 for digit in self._int[prec:]:
1621 if digit != 0:
1622 tmp = tmp._increment(round=1, context=context)
1623 if len(tmp._int) > prec:
1624 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1625 else:
1626 return tmp
1627 return tmp
1628
1629 def _round_ceiling(self, prec, expdiff, context):
1630 """Rounds up (not away from 0 if negative.)"""
1631 if self._sign:
1632 return self._round_down(prec, expdiff, context)
1633 else:
1634 return self._round_up(prec, expdiff, context)
1635
1636 def _round_floor(self, prec, expdiff, context):
1637 """Rounds down (not towards 0 if negative)"""
1638 if not self._sign:
1639 return self._round_down(prec, expdiff, context)
1640 else:
1641 return self._round_up(prec, expdiff, context)
1642
1643 def __pow__(self, n, modulo = None, context=None):
1644 """Return self ** n (mod modulo)
1645
1646 If modulo is None (default), don't take it mod modulo.
1647 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001648 n = _convert_other(n)
1649
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001650 if context is None:
1651 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001652
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001653 if self._is_special or n._is_special or n.adjusted() > 8:
1654 #Because the spot << doesn't work with really big exponents
1655 if n._isinfinity() or n.adjusted() > 8:
1656 return context._raise_error(InvalidOperation, 'x ** INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001657
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001658 ans = self._check_nans(n, context)
1659 if ans:
1660 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001661
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001662 if not n._isinteger():
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001663 return context._raise_error(InvalidOperation, 'x ** (non-integer)')
1664
1665 if not self and not n:
1666 return context._raise_error(InvalidOperation, '0 ** 0')
1667
1668 if not n:
1669 return Decimal(1)
1670
1671 if self == Decimal(1):
1672 return Decimal(1)
1673
1674 sign = self._sign and not n._iseven()
1675 n = int(n)
1676
1677 if self._isinfinity():
1678 if modulo:
1679 return context._raise_error(InvalidOperation, 'INF % x')
1680 if n > 0:
1681 return Infsign[sign]
1682 return Decimal( (sign, (0,), 0) )
1683
1684 #with ludicrously large exponent, just raise an overflow and return inf.
1685 if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
1686 and self:
1687
1688 tmp = Decimal('inf')
1689 tmp._sign = sign
1690 context._raise_error(Rounded)
1691 context._raise_error(Inexact)
1692 context._raise_error(Overflow, 'Big power', sign)
1693 return tmp
1694
1695 elength = len(str(abs(n)))
1696 firstprec = context.prec
1697
Raymond Hettinger99148e72004-07-14 19:56:56 +00001698 if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001699 return context._raise_error(Overflow, 'Too much precision.', sign)
1700
1701 mul = Decimal(self)
1702 val = Decimal(1)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001703 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001704 context.prec = firstprec + elength + 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001705 if n < 0:
1706 #n is a long now, not Decimal instance
1707 n = -n
1708 mul = Decimal(1).__div__(mul, context=context)
1709
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001710 spot = 1
1711 while spot <= n:
1712 spot <<= 1
1713
1714 spot >>= 1
1715 #Spot is the highest power of 2 less than n
1716 while spot:
1717 val = val.__mul__(val, context=context)
1718 if val._isinfinity():
1719 val = Infsign[sign]
1720 break
1721 if spot & n:
1722 val = val.__mul__(mul, context=context)
1723 if modulo is not None:
1724 val = val.__mod__(modulo, context=context)
1725 spot >>= 1
1726 context.prec = firstprec
1727
Raymond Hettinger76e60d62004-10-20 06:58:28 +00001728 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001729 return val._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001730 return val
1731
1732 def __rpow__(self, other, context=None):
1733 """Swaps self/other and returns __pow__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001734 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001735 return other.__pow__(self, context=context)
1736
1737 def normalize(self, context=None):
1738 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001739
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001740 if self._is_special:
1741 ans = self._check_nans(context=context)
1742 if ans:
1743 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001744
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001745 dup = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001746 if dup._isinfinity():
1747 return dup
1748
1749 if not dup:
1750 return Decimal( (dup._sign, (0,), 0) )
1751 end = len(dup._int)
1752 exp = dup._exp
1753 while dup._int[end-1] == 0:
1754 exp += 1
1755 end -= 1
1756 return Decimal( (dup._sign, dup._int[:end], exp) )
1757
1758
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001759 def quantize(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001760 """Quantize self so its exponent is the same as that of exp.
1761
1762 Similar to self._rescale(exp._exp) but with error checking.
1763 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001764 if self._is_special or exp._is_special:
1765 ans = self._check_nans(exp, context)
1766 if ans:
1767 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001768
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001769 if exp._isinfinity() or self._isinfinity():
1770 if exp._isinfinity() and self._isinfinity():
1771 return self #if both are inf, it is OK
1772 if context is None:
1773 context = getcontext()
1774 return context._raise_error(InvalidOperation,
1775 'quantize with one INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001776 return self._rescale(exp._exp, rounding, context, watchexp)
1777
1778 def same_quantum(self, other):
1779 """Test whether self and other have the same exponent.
1780
1781 same as self._exp == other._exp, except NaN == sNaN
1782 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001783 if self._is_special or other._is_special:
1784 if self._isnan() or other._isnan():
1785 return self._isnan() and other._isnan() and True
1786 if self._isinfinity() or other._isinfinity():
1787 return self._isinfinity() and other._isinfinity() and True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001788 return self._exp == other._exp
1789
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001790 def _rescale(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001791 """Rescales so that the exponent is exp.
1792
1793 exp = exp to scale to (an integer)
1794 rounding = rounding version
1795 watchexp: if set (default) an error is returned if exp is greater
1796 than Emax or less than Etiny.
1797 """
1798 if context is None:
1799 context = getcontext()
1800
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001801 if self._is_special:
1802 if self._isinfinity():
1803 return context._raise_error(InvalidOperation, 'rescale with an INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001804
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001805 ans = self._check_nans(context=context)
1806 if ans:
1807 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001808
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001809 if watchexp and (context.Emax < exp or context.Etiny() > exp):
1810 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1811
1812 if not self:
1813 ans = Decimal(self)
1814 ans._int = (0,)
1815 ans._exp = exp
1816 return ans
1817
1818 diff = self._exp - exp
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001819 digits = len(self._int) + diff
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001820
1821 if watchexp and digits > context.prec:
1822 return context._raise_error(InvalidOperation, 'Rescale > prec')
1823
1824 tmp = Decimal(self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001825 tmp._int = (0,) + tmp._int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001826 digits += 1
1827
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001828 if digits < 0:
1829 tmp._exp = -digits + tmp._exp
1830 tmp._int = (0,1)
1831 digits = 1
1832 tmp = tmp._round(digits, rounding, context=context)
1833
1834 if tmp._int[0] == 0 and len(tmp._int) > 1:
1835 tmp._int = tmp._int[1:]
1836 tmp._exp = exp
1837
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001838 tmp_adjusted = tmp.adjusted()
1839 if tmp and tmp_adjusted < context.Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001840 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001841 elif tmp and tmp_adjusted > context.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001842 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1843 return tmp
1844
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001845 def to_integral(self, rounding=None, context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001846 """Rounds to the nearest integer, without raising inexact, rounded."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001847 if self._is_special:
1848 ans = self._check_nans(context=context)
1849 if ans:
1850 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001851 if self._exp >= 0:
1852 return self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001853 if context is None:
1854 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001855 flags = context._ignore_flags(Rounded, Inexact)
1856 ans = self._rescale(0, rounding, context=context)
1857 context._regard_flags(flags)
1858 return ans
1859
1860 def sqrt(self, context=None):
1861 """Return the square root of self.
1862
1863 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
1864 Should quadratically approach the right answer.
1865 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001866 if self._is_special:
1867 ans = self._check_nans(context=context)
1868 if ans:
1869 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001870
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001871 if self._isinfinity() and self._sign == 0:
1872 return Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001873
1874 if not self:
1875 #exponent = self._exp / 2, using round_down.
1876 #if self._exp < 0:
1877 # exp = (self._exp+1) // 2
1878 #else:
1879 exp = (self._exp) // 2
1880 if self._sign == 1:
1881 #sqrt(-0) = -0
1882 return Decimal( (1, (0,), exp))
1883 else:
1884 return Decimal( (0, (0,), exp))
1885
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001886 if context is None:
1887 context = getcontext()
1888
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001889 if self._sign == 1:
1890 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
1891
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001892 tmp = Decimal(self)
1893
Raymond Hettinger4837a222004-09-27 14:23:40 +00001894 expadd = tmp._exp // 2
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001895 if tmp._exp & 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001896 tmp._int += (0,)
1897 tmp._exp = 0
1898 else:
1899 tmp._exp = 0
1900
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001901 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001902 flags = context._ignore_all_flags()
1903 firstprec = context.prec
1904 context.prec = 3
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001905 if tmp.adjusted() & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001906 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) )
1907 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
1908 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00001909 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001910 else:
1911 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
1912 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
1913 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00001914 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001915
1916 #ans is now a linear approximation.
1917
1918 Emax, Emin = context.Emax, context.Emin
Raymond Hettinger99148e72004-07-14 19:56:56 +00001919 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001920
1921 half = Decimal('0.5')
1922
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001923 maxp = firstprec + 2
1924 rounding = context._set_rounding(ROUND_HALF_EVEN)
1925 while 1:
1926 context.prec = min(2*context.prec - 2, maxp)
1927 ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
1928 context=context), context=context)
1929 if context.prec == maxp:
1930 break
1931
1932 #round to the answer's precision-- the only error can be 1 ulp.
1933 context.prec = firstprec
1934 prevexp = ans.adjusted()
1935 ans = ans._round(context=context)
1936
1937 #Now, check if the other last digits are better.
1938 context.prec = firstprec + 1
1939 # In case we rounded up another digit and we should actually go lower.
1940 if prevexp != ans.adjusted():
1941 ans._int += (0,)
1942 ans._exp -= 1
1943
1944
1945 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
1946 context._set_rounding(ROUND_UP)
1947 if lower.__mul__(lower, context=context) > (tmp):
1948 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
1949
1950 else:
1951 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
1952 context._set_rounding(ROUND_DOWN)
1953 if upper.__mul__(upper, context=context) < tmp:
1954 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
1955
1956 ans._exp += expadd
1957
1958 context.prec = firstprec
1959 context.rounding = rounding
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001960 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001961
1962 rounding = context._set_rounding_decision(NEVER_ROUND)
1963 if not ans.__mul__(ans, context=context) == self:
1964 # Only rounded/inexact if here.
1965 context._regard_flags(flags)
1966 context._raise_error(Rounded)
1967 context._raise_error(Inexact)
1968 else:
1969 #Exact answer, so let's set the exponent right.
1970 #if self._exp < 0:
1971 # exp = (self._exp +1)// 2
1972 #else:
1973 exp = self._exp // 2
1974 context.prec += ans._exp - exp
1975 ans = ans._rescale(exp, context=context)
1976 context.prec = firstprec
1977 context._regard_flags(flags)
1978 context.Emax, context.Emin = Emax, Emin
1979
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001980 return ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001981
1982 def max(self, other, context=None):
1983 """Returns the larger value.
1984
1985 like max(self, other) except if one is not a number, returns
1986 NaN (and signals if one is sNaN). Also rounds.
1987 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001988 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001989
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001990 if self._is_special or other._is_special:
1991 # if one operand is a quiet NaN and the other is number, then the
1992 # number is always returned
1993 sn = self._isnan()
1994 on = other._isnan()
1995 if sn or on:
1996 if on == 1 and sn != 2:
1997 return self
1998 if sn == 1 and on != 2:
1999 return other
2000 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002001
2002 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002003 c = self.__cmp__(other)
2004 if c == 0:
2005 # if both operands are finite and equal in numerical value
2006 # then an ordering is applied:
2007 #
2008 # if the signs differ then max returns the operand with the
2009 # positive sign and min returns the operand with the negative sign
2010 #
2011 # if the signs are the same then the exponent is used to select
2012 # the result.
2013 if self._sign != other._sign:
2014 if self._sign:
2015 ans = other
2016 elif self._exp < other._exp and not self._sign:
2017 ans = other
2018 elif self._exp > other._exp and self._sign:
2019 ans = other
2020 elif c == -1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002021 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002022
2023 if context is None:
2024 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002025 if context._rounding_decision == ALWAYS_ROUND:
2026 return ans._fix(context)
2027 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002028
2029 def min(self, other, context=None):
2030 """Returns the smaller value.
2031
2032 like min(self, other) except if one is not a number, returns
2033 NaN (and signals if one is sNaN). Also rounds.
2034 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002035 other = _convert_other(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002036
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002037 if self._is_special or other._is_special:
2038 # if one operand is a quiet NaN and the other is number, then the
2039 # number is always returned
2040 sn = self._isnan()
2041 on = other._isnan()
2042 if sn or on:
2043 if on == 1 and sn != 2:
2044 return self
2045 if sn == 1 and on != 2:
2046 return other
2047 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002048
2049 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002050 c = self.__cmp__(other)
2051 if c == 0:
2052 # if both operands are finite and equal in numerical value
2053 # then an ordering is applied:
2054 #
2055 # if the signs differ then max returns the operand with the
2056 # positive sign and min returns the operand with the negative sign
2057 #
2058 # if the signs are the same then the exponent is used to select
2059 # the result.
2060 if self._sign != other._sign:
2061 if other._sign:
2062 ans = other
2063 elif self._exp > other._exp and not self._sign:
2064 ans = other
2065 elif self._exp < other._exp and self._sign:
2066 ans = other
2067 elif c == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002068 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002069
2070 if context is None:
2071 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002072 if context._rounding_decision == ALWAYS_ROUND:
2073 return ans._fix(context)
2074 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002075
2076 def _isinteger(self):
2077 """Returns whether self is an integer"""
2078 if self._exp >= 0:
2079 return True
2080 rest = self._int[self._exp:]
2081 return rest == (0,)*len(rest)
2082
2083 def _iseven(self):
2084 """Returns 1 if self is even. Assumes self is an integer."""
2085 if self._exp > 0:
2086 return 1
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002087 return self._int[-1+self._exp] & 1 == 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002088
2089 def adjusted(self):
2090 """Return the adjusted exponent of self"""
2091 try:
2092 return self._exp + len(self._int) - 1
2093 #If NaN or Infinity, self._exp is string
2094 except TypeError:
2095 return 0
2096
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002097 # support for pickling, copy, and deepcopy
2098 def __reduce__(self):
2099 return (self.__class__, (str(self),))
2100
2101 def __copy__(self):
2102 if type(self) == Decimal:
2103 return self # I'm immutable; therefore I am my own clone
2104 return self.__class__(str(self))
2105
2106 def __deepcopy__(self, memo):
2107 if type(self) == Decimal:
2108 return self # My components are also immutable
2109 return self.__class__(str(self))
2110
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002111##### Context class ###########################################
2112
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002113
2114# get rounding method function:
2115rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
2116for name in rounding_functions:
2117 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
2118 globalname = name[1:].upper()
2119 val = globals()[globalname]
2120 Decimal._pick_rounding_function[val] = name
2121
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002122del name, val, globalname, rounding_functions
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002123
2124class Context(object):
2125 """Contains the context for a Decimal instance.
2126
2127 Contains:
2128 prec - precision (for use in rounding, division, square roots..)
2129 rounding - rounding type. (how you round)
2130 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
Raymond Hettingerbf440692004-07-10 14:14:37 +00002131 traps - If traps[exception] = 1, then the exception is
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002132 raised when it is caused. Otherwise, a value is
2133 substituted in.
2134 flags - When an exception is caused, flags[exception] is incremented.
2135 (Whether or not the trap_enabler is set)
2136 Should be reset by user of Decimal instance.
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002137 Emin - Minimum exponent
2138 Emax - Maximum exponent
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002139 capitals - If 1, 1*10^1 is printed as 1E+1.
2140 If 0, printed as 1e1
Raymond Hettingere0f15812004-07-05 05:36:39 +00002141 _clamp - If 1, change exponents if too high (Default 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002142 """
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002143
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002144 def __init__(self, prec=None, rounding=None,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002145 traps=None, flags=None,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002146 _rounding_decision=None,
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002147 Emin=None, Emax=None,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002148 capitals=None, _clamp=0,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002149 _ignored_flags=None):
2150 if flags is None:
2151 flags = []
2152 if _ignored_flags is None:
2153 _ignored_flags = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002154 if not isinstance(flags, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002155 flags = dict([(s,s in flags) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002156 del s
Raymond Hettingerbf440692004-07-10 14:14:37 +00002157 if traps is not None and not isinstance(traps, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002158 traps = dict([(s,s in traps) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002159 del s
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002160 for name, val in locals().items():
2161 if val is None:
2162 setattr(self, name, copy.copy(getattr(DefaultContext, name)))
2163 else:
2164 setattr(self, name, val)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002165 del self.self
2166
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002167 def __repr__(self):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002168 """Show the current context."""
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002169 s = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002170 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
2171 s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
2172 s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002173 return ', '.join(s) + ')'
2174
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002175 def clear_flags(self):
2176 """Reset all flags to zero"""
2177 for flag in self.flags:
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002178 self.flags[flag] = 0
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002179
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002180 def _shallow_copy(self):
2181 """Returns a shallow copy from self."""
Raymond Hettingerbf440692004-07-10 14:14:37 +00002182 nc = Context(self.prec, self.rounding, self.traps, self.flags,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002183 self._rounding_decision, self.Emin, self.Emax,
2184 self.capitals, self._clamp, self._ignored_flags)
2185 return nc
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002186
2187 def copy(self):
2188 """Returns a deep copy from self."""
2189 nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
2190 self._rounding_decision, self.Emin, self.Emax,
2191 self.capitals, self._clamp, self._ignored_flags)
2192 return nc
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002193 __copy__ = copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002194
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002195 def _raise_error(self, condition, explanation = None, *args):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002196 """Handles an error
2197
2198 If the flag is in _ignored_flags, returns the default response.
2199 Otherwise, it increments the flag, then, if the corresponding
2200 trap_enabler is set, it reaises the exception. Otherwise, it returns
2201 the default value after incrementing the flag.
2202 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002203 error = _condition_map.get(condition, condition)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002204 if error in self._ignored_flags:
2205 #Don't touch the flag
2206 return error().handle(self, *args)
2207
2208 self.flags[error] += 1
Raymond Hettingerbf440692004-07-10 14:14:37 +00002209 if not self.traps[error]:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002210 #The errors define how to handle themselves.
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002211 return condition().handle(self, *args)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002212
2213 # Errors should only be risked on copies of the context
2214 #self._ignored_flags = []
2215 raise error, explanation
2216
2217 def _ignore_all_flags(self):
2218 """Ignore all flags, if they are raised"""
Raymond Hettingerfed52962004-07-14 15:41:57 +00002219 return self._ignore_flags(*_signals)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002220
2221 def _ignore_flags(self, *flags):
2222 """Ignore the flags, if they are raised"""
2223 # Do not mutate-- This way, copies of a context leave the original
2224 # alone.
2225 self._ignored_flags = (self._ignored_flags + list(flags))
2226 return list(flags)
2227
2228 def _regard_flags(self, *flags):
2229 """Stop ignoring the flags, if they are raised"""
2230 if flags and isinstance(flags[0], (tuple,list)):
2231 flags = flags[0]
2232 for flag in flags:
2233 self._ignored_flags.remove(flag)
2234
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002235 def __hash__(self):
2236 """A Context cannot be hashed."""
2237 # We inherit object.__hash__, so we must deny this explicitly
2238 raise TypeError, "Cannot hash a Context."
2239
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002240 def Etiny(self):
2241 """Returns Etiny (= Emin - prec + 1)"""
2242 return int(self.Emin - self.prec + 1)
2243
2244 def Etop(self):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002245 """Returns maximum exponent (= Emax - prec + 1)"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002246 return int(self.Emax - self.prec + 1)
2247
2248 def _set_rounding_decision(self, type):
2249 """Sets the rounding decision.
2250
2251 Sets the rounding decision, and returns the current (previous)
2252 rounding decision. Often used like:
2253
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002254 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002255 # That so you don't change the calling context
2256 # if an error occurs in the middle (say DivisionImpossible is raised).
2257
2258 rounding = context._set_rounding_decision(NEVER_ROUND)
2259 instance = instance / Decimal(2)
2260 context._set_rounding_decision(rounding)
2261
2262 This will make it not round for that operation.
2263 """
2264
2265 rounding = self._rounding_decision
2266 self._rounding_decision = type
2267 return rounding
2268
2269 def _set_rounding(self, type):
2270 """Sets the rounding type.
2271
2272 Sets the rounding type, and returns the current (previous)
2273 rounding type. Often used like:
2274
2275 context = context.copy()
2276 # so you don't change the calling context
2277 # if an error occurs in the middle.
2278 rounding = context._set_rounding(ROUND_UP)
2279 val = self.__sub__(other, context=context)
2280 context._set_rounding(rounding)
2281
2282 This will make it round up for that operation.
2283 """
2284 rounding = self.rounding
2285 self.rounding= type
2286 return rounding
2287
Raymond Hettingerfed52962004-07-14 15:41:57 +00002288 def create_decimal(self, num='0'):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002289 """Creates a new Decimal instance but using self as context."""
2290 d = Decimal(num, context=self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002291 return d._fix(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002292
2293 #Methods
2294 def abs(self, a):
2295 """Returns the absolute value of the operand.
2296
2297 If the operand is negative, the result is the same as using the minus
2298 operation on the operand. Otherwise, the result is the same as using
2299 the plus operation on the operand.
2300
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002301 >>> ExtendedContext.abs(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002302 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002303 >>> ExtendedContext.abs(Decimal('-100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002304 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002305 >>> ExtendedContext.abs(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002306 Decimal("101.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002307 >>> ExtendedContext.abs(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002308 Decimal("101.5")
2309 """
2310 return a.__abs__(context=self)
2311
2312 def add(self, a, b):
2313 """Return the sum of the two operands.
2314
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002315 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002316 Decimal("19.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002317 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002318 Decimal("1.02E+4")
2319 """
2320 return a.__add__(b, context=self)
2321
2322 def _apply(self, a):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002323 return str(a._fix(self))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002324
2325 def compare(self, a, b):
2326 """Compares values numerically.
2327
2328 If the signs of the operands differ, a value representing each operand
2329 ('-1' if the operand is less than zero, '0' if the operand is zero or
2330 negative zero, or '1' if the operand is greater than zero) is used in
2331 place of that operand for the comparison instead of the actual
2332 operand.
2333
2334 The comparison is then effected by subtracting the second operand from
2335 the first and then returning a value according to the result of the
2336 subtraction: '-1' if the result is less than zero, '0' if the result is
2337 zero or negative zero, or '1' if the result is greater than zero.
2338
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002339 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002340 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002341 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002342 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002343 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002344 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002345 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002346 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002347 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002348 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002349 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002350 Decimal("-1")
2351 """
2352 return a.compare(b, context=self)
2353
2354 def divide(self, a, b):
2355 """Decimal division in a specified context.
2356
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002357 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002358 Decimal("0.333333333")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002359 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002360 Decimal("0.666666667")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002361 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002362 Decimal("2.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002363 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002364 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002365 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002366 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002367 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002368 Decimal("4.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002369 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002370 Decimal("1.20")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002371 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002372 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002373 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002374 Decimal("1000")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002375 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002376 Decimal("1.20E+6")
2377 """
2378 return a.__div__(b, context=self)
2379
2380 def divide_int(self, a, b):
2381 """Divides two numbers and returns the integer part of the result.
2382
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002383 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002384 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002385 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002386 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002387 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002388 Decimal("3")
2389 """
2390 return a.__floordiv__(b, context=self)
2391
2392 def divmod(self, a, b):
2393 return a.__divmod__(b, context=self)
2394
2395 def max(self, a,b):
2396 """max compares two values numerically and returns the maximum.
2397
2398 If either operand is a NaN then the general rules apply.
2399 Otherwise, the operands are compared as as though by the compare
2400 operation. If they are numerically equal then the left-hand operand
2401 is chosen as the result. Otherwise the maximum (closer to positive
2402 infinity) of the two operands is chosen as the result.
2403
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002404 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002405 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002406 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002407 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002408 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002409 Decimal("1")
2410 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
2411 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002412 """
2413 return a.max(b, context=self)
2414
2415 def min(self, a,b):
2416 """min compares two values numerically and returns the minimum.
2417
2418 If either operand is a NaN then the general rules apply.
2419 Otherwise, the operands are compared as as though by the compare
2420 operation. If they are numerically equal then the left-hand operand
2421 is chosen as the result. Otherwise the minimum (closer to negative
2422 infinity) of the two operands is chosen as the result.
2423
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002424 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002425 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002426 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002427 Decimal("-10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002428 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002429 Decimal("1.0")
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002430 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
2431 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002432 """
2433 return a.min(b, context=self)
2434
2435 def minus(self, a):
2436 """Minus corresponds to unary prefix minus in Python.
2437
2438 The operation is evaluated using the same rules as subtract; the
2439 operation minus(a) is calculated as subtract('0', a) where the '0'
2440 has the same exponent as the operand.
2441
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002442 >>> ExtendedContext.minus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002443 Decimal("-1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002444 >>> ExtendedContext.minus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002445 Decimal("1.3")
2446 """
2447 return a.__neg__(context=self)
2448
2449 def multiply(self, a, b):
2450 """multiply multiplies two operands.
2451
2452 If either operand is a special value then the general rules apply.
2453 Otherwise, the operands are multiplied together ('long multiplication'),
2454 resulting in a number which may be as long as the sum of the lengths
2455 of the two operands.
2456
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002457 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002458 Decimal("3.60")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002459 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002460 Decimal("21")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002461 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002462 Decimal("0.72")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002463 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002464 Decimal("-0.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002465 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002466 Decimal("4.28135971E+11")
2467 """
2468 return a.__mul__(b, context=self)
2469
2470 def normalize(self, a):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002471 """normalize reduces an operand to its simplest form.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002472
2473 Essentially a plus operation with all trailing zeros removed from the
2474 result.
2475
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002476 >>> ExtendedContext.normalize(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002477 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002478 >>> ExtendedContext.normalize(Decimal('-2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002479 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002480 >>> ExtendedContext.normalize(Decimal('1.200'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002481 Decimal("1.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002482 >>> ExtendedContext.normalize(Decimal('-120'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002483 Decimal("-1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002484 >>> ExtendedContext.normalize(Decimal('120.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002485 Decimal("1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002486 >>> ExtendedContext.normalize(Decimal('0.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002487 Decimal("0")
2488 """
2489 return a.normalize(context=self)
2490
2491 def plus(self, a):
2492 """Plus corresponds to unary prefix plus in Python.
2493
2494 The operation is evaluated using the same rules as add; the
2495 operation plus(a) is calculated as add('0', a) where the '0'
2496 has the same exponent as the operand.
2497
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002498 >>> ExtendedContext.plus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002499 Decimal("1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002500 >>> ExtendedContext.plus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002501 Decimal("-1.3")
2502 """
2503 return a.__pos__(context=self)
2504
2505 def power(self, a, b, modulo=None):
2506 """Raises a to the power of b, to modulo if given.
2507
2508 The right-hand operand must be a whole number whose integer part (after
2509 any exponent has been applied) has no more than 9 digits and whose
2510 fractional part (if any) is all zeros before any rounding. The operand
2511 may be positive, negative, or zero; if negative, the absolute value of
2512 the power is used, and the left-hand operand is inverted (divided into
2513 1) before use.
2514
2515 If the increased precision needed for the intermediate calculations
2516 exceeds the capabilities of the implementation then an Invalid operation
2517 condition is raised.
2518
2519 If, when raising to a negative power, an underflow occurs during the
2520 division into 1, the operation is not halted at that point but
2521 continues.
2522
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002523 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002524 Decimal("8")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002525 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002526 Decimal("0.125")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002527 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002528 Decimal("69.7575744")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002529 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002530 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002531 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002532 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002533 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002534 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002535 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002536 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002537 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002538 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002539 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002540 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002541 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002542 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002543 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002544 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002545 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002546 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002547 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002548 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002549 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002550 Decimal("NaN")
2551 """
2552 return a.__pow__(b, modulo, context=self)
2553
2554 def quantize(self, a, b):
2555 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
2556
2557 The coefficient of the result is derived from that of the left-hand
2558 operand. It may be rounded using the current rounding setting (if the
2559 exponent is being increased), multiplied by a positive power of ten (if
2560 the exponent is being decreased), or is unchanged (if the exponent is
2561 already equal to that of the right-hand operand).
2562
2563 Unlike other operations, if the length of the coefficient after the
2564 quantize operation would be greater than precision then an Invalid
2565 operation condition is raised. This guarantees that, unless there is an
2566 error condition, the exponent of the result of a quantize is always
2567 equal to that of the right-hand operand.
2568
2569 Also unlike other operations, quantize will never raise Underflow, even
2570 if the result is subnormal and inexact.
2571
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002572 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002573 Decimal("2.170")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002574 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002575 Decimal("2.17")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002576 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002577 Decimal("2.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002578 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002579 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002580 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002581 Decimal("0E+1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002582 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002583 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002584 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002585 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002586 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002587 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002588 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002589 Decimal("-0E+5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002590 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002591 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002592 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002593 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002594 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002595 Decimal("217.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002596 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002597 Decimal("217")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002598 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002599 Decimal("2.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002600 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002601 Decimal("2E+2")
2602 """
2603 return a.quantize(b, context=self)
2604
2605 def remainder(self, a, b):
2606 """Returns the remainder from integer division.
2607
2608 The result is the residue of the dividend after the operation of
2609 calculating integer division as described for divide-integer, rounded to
2610 precision digits if necessary. The sign of the result, if non-zero, is
2611 the same as that of the original dividend.
2612
2613 This operation will fail under the same conditions as integer division
2614 (that is, if integer division on the same two operands would fail, the
2615 remainder cannot be calculated).
2616
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002617 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002618 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002619 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002620 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002621 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002622 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002623 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002624 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002625 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002626 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002627 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002628 Decimal("1.0")
2629 """
2630 return a.__mod__(b, context=self)
2631
2632 def remainder_near(self, a, b):
2633 """Returns to be "a - b * n", where n is the integer nearest the exact
2634 value of "x / b" (if two integers are equally near then the even one
2635 is chosen). If the result is equal to 0 then its sign will be the
2636 sign of a.
2637
2638 This operation will fail under the same conditions as integer division
2639 (that is, if integer division on the same two operands would fail, the
2640 remainder cannot be calculated).
2641
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002642 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002643 Decimal("-0.9")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002644 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002645 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002646 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002647 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002648 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002649 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002650 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002651 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002652 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002653 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002654 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002655 Decimal("-0.3")
2656 """
2657 return a.remainder_near(b, context=self)
2658
2659 def same_quantum(self, a, b):
2660 """Returns True if the two operands have the same exponent.
2661
2662 The result is never affected by either the sign or the coefficient of
2663 either operand.
2664
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002665 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002666 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002667 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002668 True
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002669 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002670 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002671 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002672 True
2673 """
2674 return a.same_quantum(b)
2675
2676 def sqrt(self, a):
2677 """Returns the square root of a non-negative number to context precision.
2678
2679 If the result must be inexact, it is rounded using the round-half-even
2680 algorithm.
2681
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002682 >>> ExtendedContext.sqrt(Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002683 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002684 >>> ExtendedContext.sqrt(Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002685 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002686 >>> ExtendedContext.sqrt(Decimal('0.39'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002687 Decimal("0.624499800")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002688 >>> ExtendedContext.sqrt(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002689 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002690 >>> ExtendedContext.sqrt(Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002691 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002692 >>> ExtendedContext.sqrt(Decimal('1.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002693 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002694 >>> ExtendedContext.sqrt(Decimal('1.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002695 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002696 >>> ExtendedContext.sqrt(Decimal('7'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002697 Decimal("2.64575131")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002698 >>> ExtendedContext.sqrt(Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002699 Decimal("3.16227766")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002700 >>> ExtendedContext.prec
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002701 9
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002702 """
2703 return a.sqrt(context=self)
2704
2705 def subtract(self, a, b):
2706 """Return the sum of the two operands.
2707
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002708 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002709 Decimal("0.23")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002710 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002711 Decimal("0.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002712 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002713 Decimal("-0.77")
2714 """
2715 return a.__sub__(b, context=self)
2716
2717 def to_eng_string(self, a):
2718 """Converts a number to a string, using scientific notation.
2719
2720 The operation is not affected by the context.
2721 """
2722 return a.to_eng_string(context=self)
2723
2724 def to_sci_string(self, a):
2725 """Converts a number to a string, using scientific notation.
2726
2727 The operation is not affected by the context.
2728 """
2729 return a.__str__(context=self)
2730
2731 def to_integral(self, a):
2732 """Rounds to an integer.
2733
2734 When the operand has a negative exponent, the result is the same
2735 as using the quantize() operation using the given operand as the
2736 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2737 of the operand as the precision setting, except that no flags will
2738 be set. The rounding mode is taken from the context.
2739
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002740 >>> ExtendedContext.to_integral(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002741 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002742 >>> ExtendedContext.to_integral(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002743 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002744 >>> ExtendedContext.to_integral(Decimal('100.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002745 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002746 >>> ExtendedContext.to_integral(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002747 Decimal("102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002748 >>> ExtendedContext.to_integral(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002749 Decimal("-102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002750 >>> ExtendedContext.to_integral(Decimal('10E+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002751 Decimal("1.0E+6")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002752 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002753 Decimal("7.89E+77")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002754 >>> ExtendedContext.to_integral(Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002755 Decimal("-Infinity")
2756 """
2757 return a.to_integral(context=self)
2758
2759class _WorkRep(object):
2760 __slots__ = ('sign','int','exp')
Raymond Hettinger17931de2004-10-27 06:21:46 +00002761 # sign: 0 or 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002762 # int: int or long
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002763 # exp: None, int, or string
2764
2765 def __init__(self, value=None):
2766 if value is None:
2767 self.sign = None
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002768 self.int = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002769 self.exp = None
Raymond Hettinger17931de2004-10-27 06:21:46 +00002770 elif isinstance(value, Decimal):
2771 self.sign = value._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002772 cum = 0
Raymond Hettinger17931de2004-10-27 06:21:46 +00002773 for digit in value._int:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002774 cum = cum * 10 + digit
2775 self.int = cum
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002776 self.exp = value._exp
Raymond Hettinger17931de2004-10-27 06:21:46 +00002777 else:
2778 # assert isinstance(value, tuple)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002779 self.sign = value[0]
2780 self.int = value[1]
2781 self.exp = value[2]
2782
2783 def __repr__(self):
2784 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2785
2786 __str__ = __repr__
2787
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002788
2789
2790def _normalize(op1, op2, shouldround = 0, prec = 0):
2791 """Normalizes op1, op2 to have the same exp and length of coefficient.
2792
2793 Done during addition.
2794 """
2795 # Yes, the exponent is a long, but the difference between exponents
2796 # must be an int-- otherwise you'd get a big memory problem.
2797 numdigits = int(op1.exp - op2.exp)
2798 if numdigits < 0:
2799 numdigits = -numdigits
2800 tmp = op2
2801 other = op1
2802 else:
2803 tmp = op1
2804 other = op2
2805
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002806
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002807 if shouldround and numdigits > prec + 1:
2808 # Big difference in exponents - check the adjusted exponents
2809 tmp_len = len(str(tmp.int))
2810 other_len = len(str(other.int))
2811 if numdigits > (other_len + prec + 1 - tmp_len):
2812 # If the difference in adjusted exps is > prec+1, we know
2813 # other is insignificant, so might as well put a 1 after the precision.
2814 # (since this is only for addition.) Also stops use of massive longs.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002815
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002816 extend = prec + 2 - tmp_len
2817 if extend <= 0:
2818 extend = 1
2819 tmp.int *= 10 ** extend
2820 tmp.exp -= extend
2821 other.int = 1
2822 other.exp = tmp.exp
2823 return op1, op2
2824
2825 tmp.int *= 10 ** numdigits
2826 tmp.exp -= numdigits
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002827 return op1, op2
2828
2829def _adjust_coefficients(op1, op2):
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002830 """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002831
2832 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2833
2834 Used on _WorkRep instances during division.
2835 """
2836 adjust = 0
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002837 #If op1 is smaller, make it larger
2838 while op2.int > op1.int:
2839 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002840 op1.exp -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002841 adjust += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002842
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002843 #If op2 is too small, make it larger
2844 while op1.int >= (10 * op2.int):
2845 op2.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002846 op2.exp -= 1
2847 adjust -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002848
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002849 return op1, op2, adjust
2850
2851##### Helper Functions ########################################
2852
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002853def _convert_other(other):
2854 """Convert other to Decimal.
2855
2856 Verifies that it's ok to use in an implicit construction.
2857 """
2858 if isinstance(other, Decimal):
2859 return other
2860 if isinstance(other, (int, long)):
2861 return Decimal(other)
2862
2863 raise TypeError, "You can interact Decimal only with int, long or Decimal data types."
2864
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002865_infinity_map = {
2866 'inf' : 1,
2867 'infinity' : 1,
2868 '+inf' : 1,
2869 '+infinity' : 1,
2870 '-inf' : -1,
2871 '-infinity' : -1
2872}
2873
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002874def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002875 """Determines whether a string or float is infinity.
2876
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002877 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002878 """
2879 num = str(num).lower()
2880 return _infinity_map.get(num, 0)
2881
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002882def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002883 """Determines whether a string or float is NaN
2884
2885 (1, sign, diagnostic info as string) => NaN
2886 (2, sign, diagnostic info as string) => sNaN
2887 0 => not a NaN
2888 """
2889 num = str(num).lower()
2890 if not num:
2891 return 0
2892
2893 #get the sign, get rid of trailing [+-]
2894 sign = 0
2895 if num[0] == '+':
2896 num = num[1:]
2897 elif num[0] == '-': #elif avoids '+-nan'
2898 num = num[1:]
2899 sign = 1
2900
2901 if num.startswith('nan'):
2902 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
2903 return 0
2904 return (1, sign, num[3:].lstrip('0'))
2905 if num.startswith('snan'):
2906 if len(num) > 4 and not num[4:].isdigit():
2907 return 0
2908 return (2, sign, num[4:].lstrip('0'))
2909 return 0
2910
2911
2912##### Setup Specific Contexts ################################
2913
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002914# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00002915# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002916
2917DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002918 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002919 traps=[DivisionByZero, Overflow, InvalidOperation],
2920 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002921 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00002922 Emax=999999999,
2923 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002924 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002925)
2926
2927# Pre-made alternate contexts offered by the specification
2928# Don't change these; the user should be able to select these
2929# contexts and be able to reproduce results from other implementations
2930# of the spec.
2931
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002932BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002933 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002934 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
2935 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002936)
2937
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002938ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002939 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002940 traps=[],
2941 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002942)
2943
2944
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002945##### Useful Constants (internal use only) ####################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002946
2947#Reusable defaults
2948Inf = Decimal('Inf')
2949negInf = Decimal('-Inf')
2950
2951#Infsign[sign] is infinity w/ that sign
2952Infsign = (Inf, negInf)
2953
2954NaN = Decimal('NaN')
2955
2956
2957##### crud for parsing strings #################################
2958import re
2959
2960# There's an optional sign at the start, and an optional exponent
2961# at the end. The exponent has an optional sign and at least one
2962# digit. In between, must have either at least one digit followed
2963# by an optional fraction, or a decimal point followed by at least
2964# one digit. Yuck.
2965
2966_parser = re.compile(r"""
2967# \s*
2968 (?P<sign>[-+])?
2969 (
2970 (?P<int>\d+) (\. (?P<frac>\d*))?
2971 |
2972 \. (?P<onlyfrac>\d+)
2973 )
2974 ([eE](?P<exp>[-+]? \d+))?
2975# \s*
2976 $
2977""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
2978
2979del re
2980
2981# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
2982
2983def _string2exact(s):
2984 m = _parser(s)
2985 if m is None:
2986 raise ValueError("invalid literal for Decimal: %r" % s)
2987
2988 if m.group('sign') == "-":
2989 sign = 1
2990 else:
2991 sign = 0
2992
2993 exp = m.group('exp')
2994 if exp is None:
2995 exp = 0
2996 else:
2997 exp = int(exp)
2998
2999 intpart = m.group('int')
3000 if intpart is None:
3001 intpart = ""
3002 fracpart = m.group('onlyfrac')
3003 else:
3004 fracpart = m.group('frac')
3005 if fracpart is None:
3006 fracpart = ""
3007
3008 exp -= len(fracpart)
3009
3010 mantissa = intpart + fracpart
3011 tmp = map(int, mantissa)
3012 backup = tmp
3013 while tmp and tmp[0] == 0:
3014 del tmp[0]
3015
3016 # It's a zero
3017 if not tmp:
3018 if backup:
3019 return (sign, tuple(backup), exp)
3020 return (sign, (0,), exp)
3021 mantissa = tuple(tmp)
3022
3023 return (sign, mantissa, exp)
3024
3025
3026if __name__ == '__main__':
3027 import doctest, sys
3028 doctest.testmod(sys.modules[__name__])