blob: 5216ac4cfe123ffb732114c2cd3383d5dc91652e [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 Hettinger61992ef2004-08-06 23:42:16 +0000395 context = copy.deepcopy(context)
396 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()
416
417 def getcontext(_local=local):
418 """Returns this thread's context.
419
420 If this thread does not yet have a context, returns
421 a new context and sets this thread's context.
422 New contexts are copies of DefaultContext.
423 """
424 try:
425 return _local.__decimal_context__
426 except AttributeError:
427 context = Context()
428 _local.__decimal_context__ = context
429 return context
430
431 def setcontext(context, _local=local):
432 """Set this thread's context to context."""
433 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000434 context = copy.deepcopy(context)
435 context.clear_flags()
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000436 _local.__decimal_context__ = context
437
438 del threading, local # Don't contaminate the namespace
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000439
440
441##### Decimal class ###########################################
442
443class Decimal(object):
444 """Floating point class for decimal arithmetic."""
445
446 __slots__ = ('_exp','_int','_sign')
447
448 def __init__(self, value="0", context=None):
449 """Create a decimal point instance.
450
451 >>> Decimal('3.14') # string input
452 Decimal("3.14")
453 >>> Decimal((0, (3, 1, 4), -2)) # tuple input (sign, digit_tuple, exponent)
454 Decimal("3.14")
455 >>> Decimal(314) # int or long
456 Decimal("314")
457 >>> Decimal(Decimal(314)) # another decimal instance
458 Decimal("314")
459 """
460 if context is None:
461 context = getcontext()
462
463 if isinstance(value, (int,long)):
464 value = str(value)
465
466 # String?
467 # REs insist on real strings, so we can too.
468 if isinstance(value, basestring):
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000469 if _isinfinity(value):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000470 self._exp = 'F'
471 self._int = (0,)
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000472 sign = _isinfinity(value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000473 if sign == 1:
474 self._sign = 0
475 else:
476 self._sign = 1
477 return
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000478 if _isnan(value):
479 sig, sign, diag = _isnan(value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000480 if len(diag) > context.prec: #Diagnostic info too long
481 self._sign, self._int, self._exp = \
482 context._raise_error(ConversionSyntax)
483 return
484 if sig == 1:
485 self._exp = 'n' #qNaN
486 else: #sig == 2
487 self._exp = 'N' #sNaN
488 self._sign = sign
489 self._int = tuple(map(int, diag)) #Diagnostic info
490 return
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +0000491 try:
492 self._sign, self._int, self._exp = _string2exact(value)
493 except ValueError:
494 self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000495 return
496
497 # tuple/list conversion (possibly from as_tuple())
498 if isinstance(value, (list,tuple)):
499 if len(value) != 3:
500 raise ValueError, 'Invalid arguments'
501 if value[0] not in [0,1]:
502 raise ValueError, 'Invalid sign'
503 for digit in value[1]:
504 if not isinstance(digit, (int,long)) or digit < 0:
505 raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
506
507 self._sign = value[0]
508 self._int = tuple(value[1])
509 if value[2] in ('F','n','N'):
510 self._exp = value[2]
511 else:
512 self._exp = int(value[2])
513 return
514
515 # Turn an intermediate value back to Decimal()
516 if isinstance(value, _WorkRep):
517 if value.sign == 1:
518 self._sign = 0
519 else:
520 self._sign = 1
521 self._int = tuple(value.int)
522 self._exp = int(value.exp)
523 return
524
525 if isinstance(value, Decimal):
Tim Peters4e0e1b62004-07-07 20:54:48 +0000526 self._exp = value._exp
527 self._sign = value._sign
528 self._int = value._int
529 return
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000530
Raymond Hettingerbf440692004-07-10 14:14:37 +0000531 if isinstance(value, float):
532 raise TypeError("Cannot convert float to Decimal. " +
533 "First convert the float to a string")
534
535 raise TypeError("Cannot convert %r" % value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000536
537 def _convert_other(self, other):
538 """Convert other to Decimal.
539
540 Verifies that it's ok to use in an implicit construction.
541 """
542 if isinstance(other, Decimal):
543 return other
544 if isinstance(other, (int, long)):
545 other = Decimal(other)
546 return other
547
548 raise TypeError, "You can interact Decimal only with int, long or Decimal data types."
549
550 def _isnan(self):
551 """Returns whether the number is not actually one.
552
553 0 if a number
554 1 if NaN
555 2 if sNaN
556 """
557 if self._exp == 'n':
558 return 1
559 elif self._exp == 'N':
560 return 2
561 return 0
562
563 def _isinfinity(self):
564 """Returns whether the number is infinite
565
566 0 if finite or not a number
567 1 if +INF
568 -1 if -INF
569 """
570 if self._exp == 'F':
571 if self._sign:
572 return -1
573 return 1
574 return 0
575
576 def _check_nans(self, other = None, context=None):
577 """Returns whether the number is not actually one.
578
579 if self, other are sNaN, signal
580 if self, other are NaN return nan
581 return 0
582
583 Done before operations.
584 """
585 if context is None:
586 context = getcontext()
587
588 if self._isnan() == 2:
589 return context._raise_error(InvalidOperation, 'sNaN',
590 1, self)
591 if other is not None and other._isnan() == 2:
592 return context._raise_error(InvalidOperation, 'sNaN',
593 1, other)
594 if self._isnan():
595 return self
596 if other is not None and other._isnan():
597 return other
598 return 0
599
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000600 def __nonzero__(self):
601 """Is the number non-zero?
602
603 0 if self == 0
604 1 if self != 0
605 """
606 if isinstance(self._exp, str):
607 return 1
608 return self._int != (0,)*len(self._int)
609
610 def __cmp__(self, other, context=None):
611 if context is None:
612 context = getcontext()
613 other = self._convert_other(other)
614
615 ans = self._check_nans(other, context)
616 if ans:
617 return 1
618
619 if not self and not other:
620 return 0 #If both 0, sign comparison isn't certain.
621
622 #If different signs, neg one is less
623 if other._sign < self._sign:
624 return -1
625 if self._sign < other._sign:
626 return 1
627
628 # INF = INF
629 if self._isinfinity() and other._isinfinity():
630 return 0
631 if self._isinfinity():
632 return (-1)**self._sign
633 if other._isinfinity():
634 return -((-1)**other._sign)
635
636 if self.adjusted() == other.adjusted() and \
637 self._int + (0,)*(self._exp - other._exp) == \
638 other._int + (0,)*(other._exp - self._exp):
639 return 0 #equal, except in precision. ([0]*(-x) = [])
640 elif self.adjusted() > other.adjusted() and self._int[0] != 0:
641 return (-1)**self._sign
642 elif self.adjusted < other.adjusted() and other._int[0] != 0:
643 return -((-1)**self._sign)
644
645 context = context.copy()
646 rounding = context._set_rounding(ROUND_UP) #round away from 0
647
648 flags = context._ignore_all_flags()
649 res = self.__sub__(other, context=context)
650
651 context._regard_flags(*flags)
652
653 context.rounding = rounding
654
655 if not res:
656 return 0
657 elif res._sign:
658 return -1
659 return 1
660
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000661 def __eq__(self, other):
662 if not isinstance(other, (Decimal, int, long)):
663 return False
664 return self.__cmp__(other) == 0
665
666 def __ne__(self, other):
667 if not isinstance(other, (Decimal, int, long)):
668 return True
669 return self.__cmp__(other) != 0
670
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000671 def compare(self, other, context=None):
672 """Compares one to another.
673
674 -1 => a < b
675 0 => a = b
676 1 => a > b
677 NaN => one is NaN
678 Like __cmp__, but returns Decimal instances.
679 """
680 if context is None:
681 context = getcontext()
682 other = self._convert_other(other)
683
684 #compare(NaN, NaN) = NaN
685 ans = self._check_nans(other, context)
686 if ans:
687 return ans
688
689 return Decimal(self.__cmp__(other, context))
690
691 def __hash__(self):
692 """x.__hash__() <==> hash(x)"""
693 # Decimal integers must hash the same as the ints
694 # Non-integer decimals are normalized and hashed as strings
695 # Normalization assures that hast(100E-1) == hash(10)
696 i = int(self)
697 if self == Decimal(i):
698 return hash(i)
699 assert self.__nonzero__() # '-0' handled by integer case
700 return hash(str(self.normalize()))
701
702 def as_tuple(self):
703 """Represents the number as a triple tuple.
704
705 To show the internals exactly as they are.
706 """
707 return (self._sign, self._int, self._exp)
708
709 def __repr__(self):
710 """Represents the number as an instance of Decimal."""
711 # Invariant: eval(repr(d)) == d
712 return 'Decimal("%s")' % str(self)
713
714 def __str__(self, eng = 0, context=None):
715 """Return string representation of the number in scientific notation.
716
717 Captures all of the information in the underlying representation.
718 """
719
720 if self._isnan():
721 minus = '-'*self._sign
722 if self._int == (0,):
723 info = ''
724 else:
725 info = ''.join(map(str, self._int))
726 if self._isnan() == 2:
727 return minus + 'sNaN' + info
728 return minus + 'NaN' + info
729 if self._isinfinity():
730 minus = '-'*self._sign
731 return minus + 'Infinity'
732
733 if context is None:
734 context = getcontext()
735
736 tmp = map(str, self._int)
737 numdigits = len(self._int)
738 leftdigits = self._exp + numdigits
739 if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
740 if self._exp < 0 and self._exp >= -6: #short, no need for e/E
741 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
742 return s
743 #exp is closest mult. of 3 >= self._exp
744 exp = ((self._exp - 1)// 3 + 1) * 3
745 if exp != self._exp:
746 s = '0.'+'0'*(exp - self._exp)
747 else:
748 s = '0'
749 if exp != 0:
750 if context.capitals:
751 s += 'E'
752 else:
753 s += 'e'
754 if exp > 0:
755 s += '+' #0.0e+3, not 0.0e3
756 s += str(exp)
757 s = '-'*self._sign + s
758 return s
759 if eng:
760 dotplace = (leftdigits-1)%3+1
761 adjexp = leftdigits -1 - (leftdigits-1)%3
762 else:
763 adjexp = leftdigits-1
764 dotplace = 1
765 if self._exp == 0:
766 pass
767 elif self._exp < 0 and adjexp >= 0:
768 tmp.insert(leftdigits, '.')
769 elif self._exp < 0 and adjexp >= -6:
770 tmp[0:0] = ['0'] * int(-leftdigits)
771 tmp.insert(0, '0.')
772 else:
773 if numdigits > dotplace:
774 tmp.insert(dotplace, '.')
775 elif numdigits < dotplace:
776 tmp.extend(['0']*(dotplace-numdigits))
777 if adjexp:
778 if not context.capitals:
779 tmp.append('e')
780 else:
781 tmp.append('E')
782 if adjexp > 0:
783 tmp.append('+')
784 tmp.append(str(adjexp))
785 if eng:
786 while tmp[0:1] == ['0']:
787 tmp[0:1] = []
788 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
789 tmp[0:0] = ['0']
790 if self._sign:
791 tmp.insert(0, '-')
792
793 return ''.join(tmp)
794
795 def to_eng_string(self, context=None):
796 """Convert to engineering-type string.
797
798 Engineering notation has an exponent which is a multiple of 3, so there
799 are up to 3 digits left of the decimal place.
800
801 Same rules for when in exponential and when as a value as in __str__.
802 """
803 if context is None:
804 context = getcontext()
805 return self.__str__(eng=1, context=context)
806
807 def __neg__(self, context=None):
808 """Returns a copy with the sign switched.
809
810 Rounds, if it has reason.
811 """
812 if context is None:
813 context = getcontext()
814 ans = self._check_nans(context=context)
815 if ans:
816 return ans
817
818 if not self:
819 # -Decimal('0') is Decimal('0'), not Decimal('-0')
820 sign = 0
821 elif self._sign:
822 sign = 0
823 else:
824 sign = 1
825 if context._rounding_decision == ALWAYS_ROUND:
826 return Decimal((sign, self._int, self._exp))._fix(context=context)
827 return Decimal( (sign, self._int, self._exp))
828
829 def __pos__(self, context=None):
830 """Returns a copy, unless it is a sNaN.
831
832 Rounds the number (if more then precision digits)
833 """
834 if context is None:
835 context = getcontext()
836 ans = self._check_nans(context=context)
837 if ans:
838 return ans
839
840 sign = self._sign
841 if not self:
842 # + (-0) = 0
843 sign = 0
844
845 if context._rounding_decision == ALWAYS_ROUND:
846 ans = self._fix(context=context)
847 else:
848 ans = Decimal(self)
849 ans._sign = sign
850 return ans
851
852 def __abs__(self, round=1, context=None):
853 """Returns the absolute value of self.
854
855 If the second argument is 0, do not round.
856 """
857 if context is None:
858 context = getcontext()
859 ans = self._check_nans(context=context)
860 if ans:
861 return ans
862
863 if not round:
864 context = context.copy()
865 context._set_rounding_decision(NEVER_ROUND)
866
867 if self._sign:
868 ans = self.__neg__(context=context)
869 else:
870 ans = self.__pos__(context=context)
871
872 return ans
873
874 def __add__(self, other, context=None):
875 """Returns self + other.
876
877 -INF + INF (or the reverse) cause InvalidOperation errors.
878 """
879 if context is None:
880 context = getcontext()
881 other = self._convert_other(other)
882
883 ans = self._check_nans(other, context)
884 if ans:
885 return ans
886
887 if self._isinfinity():
888 #If both INF, same sign => same as both, opposite => error.
889 if self._sign != other._sign and other._isinfinity():
890 return context._raise_error(InvalidOperation, '-INF + INF')
891 return Decimal(self)
892 if other._isinfinity():
893 return Decimal(other) #Can't both be infinity here
894
895 shouldround = context._rounding_decision == ALWAYS_ROUND
896
897 exp = min(self._exp, other._exp)
898 negativezero = 0
899 if context.rounding == ROUND_FLOOR and self._sign != other._sign:
900 #If the answer is 0, the sign should be negative, in this case.
901 negativezero = 1
902
903 if not self and not other:
904 sign = min(self._sign, other._sign)
905 if negativezero:
906 sign = 1
907 return Decimal( (sign, (0,), exp))
908 if not self:
909 if exp < other._exp - context.prec-1:
910 exp = other._exp - context.prec-1
911 ans = other._rescale(exp, watchexp=0, context=context)
912 if shouldround:
913 ans = ans._fix(context=context)
914 return ans
915 if not other:
916 if exp < self._exp - context.prec-1:
917 exp = self._exp - context.prec-1
918 ans = self._rescale(exp, watchexp=0, context=context)
919 if shouldround:
920 ans = ans._fix(context=context)
921 return ans
922
923 op1 = _WorkRep(self)
924 op2 = _WorkRep(other)
925 op1, op2 = _normalize(op1, op2, shouldround, context.prec)
926
927 result = _WorkRep()
928
929 if op1.sign != op2.sign:
930 diff = cmp(abs(op1), abs(op2))
931 # Equal and opposite
932 if diff == 0:
933 if exp < context.Etiny():
934 exp = context.Etiny()
935 context._raise_error(Clamped)
936 return Decimal((negativezero, (0,), exp))
937 if diff < 0:
938 op1, op2 = op2, op1
939 #OK, now abs(op1) > abs(op2)
940 if op1.sign == -1:
941 result.sign = -1
942 op1.sign, op2.sign = op2.sign, op1.sign
943 else:
944 result.sign = 1
945 #So we know the sign, and op1 > 0.
946 elif op1.sign == -1:
947 result.sign = -1
948 op1.sign, op2.sign = (1, 1)
949 else:
950 result.sign = 1
951 #Now, op1 > abs(op2) > 0
952
953 op1.int.reverse()
954 op2.int.reverse()
955
956 if op2.sign == 1:
957 result.int = resultint = map(operator.add, op1.int, op2.int)
958 carry = 0
959 for i in xrange(len(op1.int)):
960 tmp = resultint[i] + carry
961 carry = 0
962 if tmp > 9:
963 carry = 1
964 tmp -= 10
965 resultint[i] = tmp
966 if carry:
967 resultint.append(1)
968 else:
969 result.int = resultint = map(operator.sub, op1.int, op2.int)
970 loan = 0
971 for i in xrange(len(op1.int)):
972 tmp = resultint[i] - loan
973 loan = 0
974 if tmp < 0:
975 loan = 1
976 tmp += 10
977 resultint[i] = tmp
978 assert not loan
979
980 while resultint[-1] == 0:
981 resultint.pop()
982 resultint.reverse()
983
984 result.exp = op1.exp
985 ans = Decimal(result)
986 if shouldround:
987 ans = ans._fix(context=context)
988 return ans
989
990 __radd__ = __add__
991
992 def __sub__(self, other, context=None):
993 """Return self + (-other)"""
994 if context is None:
995 context = getcontext()
996 other = self._convert_other(other)
997
998 ans = self._check_nans(other, context=context)
999 if ans:
1000 return ans
1001
1002 # -Decimal(0) = Decimal(0), which we don't want since
1003 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
1004 # so we change the sign directly to a copy
1005 tmp = Decimal(other)
1006 tmp._sign = 1-tmp._sign
1007
1008 return self.__add__(tmp, context=context)
1009
1010 def __rsub__(self, other, context=None):
1011 """Return other + (-self)"""
1012 if context is None:
1013 context = getcontext()
1014 other = self._convert_other(other)
1015
1016 tmp = Decimal(self)
1017 tmp._sign = 1 - tmp._sign
1018 return other.__add__(tmp, context=context)
1019
1020 def _increment(self, round=1, context=None):
1021 """Special case of add, adding 1eExponent
1022
1023 Since it is common, (rounding, for example) this adds
1024 (sign)*one E self._exp to the number more efficiently than add.
1025
1026 For example:
1027 Decimal('5.624e10')._increment() == Decimal('5.625e10')
1028 """
1029 if context is None:
1030 context = getcontext()
1031 ans = self._check_nans(context=context)
1032 if ans:
1033 return ans
1034
1035 L = list(self._int)
1036 L[-1] += 1
1037 spot = len(L)-1
1038 while L[spot] == 10:
1039 L[spot] = 0
1040 if spot == 0:
1041 L[0:0] = [1]
1042 break
1043 L[spot-1] += 1
1044 spot -= 1
1045 ans = Decimal((self._sign, L, self._exp))
1046
1047 if round and context._rounding_decision == ALWAYS_ROUND:
1048 ans = ans._fix(context=context)
1049 return ans
1050
1051 def __mul__(self, other, context=None):
1052 """Return self * other.
1053
1054 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1055 """
1056 if context is None:
1057 context = getcontext()
1058 other = self._convert_other(other)
1059
1060 ans = self._check_nans(other, context)
1061 if ans:
1062 return ans
1063
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001064 resultsign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001065 if self._isinfinity():
1066 if not other:
1067 return context._raise_error(InvalidOperation, '(+-)INF * 0')
1068 return Infsign[resultsign]
1069
1070 if other._isinfinity():
1071 if not self:
1072 return context._raise_error(InvalidOperation, '0 * (+-)INF')
1073 return Infsign[resultsign]
1074
1075 resultexp = self._exp + other._exp
1076 shouldround = context._rounding_decision == ALWAYS_ROUND
1077
1078 # Special case for multiplying by zero
1079 if not self or not other:
1080 ans = Decimal((resultsign, (0,), resultexp))
1081 if shouldround:
1082 #Fixing in case the exponent is out of bounds
1083 ans = ans._fix(context=context)
1084 return ans
1085
1086 # Special case for multiplying by power of 10
1087 if self._int == (1,):
1088 ans = Decimal((resultsign, other._int, resultexp))
1089 if shouldround:
1090 ans = ans._fix(context=context)
1091 return ans
1092 if other._int == (1,):
1093 ans = Decimal((resultsign, self._int, resultexp))
1094 if shouldround:
1095 ans = ans._fix(context=context)
1096 return ans
1097
1098 op1 = list(self._int)
1099 op2 = list(other._int)
1100 op1.reverse()
1101 op2.reverse()
1102 # Minimize Decimal additions
1103 if len(op2) > len(op1):
1104 op1, op2 = op2, op1
1105
1106 _divmod = divmod
1107 accumulator = [0]*(len(self._int) + len(other._int))
1108 for i in xrange(len(op2)):
1109 if op2[i] == 0:
1110 continue
1111 mult = op2[i]
1112 carry = 0
1113 for j in xrange(len(op1)):
1114 carry, accumulator[i+j] = _divmod( mult * op1[j] + carry
1115 + accumulator[i+j], 10)
1116
1117 if carry:
1118 accumulator[i + j + 1] += carry
1119 while not accumulator[-1]:
1120 accumulator.pop()
1121 accumulator.reverse()
1122
1123 ans = Decimal( (resultsign, accumulator, resultexp))
1124 if shouldround:
1125 ans = ans._fix(context=context)
1126
1127 return ans
1128 __rmul__ = __mul__
1129
1130 def __div__(self, other, context=None):
1131 """Return self / other."""
1132 return self._divide(other, context=context)
1133 __truediv__ = __div__
1134
1135 def _divide(self, other, divmod = 0, context=None):
1136 """Return a / b, to context.prec precision.
1137
1138 divmod:
1139 0 => true division
1140 1 => (a //b, a%b)
1141 2 => a //b
1142 3 => a%b
1143
1144 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1145 computing the other value are not raised.
1146 """
1147 if context is None:
1148 context = getcontext()
1149 other = self._convert_other(other)
1150
1151 ans = self._check_nans(other, context)
1152 if ans:
1153 if divmod:
1154 return (ans, ans)
1155 else:
1156 return ans
1157
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001158 sign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001159 if not self and not other:
1160 if divmod:
1161 return context._raise_error(DivisionUndefined, '0 / 0', 1)
1162 return context._raise_error(DivisionUndefined, '0 / 0')
1163 if self._isinfinity() and other._isinfinity():
1164 if not divmod:
1165 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
1166 else:
1167 return (context._raise_error(InvalidOperation,
1168 '(+-)INF // (+-)INF'),
1169 context._raise_error(InvalidOperation,
1170 '(+-)INF % (+-)INF'))
1171
1172 if not divmod:
1173 if other._isinfinity():
1174 context._raise_error(Clamped, 'Division by infinity')
1175 return Decimal((sign, (0,), context.Etiny()))
1176 if self._isinfinity():
1177 return Infsign[sign]
1178 #These two have different precision.
1179 if not self:
1180 exp = self._exp - other._exp
1181 if exp < context.Etiny():
1182 exp = context.Etiny()
1183 context._raise_error(Clamped, '0e-x / y')
1184 if exp > context.Emax:
1185 exp = context.Emax
1186 context._raise_error(Clamped, '0e+x / y')
1187 return Decimal( (sign, (0,), exp) )
1188
1189 if not other:
1190 return context._raise_error(DivisionByZero, 'x / 0', sign)
1191 if divmod:
1192 if other._isinfinity():
1193 return (Decimal((sign, (0,), 0)), Decimal(self))
1194 if self._isinfinity():
1195 if divmod == 1:
1196 return (Infsign[sign],
1197 context._raise_error(InvalidOperation, 'INF % x'))
1198 elif divmod == 2:
1199 return (Infsign[sign], NaN)
1200 elif divmod == 3:
1201 return (Infsign[sign],
1202 context._raise_error(InvalidOperation, 'INF % x'))
1203 if not self:
1204 otherside = Decimal(self)
1205 otherside._exp = min(self._exp, other._exp)
1206 return (Decimal((sign, (0,), 0)), otherside)
1207
1208 if not other:
1209 return context._raise_error(DivisionByZero, 'divmod(x,0)',
1210 sign, 1)
1211
1212 #OK, so neither = 0, INF
1213
1214 shouldround = context._rounding_decision == ALWAYS_ROUND
1215
1216 #If we're dividing into ints, and self < other, stop.
1217 #self.__abs__(0) does not round.
1218 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
1219
1220 if divmod == 1 or divmod == 3:
1221 exp = min(self._exp, other._exp)
1222 ans2 = self._rescale(exp, context=context, watchexp=0)
1223 if shouldround:
1224 ans2 = ans2._fix(context=context)
1225 return (Decimal( (sign, (0,), 0) ),
1226 ans2)
1227
1228 elif divmod == 2:
1229 #Don't round the mod part, if we don't need it.
1230 return (Decimal( (sign, (0,), 0) ), Decimal(self))
1231
1232 if sign:
1233 sign = -1
1234 else:
1235 sign = 1
1236 adjust = 0
1237 op1 = _WorkRep(self)
1238 op2 = _WorkRep(other)
1239 op1, op2, adjust = _adjust_coefficients(op1, op2)
1240 res = _WorkRep( (sign, [0], (op1.exp - op2.exp)) )
1241 if divmod and res.exp > context.prec + 1:
1242 return context._raise_error(DivisionImpossible)
1243
1244 ans = None
1245 while 1:
1246 while( (len(op2.int) < len(op1.int) and op1.int[0]) or
1247 (len(op2.int) == len(op1.int) and op2.int <= op1.int)):
1248 #Meaning, while op2.int < op1.int, when normalized.
1249 res._increment()
1250 op1.subtract(op2.int)
1251 if res.exp == 0 and divmod:
1252 if len(res.int) > context.prec and shouldround:
1253 return context._raise_error(DivisionImpossible)
1254 otherside = Decimal(op1)
1255 frozen = context._ignore_all_flags()
1256
1257 exp = min(self._exp, other._exp)
1258 otherside = otherside._rescale(exp, context=context,
1259 watchexp=0)
1260 context._regard_flags(*frozen)
1261 if shouldround:
1262 otherside = otherside._fix(context=context)
1263 return (Decimal(res), otherside)
1264
1265 if op1.int == [0]*len(op1.int) and adjust >= 0 and not divmod:
1266 break
1267 if (len(res.int) > context.prec) and shouldround:
1268 if divmod:
1269 return context._raise_error(DivisionImpossible)
1270 shouldround=1
1271 # Really, the answer is a bit higher, so adding a one to
1272 # the end will make sure the rounding is right.
1273 if op1.int != [0]*len(op1.int):
1274 res.int.append(1)
1275 res.exp -= 1
1276
1277 break
1278 res.exp -= 1
1279 adjust += 1
1280 res.int.append(0)
1281 op1.int.append(0)
1282 op1.exp -= 1
1283
1284 if res.exp == 0 and divmod and (len(op2.int) > len(op1.int) or
1285 (len(op2.int) == len(op1.int) and
1286 op2.int > op1.int)):
1287 #Solves an error in precision. Same as a previous block.
1288
1289 if len(res.int) > context.prec and shouldround:
1290 return context._raise_error(DivisionImpossible)
1291 otherside = Decimal(op1)
1292 frozen = context._ignore_all_flags()
1293
1294 exp = min(self._exp, other._exp)
1295 otherside = otherside._rescale(exp, context=context)
1296
1297 context._regard_flags(*frozen)
1298
1299 return (Decimal(res), otherside)
1300
1301 ans = Decimal(res)
1302 if shouldround:
1303 ans = ans._fix(context=context)
1304 return ans
1305
1306 def __rdiv__(self, other, context=None):
1307 """Swaps self/other and returns __div__."""
1308 other = self._convert_other(other)
1309 return other.__div__(self, context=context)
1310 __rtruediv__ = __rdiv__
1311
1312 def __divmod__(self, other, context=None):
1313 """
1314 (self // other, self % other)
1315 """
1316 return self._divide(other, 1, context)
1317
1318 def __rdivmod__(self, other, context=None):
1319 """Swaps self/other and returns __divmod__."""
1320 other = self._convert_other(other)
1321 return other.__divmod__(self, context=context)
1322
1323 def __mod__(self, other, context=None):
1324 """
1325 self % other
1326 """
1327 if context is None:
1328 context = getcontext()
1329 other = self._convert_other(other)
1330
1331 ans = self._check_nans(other, context)
1332 if ans:
1333 return ans
1334
1335 if self and not other:
1336 return context._raise_error(InvalidOperation, 'x % 0')
1337
1338 return self._divide(other, 3, context)[1]
1339
1340 def __rmod__(self, other, context=None):
1341 """Swaps self/other and returns __mod__."""
1342 other = self._convert_other(other)
1343 return other.__mod__(self, context=context)
1344
1345 def remainder_near(self, other, context=None):
1346 """
1347 Remainder nearest to 0- abs(remainder-near) <= other/2
1348 """
1349 if context is None:
1350 context = getcontext()
1351 other = self._convert_other(other)
1352
1353 ans = self._check_nans(other, context)
1354 if ans:
1355 return ans
1356 if self and not other:
1357 return context._raise_error(InvalidOperation, 'x % 0')
1358
1359 # If DivisionImpossible causes an error, do not leave Rounded/Inexact
1360 # ignored in the calling function.
1361 context = context.copy()
1362 flags = context._ignore_flags(Rounded, Inexact)
1363 #keep DivisionImpossible flags
1364 (side, r) = self.__divmod__(other, context=context)
1365
1366 if r._isnan():
1367 context._regard_flags(*flags)
1368 return r
1369
1370 context = context.copy()
1371 rounding = context._set_rounding_decision(NEVER_ROUND)
1372
1373 if other._sign:
1374 comparison = other.__div__(Decimal(-2), context=context)
1375 else:
1376 comparison = other.__div__(Decimal(2), context=context)
1377
1378 context._set_rounding_decision(rounding)
1379 context._regard_flags(*flags)
1380
1381 s1, s2 = r._sign, comparison._sign
1382 r._sign, comparison._sign = 0, 0
1383
1384 if r < comparison:
1385 r._sign, comparison._sign = s1, s2
1386 #Get flags now
1387 self.__divmod__(other, context=context)
1388 return r._fix(context=context)
1389 r._sign, comparison._sign = s1, s2
1390
1391 rounding = context._set_rounding_decision(NEVER_ROUND)
1392
1393 (side, r) = self.__divmod__(other, context=context)
1394 context._set_rounding_decision(rounding)
1395 if r._isnan():
1396 return r
1397
1398 decrease = not side._iseven()
1399 rounding = context._set_rounding_decision(NEVER_ROUND)
1400 side = side.__abs__(context=context)
1401 context._set_rounding_decision(rounding)
1402
1403 s1, s2 = r._sign, comparison._sign
1404 r._sign, comparison._sign = 0, 0
1405 if r > comparison or decrease and r == comparison:
1406 r._sign, comparison._sign = s1, s2
1407 context.prec += 1
1408 if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
1409 context.prec -= 1
1410 return context._raise_error(DivisionImpossible)[1]
1411 context.prec -= 1
1412 if self._sign == other._sign:
1413 r = r.__sub__(other, context=context)
1414 else:
1415 r = r.__add__(other, context=context)
1416 else:
1417 r._sign, comparison._sign = s1, s2
1418
1419 return r._fix(context=context)
1420
1421 def __floordiv__(self, other, context=None):
1422 """self // other"""
1423 return self._divide(other, 2, context)[0]
1424
1425 def __rfloordiv__(self, other, context=None):
1426 """Swaps self/other and returns __floordiv__."""
1427 other = self._convert_other(other)
1428 return other.__floordiv__(self, context=context)
1429
1430 def __float__(self):
1431 """Float representation."""
1432 return float(str(self))
1433
1434 def __int__(self):
1435 """Converts self to a int, truncating if necessary."""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001436 if self._isnan():
1437 context = getcontext()
1438 return context._raise_error(InvalidContext)
1439 elif self._isinfinity():
1440 raise OverflowError, "Cannot convert infinity to long"
1441 if not self:
1442 return 0
1443 sign = '-'*self._sign
1444 if self._exp >= 0:
1445 s = sign + ''.join(map(str, self._int)) + '0'*self._exp
1446 return int(s)
1447 s = sign + ''.join(map(str, self._int))[:self._exp]
1448 return int(s)
1449 tmp = list(self._int)
1450 tmp.reverse()
1451 val = 0
1452 while tmp:
1453 val *= 10
1454 val += tmp.pop()
1455 return int(((-1) ** self._sign) * val * 10.**int(self._exp))
1456
1457 def __long__(self):
1458 """Converts to a long.
1459
1460 Equivalent to long(int(self))
1461 """
1462 return long(self.__int__())
1463
1464 def _fix(self, prec=None, rounding=None, folddown=None, context=None):
1465 """Round if it is necessary to keep self within prec precision.
1466
1467 Rounds and fixes the exponent. Does not raise on a sNaN.
1468
1469 Arguments:
1470 self - Decimal instance
1471 prec - precision to which to round. By default, the context decides.
1472 rounding - Rounding method. By default, the context decides.
1473 folddown - Fold down high elements, by default context._clamp
1474 context - context used.
1475 """
1476 if self._isinfinity() or self._isnan():
1477 return self
1478 if context is None:
1479 context = getcontext()
1480 if prec is None:
1481 prec = context.prec
1482 ans = Decimal(self)
1483 ans = ans._fixexponents(prec, rounding, folddown=folddown,
1484 context=context)
1485 if len(ans._int) > prec:
1486 ans = ans._round(prec, rounding, context=context)
1487 ans = ans._fixexponents(prec, rounding, folddown=folddown,
1488 context=context)
1489 return ans
1490
1491 def _fixexponents(self, prec=None, rounding=None, folddown=None,
1492 context=None):
1493 """Fix the exponents and return a copy with the exponent in bounds."""
1494 if self._isinfinity():
1495 return self
1496 if context is None:
1497 context = getcontext()
1498 if prec is None:
1499 prec = context.prec
1500 if folddown is None:
1501 folddown = context._clamp
1502 Emin, Emax = context.Emin, context.Emax
1503 Etop = context.Etop()
1504 ans = Decimal(self)
1505 if ans.adjusted() < Emin:
1506 Etiny = context.Etiny()
1507 if ans._exp < Etiny:
1508 if not ans:
1509 ans._exp = Etiny
1510 context._raise_error(Clamped)
1511 return ans
1512 ans = ans._rescale(Etiny, context=context)
1513 #It isn't zero, and exp < Emin => subnormal
1514 context._raise_error(Subnormal)
1515 if context.flags[Inexact]:
1516 context._raise_error(Underflow)
1517 else:
1518 if ans:
1519 #Only raise subnormal if non-zero.
1520 context._raise_error(Subnormal)
1521 elif folddown and ans._exp > Etop:
1522 context._raise_error(Clamped)
1523 ans = ans._rescale(Etop, context=context)
1524 elif ans.adjusted() > Emax:
1525 if not ans:
1526 ans._exp = Emax
1527 context._raise_error(Clamped)
1528 return ans
1529 context._raise_error(Inexact)
1530 context._raise_error(Rounded)
1531 return context._raise_error(Overflow, 'above Emax', ans._sign)
1532 return ans
1533
1534 def _round(self, prec=None, rounding=None, context=None):
1535 """Returns a rounded version of self.
1536
1537 You can specify the precision or rounding method. Otherwise, the
1538 context determines it.
1539 """
1540
1541 if context is None:
1542 context = getcontext()
1543 ans = self._check_nans(context=context)
1544 if ans:
1545 return ans
1546
1547 if self._isinfinity():
1548 return Decimal(self)
1549
1550 if rounding is None:
1551 rounding = context.rounding
1552 if prec is None:
1553 prec = context.prec
1554
1555 if not self:
1556 if prec <= 0:
1557 dig = (0,)
1558 exp = len(self._int) - prec + self._exp
1559 else:
1560 dig = (0,) * prec
1561 exp = len(self._int) + self._exp - prec
1562 ans = Decimal((self._sign, dig, exp))
1563 context._raise_error(Rounded)
1564 return ans
1565
1566 if prec == 0:
1567 temp = Decimal(self)
1568 temp._int = (0,)+temp._int
1569 prec = 1
1570 elif prec < 0:
1571 exp = self._exp + len(self._int) - prec - 1
1572 temp = Decimal( (self._sign, (0, 1), exp))
1573 prec = 1
1574 else:
1575 temp = Decimal(self)
1576
1577 numdigits = len(temp._int)
1578 if prec == numdigits:
1579 return temp
1580
1581 # See if we need to extend precision
1582 expdiff = prec - numdigits
1583 if expdiff > 0:
1584 tmp = list(temp._int)
1585 tmp.extend([0] * expdiff)
1586 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff))
1587 return ans
1588
1589 #OK, but maybe all the lost digits are 0.
1590 lostdigits = self._int[expdiff:]
1591 if lostdigits == (0,) * len(lostdigits):
1592 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
1593 #Rounded, but not Inexact
1594 context._raise_error(Rounded)
1595 return ans
1596
1597 # Okay, let's round and lose data
1598
1599 this_function = getattr(temp, self._pick_rounding_function[rounding])
1600 #Now we've got the rounding function
1601
1602 if prec != context.prec:
1603 context = context.copy()
1604 context.prec = prec
1605 ans = this_function(prec, expdiff, context)
1606 context._raise_error(Rounded)
1607 context._raise_error(Inexact, 'Changed in rounding')
1608
1609 return ans
1610
1611 _pick_rounding_function = {}
1612
1613 def _round_down(self, prec, expdiff, context):
1614 """Also known as round-towards-0, truncate."""
1615 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1616
1617 def _round_half_up(self, prec, expdiff, context, tmp = None):
1618 """Rounds 5 up (away from 0)"""
1619
1620 if tmp is None:
1621 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
1622 if self._int[prec] >= 5:
1623 tmp = tmp._increment(round=0, context=context)
1624 if len(tmp._int) > prec:
1625 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1626 return tmp
1627
1628 def _round_half_even(self, prec, expdiff, context):
1629 """Round 5 to even, rest to nearest."""
1630
1631 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1632 half = (self._int[prec] == 5)
1633 if half:
1634 for digit in self._int[prec+1:]:
1635 if digit != 0:
1636 half = 0
1637 break
1638 if half:
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001639 if self._int[prec-1] & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001640 return tmp
1641 return self._round_half_up(prec, expdiff, context, tmp)
1642
1643 def _round_half_down(self, prec, expdiff, context):
1644 """Round 5 down"""
1645
1646 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1647 half = (self._int[prec] == 5)
1648 if half:
1649 for digit in self._int[prec+1:]:
1650 if digit != 0:
1651 half = 0
1652 break
1653 if half:
1654 return tmp
1655 return self._round_half_up(prec, expdiff, context, tmp)
1656
1657 def _round_up(self, prec, expdiff, context):
1658 """Rounds away from 0."""
1659 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1660 for digit in self._int[prec:]:
1661 if digit != 0:
1662 tmp = tmp._increment(round=1, context=context)
1663 if len(tmp._int) > prec:
1664 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1665 else:
1666 return tmp
1667 return tmp
1668
1669 def _round_ceiling(self, prec, expdiff, context):
1670 """Rounds up (not away from 0 if negative.)"""
1671 if self._sign:
1672 return self._round_down(prec, expdiff, context)
1673 else:
1674 return self._round_up(prec, expdiff, context)
1675
1676 def _round_floor(self, prec, expdiff, context):
1677 """Rounds down (not towards 0 if negative)"""
1678 if not self._sign:
1679 return self._round_down(prec, expdiff, context)
1680 else:
1681 return self._round_up(prec, expdiff, context)
1682
1683 def __pow__(self, n, modulo = None, context=None):
1684 """Return self ** n (mod modulo)
1685
1686 If modulo is None (default), don't take it mod modulo.
1687 """
1688 if context is None:
1689 context = getcontext()
1690 n = self._convert_other(n)
1691
1692 #Because the spot << doesn't work with really big exponents
1693 if n._isinfinity() or n.adjusted() > 8:
1694 return context._raise_error(InvalidOperation, 'x ** INF')
1695
1696 ans = self._check_nans(n, context)
1697 if ans:
1698 return ans
1699
1700 if not n._isinfinity() and not n._isinteger():
1701 return context._raise_error(InvalidOperation, 'x ** (non-integer)')
1702
1703 if not self and not n:
1704 return context._raise_error(InvalidOperation, '0 ** 0')
1705
1706 if not n:
1707 return Decimal(1)
1708
1709 if self == Decimal(1):
1710 return Decimal(1)
1711
1712 sign = self._sign and not n._iseven()
1713 n = int(n)
1714
1715 if self._isinfinity():
1716 if modulo:
1717 return context._raise_error(InvalidOperation, 'INF % x')
1718 if n > 0:
1719 return Infsign[sign]
1720 return Decimal( (sign, (0,), 0) )
1721
1722 #with ludicrously large exponent, just raise an overflow and return inf.
1723 if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
1724 and self:
1725
1726 tmp = Decimal('inf')
1727 tmp._sign = sign
1728 context._raise_error(Rounded)
1729 context._raise_error(Inexact)
1730 context._raise_error(Overflow, 'Big power', sign)
1731 return tmp
1732
1733 elength = len(str(abs(n)))
1734 firstprec = context.prec
1735
Raymond Hettinger99148e72004-07-14 19:56:56 +00001736 if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001737 return context._raise_error(Overflow, 'Too much precision.', sign)
1738
1739 mul = Decimal(self)
1740 val = Decimal(1)
1741 context = context.copy()
1742 context.prec = firstprec + elength + 1
1743 rounding = context.rounding
1744 if n < 0:
1745 #n is a long now, not Decimal instance
1746 n = -n
1747 mul = Decimal(1).__div__(mul, context=context)
1748
1749 shouldround = context._rounding_decision == ALWAYS_ROUND
1750
1751 spot = 1
1752 while spot <= n:
1753 spot <<= 1
1754
1755 spot >>= 1
1756 #Spot is the highest power of 2 less than n
1757 while spot:
1758 val = val.__mul__(val, context=context)
1759 if val._isinfinity():
1760 val = Infsign[sign]
1761 break
1762 if spot & n:
1763 val = val.__mul__(mul, context=context)
1764 if modulo is not None:
1765 val = val.__mod__(modulo, context=context)
1766 spot >>= 1
1767 context.prec = firstprec
1768
1769 if shouldround:
1770 return val._fix(context=context)
1771 return val
1772
1773 def __rpow__(self, other, context=None):
1774 """Swaps self/other and returns __pow__."""
1775 other = self._convert_other(other)
1776 return other.__pow__(self, context=context)
1777
1778 def normalize(self, context=None):
1779 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
1780 if context is None:
1781 context = getcontext()
1782
1783 ans = self._check_nans(context=context)
1784 if ans:
1785 return ans
1786
1787 dup = self._fix(context=context)
1788 if dup._isinfinity():
1789 return dup
1790
1791 if not dup:
1792 return Decimal( (dup._sign, (0,), 0) )
1793 end = len(dup._int)
1794 exp = dup._exp
1795 while dup._int[end-1] == 0:
1796 exp += 1
1797 end -= 1
1798 return Decimal( (dup._sign, dup._int[:end], exp) )
1799
1800
1801 def quantize(self, exp, rounding = None, context=None, watchexp = 1):
1802 """Quantize self so its exponent is the same as that of exp.
1803
1804 Similar to self._rescale(exp._exp) but with error checking.
1805 """
1806 if context is None:
1807 context = getcontext()
1808
1809 ans = self._check_nans(exp, context)
1810 if ans:
1811 return ans
1812
1813 if exp._isinfinity() or self._isinfinity():
1814 if exp._isinfinity() and self._isinfinity():
1815 return self #if both are inf, it is OK
1816 return context._raise_error(InvalidOperation,
1817 'quantize with one INF')
1818 return self._rescale(exp._exp, rounding, context, watchexp)
1819
1820 def same_quantum(self, other):
1821 """Test whether self and other have the same exponent.
1822
1823 same as self._exp == other._exp, except NaN == sNaN
1824 """
1825 if self._isnan() or other._isnan():
1826 return self._isnan() and other._isnan() and True
1827 if self._isinfinity() or other._isinfinity():
1828 return self._isinfinity() and other._isinfinity() and True
1829 return self._exp == other._exp
1830
1831 def _rescale(self, exp, rounding = None, context=None, watchexp = 1):
1832 """Rescales so that the exponent is exp.
1833
1834 exp = exp to scale to (an integer)
1835 rounding = rounding version
1836 watchexp: if set (default) an error is returned if exp is greater
1837 than Emax or less than Etiny.
1838 """
1839 if context is None:
1840 context = getcontext()
1841
1842 if self._isinfinity():
1843 return context._raise_error(InvalidOperation, 'rescale with an INF')
1844
1845 ans = self._check_nans(context=context)
1846 if ans:
1847 return ans
1848
1849 out = 0
1850
1851 if watchexp and (context.Emax < exp or context.Etiny() > exp):
1852 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1853
1854 if not self:
1855 ans = Decimal(self)
1856 ans._int = (0,)
1857 ans._exp = exp
1858 return ans
1859
1860 diff = self._exp - exp
1861 digits = len(self._int)+diff
1862
1863 if watchexp and digits > context.prec:
1864 return context._raise_error(InvalidOperation, 'Rescale > prec')
1865
1866 tmp = Decimal(self)
1867 tmp._int = (0,)+tmp._int
1868 digits += 1
1869
1870 prevexact = context.flags[Inexact]
1871 if digits < 0:
1872 tmp._exp = -digits + tmp._exp
1873 tmp._int = (0,1)
1874 digits = 1
1875 tmp = tmp._round(digits, rounding, context=context)
1876
1877 if tmp._int[0] == 0 and len(tmp._int) > 1:
1878 tmp._int = tmp._int[1:]
1879 tmp._exp = exp
1880
1881 if tmp and tmp.adjusted() < context.Emin:
1882 context._raise_error(Subnormal)
1883 elif tmp and tmp.adjusted() > context.Emax:
1884 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1885 return tmp
1886
1887 def to_integral(self, rounding = None, context=None):
1888 """Rounds to the nearest integer, without raising inexact, rounded."""
1889 if context is None:
1890 context = getcontext()
1891 ans = self._check_nans(context=context)
1892 if ans:
1893 return ans
1894 if self._exp >= 0:
1895 return self
1896 flags = context._ignore_flags(Rounded, Inexact)
1897 ans = self._rescale(0, rounding, context=context)
1898 context._regard_flags(flags)
1899 return ans
1900
1901 def sqrt(self, context=None):
1902 """Return the square root of self.
1903
1904 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
1905 Should quadratically approach the right answer.
1906 """
1907 if context is None:
1908 context = getcontext()
1909
1910 ans = self._check_nans(context=context)
1911 if ans:
1912 return ans
1913
1914 if not self:
1915 #exponent = self._exp / 2, using round_down.
1916 #if self._exp < 0:
1917 # exp = (self._exp+1) // 2
1918 #else:
1919 exp = (self._exp) // 2
1920 if self._sign == 1:
1921 #sqrt(-0) = -0
1922 return Decimal( (1, (0,), exp))
1923 else:
1924 return Decimal( (0, (0,), exp))
1925
1926 if self._sign == 1:
1927 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
1928
1929 if self._isinfinity():
1930 return Decimal(self)
1931
1932 tmp = Decimal(self)
1933
1934 expadd = tmp._exp / 2
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001935 if tmp._exp & 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001936 tmp._int += (0,)
1937 tmp._exp = 0
1938 else:
1939 tmp._exp = 0
1940
1941 context = context.copy()
1942 flags = context._ignore_all_flags()
1943 firstprec = context.prec
1944 context.prec = 3
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001945 if tmp.adjusted() & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001946 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) )
1947 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
1948 context=context), context=context)
1949 ans._exp -= 1 + tmp.adjusted()/2
1950 else:
1951 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
1952 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
1953 context=context), context=context)
1954 ans._exp -= 1 + tmp.adjusted()/2
1955
1956 #ans is now a linear approximation.
1957
1958 Emax, Emin = context.Emax, context.Emin
Raymond Hettinger99148e72004-07-14 19:56:56 +00001959 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001960
1961 half = Decimal('0.5')
1962
1963 count = 1
1964 maxp = firstprec + 2
1965 rounding = context._set_rounding(ROUND_HALF_EVEN)
1966 while 1:
1967 context.prec = min(2*context.prec - 2, maxp)
1968 ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
1969 context=context), context=context)
1970 if context.prec == maxp:
1971 break
1972
1973 #round to the answer's precision-- the only error can be 1 ulp.
1974 context.prec = firstprec
1975 prevexp = ans.adjusted()
1976 ans = ans._round(context=context)
1977
1978 #Now, check if the other last digits are better.
1979 context.prec = firstprec + 1
1980 # In case we rounded up another digit and we should actually go lower.
1981 if prevexp != ans.adjusted():
1982 ans._int += (0,)
1983 ans._exp -= 1
1984
1985
1986 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
1987 context._set_rounding(ROUND_UP)
1988 if lower.__mul__(lower, context=context) > (tmp):
1989 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
1990
1991 else:
1992 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
1993 context._set_rounding(ROUND_DOWN)
1994 if upper.__mul__(upper, context=context) < tmp:
1995 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
1996
1997 ans._exp += expadd
1998
1999 context.prec = firstprec
2000 context.rounding = rounding
2001 ans = ans._fix(context=context)
2002
2003 rounding = context._set_rounding_decision(NEVER_ROUND)
2004 if not ans.__mul__(ans, context=context) == self:
2005 # Only rounded/inexact if here.
2006 context._regard_flags(flags)
2007 context._raise_error(Rounded)
2008 context._raise_error(Inexact)
2009 else:
2010 #Exact answer, so let's set the exponent right.
2011 #if self._exp < 0:
2012 # exp = (self._exp +1)// 2
2013 #else:
2014 exp = self._exp // 2
2015 context.prec += ans._exp - exp
2016 ans = ans._rescale(exp, context=context)
2017 context.prec = firstprec
2018 context._regard_flags(flags)
2019 context.Emax, context.Emin = Emax, Emin
2020
2021 return ans._fix(context=context)
2022
2023 def max(self, other, context=None):
2024 """Returns the larger value.
2025
2026 like max(self, other) except if one is not a number, returns
2027 NaN (and signals if one is sNaN). Also rounds.
2028 """
2029 if context is None:
2030 context = getcontext()
2031 other = self._convert_other(other)
2032
2033 ans = self._check_nans(other, context)
2034 if ans:
2035 return ans
2036
2037 ans = self
2038 if self < other:
2039 ans = other
2040 shouldround = context._rounding_decision == ALWAYS_ROUND
2041 if shouldround:
2042 ans = ans._fix(context=context)
2043 return ans
2044
2045 def min(self, other, context=None):
2046 """Returns the smaller value.
2047
2048 like min(self, other) except if one is not a number, returns
2049 NaN (and signals if one is sNaN). Also rounds.
2050 """
2051 if context is None:
2052 context = getcontext()
2053 other = self._convert_other(other)
2054
2055 ans = self._check_nans(other, context)
2056 if ans:
2057 return ans
2058
2059 ans = self
2060
2061 if self > other:
2062 ans = other
2063
2064 if context._rounding_decision == ALWAYS_ROUND:
2065 ans = ans._fix(context=context)
2066
2067 return ans
2068
2069 def _isinteger(self):
2070 """Returns whether self is an integer"""
2071 if self._exp >= 0:
2072 return True
2073 rest = self._int[self._exp:]
2074 return rest == (0,)*len(rest)
2075
2076 def _iseven(self):
2077 """Returns 1 if self is even. Assumes self is an integer."""
2078 if self._exp > 0:
2079 return 1
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002080 return self._int[-1+self._exp] & 1 == 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002081
2082 def adjusted(self):
2083 """Return the adjusted exponent of self"""
2084 try:
2085 return self._exp + len(self._int) - 1
2086 #If NaN or Infinity, self._exp is string
2087 except TypeError:
2088 return 0
2089
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002090 # support for pickling, copy, and deepcopy
2091 def __reduce__(self):
2092 return (self.__class__, (str(self),))
2093
2094 def __copy__(self):
2095 if type(self) == Decimal:
2096 return self # I'm immutable; therefore I am my own clone
2097 return self.__class__(str(self))
2098
2099 def __deepcopy__(self, memo):
2100 if type(self) == Decimal:
2101 return self # My components are also immutable
2102 return self.__class__(str(self))
2103
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002104##### Context class ###########################################
2105
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002106
2107# get rounding method function:
2108rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
2109for name in rounding_functions:
2110 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
2111 globalname = name[1:].upper()
2112 val = globals()[globalname]
2113 Decimal._pick_rounding_function[val] = name
2114
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002115del name, val, globalname, rounding_functions
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002116
2117class Context(object):
2118 """Contains the context for a Decimal instance.
2119
2120 Contains:
2121 prec - precision (for use in rounding, division, square roots..)
2122 rounding - rounding type. (how you round)
2123 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
Raymond Hettingerbf440692004-07-10 14:14:37 +00002124 traps - If traps[exception] = 1, then the exception is
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002125 raised when it is caused. Otherwise, a value is
2126 substituted in.
2127 flags - When an exception is caused, flags[exception] is incremented.
2128 (Whether or not the trap_enabler is set)
2129 Should be reset by user of Decimal instance.
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002130 Emin - Minimum exponent
2131 Emax - Maximum exponent
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002132 capitals - If 1, 1*10^1 is printed as 1E+1.
2133 If 0, printed as 1e1
Raymond Hettingere0f15812004-07-05 05:36:39 +00002134 _clamp - If 1, change exponents if too high (Default 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002135 """
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002136
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002137 def __init__(self, prec=None, rounding=None,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002138 traps=None, flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002139 _rounding_decision=None,
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002140 Emin=None, Emax=None,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002141 capitals=None, _clamp=0,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002142 _ignored_flags=[]):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002143 if not isinstance(flags, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002144 flags = dict([(s,s in flags) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002145 del s
Raymond Hettingerbf440692004-07-10 14:14:37 +00002146 if traps is not None and not isinstance(traps, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002147 traps = dict([(s,s in traps) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002148 del s
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002149 for name, val in locals().items():
2150 if val is None:
2151 setattr(self, name, copy.copy(getattr(DefaultContext, name)))
2152 else:
2153 setattr(self, name, val)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002154 del self.self
2155
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002156 def __repr__(self):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002157 """Show the current context."""
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002158 s = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002159 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
2160 s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
2161 s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002162 return ', '.join(s) + ')'
2163
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002164 def clear_flags(self):
2165 """Reset all flags to zero"""
2166 for flag in self.flags:
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002167 self.flags[flag] = 0
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002168
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002169 def copy(self):
2170 """Returns a copy from self."""
Raymond Hettingerbf440692004-07-10 14:14:37 +00002171 nc = Context(self.prec, self.rounding, self.traps, self.flags,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002172 self._rounding_decision, self.Emin, self.Emax,
2173 self.capitals, self._clamp, self._ignored_flags)
2174 return nc
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002175 __copy__ = copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002176
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002177 def _raise_error(self, condition, explanation = None, *args):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002178 """Handles an error
2179
2180 If the flag is in _ignored_flags, returns the default response.
2181 Otherwise, it increments the flag, then, if the corresponding
2182 trap_enabler is set, it reaises the exception. Otherwise, it returns
2183 the default value after incrementing the flag.
2184 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002185 error = _condition_map.get(condition, condition)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002186 if error in self._ignored_flags:
2187 #Don't touch the flag
2188 return error().handle(self, *args)
2189
2190 self.flags[error] += 1
Raymond Hettingerbf440692004-07-10 14:14:37 +00002191 if not self.traps[error]:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002192 #The errors define how to handle themselves.
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002193 return condition().handle(self, *args)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002194
2195 # Errors should only be risked on copies of the context
2196 #self._ignored_flags = []
2197 raise error, explanation
2198
2199 def _ignore_all_flags(self):
2200 """Ignore all flags, if they are raised"""
Raymond Hettingerfed52962004-07-14 15:41:57 +00002201 return self._ignore_flags(*_signals)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002202
2203 def _ignore_flags(self, *flags):
2204 """Ignore the flags, if they are raised"""
2205 # Do not mutate-- This way, copies of a context leave the original
2206 # alone.
2207 self._ignored_flags = (self._ignored_flags + list(flags))
2208 return list(flags)
2209
2210 def _regard_flags(self, *flags):
2211 """Stop ignoring the flags, if they are raised"""
2212 if flags and isinstance(flags[0], (tuple,list)):
2213 flags = flags[0]
2214 for flag in flags:
2215 self._ignored_flags.remove(flag)
2216
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002217 def __hash__(self):
2218 """A Context cannot be hashed."""
2219 # We inherit object.__hash__, so we must deny this explicitly
2220 raise TypeError, "Cannot hash a Context."
2221
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002222 def Etiny(self):
2223 """Returns Etiny (= Emin - prec + 1)"""
2224 return int(self.Emin - self.prec + 1)
2225
2226 def Etop(self):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002227 """Returns maximum exponent (= Emax - prec + 1)"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002228 return int(self.Emax - self.prec + 1)
2229
2230 def _set_rounding_decision(self, type):
2231 """Sets the rounding decision.
2232
2233 Sets the rounding decision, and returns the current (previous)
2234 rounding decision. Often used like:
2235
2236 context = context.copy()
2237 # That so you don't change the calling context
2238 # if an error occurs in the middle (say DivisionImpossible is raised).
2239
2240 rounding = context._set_rounding_decision(NEVER_ROUND)
2241 instance = instance / Decimal(2)
2242 context._set_rounding_decision(rounding)
2243
2244 This will make it not round for that operation.
2245 """
2246
2247 rounding = self._rounding_decision
2248 self._rounding_decision = type
2249 return rounding
2250
2251 def _set_rounding(self, type):
2252 """Sets the rounding type.
2253
2254 Sets the rounding type, and returns the current (previous)
2255 rounding type. Often used like:
2256
2257 context = context.copy()
2258 # so you don't change the calling context
2259 # if an error occurs in the middle.
2260 rounding = context._set_rounding(ROUND_UP)
2261 val = self.__sub__(other, context=context)
2262 context._set_rounding(rounding)
2263
2264 This will make it round up for that operation.
2265 """
2266 rounding = self.rounding
2267 self.rounding= type
2268 return rounding
2269
Raymond Hettingerfed52962004-07-14 15:41:57 +00002270 def create_decimal(self, num='0'):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002271 """Creates a new Decimal instance but using self as context."""
2272 d = Decimal(num, context=self)
2273 return d._fix(context=self)
2274
2275 #Methods
2276 def abs(self, a):
2277 """Returns the absolute value of the operand.
2278
2279 If the operand is negative, the result is the same as using the minus
2280 operation on the operand. Otherwise, the result is the same as using
2281 the plus operation on the operand.
2282
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002283 >>> ExtendedContext.abs(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002284 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002285 >>> ExtendedContext.abs(Decimal('-100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002286 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002287 >>> ExtendedContext.abs(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002288 Decimal("101.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002289 >>> ExtendedContext.abs(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002290 Decimal("101.5")
2291 """
2292 return a.__abs__(context=self)
2293
2294 def add(self, a, b):
2295 """Return the sum of the two operands.
2296
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002297 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002298 Decimal("19.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002299 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002300 Decimal("1.02E+4")
2301 """
2302 return a.__add__(b, context=self)
2303
2304 def _apply(self, a):
2305 return str(a._fix(context=self))
2306
2307 def compare(self, a, b):
2308 """Compares values numerically.
2309
2310 If the signs of the operands differ, a value representing each operand
2311 ('-1' if the operand is less than zero, '0' if the operand is zero or
2312 negative zero, or '1' if the operand is greater than zero) is used in
2313 place of that operand for the comparison instead of the actual
2314 operand.
2315
2316 The comparison is then effected by subtracting the second operand from
2317 the first and then returning a value according to the result of the
2318 subtraction: '-1' if the result is less than zero, '0' if the result is
2319 zero or negative zero, or '1' if the result is greater than zero.
2320
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002321 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002322 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002323 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002324 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002325 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002326 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002327 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002328 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002329 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002330 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002331 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002332 Decimal("-1")
2333 """
2334 return a.compare(b, context=self)
2335
2336 def divide(self, a, b):
2337 """Decimal division in a specified context.
2338
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002339 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002340 Decimal("0.333333333")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002341 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002342 Decimal("0.666666667")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002343 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002344 Decimal("2.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002345 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002346 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002347 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002348 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002349 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002350 Decimal("4.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002351 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002352 Decimal("1.20")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002353 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002354 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002355 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002356 Decimal("1000")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002357 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002358 Decimal("1.20E+6")
2359 """
2360 return a.__div__(b, context=self)
2361
2362 def divide_int(self, a, b):
2363 """Divides two numbers and returns the integer part of the result.
2364
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002365 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002366 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002367 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002368 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002369 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002370 Decimal("3")
2371 """
2372 return a.__floordiv__(b, context=self)
2373
2374 def divmod(self, a, b):
2375 return a.__divmod__(b, context=self)
2376
2377 def max(self, a,b):
2378 """max compares two values numerically and returns the maximum.
2379
2380 If either operand is a NaN then the general rules apply.
2381 Otherwise, the operands are compared as as though by the compare
2382 operation. If they are numerically equal then the left-hand operand
2383 is chosen as the result. Otherwise the maximum (closer to positive
2384 infinity) of the two operands is chosen as the result.
2385
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002386 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002387 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002388 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002389 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002390 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002391 Decimal("1.0")
2392 """
2393 return a.max(b, context=self)
2394
2395 def min(self, a,b):
2396 """min compares two values numerically and returns the minimum.
2397
2398 If either operand is a NaN then the general rules apply.
2399 Otherwise, the operands are compared as as though by the compare
2400 operation. If they are numerically equal then the left-hand operand
2401 is chosen as the result. Otherwise the minimum (closer to negative
2402 infinity) of the two operands is chosen as the result.
2403
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002404 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002405 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002406 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002407 Decimal("-10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002408 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002409 Decimal("1.0")
2410 """
2411 return a.min(b, context=self)
2412
2413 def minus(self, a):
2414 """Minus corresponds to unary prefix minus in Python.
2415
2416 The operation is evaluated using the same rules as subtract; the
2417 operation minus(a) is calculated as subtract('0', a) where the '0'
2418 has the same exponent as the operand.
2419
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002420 >>> ExtendedContext.minus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002421 Decimal("-1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002422 >>> ExtendedContext.minus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002423 Decimal("1.3")
2424 """
2425 return a.__neg__(context=self)
2426
2427 def multiply(self, a, b):
2428 """multiply multiplies two operands.
2429
2430 If either operand is a special value then the general rules apply.
2431 Otherwise, the operands are multiplied together ('long multiplication'),
2432 resulting in a number which may be as long as the sum of the lengths
2433 of the two operands.
2434
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002435 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002436 Decimal("3.60")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002437 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002438 Decimal("21")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002439 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002440 Decimal("0.72")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002441 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002442 Decimal("-0.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002443 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002444 Decimal("4.28135971E+11")
2445 """
2446 return a.__mul__(b, context=self)
2447
2448 def normalize(self, a):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002449 """normalize reduces an operand to its simplest form.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002450
2451 Essentially a plus operation with all trailing zeros removed from the
2452 result.
2453
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002454 >>> ExtendedContext.normalize(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002455 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002456 >>> ExtendedContext.normalize(Decimal('-2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002457 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002458 >>> ExtendedContext.normalize(Decimal('1.200'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002459 Decimal("1.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002460 >>> ExtendedContext.normalize(Decimal('-120'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002461 Decimal("-1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002462 >>> ExtendedContext.normalize(Decimal('120.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002463 Decimal("1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002464 >>> ExtendedContext.normalize(Decimal('0.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002465 Decimal("0")
2466 """
2467 return a.normalize(context=self)
2468
2469 def plus(self, a):
2470 """Plus corresponds to unary prefix plus in Python.
2471
2472 The operation is evaluated using the same rules as add; the
2473 operation plus(a) is calculated as add('0', a) where the '0'
2474 has the same exponent as the operand.
2475
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002476 >>> ExtendedContext.plus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002477 Decimal("1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002478 >>> ExtendedContext.plus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002479 Decimal("-1.3")
2480 """
2481 return a.__pos__(context=self)
2482
2483 def power(self, a, b, modulo=None):
2484 """Raises a to the power of b, to modulo if given.
2485
2486 The right-hand operand must be a whole number whose integer part (after
2487 any exponent has been applied) has no more than 9 digits and whose
2488 fractional part (if any) is all zeros before any rounding. The operand
2489 may be positive, negative, or zero; if negative, the absolute value of
2490 the power is used, and the left-hand operand is inverted (divided into
2491 1) before use.
2492
2493 If the increased precision needed for the intermediate calculations
2494 exceeds the capabilities of the implementation then an Invalid operation
2495 condition is raised.
2496
2497 If, when raising to a negative power, an underflow occurs during the
2498 division into 1, the operation is not halted at that point but
2499 continues.
2500
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002501 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002502 Decimal("8")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002503 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002504 Decimal("0.125")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002505 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002506 Decimal("69.7575744")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002507 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002508 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002509 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002510 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002511 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002512 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002513 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002514 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002515 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002516 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002517 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002518 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002519 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002520 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002521 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002522 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002523 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002524 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002525 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002526 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002527 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002528 Decimal("NaN")
2529 """
2530 return a.__pow__(b, modulo, context=self)
2531
2532 def quantize(self, a, b):
2533 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
2534
2535 The coefficient of the result is derived from that of the left-hand
2536 operand. It may be rounded using the current rounding setting (if the
2537 exponent is being increased), multiplied by a positive power of ten (if
2538 the exponent is being decreased), or is unchanged (if the exponent is
2539 already equal to that of the right-hand operand).
2540
2541 Unlike other operations, if the length of the coefficient after the
2542 quantize operation would be greater than precision then an Invalid
2543 operation condition is raised. This guarantees that, unless there is an
2544 error condition, the exponent of the result of a quantize is always
2545 equal to that of the right-hand operand.
2546
2547 Also unlike other operations, quantize will never raise Underflow, even
2548 if the result is subnormal and inexact.
2549
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002550 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002551 Decimal("2.170")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002552 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002553 Decimal("2.17")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002554 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002555 Decimal("2.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002556 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002557 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002558 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002559 Decimal("0E+1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002560 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002561 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002562 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002563 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002564 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002565 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002566 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002567 Decimal("-0E+5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002568 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002569 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002570 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002571 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002572 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002573 Decimal("217.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002574 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002575 Decimal("217")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002576 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002577 Decimal("2.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002578 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002579 Decimal("2E+2")
2580 """
2581 return a.quantize(b, context=self)
2582
2583 def remainder(self, a, b):
2584 """Returns the remainder from integer division.
2585
2586 The result is the residue of the dividend after the operation of
2587 calculating integer division as described for divide-integer, rounded to
2588 precision digits if necessary. The sign of the result, if non-zero, is
2589 the same as that of the original dividend.
2590
2591 This operation will fail under the same conditions as integer division
2592 (that is, if integer division on the same two operands would fail, the
2593 remainder cannot be calculated).
2594
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002595 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002596 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002597 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002598 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002599 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002600 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002601 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002602 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002603 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002604 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002605 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002606 Decimal("1.0")
2607 """
2608 return a.__mod__(b, context=self)
2609
2610 def remainder_near(self, a, b):
2611 """Returns to be "a - b * n", where n is the integer nearest the exact
2612 value of "x / b" (if two integers are equally near then the even one
2613 is chosen). If the result is equal to 0 then its sign will be the
2614 sign of a.
2615
2616 This operation will fail under the same conditions as integer division
2617 (that is, if integer division on the same two operands would fail, the
2618 remainder cannot be calculated).
2619
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002620 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002621 Decimal("-0.9")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002622 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002623 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002624 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002625 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002626 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002627 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002628 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002629 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002630 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002631 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002632 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002633 Decimal("-0.3")
2634 """
2635 return a.remainder_near(b, context=self)
2636
2637 def same_quantum(self, a, b):
2638 """Returns True if the two operands have the same exponent.
2639
2640 The result is never affected by either the sign or the coefficient of
2641 either operand.
2642
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002643 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002644 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002645 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002646 True
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002647 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002648 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002649 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002650 True
2651 """
2652 return a.same_quantum(b)
2653
2654 def sqrt(self, a):
2655 """Returns the square root of a non-negative number to context precision.
2656
2657 If the result must be inexact, it is rounded using the round-half-even
2658 algorithm.
2659
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002660 >>> ExtendedContext.sqrt(Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002661 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002662 >>> ExtendedContext.sqrt(Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002663 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002664 >>> ExtendedContext.sqrt(Decimal('0.39'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002665 Decimal("0.624499800")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002666 >>> ExtendedContext.sqrt(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002667 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002668 >>> ExtendedContext.sqrt(Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002669 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002670 >>> ExtendedContext.sqrt(Decimal('1.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002671 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002672 >>> ExtendedContext.sqrt(Decimal('1.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002673 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002674 >>> ExtendedContext.sqrt(Decimal('7'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002675 Decimal("2.64575131")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002676 >>> ExtendedContext.sqrt(Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002677 Decimal("3.16227766")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002678 >>> ExtendedContext.prec
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002679 9
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002680 """
2681 return a.sqrt(context=self)
2682
2683 def subtract(self, a, b):
2684 """Return the sum of the two operands.
2685
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002686 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002687 Decimal("0.23")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002688 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002689 Decimal("0.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002690 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002691 Decimal("-0.77")
2692 """
2693 return a.__sub__(b, context=self)
2694
2695 def to_eng_string(self, a):
2696 """Converts a number to a string, using scientific notation.
2697
2698 The operation is not affected by the context.
2699 """
2700 return a.to_eng_string(context=self)
2701
2702 def to_sci_string(self, a):
2703 """Converts a number to a string, using scientific notation.
2704
2705 The operation is not affected by the context.
2706 """
2707 return a.__str__(context=self)
2708
2709 def to_integral(self, a):
2710 """Rounds to an integer.
2711
2712 When the operand has a negative exponent, the result is the same
2713 as using the quantize() operation using the given operand as the
2714 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2715 of the operand as the precision setting, except that no flags will
2716 be set. The rounding mode is taken from the context.
2717
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002718 >>> ExtendedContext.to_integral(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002719 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002720 >>> ExtendedContext.to_integral(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002721 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002722 >>> ExtendedContext.to_integral(Decimal('100.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002723 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002724 >>> ExtendedContext.to_integral(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002725 Decimal("102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002726 >>> ExtendedContext.to_integral(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002727 Decimal("-102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002728 >>> ExtendedContext.to_integral(Decimal('10E+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002729 Decimal("1.0E+6")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002730 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002731 Decimal("7.89E+77")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002732 >>> ExtendedContext.to_integral(Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002733 Decimal("-Infinity")
2734 """
2735 return a.to_integral(context=self)
2736
2737class _WorkRep(object):
2738 __slots__ = ('sign','int','exp')
2739 # sign: -1 None 1
2740 # int: list
2741 # exp: None, int, or string
2742
2743 def __init__(self, value=None):
2744 if value is None:
2745 self.sign = None
2746 self.int = []
2747 self.exp = None
2748 if isinstance(value, Decimal):
2749 if value._sign:
2750 self.sign = -1
2751 else:
2752 self.sign = 1
2753 self.int = list(value._int)
2754 self.exp = value._exp
2755 if isinstance(value, tuple):
2756 self.sign = value[0]
2757 self.int = value[1]
2758 self.exp = value[2]
2759
2760 def __repr__(self):
2761 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2762
2763 __str__ = __repr__
2764
2765 def __neg__(self):
2766 if self.sign == 1:
2767 return _WorkRep( (-1, self.int, self.exp) )
2768 else:
2769 return _WorkRep( (1, self.int, self.exp) )
2770
2771 def __abs__(self):
2772 if self.sign == -1:
2773 return -self
2774 else:
2775 return self
2776
2777 def __cmp__(self, other):
2778 if self.exp != other.exp:
2779 raise ValueError("Operands not normalized: %r, %r" % (self, other))
2780 if self.sign != other.sign:
2781 if self.sign == -1:
2782 return -1
2783 else:
2784 return 1
2785 if self.sign == -1:
2786 direction = -1
2787 else:
2788 direction = 1
2789 int1 = self.int
2790 int2 = other.int
2791 if len(int1) > len(int2):
2792 return direction * 1
2793 if len(int1) < len(int2):
2794 return direction * -1
2795 for i in xrange(len(int1)):
2796 if int1[i] > int2[i]:
2797 return direction * 1
2798 if int1[i] < int2[i]:
2799 return direction * -1
2800 return 0
2801
2802 def _increment(self):
2803 curspot = len(self.int) - 1
2804 self.int[curspot]+= 1
2805 while (self.int[curspot] >= 10):
2806 self.int[curspot] -= 10
2807 if curspot == 0:
2808 self.int[0:0] = [1]
2809 break
2810 self.int[curspot-1] += 1
2811 curspot -= 1
2812
2813 def subtract(self, alist):
2814 """Subtract a list from the current int (in place).
2815
2816 It is assured that (len(list) = len(self.int) and list < self.int) or
2817 len(list) = len(self.int)-1
2818 (i.e. that int(join(list)) < int(join(self.int)))
2819 """
2820
2821 selfint = self.int
2822 selfint.reverse()
2823 alist.reverse()
2824
2825 carry = 0
2826 for x in xrange(len(alist)):
2827 selfint[x] -= alist[x] + carry
2828 if selfint[x] < 0:
2829 carry = 1
2830 selfint[x] += 10
2831 else:
Tim Peters4e0e1b62004-07-07 20:54:48 +00002832 carry = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002833 if carry:
2834 selfint[x+1] -= 1
2835 last = len(selfint)-1
2836 while len(selfint) > 1 and selfint[last] == 0:
2837 last -= 1
2838 if last == 0:
2839 break
2840 selfint[last+1:]=[]
2841 selfint.reverse()
2842 alist.reverse()
2843 return
2844
2845
2846def _normalize(op1, op2, shouldround = 0, prec = 0):
2847 """Normalizes op1, op2 to have the same exp and length of coefficient.
2848
2849 Done during addition.
2850 """
2851 # Yes, the exponent is a long, but the difference between exponents
2852 # must be an int-- otherwise you'd get a big memory problem.
2853 numdigits = int(op1.exp - op2.exp)
2854 if numdigits < 0:
2855 numdigits = -numdigits
2856 tmp = op2
2857 other = op1
2858 else:
2859 tmp = op1
2860 other = op2
2861
2862 if shouldround and numdigits > len(other.int) + prec + 1 -len(tmp.int):
2863 # If the difference in adjusted exps is > prec+1, we know
2864 # other is insignificant, so might as well put a 1 after the precision.
2865 # (since this is only for addition.) Also stops MemoryErrors.
2866
2867 extend = prec + 2 -len(tmp.int)
2868 if extend <= 0:
2869 extend = 1
2870 tmp.int.extend([0]*extend)
2871 tmp.exp -= extend
2872 other.int[:] = [0]*(len(tmp.int)-1)+[1]
2873 other.exp = tmp.exp
2874 return op1, op2
2875
2876 tmp.int.extend([0] * numdigits)
2877 tmp.exp = tmp.exp - numdigits
2878 numdigits = len(op1.int) - len(op2.int)
2879 # numdigits != 0 => They have the same exponent, but not the same length
2880 # of the coefficient.
2881 if numdigits < 0:
2882 numdigits = -numdigits
2883 tmp = op1
2884 else:
2885 tmp = op2
2886 tmp.int[0:0] = [0] * numdigits
2887 return op1, op2
2888
2889def _adjust_coefficients(op1, op2):
2890 """Adjust op1, op2 so that op2.int+[0] > op1.int >= op2.int.
2891
2892 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2893
2894 Used on _WorkRep instances during division.
2895 """
2896 adjust = 0
2897 #If op1 is smaller, get it to same size
2898 if len(op2.int) > len(op1.int):
2899 diff = len(op2.int) - len(op1.int)
2900 op1.int.extend([0]*diff)
2901 op1.exp -= diff
2902 adjust = diff
2903
2904 #Same length, wrong order
2905 if len(op1.int) == len(op2.int) and op1.int < op2.int:
2906 op1.int.append(0)
2907 op1.exp -= 1
2908 adjust+= 1
2909 return op1, op2, adjust
2910
2911 if len(op1.int) > len(op2.int) + 1:
2912 diff = len(op1.int) - len(op2.int) - 1
2913 op2.int.extend([0]*diff)
2914 op2.exp -= diff
2915 adjust -= diff
2916
2917 if len(op1.int) == len(op2.int)+1 and op1.int > op2.int:
2918
2919 op2.int.append(0)
2920 op2.exp -= 1
2921 adjust -= 1
2922 return op1, op2, adjust
2923
2924##### Helper Functions ########################################
2925
2926_infinity_map = {
2927 'inf' : 1,
2928 'infinity' : 1,
2929 '+inf' : 1,
2930 '+infinity' : 1,
2931 '-inf' : -1,
2932 '-infinity' : -1
2933}
2934
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002935def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002936 """Determines whether a string or float is infinity.
2937
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002938 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002939 """
2940 num = str(num).lower()
2941 return _infinity_map.get(num, 0)
2942
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002943def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002944 """Determines whether a string or float is NaN
2945
2946 (1, sign, diagnostic info as string) => NaN
2947 (2, sign, diagnostic info as string) => sNaN
2948 0 => not a NaN
2949 """
2950 num = str(num).lower()
2951 if not num:
2952 return 0
2953
2954 #get the sign, get rid of trailing [+-]
2955 sign = 0
2956 if num[0] == '+':
2957 num = num[1:]
2958 elif num[0] == '-': #elif avoids '+-nan'
2959 num = num[1:]
2960 sign = 1
2961
2962 if num.startswith('nan'):
2963 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
2964 return 0
2965 return (1, sign, num[3:].lstrip('0'))
2966 if num.startswith('snan'):
2967 if len(num) > 4 and not num[4:].isdigit():
2968 return 0
2969 return (2, sign, num[4:].lstrip('0'))
2970 return 0
2971
2972
2973##### Setup Specific Contexts ################################
2974
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002975# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00002976# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002977
2978DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002979 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002980 traps=[DivisionByZero, Overflow, InvalidOperation],
2981 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002982 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00002983 Emax=999999999,
2984 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002985 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002986)
2987
2988# Pre-made alternate contexts offered by the specification
2989# Don't change these; the user should be able to select these
2990# contexts and be able to reproduce results from other implementations
2991# of the spec.
2992
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002993BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002994 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00002995 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
2996 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002997)
2998
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002999ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003000 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003001 traps=[],
3002 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003003)
3004
3005
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00003006##### Useful Constants (internal use only) ####################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003007
3008#Reusable defaults
3009Inf = Decimal('Inf')
3010negInf = Decimal('-Inf')
3011
3012#Infsign[sign] is infinity w/ that sign
3013Infsign = (Inf, negInf)
3014
3015NaN = Decimal('NaN')
3016
3017
3018##### crud for parsing strings #################################
3019import re
3020
3021# There's an optional sign at the start, and an optional exponent
3022# at the end. The exponent has an optional sign and at least one
3023# digit. In between, must have either at least one digit followed
3024# by an optional fraction, or a decimal point followed by at least
3025# one digit. Yuck.
3026
3027_parser = re.compile(r"""
3028# \s*
3029 (?P<sign>[-+])?
3030 (
3031 (?P<int>\d+) (\. (?P<frac>\d*))?
3032 |
3033 \. (?P<onlyfrac>\d+)
3034 )
3035 ([eE](?P<exp>[-+]? \d+))?
3036# \s*
3037 $
3038""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
3039
3040del re
3041
3042# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
3043
3044def _string2exact(s):
3045 m = _parser(s)
3046 if m is None:
3047 raise ValueError("invalid literal for Decimal: %r" % s)
3048
3049 if m.group('sign') == "-":
3050 sign = 1
3051 else:
3052 sign = 0
3053
3054 exp = m.group('exp')
3055 if exp is None:
3056 exp = 0
3057 else:
3058 exp = int(exp)
3059
3060 intpart = m.group('int')
3061 if intpart is None:
3062 intpart = ""
3063 fracpart = m.group('onlyfrac')
3064 else:
3065 fracpart = m.group('frac')
3066 if fracpart is None:
3067 fracpart = ""
3068
3069 exp -= len(fracpart)
3070
3071 mantissa = intpart + fracpart
3072 tmp = map(int, mantissa)
3073 backup = tmp
3074 while tmp and tmp[0] == 0:
3075 del tmp[0]
3076
3077 # It's a zero
3078 if not tmp:
3079 if backup:
3080 return (sign, tuple(backup), exp)
3081 return (sign, (0,), exp)
3082 mantissa = tuple(tmp)
3083
3084 return (sign, mantissa, exp)
3085
3086
3087if __name__ == '__main__':
3088 import doctest, sys
3089 doctest.testmod(sys.modules[__name__])