blob: 63f99915151302c34a6a8b942d1f294ebbaed929 [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
10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000011"""
12This is a Py2.3 implementation of decimal floating point arithmetic based on
13the General Decimal Arithmetic Specification:
14
15 www2.hursley.ibm.com/decimal/decarith.html
16
Raymond Hettinger0ea241e2004-07-04 13:53:24 +000017and IEEE standard 854-1987:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000018
19 www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html
20
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000021Decimal floating point has finite precision with arbitrarily large bounds.
22
23The purpose of the module is to support arithmetic using familiar
24"schoolhouse" rules and to avoid the some of tricky representation
25issues associated with binary floating point. The package is especially
26useful for financial applications or for contexts where users have
27expectations that are at odds with binary floating point (for instance,
28in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead
29of the expected Decimal("0.00") returned by decimal floating point).
30
31Here are some examples of using the decimal module:
32
33>>> from decimal import *
Raymond Hettingerbd7f76d2004-07-08 00:49:18 +000034>>> setcontext(ExtendedContext)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000035>>> Decimal(0)
36Decimal("0")
37>>> Decimal("1")
38Decimal("1")
39>>> Decimal("-.0123")
40Decimal("-0.0123")
41>>> Decimal(123456)
42Decimal("123456")
43>>> Decimal("123.45e12345678901234567890")
44Decimal("1.2345E+12345678901234567892")
45>>> Decimal("1.33") + Decimal("1.27")
46Decimal("2.60")
47>>> Decimal("12.34") + Decimal("3.87") - Decimal("18.41")
48Decimal("-2.20")
49>>> dig = Decimal(1)
50>>> print dig / Decimal(3)
510.333333333
52>>> getcontext().prec = 18
53>>> print dig / Decimal(3)
540.333333333333333333
55>>> print dig.sqrt()
561
57>>> print Decimal(3).sqrt()
581.73205080756887729
59>>> print Decimal(3) ** 123
604.85192780976896427E+58
61>>> inf = Decimal(1) / Decimal(0)
62>>> print inf
63Infinity
64>>> neginf = Decimal(-1) / Decimal(0)
65>>> print neginf
66-Infinity
67>>> print neginf + inf
68NaN
69>>> print neginf * inf
70-Infinity
71>>> print dig / 0
72Infinity
Raymond Hettingerbf440692004-07-10 14:14:37 +000073>>> getcontext().traps[DivisionByZero] = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000074>>> print dig / 0
75Traceback (most recent call last):
76 ...
77 ...
78 ...
79DivisionByZero: x / 0
80>>> c = Context()
Raymond Hettingerbf440692004-07-10 14:14:37 +000081>>> c.traps[InvalidOperation] = 0
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000082>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000830
84>>> c.divide(Decimal(0), Decimal(0))
85Decimal("NaN")
Raymond Hettingerbf440692004-07-10 14:14:37 +000086>>> c.traps[InvalidOperation] = 1
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000087>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000881
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000089>>> c.flags[InvalidOperation] = 0
90>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000910
92>>> print c.divide(Decimal(0), Decimal(0))
93Traceback (most recent call last):
94 ...
95 ...
96 ...
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000097InvalidOperation: 0 / 0
98>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000991
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000100>>> c.flags[InvalidOperation] = 0
Raymond Hettingerbf440692004-07-10 14:14:37 +0000101>>> c.traps[InvalidOperation] = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000102>>> print c.divide(Decimal(0), Decimal(0))
103NaN
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000104>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001051
106>>>
107"""
108
109__all__ = [
110 # Two major classes
111 'Decimal', 'Context',
112
113 # Contexts
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +0000114 'DefaultContext', 'BasicContext', 'ExtendedContext',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000115
116 # Exceptions
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +0000117 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
118 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000119
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000120 # Constants for use in setting up contexts
121 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING',
122 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000123
124 # Functions for manipulating contexts
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000125 'setcontext', 'getcontext'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000126]
127
128import threading
129import copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000130import operator
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000131
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000132#Rounding
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000133ROUND_DOWN = 'ROUND_DOWN'
134ROUND_HALF_UP = 'ROUND_HALF_UP'
135ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
136ROUND_CEILING = 'ROUND_CEILING'
137ROUND_FLOOR = 'ROUND_FLOOR'
138ROUND_UP = 'ROUND_UP'
139ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000140
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +0000141#Rounding decision (not part of the public API)
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000142NEVER_ROUND = 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY
143ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000144
145#Errors
146
147class DecimalException(ArithmeticError):
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000148 """Base exception class.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000149
150 Used exceptions derive from this.
151 If an exception derives from another exception besides this (such as
152 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
153 called if the others are present. This isn't actually used for
154 anything, though.
155
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000156 handle -- Called when context._raise_error is called and the
157 trap_enabler is set. First argument is self, second is the
158 context. More arguments can be given, those being after
159 the explanation in _raise_error (For example,
160 context._raise_error(NewError, '(-x)!', self._sign) would
161 call NewError().handle(context, self._sign).)
162
163 To define a new exception, it should be sufficient to have it derive
164 from DecimalException.
165 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000166 def handle(self, context, *args):
167 pass
168
169
170class Clamped(DecimalException):
171 """Exponent of a 0 changed to fit bounds.
172
173 This occurs and signals clamped if the exponent of a result has been
174 altered in order to fit the constraints of a specific concrete
175 representation. This may occur when the exponent of a zero result would
176 be outside the bounds of a representation, or when a large normal
177 number would have an encoded exponent that cannot be represented. In
178 this latter case, the exponent is reduced to fit and the corresponding
179 number of zero digits are appended to the coefficient ("fold-down").
180 """
181
182
183class InvalidOperation(DecimalException):
184 """An invalid operation was performed.
185
186 Various bad things cause this:
187
188 Something creates a signaling NaN
189 -INF + INF
190 0 * (+-)INF
191 (+-)INF / (+-)INF
192 x % 0
193 (+-)INF % x
194 x._rescale( non-integer )
195 sqrt(-x) , x > 0
196 0 ** 0
197 x ** (non-integer)
198 x ** (+-)INF
199 An operand is invalid
200 """
201 def handle(self, context, *args):
202 if args:
203 if args[0] == 1: #sNaN, must drop 's' but keep diagnostics
204 return Decimal( (args[1]._sign, args[1]._int, 'n') )
205 return NaN
206
207class ConversionSyntax(InvalidOperation):
208 """Trying to convert badly formed string.
209
210 This occurs and signals invalid-operation if an string is being
211 converted to a number and it does not conform to the numeric string
212 syntax. The result is [0,qNaN].
213 """
214
215 def handle(self, context, *args):
216 return (0, (0,), 'n') #Passed to something which uses a tuple.
217
218class DivisionByZero(DecimalException, ZeroDivisionError):
219 """Division by 0.
220
221 This occurs and signals division-by-zero if division of a finite number
222 by zero was attempted (during a divide-integer or divide operation, or a
223 power operation with negative right-hand operand), and the dividend was
224 not zero.
225
226 The result of the operation is [sign,inf], where sign is the exclusive
227 or of the signs of the operands for divide, or is 1 for an odd power of
228 -0, for power.
229 """
230
231 def handle(self, context, sign, double = None, *args):
232 if double is not None:
233 return (Infsign[sign],)*2
234 return Infsign[sign]
235
236class DivisionImpossible(InvalidOperation):
237 """Cannot perform the division adequately.
238
239 This occurs and signals invalid-operation if the integer result of a
240 divide-integer or remainder operation had too many digits (would be
241 longer than precision). The result is [0,qNaN].
242 """
243
244 def handle(self, context, *args):
245 return (NaN, NaN)
246
247class DivisionUndefined(InvalidOperation, ZeroDivisionError):
248 """Undefined result of division.
249
250 This occurs and signals invalid-operation if division by zero was
251 attempted (during a divide-integer, divide, or remainder operation), and
252 the dividend is also zero. The result is [0,qNaN].
253 """
254
255 def handle(self, context, tup=None, *args):
256 if tup is not None:
257 return (NaN, NaN) #for 0 %0, 0 // 0
258 return NaN
259
260class Inexact(DecimalException):
261 """Had to round, losing information.
262
263 This occurs and signals inexact whenever the result of an operation is
264 not exact (that is, it needed to be rounded and any discarded digits
265 were non-zero), or if an overflow or underflow condition occurs. The
266 result in all cases is unchanged.
267
268 The inexact signal may be tested (or trapped) to determine if a given
269 operation (or sequence of operations) was inexact.
270 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000271 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000272
273class InvalidContext(InvalidOperation):
274 """Invalid context. Unknown rounding, for example.
275
276 This occurs and signals invalid-operation if an invalid context was
277 detected during an operation. This can occur if contexts are not checked
278 on creation and either the precision exceeds the capability of the
279 underlying concrete representation or an unknown or unsupported rounding
280 was specified. These aspects of the context need only be checked when
281 the values are required to be used. The result is [0,qNaN].
282 """
283
284 def handle(self, context, *args):
285 return NaN
286
287class Rounded(DecimalException):
288 """Number got rounded (not necessarily changed during rounding).
289
290 This occurs and signals rounded whenever the result of an operation is
291 rounded (that is, some zero or non-zero digits were discarded from the
292 coefficient), or if an overflow or underflow condition occurs. The
293 result in all cases is unchanged.
294
295 The rounded signal may be tested (or trapped) to determine if a given
296 operation (or sequence of operations) caused a loss of precision.
297 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000298 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000299
300class Subnormal(DecimalException):
301 """Exponent < Emin before rounding.
302
303 This occurs and signals subnormal whenever the result of a conversion or
304 operation is subnormal (that is, its adjusted exponent is less than
305 Emin, before any rounding). The result in all cases is unchanged.
306
307 The subnormal signal may be tested (or trapped) to determine if a given
308 or operation (or sequence of operations) yielded a subnormal result.
309 """
310 pass
311
312class Overflow(Inexact, Rounded):
313 """Numerical overflow.
314
315 This occurs and signals overflow if the adjusted exponent of a result
316 (from a conversion or from an operation that is not an attempt to divide
317 by zero), after rounding, would be greater than the largest value that
318 can be handled by the implementation (the value Emax).
319
320 The result depends on the rounding mode:
321
322 For round-half-up and round-half-even (and for round-half-down and
323 round-up, if implemented), the result of the operation is [sign,inf],
324 where sign is the sign of the intermediate result. For round-down, the
325 result is the largest finite number that can be represented in the
326 current precision, with the sign of the intermediate result. For
327 round-ceiling, the result is the same as for round-down if the sign of
328 the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
329 the result is the same as for round-down if the sign of the intermediate
330 result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
331 will also be raised.
332 """
333
334 def handle(self, context, sign, *args):
335 if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
336 ROUND_HALF_DOWN, ROUND_UP):
337 return Infsign[sign]
338 if sign == 0:
339 if context.rounding == ROUND_CEILING:
340 return Infsign[sign]
341 return Decimal((sign, (9,)*context.prec,
342 context.Emax-context.prec+1))
343 if sign == 1:
344 if context.rounding == ROUND_FLOOR:
345 return Infsign[sign]
346 return Decimal( (sign, (9,)*context.prec,
347 context.Emax-context.prec+1))
348
349
350class Underflow(Inexact, Rounded, Subnormal):
351 """Numerical underflow with result rounded to 0.
352
353 This occurs and signals underflow if a result is inexact and the
354 adjusted exponent of the result would be smaller (more negative) than
355 the smallest value that can be handled by the implementation (the value
356 Emin). That is, the result is both inexact and subnormal.
357
358 The result after an underflow will be a subnormal number rounded, if
359 necessary, so that its exponent is not less than Etiny. This may result
360 in 0 with the sign of the intermediate result and an exponent of Etiny.
361
362 In all cases, Inexact, Rounded, and Subnormal will also be raised.
363 """
364
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000365# List of public traps and flags
Raymond Hettingerfed52962004-07-14 15:41:57 +0000366_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000367 Underflow, InvalidOperation, Subnormal]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000368
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000369# Map conditions (per the spec) to signals
370_condition_map = {ConversionSyntax:InvalidOperation,
371 DivisionImpossible:InvalidOperation,
372 DivisionUndefined:InvalidOperation,
373 InvalidContext:InvalidOperation}
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000374
375##### Context Functions #######################################
376
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000377# The getcontext() and setcontext() function manage access to a thread-local
378# current context. Py2.4 offers direct support for thread locals. If that
379# is not available, use threading.currentThread() which is slower but will
380# work for older Pythons.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000381
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000382try:
383 threading.local
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000384
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000385except AttributeError:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000386
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000387 #To fix reloading, force it to create a new context
388 #Old contexts have different exceptions in their dicts, making problems.
389 if hasattr(threading.currentThread(), '__decimal_context__'):
390 del threading.currentThread().__decimal_context__
391
392 def setcontext(context):
393 """Set this thread's context to context."""
394 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000395 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000396 context.clear_flags()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000397 threading.currentThread().__decimal_context__ = context
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000398
399 def getcontext():
400 """Returns this thread's context.
401
402 If this thread does not yet have a context, returns
403 a new context and sets this thread's context.
404 New contexts are copies of DefaultContext.
405 """
406 try:
407 return threading.currentThread().__decimal_context__
408 except AttributeError:
409 context = Context()
410 threading.currentThread().__decimal_context__ = context
411 return context
412
413else:
414
415 local = threading.local()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000416 if hasattr(local, '__decimal_context__'):
417 del local.__decimal_context__
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000418
419 def getcontext(_local=local):
420 """Returns this thread's context.
421
422 If this thread does not yet have a context, returns
423 a new context and sets this thread's context.
424 New contexts are copies of DefaultContext.
425 """
426 try:
427 return _local.__decimal_context__
428 except AttributeError:
429 context = Context()
430 _local.__decimal_context__ = context
431 return context
432
433 def setcontext(context, _local=local):
434 """Set this thread's context to context."""
435 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000436 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000437 context.clear_flags()
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000438 _local.__decimal_context__ = context
439
440 del threading, local # Don't contaminate the namespace
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000441
442
443##### Decimal class ###########################################
444
445class Decimal(object):
446 """Floating point class for decimal arithmetic."""
447
448 __slots__ = ('_exp','_int','_sign')
449
450 def __init__(self, value="0", context=None):
451 """Create a decimal point instance.
452
453 >>> Decimal('3.14') # string input
454 Decimal("3.14")
455 >>> Decimal((0, (3, 1, 4), -2)) # tuple input (sign, digit_tuple, exponent)
456 Decimal("3.14")
457 >>> Decimal(314) # int or long
458 Decimal("314")
459 >>> Decimal(Decimal(314)) # another decimal instance
460 Decimal("314")
461 """
462 if context is None:
463 context = getcontext()
464
465 if isinstance(value, (int,long)):
466 value = str(value)
467
468 # String?
469 # REs insist on real strings, so we can too.
470 if isinstance(value, basestring):
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000471 if _isinfinity(value):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000472 self._exp = 'F'
473 self._int = (0,)
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000474 sign = _isinfinity(value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000475 if sign == 1:
476 self._sign = 0
477 else:
478 self._sign = 1
479 return
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000480 if _isnan(value):
481 sig, sign, diag = _isnan(value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000482 if len(diag) > context.prec: #Diagnostic info too long
483 self._sign, self._int, self._exp = \
484 context._raise_error(ConversionSyntax)
485 return
486 if sig == 1:
487 self._exp = 'n' #qNaN
488 else: #sig == 2
489 self._exp = 'N' #sNaN
490 self._sign = sign
491 self._int = tuple(map(int, diag)) #Diagnostic info
492 return
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +0000493 try:
494 self._sign, self._int, self._exp = _string2exact(value)
495 except ValueError:
496 self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000497 return
498
499 # tuple/list conversion (possibly from as_tuple())
500 if isinstance(value, (list,tuple)):
501 if len(value) != 3:
502 raise ValueError, 'Invalid arguments'
503 if value[0] not in [0,1]:
504 raise ValueError, 'Invalid sign'
505 for digit in value[1]:
506 if not isinstance(digit, (int,long)) or digit < 0:
507 raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
508
509 self._sign = value[0]
510 self._int = tuple(value[1])
511 if value[2] in ('F','n','N'):
512 self._exp = value[2]
513 else:
514 self._exp = int(value[2])
515 return
516
517 # Turn an intermediate value back to Decimal()
518 if isinstance(value, _WorkRep):
519 if value.sign == 1:
520 self._sign = 0
521 else:
522 self._sign = 1
523 self._int = tuple(value.int)
524 self._exp = int(value.exp)
525 return
526
527 if isinstance(value, Decimal):
Tim Peters4e0e1b62004-07-07 20:54:48 +0000528 self._exp = value._exp
529 self._sign = value._sign
530 self._int = value._int
531 return
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000532
Raymond Hettingerbf440692004-07-10 14:14:37 +0000533 if isinstance(value, float):
534 raise TypeError("Cannot convert float to Decimal. " +
535 "First convert the float to a string")
536
537 raise TypeError("Cannot convert %r" % value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000538
539 def _convert_other(self, other):
540 """Convert other to Decimal.
541
542 Verifies that it's ok to use in an implicit construction.
543 """
544 if isinstance(other, Decimal):
545 return other
546 if isinstance(other, (int, long)):
547 other = Decimal(other)
548 return other
549
550 raise TypeError, "You can interact Decimal only with int, long or Decimal data types."
551
552 def _isnan(self):
553 """Returns whether the number is not actually one.
554
555 0 if a number
556 1 if NaN
557 2 if sNaN
558 """
559 if self._exp == 'n':
560 return 1
561 elif self._exp == 'N':
562 return 2
563 return 0
564
565 def _isinfinity(self):
566 """Returns whether the number is infinite
567
568 0 if finite or not a number
569 1 if +INF
570 -1 if -INF
571 """
572 if self._exp == 'F':
573 if self._sign:
574 return -1
575 return 1
576 return 0
577
578 def _check_nans(self, other = None, context=None):
579 """Returns whether the number is not actually one.
580
581 if self, other are sNaN, signal
582 if self, other are NaN return nan
583 return 0
584
585 Done before operations.
586 """
587 if context is None:
588 context = getcontext()
589
590 if self._isnan() == 2:
591 return context._raise_error(InvalidOperation, 'sNaN',
592 1, self)
593 if other is not None and other._isnan() == 2:
594 return context._raise_error(InvalidOperation, 'sNaN',
595 1, other)
596 if self._isnan():
597 return self
598 if other is not None and other._isnan():
599 return other
600 return 0
601
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000602 def __nonzero__(self):
603 """Is the number non-zero?
604
605 0 if self == 0
606 1 if self != 0
607 """
608 if isinstance(self._exp, str):
609 return 1
610 return self._int != (0,)*len(self._int)
611
612 def __cmp__(self, other, context=None):
613 if context is None:
614 context = getcontext()
615 other = self._convert_other(other)
616
617 ans = self._check_nans(other, context)
618 if ans:
619 return 1
620
621 if not self and not other:
622 return 0 #If both 0, sign comparison isn't certain.
623
624 #If different signs, neg one is less
625 if other._sign < self._sign:
626 return -1
627 if self._sign < other._sign:
628 return 1
629
630 # INF = INF
631 if self._isinfinity() and other._isinfinity():
632 return 0
633 if self._isinfinity():
634 return (-1)**self._sign
635 if other._isinfinity():
636 return -((-1)**other._sign)
637
638 if self.adjusted() == other.adjusted() and \
639 self._int + (0,)*(self._exp - other._exp) == \
640 other._int + (0,)*(other._exp - self._exp):
641 return 0 #equal, except in precision. ([0]*(-x) = [])
642 elif self.adjusted() > other.adjusted() and self._int[0] != 0:
643 return (-1)**self._sign
644 elif self.adjusted < other.adjusted() and other._int[0] != 0:
645 return -((-1)**self._sign)
646
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000647 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000648 rounding = context._set_rounding(ROUND_UP) #round away from 0
649
650 flags = context._ignore_all_flags()
651 res = self.__sub__(other, context=context)
652
653 context._regard_flags(*flags)
654
655 context.rounding = rounding
656
657 if not res:
658 return 0
659 elif res._sign:
660 return -1
661 return 1
662
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000663 def __eq__(self, other):
664 if not isinstance(other, (Decimal, int, long)):
665 return False
666 return self.__cmp__(other) == 0
667
668 def __ne__(self, other):
669 if not isinstance(other, (Decimal, int, long)):
670 return True
671 return self.__cmp__(other) != 0
672
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000673 def compare(self, other, context=None):
674 """Compares one to another.
675
676 -1 => a < b
677 0 => a = b
678 1 => a > b
679 NaN => one is NaN
680 Like __cmp__, but returns Decimal instances.
681 """
682 if context is None:
683 context = getcontext()
684 other = self._convert_other(other)
685
686 #compare(NaN, NaN) = NaN
687 ans = self._check_nans(other, context)
688 if ans:
689 return ans
690
691 return Decimal(self.__cmp__(other, context))
692
693 def __hash__(self):
694 """x.__hash__() <==> hash(x)"""
695 # Decimal integers must hash the same as the ints
696 # Non-integer decimals are normalized and hashed as strings
697 # Normalization assures that hast(100E-1) == hash(10)
698 i = int(self)
699 if self == Decimal(i):
700 return hash(i)
701 assert self.__nonzero__() # '-0' handled by integer case
702 return hash(str(self.normalize()))
703
704 def as_tuple(self):
705 """Represents the number as a triple tuple.
706
707 To show the internals exactly as they are.
708 """
709 return (self._sign, self._int, self._exp)
710
711 def __repr__(self):
712 """Represents the number as an instance of Decimal."""
713 # Invariant: eval(repr(d)) == d
714 return 'Decimal("%s")' % str(self)
715
716 def __str__(self, eng = 0, context=None):
717 """Return string representation of the number in scientific notation.
718
719 Captures all of the information in the underlying representation.
720 """
721
722 if self._isnan():
723 minus = '-'*self._sign
724 if self._int == (0,):
725 info = ''
726 else:
727 info = ''.join(map(str, self._int))
728 if self._isnan() == 2:
729 return minus + 'sNaN' + info
730 return minus + 'NaN' + info
731 if self._isinfinity():
732 minus = '-'*self._sign
733 return minus + 'Infinity'
734
735 if context is None:
736 context = getcontext()
737
738 tmp = map(str, self._int)
739 numdigits = len(self._int)
740 leftdigits = self._exp + numdigits
741 if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
742 if self._exp < 0 and self._exp >= -6: #short, no need for e/E
743 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
744 return s
745 #exp is closest mult. of 3 >= self._exp
746 exp = ((self._exp - 1)// 3 + 1) * 3
747 if exp != self._exp:
748 s = '0.'+'0'*(exp - self._exp)
749 else:
750 s = '0'
751 if exp != 0:
752 if context.capitals:
753 s += 'E'
754 else:
755 s += 'e'
756 if exp > 0:
757 s += '+' #0.0e+3, not 0.0e3
758 s += str(exp)
759 s = '-'*self._sign + s
760 return s
761 if eng:
762 dotplace = (leftdigits-1)%3+1
763 adjexp = leftdigits -1 - (leftdigits-1)%3
764 else:
765 adjexp = leftdigits-1
766 dotplace = 1
767 if self._exp == 0:
768 pass
769 elif self._exp < 0 and adjexp >= 0:
770 tmp.insert(leftdigits, '.')
771 elif self._exp < 0 and adjexp >= -6:
772 tmp[0:0] = ['0'] * int(-leftdigits)
773 tmp.insert(0, '0.')
774 else:
775 if numdigits > dotplace:
776 tmp.insert(dotplace, '.')
777 elif numdigits < dotplace:
778 tmp.extend(['0']*(dotplace-numdigits))
779 if adjexp:
780 if not context.capitals:
781 tmp.append('e')
782 else:
783 tmp.append('E')
784 if adjexp > 0:
785 tmp.append('+')
786 tmp.append(str(adjexp))
787 if eng:
788 while tmp[0:1] == ['0']:
789 tmp[0:1] = []
790 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
791 tmp[0:0] = ['0']
792 if self._sign:
793 tmp.insert(0, '-')
794
795 return ''.join(tmp)
796
797 def to_eng_string(self, context=None):
798 """Convert to engineering-type string.
799
800 Engineering notation has an exponent which is a multiple of 3, so there
801 are up to 3 digits left of the decimal place.
802
803 Same rules for when in exponential and when as a value as in __str__.
804 """
805 if context is None:
806 context = getcontext()
807 return self.__str__(eng=1, context=context)
808
809 def __neg__(self, context=None):
810 """Returns a copy with the sign switched.
811
812 Rounds, if it has reason.
813 """
814 if context is None:
815 context = getcontext()
816 ans = self._check_nans(context=context)
817 if ans:
818 return ans
819
820 if not self:
821 # -Decimal('0') is Decimal('0'), not Decimal('-0')
822 sign = 0
823 elif self._sign:
824 sign = 0
825 else:
826 sign = 1
827 if context._rounding_decision == ALWAYS_ROUND:
828 return Decimal((sign, self._int, self._exp))._fix(context=context)
829 return Decimal( (sign, self._int, self._exp))
830
831 def __pos__(self, context=None):
832 """Returns a copy, unless it is a sNaN.
833
834 Rounds the number (if more then precision digits)
835 """
836 if context is None:
837 context = getcontext()
838 ans = self._check_nans(context=context)
839 if ans:
840 return ans
841
842 sign = self._sign
843 if not self:
844 # + (-0) = 0
845 sign = 0
846
847 if context._rounding_decision == ALWAYS_ROUND:
848 ans = self._fix(context=context)
849 else:
850 ans = Decimal(self)
851 ans._sign = sign
852 return ans
853
854 def __abs__(self, round=1, context=None):
855 """Returns the absolute value of self.
856
857 If the second argument is 0, do not round.
858 """
859 if context is None:
860 context = getcontext()
861 ans = self._check_nans(context=context)
862 if ans:
863 return ans
864
865 if not round:
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000866 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000867 context._set_rounding_decision(NEVER_ROUND)
868
869 if self._sign:
870 ans = self.__neg__(context=context)
871 else:
872 ans = self.__pos__(context=context)
873
874 return ans
875
876 def __add__(self, other, context=None):
877 """Returns self + other.
878
879 -INF + INF (or the reverse) cause InvalidOperation errors.
880 """
881 if context is None:
882 context = getcontext()
883 other = self._convert_other(other)
884
885 ans = self._check_nans(other, context)
886 if ans:
887 return ans
888
889 if self._isinfinity():
890 #If both INF, same sign => same as both, opposite => error.
891 if self._sign != other._sign and other._isinfinity():
892 return context._raise_error(InvalidOperation, '-INF + INF')
893 return Decimal(self)
894 if other._isinfinity():
895 return Decimal(other) #Can't both be infinity here
896
897 shouldround = context._rounding_decision == ALWAYS_ROUND
898
899 exp = min(self._exp, other._exp)
900 negativezero = 0
901 if context.rounding == ROUND_FLOOR and self._sign != other._sign:
902 #If the answer is 0, the sign should be negative, in this case.
903 negativezero = 1
904
905 if not self and not other:
906 sign = min(self._sign, other._sign)
907 if negativezero:
908 sign = 1
909 return Decimal( (sign, (0,), exp))
910 if not self:
911 if exp < other._exp - context.prec-1:
912 exp = other._exp - context.prec-1
913 ans = other._rescale(exp, watchexp=0, context=context)
914 if shouldround:
915 ans = ans._fix(context=context)
916 return ans
917 if not other:
918 if exp < self._exp - context.prec-1:
919 exp = self._exp - context.prec-1
920 ans = self._rescale(exp, watchexp=0, context=context)
921 if shouldround:
922 ans = ans._fix(context=context)
923 return ans
924
925 op1 = _WorkRep(self)
926 op2 = _WorkRep(other)
927 op1, op2 = _normalize(op1, op2, shouldround, context.prec)
928
929 result = _WorkRep()
930
931 if op1.sign != op2.sign:
932 diff = cmp(abs(op1), abs(op2))
933 # Equal and opposite
934 if diff == 0:
935 if exp < context.Etiny():
936 exp = context.Etiny()
937 context._raise_error(Clamped)
938 return Decimal((negativezero, (0,), exp))
939 if diff < 0:
940 op1, op2 = op2, op1
941 #OK, now abs(op1) > abs(op2)
942 if op1.sign == -1:
943 result.sign = -1
944 op1.sign, op2.sign = op2.sign, op1.sign
945 else:
946 result.sign = 1
947 #So we know the sign, and op1 > 0.
948 elif op1.sign == -1:
949 result.sign = -1
950 op1.sign, op2.sign = (1, 1)
951 else:
952 result.sign = 1
953 #Now, op1 > abs(op2) > 0
954
955 op1.int.reverse()
956 op2.int.reverse()
957
958 if op2.sign == 1:
959 result.int = resultint = map(operator.add, op1.int, op2.int)
960 carry = 0
961 for i in xrange(len(op1.int)):
962 tmp = resultint[i] + carry
963 carry = 0
964 if tmp > 9:
965 carry = 1
966 tmp -= 10
967 resultint[i] = tmp
968 if carry:
969 resultint.append(1)
970 else:
971 result.int = resultint = map(operator.sub, op1.int, op2.int)
972 loan = 0
973 for i in xrange(len(op1.int)):
974 tmp = resultint[i] - loan
975 loan = 0
976 if tmp < 0:
977 loan = 1
978 tmp += 10
979 resultint[i] = tmp
980 assert not loan
981
982 while resultint[-1] == 0:
983 resultint.pop()
984 resultint.reverse()
985
986 result.exp = op1.exp
987 ans = Decimal(result)
988 if shouldround:
989 ans = ans._fix(context=context)
990 return ans
991
992 __radd__ = __add__
993
994 def __sub__(self, other, context=None):
995 """Return self + (-other)"""
996 if context is None:
997 context = getcontext()
998 other = self._convert_other(other)
999
1000 ans = self._check_nans(other, context=context)
1001 if ans:
1002 return ans
1003
1004 # -Decimal(0) = Decimal(0), which we don't want since
1005 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
1006 # so we change the sign directly to a copy
1007 tmp = Decimal(other)
1008 tmp._sign = 1-tmp._sign
1009
1010 return self.__add__(tmp, context=context)
1011
1012 def __rsub__(self, other, context=None):
1013 """Return other + (-self)"""
1014 if context is None:
1015 context = getcontext()
1016 other = self._convert_other(other)
1017
1018 tmp = Decimal(self)
1019 tmp._sign = 1 - tmp._sign
1020 return other.__add__(tmp, context=context)
1021
1022 def _increment(self, round=1, context=None):
1023 """Special case of add, adding 1eExponent
1024
1025 Since it is common, (rounding, for example) this adds
1026 (sign)*one E self._exp to the number more efficiently than add.
1027
1028 For example:
1029 Decimal('5.624e10')._increment() == Decimal('5.625e10')
1030 """
1031 if context is None:
1032 context = getcontext()
1033 ans = self._check_nans(context=context)
1034 if ans:
1035 return ans
1036
1037 L = list(self._int)
1038 L[-1] += 1
1039 spot = len(L)-1
1040 while L[spot] == 10:
1041 L[spot] = 0
1042 if spot == 0:
1043 L[0:0] = [1]
1044 break
1045 L[spot-1] += 1
1046 spot -= 1
1047 ans = Decimal((self._sign, L, self._exp))
1048
1049 if round and context._rounding_decision == ALWAYS_ROUND:
1050 ans = ans._fix(context=context)
1051 return ans
1052
1053 def __mul__(self, other, context=None):
1054 """Return self * other.
1055
1056 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1057 """
1058 if context is None:
1059 context = getcontext()
1060 other = self._convert_other(other)
1061
1062 ans = self._check_nans(other, context)
1063 if ans:
1064 return ans
1065
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001066 resultsign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001067 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]
1076
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
1085 ans = ans._fix(context=context)
1086 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:
1092 ans = ans._fix(context=context)
1093 return ans
1094 if other._int == (1,):
1095 ans = Decimal((resultsign, self._int, resultexp))
1096 if shouldround:
1097 ans = ans._fix(context=context)
1098 return ans
1099
1100 op1 = list(self._int)
1101 op2 = list(other._int)
1102 op1.reverse()
1103 op2.reverse()
1104 # Minimize Decimal additions
1105 if len(op2) > len(op1):
1106 op1, op2 = op2, op1
1107
1108 _divmod = divmod
1109 accumulator = [0]*(len(self._int) + len(other._int))
1110 for i in xrange(len(op2)):
1111 if op2[i] == 0:
1112 continue
1113 mult = op2[i]
1114 carry = 0
1115 for j in xrange(len(op1)):
1116 carry, accumulator[i+j] = _divmod( mult * op1[j] + carry
1117 + accumulator[i+j], 10)
1118
1119 if carry:
1120 accumulator[i + j + 1] += carry
1121 while not accumulator[-1]:
1122 accumulator.pop()
1123 accumulator.reverse()
1124
1125 ans = Decimal( (resultsign, accumulator, resultexp))
1126 if shouldround:
1127 ans = ans._fix(context=context)
1128
1129 return ans
1130 __rmul__ = __mul__
1131
1132 def __div__(self, other, context=None):
1133 """Return self / other."""
1134 return self._divide(other, context=context)
1135 __truediv__ = __div__
1136
1137 def _divide(self, other, divmod = 0, context=None):
1138 """Return a / b, to context.prec precision.
1139
1140 divmod:
1141 0 => true division
1142 1 => (a //b, a%b)
1143 2 => a //b
1144 3 => a%b
1145
1146 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1147 computing the other value are not raised.
1148 """
1149 if context is None:
1150 context = getcontext()
1151 other = self._convert_other(other)
1152
1153 ans = self._check_nans(other, context)
1154 if ans:
1155 if divmod:
1156 return (ans, ans)
1157 else:
1158 return ans
1159
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001160 sign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001161 if not self and not other:
1162 if divmod:
1163 return context._raise_error(DivisionUndefined, '0 / 0', 1)
1164 return context._raise_error(DivisionUndefined, '0 / 0')
1165 if self._isinfinity() and other._isinfinity():
1166 if not divmod:
1167 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
1168 else:
1169 return (context._raise_error(InvalidOperation,
1170 '(+-)INF // (+-)INF'),
1171 context._raise_error(InvalidOperation,
1172 '(+-)INF % (+-)INF'))
1173
1174 if not divmod:
1175 if other._isinfinity():
1176 context._raise_error(Clamped, 'Division by infinity')
1177 return Decimal((sign, (0,), context.Etiny()))
1178 if self._isinfinity():
1179 return Infsign[sign]
1180 #These two have different precision.
1181 if not self:
1182 exp = self._exp - other._exp
1183 if exp < context.Etiny():
1184 exp = context.Etiny()
1185 context._raise_error(Clamped, '0e-x / y')
1186 if exp > context.Emax:
1187 exp = context.Emax
1188 context._raise_error(Clamped, '0e+x / y')
1189 return Decimal( (sign, (0,), exp) )
1190
1191 if not other:
1192 return context._raise_error(DivisionByZero, 'x / 0', sign)
1193 if divmod:
1194 if other._isinfinity():
1195 return (Decimal((sign, (0,), 0)), Decimal(self))
1196 if self._isinfinity():
1197 if divmod == 1:
1198 return (Infsign[sign],
1199 context._raise_error(InvalidOperation, 'INF % x'))
1200 elif divmod == 2:
1201 return (Infsign[sign], NaN)
1202 elif divmod == 3:
1203 return (Infsign[sign],
1204 context._raise_error(InvalidOperation, 'INF % x'))
1205 if not self:
1206 otherside = Decimal(self)
1207 otherside._exp = min(self._exp, other._exp)
1208 return (Decimal((sign, (0,), 0)), otherside)
1209
1210 if not other:
1211 return context._raise_error(DivisionByZero, 'divmod(x,0)',
1212 sign, 1)
1213
1214 #OK, so neither = 0, INF
1215
1216 shouldround = context._rounding_decision == ALWAYS_ROUND
1217
1218 #If we're dividing into ints, and self < other, stop.
1219 #self.__abs__(0) does not round.
1220 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
1221
1222 if divmod == 1 or divmod == 3:
1223 exp = min(self._exp, other._exp)
1224 ans2 = self._rescale(exp, context=context, watchexp=0)
1225 if shouldround:
1226 ans2 = ans2._fix(context=context)
1227 return (Decimal( (sign, (0,), 0) ),
1228 ans2)
1229
1230 elif divmod == 2:
1231 #Don't round the mod part, if we don't need it.
1232 return (Decimal( (sign, (0,), 0) ), Decimal(self))
1233
1234 if sign:
1235 sign = -1
1236 else:
1237 sign = 1
1238 adjust = 0
1239 op1 = _WorkRep(self)
1240 op2 = _WorkRep(other)
1241 op1, op2, adjust = _adjust_coefficients(op1, op2)
1242 res = _WorkRep( (sign, [0], (op1.exp - op2.exp)) )
1243 if divmod and res.exp > context.prec + 1:
1244 return context._raise_error(DivisionImpossible)
1245
1246 ans = None
1247 while 1:
1248 while( (len(op2.int) < len(op1.int) and op1.int[0]) or
1249 (len(op2.int) == len(op1.int) and op2.int <= op1.int)):
1250 #Meaning, while op2.int < op1.int, when normalized.
1251 res._increment()
1252 op1.subtract(op2.int)
1253 if res.exp == 0 and divmod:
1254 if len(res.int) > context.prec and shouldround:
1255 return context._raise_error(DivisionImpossible)
1256 otherside = Decimal(op1)
1257 frozen = context._ignore_all_flags()
1258
1259 exp = min(self._exp, other._exp)
1260 otherside = otherside._rescale(exp, context=context,
1261 watchexp=0)
1262 context._regard_flags(*frozen)
1263 if shouldround:
1264 otherside = otherside._fix(context=context)
1265 return (Decimal(res), otherside)
1266
1267 if op1.int == [0]*len(op1.int) and adjust >= 0 and not divmod:
1268 break
1269 if (len(res.int) > context.prec) and shouldround:
1270 if divmod:
1271 return context._raise_error(DivisionImpossible)
1272 shouldround=1
1273 # Really, the answer is a bit higher, so adding a one to
1274 # the end will make sure the rounding is right.
1275 if op1.int != [0]*len(op1.int):
1276 res.int.append(1)
1277 res.exp -= 1
1278
1279 break
1280 res.exp -= 1
1281 adjust += 1
1282 res.int.append(0)
1283 op1.int.append(0)
1284 op1.exp -= 1
1285
1286 if res.exp == 0 and divmod and (len(op2.int) > len(op1.int) or
1287 (len(op2.int) == len(op1.int) and
1288 op2.int > op1.int)):
1289 #Solves an error in precision. Same as a previous block.
1290
1291 if len(res.int) > context.prec and shouldround:
1292 return context._raise_error(DivisionImpossible)
1293 otherside = Decimal(op1)
1294 frozen = context._ignore_all_flags()
1295
1296 exp = min(self._exp, other._exp)
1297 otherside = otherside._rescale(exp, context=context)
1298
1299 context._regard_flags(*frozen)
1300
1301 return (Decimal(res), otherside)
1302
1303 ans = Decimal(res)
1304 if shouldround:
1305 ans = ans._fix(context=context)
1306 return ans
1307
1308 def __rdiv__(self, other, context=None):
1309 """Swaps self/other and returns __div__."""
1310 other = self._convert_other(other)
1311 return other.__div__(self, context=context)
1312 __rtruediv__ = __rdiv__
1313
1314 def __divmod__(self, other, context=None):
1315 """
1316 (self // other, self % other)
1317 """
1318 return self._divide(other, 1, context)
1319
1320 def __rdivmod__(self, other, context=None):
1321 """Swaps self/other and returns __divmod__."""
1322 other = self._convert_other(other)
1323 return other.__divmod__(self, context=context)
1324
1325 def __mod__(self, other, context=None):
1326 """
1327 self % other
1328 """
1329 if context is None:
1330 context = getcontext()
1331 other = self._convert_other(other)
1332
1333 ans = self._check_nans(other, context)
1334 if ans:
1335 return ans
1336
1337 if self and not other:
1338 return context._raise_error(InvalidOperation, 'x % 0')
1339
1340 return self._divide(other, 3, context)[1]
1341
1342 def __rmod__(self, other, context=None):
1343 """Swaps self/other and returns __mod__."""
1344 other = self._convert_other(other)
1345 return other.__mod__(self, context=context)
1346
1347 def remainder_near(self, other, context=None):
1348 """
1349 Remainder nearest to 0- abs(remainder-near) <= other/2
1350 """
1351 if context is None:
1352 context = getcontext()
1353 other = self._convert_other(other)
1354
1355 ans = self._check_nans(other, context)
1356 if ans:
1357 return ans
1358 if self and not other:
1359 return context._raise_error(InvalidOperation, 'x % 0')
1360
1361 # If DivisionImpossible causes an error, do not leave Rounded/Inexact
1362 # ignored in the calling function.
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001363 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001364 flags = context._ignore_flags(Rounded, Inexact)
1365 #keep DivisionImpossible flags
1366 (side, r) = self.__divmod__(other, context=context)
1367
1368 if r._isnan():
1369 context._regard_flags(*flags)
1370 return r
1371
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001372 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001373 rounding = context._set_rounding_decision(NEVER_ROUND)
1374
1375 if other._sign:
1376 comparison = other.__div__(Decimal(-2), context=context)
1377 else:
1378 comparison = other.__div__(Decimal(2), context=context)
1379
1380 context._set_rounding_decision(rounding)
1381 context._regard_flags(*flags)
1382
1383 s1, s2 = r._sign, comparison._sign
1384 r._sign, comparison._sign = 0, 0
1385
1386 if r < comparison:
1387 r._sign, comparison._sign = s1, s2
1388 #Get flags now
1389 self.__divmod__(other, context=context)
1390 return r._fix(context=context)
1391 r._sign, comparison._sign = s1, s2
1392
1393 rounding = context._set_rounding_decision(NEVER_ROUND)
1394
1395 (side, r) = self.__divmod__(other, context=context)
1396 context._set_rounding_decision(rounding)
1397 if r._isnan():
1398 return r
1399
1400 decrease = not side._iseven()
1401 rounding = context._set_rounding_decision(NEVER_ROUND)
1402 side = side.__abs__(context=context)
1403 context._set_rounding_decision(rounding)
1404
1405 s1, s2 = r._sign, comparison._sign
1406 r._sign, comparison._sign = 0, 0
1407 if r > comparison or decrease and r == comparison:
1408 r._sign, comparison._sign = s1, s2
1409 context.prec += 1
1410 if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
1411 context.prec -= 1
1412 return context._raise_error(DivisionImpossible)[1]
1413 context.prec -= 1
1414 if self._sign == other._sign:
1415 r = r.__sub__(other, context=context)
1416 else:
1417 r = r.__add__(other, context=context)
1418 else:
1419 r._sign, comparison._sign = s1, s2
1420
1421 return r._fix(context=context)
1422
1423 def __floordiv__(self, other, context=None):
1424 """self // other"""
1425 return self._divide(other, 2, context)[0]
1426
1427 def __rfloordiv__(self, other, context=None):
1428 """Swaps self/other and returns __floordiv__."""
1429 other = self._convert_other(other)
1430 return other.__floordiv__(self, context=context)
1431
1432 def __float__(self):
1433 """Float representation."""
1434 return float(str(self))
1435
1436 def __int__(self):
1437 """Converts self to a int, truncating if necessary."""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001438 if self._isnan():
1439 context = getcontext()
1440 return context._raise_error(InvalidContext)
1441 elif self._isinfinity():
1442 raise OverflowError, "Cannot convert infinity to long"
1443 if not self:
1444 return 0
1445 sign = '-'*self._sign
1446 if self._exp >= 0:
1447 s = sign + ''.join(map(str, self._int)) + '0'*self._exp
1448 return int(s)
1449 s = sign + ''.join(map(str, self._int))[:self._exp]
1450 return int(s)
1451 tmp = list(self._int)
1452 tmp.reverse()
1453 val = 0
1454 while tmp:
1455 val *= 10
1456 val += tmp.pop()
1457 return int(((-1) ** self._sign) * val * 10.**int(self._exp))
1458
1459 def __long__(self):
1460 """Converts to a long.
1461
1462 Equivalent to long(int(self))
1463 """
1464 return long(self.__int__())
1465
1466 def _fix(self, prec=None, rounding=None, folddown=None, context=None):
1467 """Round if it is necessary to keep self within prec precision.
1468
1469 Rounds and fixes the exponent. Does not raise on a sNaN.
1470
1471 Arguments:
1472 self - Decimal instance
1473 prec - precision to which to round. By default, the context decides.
1474 rounding - Rounding method. By default, the context decides.
1475 folddown - Fold down high elements, by default context._clamp
1476 context - context used.
1477 """
1478 if self._isinfinity() or self._isnan():
1479 return self
1480 if context is None:
1481 context = getcontext()
1482 if prec is None:
1483 prec = context.prec
1484 ans = Decimal(self)
1485 ans = ans._fixexponents(prec, rounding, folddown=folddown,
1486 context=context)
1487 if len(ans._int) > prec:
1488 ans = ans._round(prec, rounding, context=context)
1489 ans = ans._fixexponents(prec, rounding, folddown=folddown,
1490 context=context)
1491 return ans
1492
1493 def _fixexponents(self, prec=None, rounding=None, folddown=None,
1494 context=None):
1495 """Fix the exponents and return a copy with the exponent in bounds."""
1496 if self._isinfinity():
1497 return self
1498 if context is None:
1499 context = getcontext()
1500 if prec is None:
1501 prec = context.prec
1502 if folddown is None:
1503 folddown = context._clamp
1504 Emin, Emax = context.Emin, context.Emax
1505 Etop = context.Etop()
1506 ans = Decimal(self)
1507 if ans.adjusted() < Emin:
1508 Etiny = context.Etiny()
1509 if ans._exp < Etiny:
1510 if not ans:
1511 ans._exp = Etiny
1512 context._raise_error(Clamped)
1513 return ans
1514 ans = ans._rescale(Etiny, context=context)
1515 #It isn't zero, and exp < Emin => subnormal
1516 context._raise_error(Subnormal)
1517 if context.flags[Inexact]:
1518 context._raise_error(Underflow)
1519 else:
1520 if ans:
1521 #Only raise subnormal if non-zero.
1522 context._raise_error(Subnormal)
1523 elif folddown and ans._exp > Etop:
1524 context._raise_error(Clamped)
1525 ans = ans._rescale(Etop, context=context)
1526 elif ans.adjusted() > Emax:
1527 if not ans:
1528 ans._exp = Emax
1529 context._raise_error(Clamped)
1530 return ans
1531 context._raise_error(Inexact)
1532 context._raise_error(Rounded)
1533 return context._raise_error(Overflow, 'above Emax', ans._sign)
1534 return ans
1535
1536 def _round(self, prec=None, rounding=None, context=None):
1537 """Returns a rounded version of self.
1538
1539 You can specify the precision or rounding method. Otherwise, the
1540 context determines it.
1541 """
1542
1543 if context is None:
1544 context = getcontext()
1545 ans = self._check_nans(context=context)
1546 if ans:
1547 return ans
1548
1549 if self._isinfinity():
1550 return Decimal(self)
1551
1552 if rounding is None:
1553 rounding = context.rounding
1554 if prec is None:
1555 prec = context.prec
1556
1557 if not self:
1558 if prec <= 0:
1559 dig = (0,)
1560 exp = len(self._int) - prec + self._exp
1561 else:
1562 dig = (0,) * prec
1563 exp = len(self._int) + self._exp - prec
1564 ans = Decimal((self._sign, dig, exp))
1565 context._raise_error(Rounded)
1566 return ans
1567
1568 if prec == 0:
1569 temp = Decimal(self)
1570 temp._int = (0,)+temp._int
1571 prec = 1
1572 elif prec < 0:
1573 exp = self._exp + len(self._int) - prec - 1
1574 temp = Decimal( (self._sign, (0, 1), exp))
1575 prec = 1
1576 else:
1577 temp = Decimal(self)
1578
1579 numdigits = len(temp._int)
1580 if prec == numdigits:
1581 return temp
1582
1583 # See if we need to extend precision
1584 expdiff = prec - numdigits
1585 if expdiff > 0:
1586 tmp = list(temp._int)
1587 tmp.extend([0] * expdiff)
1588 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff))
1589 return ans
1590
1591 #OK, but maybe all the lost digits are 0.
1592 lostdigits = self._int[expdiff:]
1593 if lostdigits == (0,) * len(lostdigits):
1594 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
1595 #Rounded, but not Inexact
1596 context._raise_error(Rounded)
1597 return ans
1598
1599 # Okay, let's round and lose data
1600
1601 this_function = getattr(temp, self._pick_rounding_function[rounding])
1602 #Now we've got the rounding function
1603
1604 if prec != context.prec:
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001605 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001606 context.prec = prec
1607 ans = this_function(prec, expdiff, context)
1608 context._raise_error(Rounded)
1609 context._raise_error(Inexact, 'Changed in rounding')
1610
1611 return ans
1612
1613 _pick_rounding_function = {}
1614
1615 def _round_down(self, prec, expdiff, context):
1616 """Also known as round-towards-0, truncate."""
1617 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1618
1619 def _round_half_up(self, prec, expdiff, context, tmp = None):
1620 """Rounds 5 up (away from 0)"""
1621
1622 if tmp is None:
1623 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
1624 if self._int[prec] >= 5:
1625 tmp = tmp._increment(round=0, context=context)
1626 if len(tmp._int) > prec:
1627 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1628 return tmp
1629
1630 def _round_half_even(self, prec, expdiff, context):
1631 """Round 5 to even, rest to nearest."""
1632
1633 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1634 half = (self._int[prec] == 5)
1635 if half:
1636 for digit in self._int[prec+1:]:
1637 if digit != 0:
1638 half = 0
1639 break
1640 if half:
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001641 if self._int[prec-1] & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001642 return tmp
1643 return self._round_half_up(prec, expdiff, context, tmp)
1644
1645 def _round_half_down(self, prec, expdiff, context):
1646 """Round 5 down"""
1647
1648 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1649 half = (self._int[prec] == 5)
1650 if half:
1651 for digit in self._int[prec+1:]:
1652 if digit != 0:
1653 half = 0
1654 break
1655 if half:
1656 return tmp
1657 return self._round_half_up(prec, expdiff, context, tmp)
1658
1659 def _round_up(self, prec, expdiff, context):
1660 """Rounds away from 0."""
1661 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1662 for digit in self._int[prec:]:
1663 if digit != 0:
1664 tmp = tmp._increment(round=1, context=context)
1665 if len(tmp._int) > prec:
1666 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1667 else:
1668 return tmp
1669 return tmp
1670
1671 def _round_ceiling(self, prec, expdiff, context):
1672 """Rounds up (not away from 0 if negative.)"""
1673 if self._sign:
1674 return self._round_down(prec, expdiff, context)
1675 else:
1676 return self._round_up(prec, expdiff, context)
1677
1678 def _round_floor(self, prec, expdiff, context):
1679 """Rounds down (not towards 0 if negative)"""
1680 if not self._sign:
1681 return self._round_down(prec, expdiff, context)
1682 else:
1683 return self._round_up(prec, expdiff, context)
1684
1685 def __pow__(self, n, modulo = None, context=None):
1686 """Return self ** n (mod modulo)
1687
1688 If modulo is None (default), don't take it mod modulo.
1689 """
1690 if context is None:
1691 context = getcontext()
1692 n = self._convert_other(n)
1693
1694 #Because the spot << doesn't work with really big exponents
1695 if n._isinfinity() or n.adjusted() > 8:
1696 return context._raise_error(InvalidOperation, 'x ** INF')
1697
1698 ans = self._check_nans(n, context)
1699 if ans:
1700 return ans
1701
1702 if not n._isinfinity() and not n._isinteger():
1703 return context._raise_error(InvalidOperation, 'x ** (non-integer)')
1704
1705 if not self and not n:
1706 return context._raise_error(InvalidOperation, '0 ** 0')
1707
1708 if not n:
1709 return Decimal(1)
1710
1711 if self == Decimal(1):
1712 return Decimal(1)
1713
1714 sign = self._sign and not n._iseven()
1715 n = int(n)
1716
1717 if self._isinfinity():
1718 if modulo:
1719 return context._raise_error(InvalidOperation, 'INF % x')
1720 if n > 0:
1721 return Infsign[sign]
1722 return Decimal( (sign, (0,), 0) )
1723
1724 #with ludicrously large exponent, just raise an overflow and return inf.
1725 if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
1726 and self:
1727
1728 tmp = Decimal('inf')
1729 tmp._sign = sign
1730 context._raise_error(Rounded)
1731 context._raise_error(Inexact)
1732 context._raise_error(Overflow, 'Big power', sign)
1733 return tmp
1734
1735 elength = len(str(abs(n)))
1736 firstprec = context.prec
1737
Raymond Hettinger99148e72004-07-14 19:56:56 +00001738 if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001739 return context._raise_error(Overflow, 'Too much precision.', sign)
1740
1741 mul = Decimal(self)
1742 val = Decimal(1)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001743 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001744 context.prec = firstprec + elength + 1
1745 rounding = context.rounding
1746 if n < 0:
1747 #n is a long now, not Decimal instance
1748 n = -n
1749 mul = Decimal(1).__div__(mul, context=context)
1750
1751 shouldround = context._rounding_decision == ALWAYS_ROUND
1752
1753 spot = 1
1754 while spot <= n:
1755 spot <<= 1
1756
1757 spot >>= 1
1758 #Spot is the highest power of 2 less than n
1759 while spot:
1760 val = val.__mul__(val, context=context)
1761 if val._isinfinity():
1762 val = Infsign[sign]
1763 break
1764 if spot & n:
1765 val = val.__mul__(mul, context=context)
1766 if modulo is not None:
1767 val = val.__mod__(modulo, context=context)
1768 spot >>= 1
1769 context.prec = firstprec
1770
1771 if shouldround:
1772 return val._fix(context=context)
1773 return val
1774
1775 def __rpow__(self, other, context=None):
1776 """Swaps self/other and returns __pow__."""
1777 other = self._convert_other(other)
1778 return other.__pow__(self, context=context)
1779
1780 def normalize(self, context=None):
1781 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
1782 if context is None:
1783 context = getcontext()
1784
1785 ans = self._check_nans(context=context)
1786 if ans:
1787 return ans
1788
1789 dup = self._fix(context=context)
1790 if dup._isinfinity():
1791 return dup
1792
1793 if not dup:
1794 return Decimal( (dup._sign, (0,), 0) )
1795 end = len(dup._int)
1796 exp = dup._exp
1797 while dup._int[end-1] == 0:
1798 exp += 1
1799 end -= 1
1800 return Decimal( (dup._sign, dup._int[:end], exp) )
1801
1802
1803 def quantize(self, exp, rounding = None, context=None, watchexp = 1):
1804 """Quantize self so its exponent is the same as that of exp.
1805
1806 Similar to self._rescale(exp._exp) but with error checking.
1807 """
1808 if context is None:
1809 context = getcontext()
1810
1811 ans = self._check_nans(exp, context)
1812 if ans:
1813 return ans
1814
1815 if exp._isinfinity() or self._isinfinity():
1816 if exp._isinfinity() and self._isinfinity():
1817 return self #if both are inf, it is OK
1818 return context._raise_error(InvalidOperation,
1819 'quantize with one INF')
1820 return self._rescale(exp._exp, rounding, context, watchexp)
1821
1822 def same_quantum(self, other):
1823 """Test whether self and other have the same exponent.
1824
1825 same as self._exp == other._exp, except NaN == sNaN
1826 """
1827 if self._isnan() or other._isnan():
1828 return self._isnan() and other._isnan() and True
1829 if self._isinfinity() or other._isinfinity():
1830 return self._isinfinity() and other._isinfinity() and True
1831 return self._exp == other._exp
1832
1833 def _rescale(self, exp, rounding = None, context=None, watchexp = 1):
1834 """Rescales so that the exponent is exp.
1835
1836 exp = exp to scale to (an integer)
1837 rounding = rounding version
1838 watchexp: if set (default) an error is returned if exp is greater
1839 than Emax or less than Etiny.
1840 """
1841 if context is None:
1842 context = getcontext()
1843
1844 if self._isinfinity():
1845 return context._raise_error(InvalidOperation, 'rescale with an INF')
1846
1847 ans = self._check_nans(context=context)
1848 if ans:
1849 return ans
1850
1851 out = 0
1852
1853 if watchexp and (context.Emax < exp or context.Etiny() > exp):
1854 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1855
1856 if not self:
1857 ans = Decimal(self)
1858 ans._int = (0,)
1859 ans._exp = exp
1860 return ans
1861
1862 diff = self._exp - exp
1863 digits = len(self._int)+diff
1864
1865 if watchexp and digits > context.prec:
1866 return context._raise_error(InvalidOperation, 'Rescale > prec')
1867
1868 tmp = Decimal(self)
1869 tmp._int = (0,)+tmp._int
1870 digits += 1
1871
1872 prevexact = context.flags[Inexact]
1873 if digits < 0:
1874 tmp._exp = -digits + tmp._exp
1875 tmp._int = (0,1)
1876 digits = 1
1877 tmp = tmp._round(digits, rounding, context=context)
1878
1879 if tmp._int[0] == 0 and len(tmp._int) > 1:
1880 tmp._int = tmp._int[1:]
1881 tmp._exp = exp
1882
1883 if tmp and tmp.adjusted() < context.Emin:
1884 context._raise_error(Subnormal)
1885 elif tmp and tmp.adjusted() > context.Emax:
1886 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1887 return tmp
1888
1889 def to_integral(self, rounding = None, context=None):
1890 """Rounds to the nearest integer, without raising inexact, rounded."""
1891 if context is None:
1892 context = getcontext()
1893 ans = self._check_nans(context=context)
1894 if ans:
1895 return ans
1896 if self._exp >= 0:
1897 return self
1898 flags = context._ignore_flags(Rounded, Inexact)
1899 ans = self._rescale(0, rounding, context=context)
1900 context._regard_flags(flags)
1901 return ans
1902
1903 def sqrt(self, context=None):
1904 """Return the square root of self.
1905
1906 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
1907 Should quadratically approach the right answer.
1908 """
1909 if context is None:
1910 context = getcontext()
1911
1912 ans = self._check_nans(context=context)
1913 if ans:
1914 return ans
1915
1916 if not self:
1917 #exponent = self._exp / 2, using round_down.
1918 #if self._exp < 0:
1919 # exp = (self._exp+1) // 2
1920 #else:
1921 exp = (self._exp) // 2
1922 if self._sign == 1:
1923 #sqrt(-0) = -0
1924 return Decimal( (1, (0,), exp))
1925 else:
1926 return Decimal( (0, (0,), exp))
1927
1928 if self._sign == 1:
1929 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
1930
1931 if self._isinfinity():
1932 return Decimal(self)
1933
1934 tmp = Decimal(self)
1935
1936 expadd = tmp._exp / 2
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001937 if tmp._exp & 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001938 tmp._int += (0,)
1939 tmp._exp = 0
1940 else:
1941 tmp._exp = 0
1942
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001943 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001944 flags = context._ignore_all_flags()
1945 firstprec = context.prec
1946 context.prec = 3
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001947 if tmp.adjusted() & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001948 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) )
1949 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
1950 context=context), context=context)
1951 ans._exp -= 1 + tmp.adjusted()/2
1952 else:
1953 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
1954 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
1955 context=context), context=context)
1956 ans._exp -= 1 + tmp.adjusted()/2
1957
1958 #ans is now a linear approximation.
1959
1960 Emax, Emin = context.Emax, context.Emin
Raymond Hettinger99148e72004-07-14 19:56:56 +00001961 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001962
1963 half = Decimal('0.5')
1964
1965 count = 1
1966 maxp = firstprec + 2
1967 rounding = context._set_rounding(ROUND_HALF_EVEN)
1968 while 1:
1969 context.prec = min(2*context.prec - 2, maxp)
1970 ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
1971 context=context), context=context)
1972 if context.prec == maxp:
1973 break
1974
1975 #round to the answer's precision-- the only error can be 1 ulp.
1976 context.prec = firstprec
1977 prevexp = ans.adjusted()
1978 ans = ans._round(context=context)
1979
1980 #Now, check if the other last digits are better.
1981 context.prec = firstprec + 1
1982 # In case we rounded up another digit and we should actually go lower.
1983 if prevexp != ans.adjusted():
1984 ans._int += (0,)
1985 ans._exp -= 1
1986
1987
1988 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
1989 context._set_rounding(ROUND_UP)
1990 if lower.__mul__(lower, context=context) > (tmp):
1991 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
1992
1993 else:
1994 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
1995 context._set_rounding(ROUND_DOWN)
1996 if upper.__mul__(upper, context=context) < tmp:
1997 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
1998
1999 ans._exp += expadd
2000
2001 context.prec = firstprec
2002 context.rounding = rounding
2003 ans = ans._fix(context=context)
2004
2005 rounding = context._set_rounding_decision(NEVER_ROUND)
2006 if not ans.__mul__(ans, context=context) == self:
2007 # Only rounded/inexact if here.
2008 context._regard_flags(flags)
2009 context._raise_error(Rounded)
2010 context._raise_error(Inexact)
2011 else:
2012 #Exact answer, so let's set the exponent right.
2013 #if self._exp < 0:
2014 # exp = (self._exp +1)// 2
2015 #else:
2016 exp = self._exp // 2
2017 context.prec += ans._exp - exp
2018 ans = ans._rescale(exp, context=context)
2019 context.prec = firstprec
2020 context._regard_flags(flags)
2021 context.Emax, context.Emin = Emax, Emin
2022
2023 return ans._fix(context=context)
2024
2025 def max(self, other, context=None):
2026 """Returns the larger value.
2027
2028 like max(self, other) except if one is not a number, returns
2029 NaN (and signals if one is sNaN). Also rounds.
2030 """
2031 if context is None:
2032 context = getcontext()
2033 other = self._convert_other(other)
2034
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002035 # if one operand is a quiet NaN and the other is number, then the
2036 # number is always returned
2037 sn = self._isnan()
2038 on = other._isnan()
2039 if sn or on:
2040 if on == 1 and sn != 2:
2041 return self
2042 if sn == 1 and on != 2:
2043 return other
2044 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002045
2046 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002047 c = self.__cmp__(other)
2048 if c == 0:
2049 # if both operands are finite and equal in numerical value
2050 # then an ordering is applied:
2051 #
2052 # if the signs differ then max returns the operand with the
2053 # positive sign and min returns the operand with the negative sign
2054 #
2055 # if the signs are the same then the exponent is used to select
2056 # the result.
2057 if self._sign != other._sign:
2058 if self._sign:
2059 ans = other
2060 elif self._exp < other._exp and not self._sign:
2061 ans = other
2062 elif self._exp > other._exp and self._sign:
2063 ans = other
2064 elif c == -1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002065 ans = other
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002066 context._rounding_decision == ALWAYS_ROUND
2067 return ans._fix(context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002068
2069 def min(self, other, context=None):
2070 """Returns the smaller value.
2071
2072 like min(self, other) except if one is not a number, returns
2073 NaN (and signals if one is sNaN). Also rounds.
2074 """
2075 if context is None:
2076 context = getcontext()
2077 other = self._convert_other(other)
2078
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002079 # if one operand is a quiet NaN and the other is number, then the
2080 # number is always returned
2081 sn = self._isnan()
2082 on = other._isnan()
2083 if sn or on:
2084 if on == 1 and sn != 2:
2085 return self
2086 if sn == 1 and on != 2:
2087 return other
2088 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002089
2090 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002091 c = self.__cmp__(other)
2092 if c == 0:
2093 # if both operands are finite and equal in numerical value
2094 # then an ordering is applied:
2095 #
2096 # if the signs differ then max returns the operand with the
2097 # positive sign and min returns the operand with the negative sign
2098 #
2099 # if the signs are the same then the exponent is used to select
2100 # the result.
2101 if self._sign != other._sign:
2102 if other._sign:
2103 ans = other
2104 elif self._exp > other._exp and not self._sign:
2105 ans = other
2106 elif self._exp < other._exp and self._sign:
2107 ans = other
2108 elif c == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002109 ans = other
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002110 context._rounding_decision == ALWAYS_ROUND
2111 return ans._fix(context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002112
2113 def _isinteger(self):
2114 """Returns whether self is an integer"""
2115 if self._exp >= 0:
2116 return True
2117 rest = self._int[self._exp:]
2118 return rest == (0,)*len(rest)
2119
2120 def _iseven(self):
2121 """Returns 1 if self is even. Assumes self is an integer."""
2122 if self._exp > 0:
2123 return 1
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002124 return self._int[-1+self._exp] & 1 == 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002125
2126 def adjusted(self):
2127 """Return the adjusted exponent of self"""
2128 try:
2129 return self._exp + len(self._int) - 1
2130 #If NaN or Infinity, self._exp is string
2131 except TypeError:
2132 return 0
2133
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002134 # support for pickling, copy, and deepcopy
2135 def __reduce__(self):
2136 return (self.__class__, (str(self),))
2137
2138 def __copy__(self):
2139 if type(self) == Decimal:
2140 return self # I'm immutable; therefore I am my own clone
2141 return self.__class__(str(self))
2142
2143 def __deepcopy__(self, memo):
2144 if type(self) == Decimal:
2145 return self # My components are also immutable
2146 return self.__class__(str(self))
2147
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002148##### Context class ###########################################
2149
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002150
2151# get rounding method function:
2152rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
2153for name in rounding_functions:
2154 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
2155 globalname = name[1:].upper()
2156 val = globals()[globalname]
2157 Decimal._pick_rounding_function[val] = name
2158
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002159del name, val, globalname, rounding_functions
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002160
2161class Context(object):
2162 """Contains the context for a Decimal instance.
2163
2164 Contains:
2165 prec - precision (for use in rounding, division, square roots..)
2166 rounding - rounding type. (how you round)
2167 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
Raymond Hettingerbf440692004-07-10 14:14:37 +00002168 traps - If traps[exception] = 1, then the exception is
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002169 raised when it is caused. Otherwise, a value is
2170 substituted in.
2171 flags - When an exception is caused, flags[exception] is incremented.
2172 (Whether or not the trap_enabler is set)
2173 Should be reset by user of Decimal instance.
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002174 Emin - Minimum exponent
2175 Emax - Maximum exponent
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002176 capitals - If 1, 1*10^1 is printed as 1E+1.
2177 If 0, printed as 1e1
Raymond Hettingere0f15812004-07-05 05:36:39 +00002178 _clamp - If 1, change exponents if too high (Default 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002179 """
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002180
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002181 def __init__(self, prec=None, rounding=None,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002182 traps=None, flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002183 _rounding_decision=None,
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002184 Emin=None, Emax=None,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002185 capitals=None, _clamp=0,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002186 _ignored_flags=[]):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002187 if not isinstance(flags, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002188 flags = dict([(s,s in flags) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002189 del s
Raymond Hettingerbf440692004-07-10 14:14:37 +00002190 if traps is not None and not isinstance(traps, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002191 traps = dict([(s,s in traps) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002192 del s
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002193 for name, val in locals().items():
2194 if val is None:
2195 setattr(self, name, copy.copy(getattr(DefaultContext, name)))
2196 else:
2197 setattr(self, name, val)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002198 del self.self
2199
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002200 def __repr__(self):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002201 """Show the current context."""
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002202 s = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002203 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
2204 s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
2205 s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002206 return ', '.join(s) + ')'
2207
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002208 def clear_flags(self):
2209 """Reset all flags to zero"""
2210 for flag in self.flags:
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002211 self.flags[flag] = 0
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002212
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002213 def _shallow_copy(self):
2214 """Returns a shallow copy from self."""
Raymond Hettingerbf440692004-07-10 14:14:37 +00002215 nc = Context(self.prec, self.rounding, self.traps, self.flags,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002216 self._rounding_decision, self.Emin, self.Emax,
2217 self.capitals, self._clamp, self._ignored_flags)
2218 return nc
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002219
2220 def copy(self):
2221 """Returns a deep copy from self."""
2222 nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
2223 self._rounding_decision, self.Emin, self.Emax,
2224 self.capitals, self._clamp, self._ignored_flags)
2225 return nc
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002226 __copy__ = copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002227
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002228 def _raise_error(self, condition, explanation = None, *args):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002229 """Handles an error
2230
2231 If the flag is in _ignored_flags, returns the default response.
2232 Otherwise, it increments the flag, then, if the corresponding
2233 trap_enabler is set, it reaises the exception. Otherwise, it returns
2234 the default value after incrementing the flag.
2235 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002236 error = _condition_map.get(condition, condition)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002237 if error in self._ignored_flags:
2238 #Don't touch the flag
2239 return error().handle(self, *args)
2240
2241 self.flags[error] += 1
Raymond Hettingerbf440692004-07-10 14:14:37 +00002242 if not self.traps[error]:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002243 #The errors define how to handle themselves.
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002244 return condition().handle(self, *args)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002245
2246 # Errors should only be risked on copies of the context
2247 #self._ignored_flags = []
2248 raise error, explanation
2249
2250 def _ignore_all_flags(self):
2251 """Ignore all flags, if they are raised"""
Raymond Hettingerfed52962004-07-14 15:41:57 +00002252 return self._ignore_flags(*_signals)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002253
2254 def _ignore_flags(self, *flags):
2255 """Ignore the flags, if they are raised"""
2256 # Do not mutate-- This way, copies of a context leave the original
2257 # alone.
2258 self._ignored_flags = (self._ignored_flags + list(flags))
2259 return list(flags)
2260
2261 def _regard_flags(self, *flags):
2262 """Stop ignoring the flags, if they are raised"""
2263 if flags and isinstance(flags[0], (tuple,list)):
2264 flags = flags[0]
2265 for flag in flags:
2266 self._ignored_flags.remove(flag)
2267
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002268 def __hash__(self):
2269 """A Context cannot be hashed."""
2270 # We inherit object.__hash__, so we must deny this explicitly
2271 raise TypeError, "Cannot hash a Context."
2272
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002273 def Etiny(self):
2274 """Returns Etiny (= Emin - prec + 1)"""
2275 return int(self.Emin - self.prec + 1)
2276
2277 def Etop(self):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002278 """Returns maximum exponent (= Emax - prec + 1)"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002279 return int(self.Emax - self.prec + 1)
2280
2281 def _set_rounding_decision(self, type):
2282 """Sets the rounding decision.
2283
2284 Sets the rounding decision, and returns the current (previous)
2285 rounding decision. Often used like:
2286
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002287 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002288 # That so you don't change the calling context
2289 # if an error occurs in the middle (say DivisionImpossible is raised).
2290
2291 rounding = context._set_rounding_decision(NEVER_ROUND)
2292 instance = instance / Decimal(2)
2293 context._set_rounding_decision(rounding)
2294
2295 This will make it not round for that operation.
2296 """
2297
2298 rounding = self._rounding_decision
2299 self._rounding_decision = type
2300 return rounding
2301
2302 def _set_rounding(self, type):
2303 """Sets the rounding type.
2304
2305 Sets the rounding type, and returns the current (previous)
2306 rounding type. Often used like:
2307
2308 context = context.copy()
2309 # so you don't change the calling context
2310 # if an error occurs in the middle.
2311 rounding = context._set_rounding(ROUND_UP)
2312 val = self.__sub__(other, context=context)
2313 context._set_rounding(rounding)
2314
2315 This will make it round up for that operation.
2316 """
2317 rounding = self.rounding
2318 self.rounding= type
2319 return rounding
2320
Raymond Hettingerfed52962004-07-14 15:41:57 +00002321 def create_decimal(self, num='0'):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002322 """Creates a new Decimal instance but using self as context."""
2323 d = Decimal(num, context=self)
2324 return d._fix(context=self)
2325
2326 #Methods
2327 def abs(self, a):
2328 """Returns the absolute value of the operand.
2329
2330 If the operand is negative, the result is the same as using the minus
2331 operation on the operand. Otherwise, the result is the same as using
2332 the plus operation on the operand.
2333
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002334 >>> ExtendedContext.abs(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002335 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002336 >>> ExtendedContext.abs(Decimal('-100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002337 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002338 >>> ExtendedContext.abs(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002339 Decimal("101.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002340 >>> ExtendedContext.abs(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002341 Decimal("101.5")
2342 """
2343 return a.__abs__(context=self)
2344
2345 def add(self, a, b):
2346 """Return the sum of the two operands.
2347
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002348 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002349 Decimal("19.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002350 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002351 Decimal("1.02E+4")
2352 """
2353 return a.__add__(b, context=self)
2354
2355 def _apply(self, a):
2356 return str(a._fix(context=self))
2357
2358 def compare(self, a, b):
2359 """Compares values numerically.
2360
2361 If the signs of the operands differ, a value representing each operand
2362 ('-1' if the operand is less than zero, '0' if the operand is zero or
2363 negative zero, or '1' if the operand is greater than zero) is used in
2364 place of that operand for the comparison instead of the actual
2365 operand.
2366
2367 The comparison is then effected by subtracting the second operand from
2368 the first and then returning a value according to the result of the
2369 subtraction: '-1' if the result is less than zero, '0' if the result is
2370 zero or negative zero, or '1' if the result is greater than zero.
2371
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002372 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002373 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002374 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002375 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002376 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002377 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002378 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002379 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002380 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002381 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002382 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002383 Decimal("-1")
2384 """
2385 return a.compare(b, context=self)
2386
2387 def divide(self, a, b):
2388 """Decimal division in a specified context.
2389
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002390 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002391 Decimal("0.333333333")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002392 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002393 Decimal("0.666666667")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002394 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002395 Decimal("2.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002396 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002397 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002398 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002399 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002400 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002401 Decimal("4.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002402 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002403 Decimal("1.20")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002404 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002405 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002406 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002407 Decimal("1000")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002408 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002409 Decimal("1.20E+6")
2410 """
2411 return a.__div__(b, context=self)
2412
2413 def divide_int(self, a, b):
2414 """Divides two numbers and returns the integer part of the result.
2415
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002416 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002417 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002418 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002419 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002420 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002421 Decimal("3")
2422 """
2423 return a.__floordiv__(b, context=self)
2424
2425 def divmod(self, a, b):
2426 return a.__divmod__(b, context=self)
2427
2428 def max(self, a,b):
2429 """max compares two values numerically and returns the maximum.
2430
2431 If either operand is a NaN then the general rules apply.
2432 Otherwise, the operands are compared as as though by the compare
2433 operation. If they are numerically equal then the left-hand operand
2434 is chosen as the result. Otherwise the maximum (closer to positive
2435 infinity) of the two operands is chosen as the result.
2436
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002437 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002438 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002439 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002440 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002441 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002442 Decimal("1")
2443 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
2444 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002445 """
2446 return a.max(b, context=self)
2447
2448 def min(self, a,b):
2449 """min compares two values numerically and returns the minimum.
2450
2451 If either operand is a NaN then the general rules apply.
2452 Otherwise, the operands are compared as as though by the compare
2453 operation. If they are numerically equal then the left-hand operand
2454 is chosen as the result. Otherwise the minimum (closer to negative
2455 infinity) of the two operands is chosen as the result.
2456
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002457 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002458 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002459 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002460 Decimal("-10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002461 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002462 Decimal("1.0")
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002463 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
2464 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002465 """
2466 return a.min(b, context=self)
2467
2468 def minus(self, a):
2469 """Minus corresponds to unary prefix minus in Python.
2470
2471 The operation is evaluated using the same rules as subtract; the
2472 operation minus(a) is calculated as subtract('0', a) where the '0'
2473 has the same exponent as the operand.
2474
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002475 >>> ExtendedContext.minus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002476 Decimal("-1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002477 >>> ExtendedContext.minus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002478 Decimal("1.3")
2479 """
2480 return a.__neg__(context=self)
2481
2482 def multiply(self, a, b):
2483 """multiply multiplies two operands.
2484
2485 If either operand is a special value then the general rules apply.
2486 Otherwise, the operands are multiplied together ('long multiplication'),
2487 resulting in a number which may be as long as the sum of the lengths
2488 of the two operands.
2489
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002490 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002491 Decimal("3.60")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002492 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002493 Decimal("21")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002494 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002495 Decimal("0.72")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002496 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002497 Decimal("-0.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002498 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002499 Decimal("4.28135971E+11")
2500 """
2501 return a.__mul__(b, context=self)
2502
2503 def normalize(self, a):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002504 """normalize reduces an operand to its simplest form.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002505
2506 Essentially a plus operation with all trailing zeros removed from the
2507 result.
2508
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002509 >>> ExtendedContext.normalize(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002510 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002511 >>> ExtendedContext.normalize(Decimal('-2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002512 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002513 >>> ExtendedContext.normalize(Decimal('1.200'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002514 Decimal("1.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002515 >>> ExtendedContext.normalize(Decimal('-120'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002516 Decimal("-1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002517 >>> ExtendedContext.normalize(Decimal('120.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002518 Decimal("1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002519 >>> ExtendedContext.normalize(Decimal('0.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002520 Decimal("0")
2521 """
2522 return a.normalize(context=self)
2523
2524 def plus(self, a):
2525 """Plus corresponds to unary prefix plus in Python.
2526
2527 The operation is evaluated using the same rules as add; the
2528 operation plus(a) is calculated as add('0', a) where the '0'
2529 has the same exponent as the operand.
2530
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002531 >>> ExtendedContext.plus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002532 Decimal("1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002533 >>> ExtendedContext.plus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002534 Decimal("-1.3")
2535 """
2536 return a.__pos__(context=self)
2537
2538 def power(self, a, b, modulo=None):
2539 """Raises a to the power of b, to modulo if given.
2540
2541 The right-hand operand must be a whole number whose integer part (after
2542 any exponent has been applied) has no more than 9 digits and whose
2543 fractional part (if any) is all zeros before any rounding. The operand
2544 may be positive, negative, or zero; if negative, the absolute value of
2545 the power is used, and the left-hand operand is inverted (divided into
2546 1) before use.
2547
2548 If the increased precision needed for the intermediate calculations
2549 exceeds the capabilities of the implementation then an Invalid operation
2550 condition is raised.
2551
2552 If, when raising to a negative power, an underflow occurs during the
2553 division into 1, the operation is not halted at that point but
2554 continues.
2555
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002556 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002557 Decimal("8")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002558 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002559 Decimal("0.125")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002560 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002561 Decimal("69.7575744")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002562 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002563 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002564 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002565 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002566 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002567 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002568 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002569 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002570 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002571 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002572 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002573 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002574 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002575 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002576 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002577 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002578 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002579 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002580 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002581 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002582 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002583 Decimal("NaN")
2584 """
2585 return a.__pow__(b, modulo, context=self)
2586
2587 def quantize(self, a, b):
2588 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
2589
2590 The coefficient of the result is derived from that of the left-hand
2591 operand. It may be rounded using the current rounding setting (if the
2592 exponent is being increased), multiplied by a positive power of ten (if
2593 the exponent is being decreased), or is unchanged (if the exponent is
2594 already equal to that of the right-hand operand).
2595
2596 Unlike other operations, if the length of the coefficient after the
2597 quantize operation would be greater than precision then an Invalid
2598 operation condition is raised. This guarantees that, unless there is an
2599 error condition, the exponent of the result of a quantize is always
2600 equal to that of the right-hand operand.
2601
2602 Also unlike other operations, quantize will never raise Underflow, even
2603 if the result is subnormal and inexact.
2604
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002605 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002606 Decimal("2.170")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002607 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002608 Decimal("2.17")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002609 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002610 Decimal("2.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002611 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002612 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002613 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002614 Decimal("0E+1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002615 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002616 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002617 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002618 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002619 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002620 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002621 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002622 Decimal("-0E+5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002623 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002624 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002625 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002626 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002627 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002628 Decimal("217.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002629 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002630 Decimal("217")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002631 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002632 Decimal("2.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002633 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002634 Decimal("2E+2")
2635 """
2636 return a.quantize(b, context=self)
2637
2638 def remainder(self, a, b):
2639 """Returns the remainder from integer division.
2640
2641 The result is the residue of the dividend after the operation of
2642 calculating integer division as described for divide-integer, rounded to
2643 precision digits if necessary. The sign of the result, if non-zero, is
2644 the same as that of the original dividend.
2645
2646 This operation will fail under the same conditions as integer division
2647 (that is, if integer division on the same two operands would fail, the
2648 remainder cannot be calculated).
2649
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002650 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002651 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002652 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002653 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002654 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002655 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002656 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002657 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002658 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002659 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002660 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002661 Decimal("1.0")
2662 """
2663 return a.__mod__(b, context=self)
2664
2665 def remainder_near(self, a, b):
2666 """Returns to be "a - b * n", where n is the integer nearest the exact
2667 value of "x / b" (if two integers are equally near then the even one
2668 is chosen). If the result is equal to 0 then its sign will be the
2669 sign of a.
2670
2671 This operation will fail under the same conditions as integer division
2672 (that is, if integer division on the same two operands would fail, the
2673 remainder cannot be calculated).
2674
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002675 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002676 Decimal("-0.9")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002677 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002678 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002679 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002680 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002681 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002682 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002683 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002684 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002685 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002686 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002687 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002688 Decimal("-0.3")
2689 """
2690 return a.remainder_near(b, context=self)
2691
2692 def same_quantum(self, a, b):
2693 """Returns True if the two operands have the same exponent.
2694
2695 The result is never affected by either the sign or the coefficient of
2696 either operand.
2697
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002698 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002699 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002700 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002701 True
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002702 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002703 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002704 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002705 True
2706 """
2707 return a.same_quantum(b)
2708
2709 def sqrt(self, a):
2710 """Returns the square root of a non-negative number to context precision.
2711
2712 If the result must be inexact, it is rounded using the round-half-even
2713 algorithm.
2714
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002715 >>> ExtendedContext.sqrt(Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002716 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002717 >>> ExtendedContext.sqrt(Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002718 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002719 >>> ExtendedContext.sqrt(Decimal('0.39'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002720 Decimal("0.624499800")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002721 >>> ExtendedContext.sqrt(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002722 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002723 >>> ExtendedContext.sqrt(Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002724 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002725 >>> ExtendedContext.sqrt(Decimal('1.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002726 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002727 >>> ExtendedContext.sqrt(Decimal('1.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002728 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002729 >>> ExtendedContext.sqrt(Decimal('7'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002730 Decimal("2.64575131")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002731 >>> ExtendedContext.sqrt(Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002732 Decimal("3.16227766")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002733 >>> ExtendedContext.prec
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002734 9
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002735 """
2736 return a.sqrt(context=self)
2737
2738 def subtract(self, a, b):
2739 """Return the sum of the two operands.
2740
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002741 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002742 Decimal("0.23")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002743 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002744 Decimal("0.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002745 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002746 Decimal("-0.77")
2747 """
2748 return a.__sub__(b, context=self)
2749
2750 def to_eng_string(self, a):
2751 """Converts a number to a string, using scientific notation.
2752
2753 The operation is not affected by the context.
2754 """
2755 return a.to_eng_string(context=self)
2756
2757 def to_sci_string(self, a):
2758 """Converts a number to a string, using scientific notation.
2759
2760 The operation is not affected by the context.
2761 """
2762 return a.__str__(context=self)
2763
2764 def to_integral(self, a):
2765 """Rounds to an integer.
2766
2767 When the operand has a negative exponent, the result is the same
2768 as using the quantize() operation using the given operand as the
2769 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2770 of the operand as the precision setting, except that no flags will
2771 be set. The rounding mode is taken from the context.
2772
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002773 >>> ExtendedContext.to_integral(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002774 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002775 >>> ExtendedContext.to_integral(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002776 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002777 >>> ExtendedContext.to_integral(Decimal('100.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002778 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002779 >>> ExtendedContext.to_integral(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002780 Decimal("102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002781 >>> ExtendedContext.to_integral(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002782 Decimal("-102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002783 >>> ExtendedContext.to_integral(Decimal('10E+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002784 Decimal("1.0E+6")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002785 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002786 Decimal("7.89E+77")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002787 >>> ExtendedContext.to_integral(Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002788 Decimal("-Infinity")
2789 """
2790 return a.to_integral(context=self)
2791
2792class _WorkRep(object):
2793 __slots__ = ('sign','int','exp')
2794 # sign: -1 None 1
2795 # int: list
2796 # exp: None, int, or string
2797
2798 def __init__(self, value=None):
2799 if value is None:
2800 self.sign = None
2801 self.int = []
2802 self.exp = None
2803 if isinstance(value, Decimal):
2804 if value._sign:
2805 self.sign = -1
2806 else:
2807 self.sign = 1
2808 self.int = list(value._int)
2809 self.exp = value._exp
2810 if isinstance(value, tuple):
2811 self.sign = value[0]
2812 self.int = value[1]
2813 self.exp = value[2]
2814
2815 def __repr__(self):
2816 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2817
2818 __str__ = __repr__
2819
2820 def __neg__(self):
2821 if self.sign == 1:
2822 return _WorkRep( (-1, self.int, self.exp) )
2823 else:
2824 return _WorkRep( (1, self.int, self.exp) )
2825
2826 def __abs__(self):
2827 if self.sign == -1:
2828 return -self
2829 else:
2830 return self
2831
2832 def __cmp__(self, other):
2833 if self.exp != other.exp:
2834 raise ValueError("Operands not normalized: %r, %r" % (self, other))
2835 if self.sign != other.sign:
2836 if self.sign == -1:
2837 return -1
2838 else:
2839 return 1
2840 if self.sign == -1:
2841 direction = -1
2842 else:
2843 direction = 1
2844 int1 = self.int
2845 int2 = other.int
2846 if len(int1) > len(int2):
2847 return direction * 1
2848 if len(int1) < len(int2):
2849 return direction * -1
2850 for i in xrange(len(int1)):
2851 if int1[i] > int2[i]:
2852 return direction * 1
2853 if int1[i] < int2[i]:
2854 return direction * -1
2855 return 0
2856
2857 def _increment(self):
2858 curspot = len(self.int) - 1
2859 self.int[curspot]+= 1
2860 while (self.int[curspot] >= 10):
2861 self.int[curspot] -= 10
2862 if curspot == 0:
2863 self.int[0:0] = [1]
2864 break
2865 self.int[curspot-1] += 1
2866 curspot -= 1
2867
2868 def subtract(self, alist):
2869 """Subtract a list from the current int (in place).
2870
2871 It is assured that (len(list) = len(self.int) and list < self.int) or
2872 len(list) = len(self.int)-1
2873 (i.e. that int(join(list)) < int(join(self.int)))
2874 """
2875
2876 selfint = self.int
2877 selfint.reverse()
2878 alist.reverse()
2879
2880 carry = 0
2881 for x in xrange(len(alist)):
2882 selfint[x] -= alist[x] + carry
2883 if selfint[x] < 0:
2884 carry = 1
2885 selfint[x] += 10
2886 else:
Tim Peters4e0e1b62004-07-07 20:54:48 +00002887 carry = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002888 if carry:
2889 selfint[x+1] -= 1
2890 last = len(selfint)-1
2891 while len(selfint) > 1 and selfint[last] == 0:
2892 last -= 1
2893 if last == 0:
2894 break
2895 selfint[last+1:]=[]
2896 selfint.reverse()
2897 alist.reverse()
2898 return
2899
2900
2901def _normalize(op1, op2, shouldround = 0, prec = 0):
2902 """Normalizes op1, op2 to have the same exp and length of coefficient.
2903
2904 Done during addition.
2905 """
2906 # Yes, the exponent is a long, but the difference between exponents
2907 # must be an int-- otherwise you'd get a big memory problem.
2908 numdigits = int(op1.exp - op2.exp)
2909 if numdigits < 0:
2910 numdigits = -numdigits
2911 tmp = op2
2912 other = op1
2913 else:
2914 tmp = op1
2915 other = op2
2916
2917 if shouldround and numdigits > len(other.int) + prec + 1 -len(tmp.int):
2918 # If the difference in adjusted exps is > prec+1, we know
2919 # other is insignificant, so might as well put a 1 after the precision.
2920 # (since this is only for addition.) Also stops MemoryErrors.
2921
2922 extend = prec + 2 -len(tmp.int)
2923 if extend <= 0:
2924 extend = 1
2925 tmp.int.extend([0]*extend)
2926 tmp.exp -= extend
2927 other.int[:] = [0]*(len(tmp.int)-1)+[1]
2928 other.exp = tmp.exp
2929 return op1, op2
2930
2931 tmp.int.extend([0] * numdigits)
2932 tmp.exp = tmp.exp - numdigits
2933 numdigits = len(op1.int) - len(op2.int)
2934 # numdigits != 0 => They have the same exponent, but not the same length
2935 # of the coefficient.
2936 if numdigits < 0:
2937 numdigits = -numdigits
2938 tmp = op1
2939 else:
2940 tmp = op2
2941 tmp.int[0:0] = [0] * numdigits
2942 return op1, op2
2943
2944def _adjust_coefficients(op1, op2):
2945 """Adjust op1, op2 so that op2.int+[0] > op1.int >= op2.int.
2946
2947 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2948
2949 Used on _WorkRep instances during division.
2950 """
2951 adjust = 0
2952 #If op1 is smaller, get it to same size
2953 if len(op2.int) > len(op1.int):
2954 diff = len(op2.int) - len(op1.int)
2955 op1.int.extend([0]*diff)
2956 op1.exp -= diff
2957 adjust = diff
2958
2959 #Same length, wrong order
2960 if len(op1.int) == len(op2.int) and op1.int < op2.int:
2961 op1.int.append(0)
2962 op1.exp -= 1
2963 adjust+= 1
2964 return op1, op2, adjust
2965
2966 if len(op1.int) > len(op2.int) + 1:
2967 diff = len(op1.int) - len(op2.int) - 1
2968 op2.int.extend([0]*diff)
2969 op2.exp -= diff
2970 adjust -= diff
2971
2972 if len(op1.int) == len(op2.int)+1 and op1.int > op2.int:
2973
2974 op2.int.append(0)
2975 op2.exp -= 1
2976 adjust -= 1
2977 return op1, op2, adjust
2978
2979##### Helper Functions ########################################
2980
2981_infinity_map = {
2982 'inf' : 1,
2983 'infinity' : 1,
2984 '+inf' : 1,
2985 '+infinity' : 1,
2986 '-inf' : -1,
2987 '-infinity' : -1
2988}
2989
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002990def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002991 """Determines whether a string or float is infinity.
2992
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002993 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002994 """
2995 num = str(num).lower()
2996 return _infinity_map.get(num, 0)
2997
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002998def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002999 """Determines whether a string or float is NaN
3000
3001 (1, sign, diagnostic info as string) => NaN
3002 (2, sign, diagnostic info as string) => sNaN
3003 0 => not a NaN
3004 """
3005 num = str(num).lower()
3006 if not num:
3007 return 0
3008
3009 #get the sign, get rid of trailing [+-]
3010 sign = 0
3011 if num[0] == '+':
3012 num = num[1:]
3013 elif num[0] == '-': #elif avoids '+-nan'
3014 num = num[1:]
3015 sign = 1
3016
3017 if num.startswith('nan'):
3018 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
3019 return 0
3020 return (1, sign, num[3:].lstrip('0'))
3021 if num.startswith('snan'):
3022 if len(num) > 4 and not num[4:].isdigit():
3023 return 0
3024 return (2, sign, num[4:].lstrip('0'))
3025 return 0
3026
3027
3028##### Setup Specific Contexts ################################
3029
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003030# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00003031# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003032
3033DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003034 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003035 traps=[DivisionByZero, Overflow, InvalidOperation],
3036 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003037 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00003038 Emax=999999999,
3039 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00003040 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003041)
3042
3043# Pre-made alternate contexts offered by the specification
3044# Don't change these; the user should be able to select these
3045# contexts and be able to reproduce results from other implementations
3046# of the spec.
3047
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003048BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003049 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003050 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
3051 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003052)
3053
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003054ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003055 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003056 traps=[],
3057 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003058)
3059
3060
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00003061##### Useful Constants (internal use only) ####################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003062
3063#Reusable defaults
3064Inf = Decimal('Inf')
3065negInf = Decimal('-Inf')
3066
3067#Infsign[sign] is infinity w/ that sign
3068Infsign = (Inf, negInf)
3069
3070NaN = Decimal('NaN')
3071
3072
3073##### crud for parsing strings #################################
3074import re
3075
3076# There's an optional sign at the start, and an optional exponent
3077# at the end. The exponent has an optional sign and at least one
3078# digit. In between, must have either at least one digit followed
3079# by an optional fraction, or a decimal point followed by at least
3080# one digit. Yuck.
3081
3082_parser = re.compile(r"""
3083# \s*
3084 (?P<sign>[-+])?
3085 (
3086 (?P<int>\d+) (\. (?P<frac>\d*))?
3087 |
3088 \. (?P<onlyfrac>\d+)
3089 )
3090 ([eE](?P<exp>[-+]? \d+))?
3091# \s*
3092 $
3093""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
3094
3095del re
3096
3097# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
3098
3099def _string2exact(s):
3100 m = _parser(s)
3101 if m is None:
3102 raise ValueError("invalid literal for Decimal: %r" % s)
3103
3104 if m.group('sign') == "-":
3105 sign = 1
3106 else:
3107 sign = 0
3108
3109 exp = m.group('exp')
3110 if exp is None:
3111 exp = 0
3112 else:
3113 exp = int(exp)
3114
3115 intpart = m.group('int')
3116 if intpart is None:
3117 intpart = ""
3118 fracpart = m.group('onlyfrac')
3119 else:
3120 fracpart = m.group('frac')
3121 if fracpart is None:
3122 fracpart = ""
3123
3124 exp -= len(fracpart)
3125
3126 mantissa = intpart + fracpart
3127 tmp = map(int, mantissa)
3128 backup = tmp
3129 while tmp and tmp[0] == 0:
3130 del tmp[0]
3131
3132 # It's a zero
3133 if not tmp:
3134 if backup:
3135 return (sign, tuple(backup), exp)
3136 return (sign, (0,), exp)
3137 mantissa = tuple(tmp)
3138
3139 return (sign, mantissa, exp)
3140
3141
3142if __name__ == '__main__':
3143 import doctest, sys
3144 doctest.testmod(sys.modules[__name__])