blob: 101e5d8f8830722d0f92e4616017a79053ab6d41 [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
2035 ans = self._check_nans(other, context)
2036 if ans:
2037 return ans
2038
2039 ans = self
2040 if self < other:
2041 ans = other
2042 shouldround = context._rounding_decision == ALWAYS_ROUND
2043 if shouldround:
2044 ans = ans._fix(context=context)
2045 return ans
2046
2047 def min(self, other, context=None):
2048 """Returns the smaller value.
2049
2050 like min(self, other) except if one is not a number, returns
2051 NaN (and signals if one is sNaN). Also rounds.
2052 """
2053 if context is None:
2054 context = getcontext()
2055 other = self._convert_other(other)
2056
2057 ans = self._check_nans(other, context)
2058 if ans:
2059 return ans
2060
2061 ans = self
2062
2063 if self > other:
2064 ans = other
2065
2066 if context._rounding_decision == ALWAYS_ROUND:
2067 ans = ans._fix(context=context)
2068
2069 return ans
2070
2071 def _isinteger(self):
2072 """Returns whether self is an integer"""
2073 if self._exp >= 0:
2074 return True
2075 rest = self._int[self._exp:]
2076 return rest == (0,)*len(rest)
2077
2078 def _iseven(self):
2079 """Returns 1 if self is even. Assumes self is an integer."""
2080 if self._exp > 0:
2081 return 1
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002082 return self._int[-1+self._exp] & 1 == 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002083
2084 def adjusted(self):
2085 """Return the adjusted exponent of self"""
2086 try:
2087 return self._exp + len(self._int) - 1
2088 #If NaN or Infinity, self._exp is string
2089 except TypeError:
2090 return 0
2091
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002092 # support for pickling, copy, and deepcopy
2093 def __reduce__(self):
2094 return (self.__class__, (str(self),))
2095
2096 def __copy__(self):
2097 if type(self) == Decimal:
2098 return self # I'm immutable; therefore I am my own clone
2099 return self.__class__(str(self))
2100
2101 def __deepcopy__(self, memo):
2102 if type(self) == Decimal:
2103 return self # My components are also immutable
2104 return self.__class__(str(self))
2105
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002106##### Context class ###########################################
2107
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002108
2109# get rounding method function:
2110rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
2111for name in rounding_functions:
2112 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
2113 globalname = name[1:].upper()
2114 val = globals()[globalname]
2115 Decimal._pick_rounding_function[val] = name
2116
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002117del name, val, globalname, rounding_functions
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002118
2119class Context(object):
2120 """Contains the context for a Decimal instance.
2121
2122 Contains:
2123 prec - precision (for use in rounding, division, square roots..)
2124 rounding - rounding type. (how you round)
2125 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
Raymond Hettingerbf440692004-07-10 14:14:37 +00002126 traps - If traps[exception] = 1, then the exception is
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002127 raised when it is caused. Otherwise, a value is
2128 substituted in.
2129 flags - When an exception is caused, flags[exception] is incremented.
2130 (Whether or not the trap_enabler is set)
2131 Should be reset by user of Decimal instance.
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002132 Emin - Minimum exponent
2133 Emax - Maximum exponent
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002134 capitals - If 1, 1*10^1 is printed as 1E+1.
2135 If 0, printed as 1e1
Raymond Hettingere0f15812004-07-05 05:36:39 +00002136 _clamp - If 1, change exponents if too high (Default 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002137 """
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002138
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002139 def __init__(self, prec=None, rounding=None,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002140 traps=None, flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002141 _rounding_decision=None,
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002142 Emin=None, Emax=None,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002143 capitals=None, _clamp=0,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002144 _ignored_flags=[]):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002145 if not isinstance(flags, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002146 flags = dict([(s,s in flags) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002147 del s
Raymond Hettingerbf440692004-07-10 14:14:37 +00002148 if traps is not None and not isinstance(traps, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002149 traps = dict([(s,s in traps) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002150 del s
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002151 for name, val in locals().items():
2152 if val is None:
2153 setattr(self, name, copy.copy(getattr(DefaultContext, name)))
2154 else:
2155 setattr(self, name, val)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002156 del self.self
2157
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002158 def __repr__(self):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002159 """Show the current context."""
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002160 s = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002161 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
2162 s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
2163 s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002164 return ', '.join(s) + ')'
2165
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002166 def clear_flags(self):
2167 """Reset all flags to zero"""
2168 for flag in self.flags:
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002169 self.flags[flag] = 0
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002170
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002171 def _shallow_copy(self):
2172 """Returns a shallow copy from self."""
Raymond Hettingerbf440692004-07-10 14:14:37 +00002173 nc = Context(self.prec, self.rounding, self.traps, self.flags,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002174 self._rounding_decision, self.Emin, self.Emax,
2175 self.capitals, self._clamp, self._ignored_flags)
2176 return nc
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002177
2178 def copy(self):
2179 """Returns a deep copy from self."""
2180 nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
2181 self._rounding_decision, self.Emin, self.Emax,
2182 self.capitals, self._clamp, self._ignored_flags)
2183 return nc
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002184 __copy__ = copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002185
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002186 def _raise_error(self, condition, explanation = None, *args):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002187 """Handles an error
2188
2189 If the flag is in _ignored_flags, returns the default response.
2190 Otherwise, it increments the flag, then, if the corresponding
2191 trap_enabler is set, it reaises the exception. Otherwise, it returns
2192 the default value after incrementing the flag.
2193 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002194 error = _condition_map.get(condition, condition)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002195 if error in self._ignored_flags:
2196 #Don't touch the flag
2197 return error().handle(self, *args)
2198
2199 self.flags[error] += 1
Raymond Hettingerbf440692004-07-10 14:14:37 +00002200 if not self.traps[error]:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002201 #The errors define how to handle themselves.
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002202 return condition().handle(self, *args)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002203
2204 # Errors should only be risked on copies of the context
2205 #self._ignored_flags = []
2206 raise error, explanation
2207
2208 def _ignore_all_flags(self):
2209 """Ignore all flags, if they are raised"""
Raymond Hettingerfed52962004-07-14 15:41:57 +00002210 return self._ignore_flags(*_signals)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002211
2212 def _ignore_flags(self, *flags):
2213 """Ignore the flags, if they are raised"""
2214 # Do not mutate-- This way, copies of a context leave the original
2215 # alone.
2216 self._ignored_flags = (self._ignored_flags + list(flags))
2217 return list(flags)
2218
2219 def _regard_flags(self, *flags):
2220 """Stop ignoring the flags, if they are raised"""
2221 if flags and isinstance(flags[0], (tuple,list)):
2222 flags = flags[0]
2223 for flag in flags:
2224 self._ignored_flags.remove(flag)
2225
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002226 def __hash__(self):
2227 """A Context cannot be hashed."""
2228 # We inherit object.__hash__, so we must deny this explicitly
2229 raise TypeError, "Cannot hash a Context."
2230
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002231 def Etiny(self):
2232 """Returns Etiny (= Emin - prec + 1)"""
2233 return int(self.Emin - self.prec + 1)
2234
2235 def Etop(self):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002236 """Returns maximum exponent (= Emax - prec + 1)"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002237 return int(self.Emax - self.prec + 1)
2238
2239 def _set_rounding_decision(self, type):
2240 """Sets the rounding decision.
2241
2242 Sets the rounding decision, and returns the current (previous)
2243 rounding decision. Often used like:
2244
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002245 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002246 # That so you don't change the calling context
2247 # if an error occurs in the middle (say DivisionImpossible is raised).
2248
2249 rounding = context._set_rounding_decision(NEVER_ROUND)
2250 instance = instance / Decimal(2)
2251 context._set_rounding_decision(rounding)
2252
2253 This will make it not round for that operation.
2254 """
2255
2256 rounding = self._rounding_decision
2257 self._rounding_decision = type
2258 return rounding
2259
2260 def _set_rounding(self, type):
2261 """Sets the rounding type.
2262
2263 Sets the rounding type, and returns the current (previous)
2264 rounding type. Often used like:
2265
2266 context = context.copy()
2267 # so you don't change the calling context
2268 # if an error occurs in the middle.
2269 rounding = context._set_rounding(ROUND_UP)
2270 val = self.__sub__(other, context=context)
2271 context._set_rounding(rounding)
2272
2273 This will make it round up for that operation.
2274 """
2275 rounding = self.rounding
2276 self.rounding= type
2277 return rounding
2278
Raymond Hettingerfed52962004-07-14 15:41:57 +00002279 def create_decimal(self, num='0'):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002280 """Creates a new Decimal instance but using self as context."""
2281 d = Decimal(num, context=self)
2282 return d._fix(context=self)
2283
2284 #Methods
2285 def abs(self, a):
2286 """Returns the absolute value of the operand.
2287
2288 If the operand is negative, the result is the same as using the minus
2289 operation on the operand. Otherwise, the result is the same as using
2290 the plus operation on the operand.
2291
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002292 >>> ExtendedContext.abs(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002293 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002294 >>> ExtendedContext.abs(Decimal('-100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002295 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002296 >>> ExtendedContext.abs(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002297 Decimal("101.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002298 >>> ExtendedContext.abs(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002299 Decimal("101.5")
2300 """
2301 return a.__abs__(context=self)
2302
2303 def add(self, a, b):
2304 """Return the sum of the two operands.
2305
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002306 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002307 Decimal("19.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002308 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002309 Decimal("1.02E+4")
2310 """
2311 return a.__add__(b, context=self)
2312
2313 def _apply(self, a):
2314 return str(a._fix(context=self))
2315
2316 def compare(self, a, b):
2317 """Compares values numerically.
2318
2319 If the signs of the operands differ, a value representing each operand
2320 ('-1' if the operand is less than zero, '0' if the operand is zero or
2321 negative zero, or '1' if the operand is greater than zero) is used in
2322 place of that operand for the comparison instead of the actual
2323 operand.
2324
2325 The comparison is then effected by subtracting the second operand from
2326 the first and then returning a value according to the result of the
2327 subtraction: '-1' if the result is less than zero, '0' if the result is
2328 zero or negative zero, or '1' if the result is greater than zero.
2329
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002330 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002331 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002332 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002333 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002334 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002335 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002336 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002337 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002338 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002339 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002340 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002341 Decimal("-1")
2342 """
2343 return a.compare(b, context=self)
2344
2345 def divide(self, a, b):
2346 """Decimal division in a specified context.
2347
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002348 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002349 Decimal("0.333333333")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002350 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002351 Decimal("0.666666667")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002352 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002353 Decimal("2.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002354 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002355 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002356 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002357 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002358 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002359 Decimal("4.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002360 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002361 Decimal("1.20")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002362 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002363 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002364 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002365 Decimal("1000")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002366 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002367 Decimal("1.20E+6")
2368 """
2369 return a.__div__(b, context=self)
2370
2371 def divide_int(self, a, b):
2372 """Divides two numbers and returns the integer part of the result.
2373
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002374 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002375 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002376 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002377 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002378 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002379 Decimal("3")
2380 """
2381 return a.__floordiv__(b, context=self)
2382
2383 def divmod(self, a, b):
2384 return a.__divmod__(b, context=self)
2385
2386 def max(self, a,b):
2387 """max compares two values numerically and returns the maximum.
2388
2389 If either operand is a NaN then the general rules apply.
2390 Otherwise, the operands are compared as as though by the compare
2391 operation. If they are numerically equal then the left-hand operand
2392 is chosen as the result. Otherwise the maximum (closer to positive
2393 infinity) of the two operands is chosen as the result.
2394
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002395 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002396 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002397 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002398 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002399 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002400 Decimal("1.0")
2401 """
2402 return a.max(b, context=self)
2403
2404 def min(self, a,b):
2405 """min compares two values numerically and returns the minimum.
2406
2407 If either operand is a NaN then the general rules apply.
2408 Otherwise, the operands are compared as as though by the compare
2409 operation. If they are numerically equal then the left-hand operand
2410 is chosen as the result. Otherwise the minimum (closer to negative
2411 infinity) of the two operands is chosen as the result.
2412
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002413 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002414 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002415 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002416 Decimal("-10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002417 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002418 Decimal("1.0")
2419 """
2420 return a.min(b, context=self)
2421
2422 def minus(self, a):
2423 """Minus corresponds to unary prefix minus in Python.
2424
2425 The operation is evaluated using the same rules as subtract; the
2426 operation minus(a) is calculated as subtract('0', a) where the '0'
2427 has the same exponent as the operand.
2428
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002429 >>> ExtendedContext.minus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002430 Decimal("-1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002431 >>> ExtendedContext.minus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002432 Decimal("1.3")
2433 """
2434 return a.__neg__(context=self)
2435
2436 def multiply(self, a, b):
2437 """multiply multiplies two operands.
2438
2439 If either operand is a special value then the general rules apply.
2440 Otherwise, the operands are multiplied together ('long multiplication'),
2441 resulting in a number which may be as long as the sum of the lengths
2442 of the two operands.
2443
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002444 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002445 Decimal("3.60")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002446 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002447 Decimal("21")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002448 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002449 Decimal("0.72")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002450 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002451 Decimal("-0.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002452 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002453 Decimal("4.28135971E+11")
2454 """
2455 return a.__mul__(b, context=self)
2456
2457 def normalize(self, a):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002458 """normalize reduces an operand to its simplest form.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002459
2460 Essentially a plus operation with all trailing zeros removed from the
2461 result.
2462
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002463 >>> ExtendedContext.normalize(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002464 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002465 >>> ExtendedContext.normalize(Decimal('-2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002466 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002467 >>> ExtendedContext.normalize(Decimal('1.200'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002468 Decimal("1.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002469 >>> ExtendedContext.normalize(Decimal('-120'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002470 Decimal("-1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002471 >>> ExtendedContext.normalize(Decimal('120.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002472 Decimal("1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002473 >>> ExtendedContext.normalize(Decimal('0.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002474 Decimal("0")
2475 """
2476 return a.normalize(context=self)
2477
2478 def plus(self, a):
2479 """Plus corresponds to unary prefix plus in Python.
2480
2481 The operation is evaluated using the same rules as add; the
2482 operation plus(a) is calculated as add('0', a) where the '0'
2483 has the same exponent as the operand.
2484
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002485 >>> ExtendedContext.plus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002486 Decimal("1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002487 >>> ExtendedContext.plus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002488 Decimal("-1.3")
2489 """
2490 return a.__pos__(context=self)
2491
2492 def power(self, a, b, modulo=None):
2493 """Raises a to the power of b, to modulo if given.
2494
2495 The right-hand operand must be a whole number whose integer part (after
2496 any exponent has been applied) has no more than 9 digits and whose
2497 fractional part (if any) is all zeros before any rounding. The operand
2498 may be positive, negative, or zero; if negative, the absolute value of
2499 the power is used, and the left-hand operand is inverted (divided into
2500 1) before use.
2501
2502 If the increased precision needed for the intermediate calculations
2503 exceeds the capabilities of the implementation then an Invalid operation
2504 condition is raised.
2505
2506 If, when raising to a negative power, an underflow occurs during the
2507 division into 1, the operation is not halted at that point but
2508 continues.
2509
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002510 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002511 Decimal("8")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002512 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002513 Decimal("0.125")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002514 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002515 Decimal("69.7575744")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002516 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002517 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002518 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002519 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002520 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002521 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002522 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002523 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002524 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002525 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002526 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002527 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002528 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002529 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002530 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002531 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002532 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002533 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002534 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002535 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002536 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002537 Decimal("NaN")
2538 """
2539 return a.__pow__(b, modulo, context=self)
2540
2541 def quantize(self, a, b):
2542 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
2543
2544 The coefficient of the result is derived from that of the left-hand
2545 operand. It may be rounded using the current rounding setting (if the
2546 exponent is being increased), multiplied by a positive power of ten (if
2547 the exponent is being decreased), or is unchanged (if the exponent is
2548 already equal to that of the right-hand operand).
2549
2550 Unlike other operations, if the length of the coefficient after the
2551 quantize operation would be greater than precision then an Invalid
2552 operation condition is raised. This guarantees that, unless there is an
2553 error condition, the exponent of the result of a quantize is always
2554 equal to that of the right-hand operand.
2555
2556 Also unlike other operations, quantize will never raise Underflow, even
2557 if the result is subnormal and inexact.
2558
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002559 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002560 Decimal("2.170")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002561 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002562 Decimal("2.17")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002563 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002564 Decimal("2.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002565 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002566 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002567 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002568 Decimal("0E+1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002569 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002570 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002571 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002572 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002573 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002574 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002575 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002576 Decimal("-0E+5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002577 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002578 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002579 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002580 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002581 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002582 Decimal("217.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002583 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002584 Decimal("217")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002585 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002586 Decimal("2.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002587 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002588 Decimal("2E+2")
2589 """
2590 return a.quantize(b, context=self)
2591
2592 def remainder(self, a, b):
2593 """Returns the remainder from integer division.
2594
2595 The result is the residue of the dividend after the operation of
2596 calculating integer division as described for divide-integer, rounded to
2597 precision digits if necessary. The sign of the result, if non-zero, is
2598 the same as that of the original dividend.
2599
2600 This operation will fail under the same conditions as integer division
2601 (that is, if integer division on the same two operands would fail, the
2602 remainder cannot be calculated).
2603
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002604 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002605 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002606 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002607 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002608 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002609 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002610 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002611 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002612 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002613 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002614 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002615 Decimal("1.0")
2616 """
2617 return a.__mod__(b, context=self)
2618
2619 def remainder_near(self, a, b):
2620 """Returns to be "a - b * n", where n is the integer nearest the exact
2621 value of "x / b" (if two integers are equally near then the even one
2622 is chosen). If the result is equal to 0 then its sign will be the
2623 sign of a.
2624
2625 This operation will fail under the same conditions as integer division
2626 (that is, if integer division on the same two operands would fail, the
2627 remainder cannot be calculated).
2628
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002629 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002630 Decimal("-0.9")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002631 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002632 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002633 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002634 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002635 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002636 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002637 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002638 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002639 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002640 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002641 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002642 Decimal("-0.3")
2643 """
2644 return a.remainder_near(b, context=self)
2645
2646 def same_quantum(self, a, b):
2647 """Returns True if the two operands have the same exponent.
2648
2649 The result is never affected by either the sign or the coefficient of
2650 either operand.
2651
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002652 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002653 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002654 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002655 True
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002656 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002657 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002658 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002659 True
2660 """
2661 return a.same_quantum(b)
2662
2663 def sqrt(self, a):
2664 """Returns the square root of a non-negative number to context precision.
2665
2666 If the result must be inexact, it is rounded using the round-half-even
2667 algorithm.
2668
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002669 >>> ExtendedContext.sqrt(Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002670 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002671 >>> ExtendedContext.sqrt(Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002672 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002673 >>> ExtendedContext.sqrt(Decimal('0.39'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002674 Decimal("0.624499800")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002675 >>> ExtendedContext.sqrt(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002676 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002677 >>> ExtendedContext.sqrt(Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002678 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002679 >>> ExtendedContext.sqrt(Decimal('1.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002680 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002681 >>> ExtendedContext.sqrt(Decimal('1.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002682 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002683 >>> ExtendedContext.sqrt(Decimal('7'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002684 Decimal("2.64575131")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002685 >>> ExtendedContext.sqrt(Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002686 Decimal("3.16227766")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002687 >>> ExtendedContext.prec
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002688 9
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002689 """
2690 return a.sqrt(context=self)
2691
2692 def subtract(self, a, b):
2693 """Return the sum of the two operands.
2694
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002695 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002696 Decimal("0.23")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002697 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002698 Decimal("0.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002699 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002700 Decimal("-0.77")
2701 """
2702 return a.__sub__(b, context=self)
2703
2704 def to_eng_string(self, a):
2705 """Converts a number to a string, using scientific notation.
2706
2707 The operation is not affected by the context.
2708 """
2709 return a.to_eng_string(context=self)
2710
2711 def to_sci_string(self, a):
2712 """Converts a number to a string, using scientific notation.
2713
2714 The operation is not affected by the context.
2715 """
2716 return a.__str__(context=self)
2717
2718 def to_integral(self, a):
2719 """Rounds to an integer.
2720
2721 When the operand has a negative exponent, the result is the same
2722 as using the quantize() operation using the given operand as the
2723 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2724 of the operand as the precision setting, except that no flags will
2725 be set. The rounding mode is taken from the context.
2726
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002727 >>> ExtendedContext.to_integral(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002728 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002729 >>> ExtendedContext.to_integral(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002730 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002731 >>> ExtendedContext.to_integral(Decimal('100.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002732 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002733 >>> ExtendedContext.to_integral(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002734 Decimal("102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002735 >>> ExtendedContext.to_integral(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002736 Decimal("-102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002737 >>> ExtendedContext.to_integral(Decimal('10E+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002738 Decimal("1.0E+6")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002739 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002740 Decimal("7.89E+77")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002741 >>> ExtendedContext.to_integral(Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002742 Decimal("-Infinity")
2743 """
2744 return a.to_integral(context=self)
2745
2746class _WorkRep(object):
2747 __slots__ = ('sign','int','exp')
2748 # sign: -1 None 1
2749 # int: list
2750 # exp: None, int, or string
2751
2752 def __init__(self, value=None):
2753 if value is None:
2754 self.sign = None
2755 self.int = []
2756 self.exp = None
2757 if isinstance(value, Decimal):
2758 if value._sign:
2759 self.sign = -1
2760 else:
2761 self.sign = 1
2762 self.int = list(value._int)
2763 self.exp = value._exp
2764 if isinstance(value, tuple):
2765 self.sign = value[0]
2766 self.int = value[1]
2767 self.exp = value[2]
2768
2769 def __repr__(self):
2770 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2771
2772 __str__ = __repr__
2773
2774 def __neg__(self):
2775 if self.sign == 1:
2776 return _WorkRep( (-1, self.int, self.exp) )
2777 else:
2778 return _WorkRep( (1, self.int, self.exp) )
2779
2780 def __abs__(self):
2781 if self.sign == -1:
2782 return -self
2783 else:
2784 return self
2785
2786 def __cmp__(self, other):
2787 if self.exp != other.exp:
2788 raise ValueError("Operands not normalized: %r, %r" % (self, other))
2789 if self.sign != other.sign:
2790 if self.sign == -1:
2791 return -1
2792 else:
2793 return 1
2794 if self.sign == -1:
2795 direction = -1
2796 else:
2797 direction = 1
2798 int1 = self.int
2799 int2 = other.int
2800 if len(int1) > len(int2):
2801 return direction * 1
2802 if len(int1) < len(int2):
2803 return direction * -1
2804 for i in xrange(len(int1)):
2805 if int1[i] > int2[i]:
2806 return direction * 1
2807 if int1[i] < int2[i]:
2808 return direction * -1
2809 return 0
2810
2811 def _increment(self):
2812 curspot = len(self.int) - 1
2813 self.int[curspot]+= 1
2814 while (self.int[curspot] >= 10):
2815 self.int[curspot] -= 10
2816 if curspot == 0:
2817 self.int[0:0] = [1]
2818 break
2819 self.int[curspot-1] += 1
2820 curspot -= 1
2821
2822 def subtract(self, alist):
2823 """Subtract a list from the current int (in place).
2824
2825 It is assured that (len(list) = len(self.int) and list < self.int) or
2826 len(list) = len(self.int)-1
2827 (i.e. that int(join(list)) < int(join(self.int)))
2828 """
2829
2830 selfint = self.int
2831 selfint.reverse()
2832 alist.reverse()
2833
2834 carry = 0
2835 for x in xrange(len(alist)):
2836 selfint[x] -= alist[x] + carry
2837 if selfint[x] < 0:
2838 carry = 1
2839 selfint[x] += 10
2840 else:
Tim Peters4e0e1b62004-07-07 20:54:48 +00002841 carry = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002842 if carry:
2843 selfint[x+1] -= 1
2844 last = len(selfint)-1
2845 while len(selfint) > 1 and selfint[last] == 0:
2846 last -= 1
2847 if last == 0:
2848 break
2849 selfint[last+1:]=[]
2850 selfint.reverse()
2851 alist.reverse()
2852 return
2853
2854
2855def _normalize(op1, op2, shouldround = 0, prec = 0):
2856 """Normalizes op1, op2 to have the same exp and length of coefficient.
2857
2858 Done during addition.
2859 """
2860 # Yes, the exponent is a long, but the difference between exponents
2861 # must be an int-- otherwise you'd get a big memory problem.
2862 numdigits = int(op1.exp - op2.exp)
2863 if numdigits < 0:
2864 numdigits = -numdigits
2865 tmp = op2
2866 other = op1
2867 else:
2868 tmp = op1
2869 other = op2
2870
2871 if shouldround and numdigits > len(other.int) + prec + 1 -len(tmp.int):
2872 # If the difference in adjusted exps is > prec+1, we know
2873 # other is insignificant, so might as well put a 1 after the precision.
2874 # (since this is only for addition.) Also stops MemoryErrors.
2875
2876 extend = prec + 2 -len(tmp.int)
2877 if extend <= 0:
2878 extend = 1
2879 tmp.int.extend([0]*extend)
2880 tmp.exp -= extend
2881 other.int[:] = [0]*(len(tmp.int)-1)+[1]
2882 other.exp = tmp.exp
2883 return op1, op2
2884
2885 tmp.int.extend([0] * numdigits)
2886 tmp.exp = tmp.exp - numdigits
2887 numdigits = len(op1.int) - len(op2.int)
2888 # numdigits != 0 => They have the same exponent, but not the same length
2889 # of the coefficient.
2890 if numdigits < 0:
2891 numdigits = -numdigits
2892 tmp = op1
2893 else:
2894 tmp = op2
2895 tmp.int[0:0] = [0] * numdigits
2896 return op1, op2
2897
2898def _adjust_coefficients(op1, op2):
2899 """Adjust op1, op2 so that op2.int+[0] > op1.int >= op2.int.
2900
2901 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2902
2903 Used on _WorkRep instances during division.
2904 """
2905 adjust = 0
2906 #If op1 is smaller, get it to same size
2907 if len(op2.int) > len(op1.int):
2908 diff = len(op2.int) - len(op1.int)
2909 op1.int.extend([0]*diff)
2910 op1.exp -= diff
2911 adjust = diff
2912
2913 #Same length, wrong order
2914 if len(op1.int) == len(op2.int) and op1.int < op2.int:
2915 op1.int.append(0)
2916 op1.exp -= 1
2917 adjust+= 1
2918 return op1, op2, adjust
2919
2920 if len(op1.int) > len(op2.int) + 1:
2921 diff = len(op1.int) - len(op2.int) - 1
2922 op2.int.extend([0]*diff)
2923 op2.exp -= diff
2924 adjust -= diff
2925
2926 if len(op1.int) == len(op2.int)+1 and op1.int > op2.int:
2927
2928 op2.int.append(0)
2929 op2.exp -= 1
2930 adjust -= 1
2931 return op1, op2, adjust
2932
2933##### Helper Functions ########################################
2934
2935_infinity_map = {
2936 'inf' : 1,
2937 'infinity' : 1,
2938 '+inf' : 1,
2939 '+infinity' : 1,
2940 '-inf' : -1,
2941 '-infinity' : -1
2942}
2943
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002944def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002945 """Determines whether a string or float is infinity.
2946
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002947 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002948 """
2949 num = str(num).lower()
2950 return _infinity_map.get(num, 0)
2951
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002952def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002953 """Determines whether a string or float is NaN
2954
2955 (1, sign, diagnostic info as string) => NaN
2956 (2, sign, diagnostic info as string) => sNaN
2957 0 => not a NaN
2958 """
2959 num = str(num).lower()
2960 if not num:
2961 return 0
2962
2963 #get the sign, get rid of trailing [+-]
2964 sign = 0
2965 if num[0] == '+':
2966 num = num[1:]
2967 elif num[0] == '-': #elif avoids '+-nan'
2968 num = num[1:]
2969 sign = 1
2970
2971 if num.startswith('nan'):
2972 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
2973 return 0
2974 return (1, sign, num[3:].lstrip('0'))
2975 if num.startswith('snan'):
2976 if len(num) > 4 and not num[4:].isdigit():
2977 return 0
2978 return (2, sign, num[4:].lstrip('0'))
2979 return 0
2980
2981
2982##### Setup Specific Contexts ################################
2983
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002984# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00002985# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002986
2987DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002988 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002989 traps=[DivisionByZero, Overflow, InvalidOperation],
2990 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002991 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00002992 Emax=999999999,
2993 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002994 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002995)
2996
2997# Pre-made alternate contexts offered by the specification
2998# Don't change these; the user should be able to select these
2999# contexts and be able to reproduce results from other implementations
3000# of the spec.
3001
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003002BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003003 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003004 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
3005 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003006)
3007
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003008ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003009 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003010 traps=[],
3011 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003012)
3013
3014
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00003015##### Useful Constants (internal use only) ####################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003016
3017#Reusable defaults
3018Inf = Decimal('Inf')
3019negInf = Decimal('-Inf')
3020
3021#Infsign[sign] is infinity w/ that sign
3022Infsign = (Inf, negInf)
3023
3024NaN = Decimal('NaN')
3025
3026
3027##### crud for parsing strings #################################
3028import re
3029
3030# There's an optional sign at the start, and an optional exponent
3031# at the end. The exponent has an optional sign and at least one
3032# digit. In between, must have either at least one digit followed
3033# by an optional fraction, or a decimal point followed by at least
3034# one digit. Yuck.
3035
3036_parser = re.compile(r"""
3037# \s*
3038 (?P<sign>[-+])?
3039 (
3040 (?P<int>\d+) (\. (?P<frac>\d*))?
3041 |
3042 \. (?P<onlyfrac>\d+)
3043 )
3044 ([eE](?P<exp>[-+]? \d+))?
3045# \s*
3046 $
3047""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
3048
3049del re
3050
3051# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
3052
3053def _string2exact(s):
3054 m = _parser(s)
3055 if m is None:
3056 raise ValueError("invalid literal for Decimal: %r" % s)
3057
3058 if m.group('sign') == "-":
3059 sign = 1
3060 else:
3061 sign = 0
3062
3063 exp = m.group('exp')
3064 if exp is None:
3065 exp = 0
3066 else:
3067 exp = int(exp)
3068
3069 intpart = m.group('int')
3070 if intpart is None:
3071 intpart = ""
3072 fracpart = m.group('onlyfrac')
3073 else:
3074 fracpart = m.group('frac')
3075 if fracpart is None:
3076 fracpart = ""
3077
3078 exp -= len(fracpart)
3079
3080 mantissa = intpart + fracpart
3081 tmp = map(int, mantissa)
3082 backup = tmp
3083 while tmp and tmp[0] == 0:
3084 del tmp[0]
3085
3086 # It's a zero
3087 if not tmp:
3088 if backup:
3089 return (sign, tuple(backup), exp)
3090 return (sign, (0,), exp)
3091 mantissa = tuple(tmp)
3092
3093 return (sign, mantissa, exp)
3094
3095
3096if __name__ == '__main__':
3097 import doctest, sys
3098 doctest.testmod(sys.modules[__name__])