blob: 6dc7398d609c39f273de7557bfaf166336ceb273 [file] [log] [blame]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001# Copyright (c) 2004 Python Software Foundation.
2# All rights reserved.
3
4# Written by Eric Price <eprice at tjhsst.edu>
5# and Facundo Batista <facundo at taniquetil.com.ar>
6# and Raymond Hettinger <python at rcn.com>
Fred Drake1f34eb12004-07-01 14:28:36 +00007# and Aahz <aahz at pobox.com>
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00008# and Tim Peters
9
Raymond Hettinger27dbcf22004-08-19 22:39:55 +000010# This module is currently Py2.3 compatible and should be kept that way
11# unless a major compelling advantage arises. IOW, 2.3 compatibility is
12# strongly preferred, but not guaranteed.
13
14# Also, this module should be kept in sync with the latest updates of
15# the IBM specification as it evolves. Those updates will be treated
16# as bug fixes (deviation from the spec is a compatibility, usability
17# bug) and will be backported. At this point the spec is stabilizing
18# and the updates are becoming fewer, smaller, and less significant.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000019
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000020"""
21This is a Py2.3 implementation of decimal floating point arithmetic based on
22the General Decimal Arithmetic Specification:
23
24 www2.hursley.ibm.com/decimal/decarith.html
25
Raymond Hettinger0ea241e2004-07-04 13:53:24 +000026and IEEE standard 854-1987:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000027
28 www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html
29
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000030Decimal floating point has finite precision with arbitrarily large bounds.
31
Martin v. Löwiscfe31282006-07-19 17:18:32 +000032The purpose of the module is to support arithmetic using familiar
33"schoolhouse" rules and to avoid the some of tricky representation
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000034issues associated with binary floating point. The package is especially
35useful for financial applications or for contexts where users have
36expectations that are at odds with binary floating point (for instance,
37in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead
38of the expected Decimal("0.00") returned by decimal floating point).
39
40Here are some examples of using the decimal module:
41
42>>> from decimal import *
Raymond Hettingerbd7f76d2004-07-08 00:49:18 +000043>>> setcontext(ExtendedContext)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000044>>> Decimal(0)
45Decimal("0")
46>>> Decimal("1")
47Decimal("1")
48>>> Decimal("-.0123")
49Decimal("-0.0123")
50>>> Decimal(123456)
51Decimal("123456")
52>>> Decimal("123.45e12345678901234567890")
53Decimal("1.2345E+12345678901234567892")
54>>> Decimal("1.33") + Decimal("1.27")
55Decimal("2.60")
56>>> Decimal("12.34") + Decimal("3.87") - Decimal("18.41")
57Decimal("-2.20")
58>>> dig = Decimal(1)
59>>> print dig / Decimal(3)
600.333333333
61>>> getcontext().prec = 18
62>>> print dig / Decimal(3)
630.333333333333333333
64>>> print dig.sqrt()
651
66>>> print Decimal(3).sqrt()
671.73205080756887729
68>>> print Decimal(3) ** 123
694.85192780976896427E+58
70>>> inf = Decimal(1) / Decimal(0)
71>>> print inf
72Infinity
73>>> neginf = Decimal(-1) / Decimal(0)
74>>> print neginf
75-Infinity
76>>> print neginf + inf
77NaN
78>>> print neginf * inf
79-Infinity
80>>> print dig / 0
81Infinity
Raymond Hettingerbf440692004-07-10 14:14:37 +000082>>> getcontext().traps[DivisionByZero] = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000083>>> print dig / 0
84Traceback (most recent call last):
85 ...
86 ...
87 ...
88DivisionByZero: x / 0
89>>> c = Context()
Raymond Hettingerbf440692004-07-10 14:14:37 +000090>>> c.traps[InvalidOperation] = 0
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000091>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000920
93>>> c.divide(Decimal(0), Decimal(0))
94Decimal("NaN")
Raymond Hettingerbf440692004-07-10 14:14:37 +000095>>> c.traps[InvalidOperation] = 1
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000096>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000971
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000098>>> c.flags[InvalidOperation] = 0
99>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001000
101>>> print c.divide(Decimal(0), Decimal(0))
102Traceback (most recent call last):
103 ...
104 ...
105 ...
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000106InvalidOperation: 0 / 0
107>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001081
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000109>>> c.flags[InvalidOperation] = 0
Raymond Hettingerbf440692004-07-10 14:14:37 +0000110>>> c.traps[InvalidOperation] = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000111>>> print c.divide(Decimal(0), Decimal(0))
112NaN
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000113>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001141
115>>>
116"""
117
118__all__ = [
119 # Two major classes
120 'Decimal', 'Context',
121
122 # Contexts
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +0000123 'DefaultContext', 'BasicContext', 'ExtendedContext',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000124
125 # Exceptions
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +0000126 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
127 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000128
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000129 # Constants for use in setting up contexts
130 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING',
131 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000132
133 # Functions for manipulating contexts
Nick Coghlan8b6999b2006-08-31 12:00:43 +0000134 'setcontext', 'getcontext', 'localcontext'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000135]
136
Raymond Hettingereb260842005-06-07 18:52:34 +0000137import copy as _copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000138
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000139#Rounding
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000140ROUND_DOWN = 'ROUND_DOWN'
141ROUND_HALF_UP = 'ROUND_HALF_UP'
142ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
143ROUND_CEILING = 'ROUND_CEILING'
144ROUND_FLOOR = 'ROUND_FLOOR'
145ROUND_UP = 'ROUND_UP'
146ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000147
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000148#Rounding decision (not part of the public API)
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000149NEVER_ROUND = 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY
150ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000151
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000152#Errors
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000153
154class DecimalException(ArithmeticError):
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000155 """Base exception class.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000156
157 Used exceptions derive from this.
158 If an exception derives from another exception besides this (such as
159 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
160 called if the others are present. This isn't actually used for
161 anything, though.
162
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000163 handle -- Called when context._raise_error is called and the
164 trap_enabler is set. First argument is self, second is the
165 context. More arguments can be given, those being after
166 the explanation in _raise_error (For example,
167 context._raise_error(NewError, '(-x)!', self._sign) would
168 call NewError().handle(context, self._sign).)
169
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000170 To define a new exception, it should be sufficient to have it derive
171 from DecimalException.
172 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000173 def handle(self, context, *args):
174 pass
175
176
177class Clamped(DecimalException):
178 """Exponent of a 0 changed to fit bounds.
179
180 This occurs and signals clamped if the exponent of a result has been
181 altered in order to fit the constraints of a specific concrete
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000182 representation. This may occur when the exponent of a zero result would
183 be outside the bounds of a representation, or when a large normal
184 number would have an encoded exponent that cannot be represented. In
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000185 this latter case, the exponent is reduced to fit and the corresponding
186 number of zero digits are appended to the coefficient ("fold-down").
187 """
188
189
190class InvalidOperation(DecimalException):
191 """An invalid operation was performed.
192
193 Various bad things cause this:
194
195 Something creates a signaling NaN
196 -INF + INF
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000197 0 * (+-)INF
198 (+-)INF / (+-)INF
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000199 x % 0
200 (+-)INF % x
201 x._rescale( non-integer )
202 sqrt(-x) , x > 0
203 0 ** 0
204 x ** (non-integer)
205 x ** (+-)INF
206 An operand is invalid
207 """
208 def handle(self, context, *args):
209 if args:
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000210 if args[0] == 1: #sNaN, must drop 's' but keep diagnostics
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000211 return Decimal( (args[1]._sign, args[1]._int, 'n') )
212 return NaN
213
214class ConversionSyntax(InvalidOperation):
215 """Trying to convert badly formed string.
216
217 This occurs and signals invalid-operation if an string is being
218 converted to a number and it does not conform to the numeric string
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000219 syntax. The result is [0,qNaN].
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000220 """
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000221
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000222 def handle(self, context, *args):
223 return (0, (0,), 'n') #Passed to something which uses a tuple.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000224
225class DivisionByZero(DecimalException, ZeroDivisionError):
226 """Division by 0.
227
228 This occurs and signals division-by-zero if division of a finite number
229 by zero was attempted (during a divide-integer or divide operation, or a
230 power operation with negative right-hand operand), and the dividend was
231 not zero.
232
233 The result of the operation is [sign,inf], where sign is the exclusive
234 or of the signs of the operands for divide, or is 1 for an odd power of
235 -0, for power.
236 """
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000237
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000238 def handle(self, context, sign, double = None, *args):
239 if double is not None:
240 return (Infsign[sign],)*2
241 return Infsign[sign]
242
243class DivisionImpossible(InvalidOperation):
244 """Cannot perform the division adequately.
245
246 This occurs and signals invalid-operation if the integer result of a
247 divide-integer or remainder operation had too many digits (would be
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000248 longer than precision). The result is [0,qNaN].
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000249 """
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000250
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000251 def handle(self, context, *args):
252 return (NaN, NaN)
253
254class DivisionUndefined(InvalidOperation, ZeroDivisionError):
255 """Undefined result of division.
256
257 This occurs and signals invalid-operation if division by zero was
258 attempted (during a divide-integer, divide, or remainder operation), and
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000259 the dividend is also zero. The result is [0,qNaN].
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000260 """
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000261
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000262 def handle(self, context, tup=None, *args):
263 if tup is not None:
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000264 return (NaN, NaN) #for 0 %0, 0 // 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000265 return NaN
266
267class Inexact(DecimalException):
268 """Had to round, losing information.
269
270 This occurs and signals inexact whenever the result of an operation is
271 not exact (that is, it needed to be rounded and any discarded digits
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000272 were non-zero), or if an overflow or underflow condition occurs. The
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000273 result in all cases is unchanged.
274
275 The inexact signal may be tested (or trapped) to determine if a given
276 operation (or sequence of operations) was inexact.
277 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000278 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000279
280class InvalidContext(InvalidOperation):
281 """Invalid context. Unknown rounding, for example.
282
283 This occurs and signals invalid-operation if an invalid context was
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000284 detected during an operation. This can occur if contexts are not checked
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000285 on creation and either the precision exceeds the capability of the
286 underlying concrete representation or an unknown or unsupported rounding
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000287 was specified. These aspects of the context need only be checked when
288 the values are required to be used. The result is [0,qNaN].
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000289 """
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000290
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000291 def handle(self, context, *args):
292 return NaN
293
294class Rounded(DecimalException):
295 """Number got rounded (not necessarily changed during rounding).
296
297 This occurs and signals rounded whenever the result of an operation is
298 rounded (that is, some zero or non-zero digits were discarded from the
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000299 coefficient), or if an overflow or underflow condition occurs. The
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000300 result in all cases is unchanged.
301
302 The rounded signal may be tested (or trapped) to determine if a given
303 operation (or sequence of operations) caused a loss of precision.
304 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000305 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000306
307class Subnormal(DecimalException):
308 """Exponent < Emin before rounding.
309
310 This occurs and signals subnormal whenever the result of a conversion or
311 operation is subnormal (that is, its adjusted exponent is less than
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000312 Emin, before any rounding). The result in all cases is unchanged.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000313
314 The subnormal signal may be tested (or trapped) to determine if a given
315 or operation (or sequence of operations) yielded a subnormal result.
316 """
317 pass
318
319class Overflow(Inexact, Rounded):
320 """Numerical overflow.
321
322 This occurs and signals overflow if the adjusted exponent of a result
323 (from a conversion or from an operation that is not an attempt to divide
324 by zero), after rounding, would be greater than the largest value that
325 can be handled by the implementation (the value Emax).
326
327 The result depends on the rounding mode:
328
329 For round-half-up and round-half-even (and for round-half-down and
330 round-up, if implemented), the result of the operation is [sign,inf],
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000331 where sign is the sign of the intermediate result. For round-down, the
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000332 result is the largest finite number that can be represented in the
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000333 current precision, with the sign of the intermediate result. For
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000334 round-ceiling, the result is the same as for round-down if the sign of
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000335 the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000336 the result is the same as for round-down if the sign of the intermediate
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000337 result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000338 will also be raised.
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000339 """
340
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000341 def handle(self, context, sign, *args):
342 if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
343 ROUND_HALF_DOWN, ROUND_UP):
344 return Infsign[sign]
345 if sign == 0:
346 if context.rounding == ROUND_CEILING:
347 return Infsign[sign]
348 return Decimal((sign, (9,)*context.prec,
349 context.Emax-context.prec+1))
350 if sign == 1:
351 if context.rounding == ROUND_FLOOR:
352 return Infsign[sign]
353 return Decimal( (sign, (9,)*context.prec,
354 context.Emax-context.prec+1))
355
356
357class Underflow(Inexact, Rounded, Subnormal):
358 """Numerical underflow with result rounded to 0.
359
360 This occurs and signals underflow if a result is inexact and the
361 adjusted exponent of the result would be smaller (more negative) than
362 the smallest value that can be handled by the implementation (the value
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000363 Emin). That is, the result is both inexact and subnormal.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000364
365 The result after an underflow will be a subnormal number rounded, if
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000366 necessary, so that its exponent is not less than Etiny. This may result
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000367 in 0 with the sign of the intermediate result and an exponent of Etiny.
368
369 In all cases, Inexact, Rounded, and Subnormal will also be raised.
370 """
371
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000372# List of public traps and flags
Raymond Hettingerfed52962004-07-14 15:41:57 +0000373_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000374 Underflow, InvalidOperation, Subnormal]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000375
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000376# Map conditions (per the spec) to signals
377_condition_map = {ConversionSyntax:InvalidOperation,
378 DivisionImpossible:InvalidOperation,
379 DivisionUndefined:InvalidOperation,
380 InvalidContext:InvalidOperation}
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000381
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000382##### Context Functions #######################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000383
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000384# The getcontext() and setcontext() function manage access to a thread-local
385# current context. Py2.4 offers direct support for thread locals. If that
386# is not available, use threading.currentThread() which is slower but will
Raymond Hettinger7e71fa52004-12-18 19:07:19 +0000387# work for older Pythons. If threads are not part of the build, create a
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000388# mock threading object with threading.local() returning the module namespace.
Raymond Hettinger7e71fa52004-12-18 19:07:19 +0000389
390try:
391 import threading
392except ImportError:
393 # Python was compiled without threads; create a mock object instead
394 import sys
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000395 class MockThreading:
Raymond Hettinger7e71fa52004-12-18 19:07:19 +0000396 def local(self, sys=sys):
397 return sys.modules[__name__]
398 threading = MockThreading()
399 del sys, MockThreading
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000400
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000401try:
402 threading.local
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000403
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000404except AttributeError:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000405
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000406 #To fix reloading, force it to create a new context
407 #Old contexts have different exceptions in their dicts, making problems.
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000408 if hasattr(threading.currentThread(), '__decimal_context__'):
409 del threading.currentThread().__decimal_context__
410
411 def setcontext(context):
412 """Set this thread's context to context."""
413 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000414 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000415 context.clear_flags()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000416 threading.currentThread().__decimal_context__ = context
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000417
418 def getcontext():
419 """Returns this thread's context.
420
421 If this thread does not yet have a context, returns
422 a new context and sets this thread's context.
423 New contexts are copies of DefaultContext.
424 """
425 try:
426 return threading.currentThread().__decimal_context__
427 except AttributeError:
428 context = Context()
429 threading.currentThread().__decimal_context__ = context
430 return context
431
432else:
433
434 local = threading.local()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000435 if hasattr(local, '__decimal_context__'):
436 del local.__decimal_context__
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000437
438 def getcontext(_local=local):
439 """Returns this thread's context.
440
441 If this thread does not yet have a context, returns
442 a new context and sets this thread's context.
443 New contexts are copies of DefaultContext.
444 """
445 try:
446 return _local.__decimal_context__
447 except AttributeError:
448 context = Context()
449 _local.__decimal_context__ = context
450 return context
451
452 def setcontext(context, _local=local):
453 """Set this thread's context to context."""
454 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000455 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000456 context.clear_flags()
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000457 _local.__decimal_context__ = context
458
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000459 del threading, local # Don't contaminate the namespace
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000460
Nick Coghlan8b6999b2006-08-31 12:00:43 +0000461def localcontext(ctx=None):
462 """Return a context manager for a copy of the supplied context
463
464 Uses a copy of the current context if no context is specified
465 The returned context manager creates a local decimal context
466 in a with statement:
467 def sin(x):
468 with localcontext() as ctx:
469 ctx.prec += 2
470 # Rest of sin calculation algorithm
471 # uses a precision 2 greater than normal
472 return +s # Convert result to normal precision
473
474 def sin(x):
475 with localcontext(ExtendedContext):
476 # Rest of sin calculation algorithm
477 # uses the Extended Context from the
478 # General Decimal Arithmetic Specification
479 return +s # Convert result to normal context
480
481 """
Neal Norwitz681d8672006-09-02 18:51:34 +0000482 # The string below can't be included in the docstring until Python 2.6
Nick Coghlan8b6999b2006-08-31 12:00:43 +0000483 # as the doctest module doesn't understand __future__ statements
484 """
485 >>> from __future__ import with_statement
486 >>> print getcontext().prec
487 28
488 >>> with localcontext():
489 ... ctx = getcontext()
490 ... ctx.prec() += 2
491 ... print ctx.prec
492 ...
493 30
494 >>> with localcontext(ExtendedContext):
495 ... print getcontext().prec
496 ...
497 9
498 >>> print getcontext().prec
499 28
500 """
Nick Coghlanced12182006-09-02 03:54:17 +0000501 if ctx is None: ctx = getcontext()
502 return _ContextManager(ctx)
Nick Coghlan8b6999b2006-08-31 12:00:43 +0000503
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000504
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000505##### Decimal class ###########################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000506
507class Decimal(object):
508 """Floating point class for decimal arithmetic."""
509
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000510 __slots__ = ('_exp','_int','_sign', '_is_special')
511 # Generally, the value of the Decimal instance is given by
512 # (-1)**_sign * _int * 10**_exp
513 # Special values are signified by _is_special == True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000514
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000515 # We're immutable, so use __new__ not __init__
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000516 def __new__(cls, value="0", context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000517 """Create a decimal point instance.
518
519 >>> Decimal('3.14') # string input
520 Decimal("3.14")
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000521 >>> Decimal((0, (3, 1, 4), -2)) # tuple input (sign, digit_tuple, exponent)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000522 Decimal("3.14")
523 >>> Decimal(314) # int or long
524 Decimal("314")
525 >>> Decimal(Decimal(314)) # another decimal instance
526 Decimal("314")
527 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000528
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000529 self = object.__new__(cls)
530 self._is_special = False
531
532 # From an internal working value
533 if isinstance(value, _WorkRep):
Raymond Hettinger17931de2004-10-27 06:21:46 +0000534 self._sign = value.sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000535 self._int = tuple(map(int, str(value.int)))
536 self._exp = int(value.exp)
537 return self
538
539 # From another decimal
540 if isinstance(value, Decimal):
541 self._exp = value._exp
542 self._sign = value._sign
543 self._int = value._int
544 self._is_special = value._is_special
545 return self
546
547 # From an integer
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000548 if isinstance(value, (int,long)):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000549 if value >= 0:
550 self._sign = 0
551 else:
552 self._sign = 1
553 self._exp = 0
554 self._int = tuple(map(int, str(abs(value))))
555 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000556
557 # tuple/list conversion (possibly from as_tuple())
558 if isinstance(value, (list,tuple)):
559 if len(value) != 3:
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000560 raise ValueError, 'Invalid arguments'
Raymond Hettingerdbecd932005-02-06 06:57:08 +0000561 if value[0] not in (0,1):
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000562 raise ValueError, 'Invalid sign'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000563 for digit in value[1]:
564 if not isinstance(digit, (int,long)) or digit < 0:
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000565 raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000566
567 self._sign = value[0]
568 self._int = tuple(value[1])
569 if value[2] in ('F','n','N'):
570 self._exp = value[2]
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000571 self._is_special = True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000572 else:
573 self._exp = int(value[2])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000574 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000575
Raymond Hettingerbf440692004-07-10 14:14:37 +0000576 if isinstance(value, float):
577 raise TypeError("Cannot convert float to Decimal. " +
578 "First convert the float to a string")
579
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000580 # Other argument types may require the context during interpretation
581 if context is None:
582 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000583
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000584 # From a string
585 # REs insist on real strings, so we can too.
586 if isinstance(value, basestring):
587 if _isinfinity(value):
588 self._exp = 'F'
589 self._int = (0,)
590 self._is_special = True
591 if _isinfinity(value) == 1:
592 self._sign = 0
593 else:
594 self._sign = 1
595 return self
596 if _isnan(value):
597 sig, sign, diag = _isnan(value)
598 self._is_special = True
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000599 if len(diag) > context.prec: #Diagnostic info too long
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000600 self._sign, self._int, self._exp = \
601 context._raise_error(ConversionSyntax)
602 return self
603 if sig == 1:
604 self._exp = 'n' #qNaN
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000605 else: #sig == 2
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000606 self._exp = 'N' #sNaN
607 self._sign = sign
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000608 self._int = tuple(map(int, diag)) #Diagnostic info
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000609 return self
610 try:
611 self._sign, self._int, self._exp = _string2exact(value)
612 except ValueError:
613 self._is_special = True
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000614 self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000615 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000616
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000617 raise TypeError("Cannot convert %r to Decimal" % value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000618
619 def _isnan(self):
620 """Returns whether the number is not actually one.
621
622 0 if a number
623 1 if NaN
624 2 if sNaN
625 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000626 if self._is_special:
627 exp = self._exp
628 if exp == 'n':
629 return 1
630 elif exp == 'N':
631 return 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000632 return 0
633
634 def _isinfinity(self):
635 """Returns whether the number is infinite
636
637 0 if finite or not a number
638 1 if +INF
639 -1 if -INF
640 """
641 if self._exp == 'F':
642 if self._sign:
643 return -1
644 return 1
645 return 0
646
647 def _check_nans(self, other = None, context=None):
648 """Returns whether the number is not actually one.
649
650 if self, other are sNaN, signal
651 if self, other are NaN return nan
652 return 0
653
654 Done before operations.
655 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000656
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000657 self_is_nan = self._isnan()
658 if other is None:
659 other_is_nan = False
660 else:
661 other_is_nan = other._isnan()
662
663 if self_is_nan or other_is_nan:
664 if context is None:
665 context = getcontext()
666
667 if self_is_nan == 2:
668 return context._raise_error(InvalidOperation, 'sNaN',
669 1, self)
670 if other_is_nan == 2:
671 return context._raise_error(InvalidOperation, 'sNaN',
672 1, other)
673 if self_is_nan:
674 return self
675
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000676 return other
677 return 0
678
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000679 def __nonzero__(self):
680 """Is the number non-zero?
681
682 0 if self == 0
683 1 if self != 0
684 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000685 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000686 return 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000687 return sum(self._int) != 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000688
689 def __cmp__(self, other, context=None):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000690 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +0000691 if other is NotImplemented:
692 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000693
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000694 if self._is_special or other._is_special:
695 ans = self._check_nans(other, context)
696 if ans:
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000697 return 1 # Comparison involving NaN's always reports self > other
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000698
699 # INF = INF
700 return cmp(self._isinfinity(), other._isinfinity())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000701
702 if not self and not other:
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000703 return 0 #If both 0, sign comparison isn't certain.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000704
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000705 #If different signs, neg one is less
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000706 if other._sign < self._sign:
707 return -1
708 if self._sign < other._sign:
709 return 1
710
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000711 self_adjusted = self.adjusted()
712 other_adjusted = other.adjusted()
713 if self_adjusted == other_adjusted and \
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000714 self._int + (0,)*(self._exp - other._exp) == \
715 other._int + (0,)*(other._exp - self._exp):
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000716 return 0 #equal, except in precision. ([0]*(-x) = [])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000717 elif self_adjusted > other_adjusted and self._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000718 return (-1)**self._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000719 elif self_adjusted < other_adjusted and other._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000720 return -((-1)**self._sign)
721
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000722 # Need to round, so make sure we have a valid context
723 if context is None:
724 context = getcontext()
725
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000726 context = context._shallow_copy()
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000727 rounding = context._set_rounding(ROUND_UP) #round away from 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000728
729 flags = context._ignore_all_flags()
730 res = self.__sub__(other, context=context)
731
732 context._regard_flags(*flags)
733
734 context.rounding = rounding
735
736 if not res:
737 return 0
738 elif res._sign:
739 return -1
740 return 1
741
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000742 def __eq__(self, other):
743 if not isinstance(other, (Decimal, int, long)):
Raymond Hettinger267b8682005-03-27 10:47:39 +0000744 return NotImplemented
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000745 return self.__cmp__(other) == 0
746
747 def __ne__(self, other):
748 if not isinstance(other, (Decimal, int, long)):
Raymond Hettinger267b8682005-03-27 10:47:39 +0000749 return NotImplemented
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000750 return self.__cmp__(other) != 0
751
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000752 def compare(self, other, context=None):
753 """Compares one to another.
754
755 -1 => a < b
756 0 => a = b
757 1 => a > b
758 NaN => one is NaN
759 Like __cmp__, but returns Decimal instances.
760 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000761 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +0000762 if other is NotImplemented:
763 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000764
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000765 #compare(NaN, NaN) = NaN
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000766 if (self._is_special or other and other._is_special):
767 ans = self._check_nans(other, context)
768 if ans:
769 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000770
771 return Decimal(self.__cmp__(other, context))
772
773 def __hash__(self):
774 """x.__hash__() <==> hash(x)"""
775 # Decimal integers must hash the same as the ints
776 # Non-integer decimals are normalized and hashed as strings
Georg Brandl1fb9f522006-05-11 19:57:09 +0000777 # Normalization assures that hash(100E-1) == hash(10)
Raymond Hettingerbea3f6f2005-03-15 04:59:17 +0000778 if self._is_special:
779 if self._isnan():
780 raise TypeError('Cannot hash a NaN value.')
781 return hash(str(self))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000782 i = int(self)
783 if self == Decimal(i):
784 return hash(i)
785 assert self.__nonzero__() # '-0' handled by integer case
786 return hash(str(self.normalize()))
787
788 def as_tuple(self):
789 """Represents the number as a triple tuple.
790
791 To show the internals exactly as they are.
792 """
793 return (self._sign, self._int, self._exp)
794
795 def __repr__(self):
796 """Represents the number as an instance of Decimal."""
797 # Invariant: eval(repr(d)) == d
798 return 'Decimal("%s")' % str(self)
799
800 def __str__(self, eng = 0, context=None):
801 """Return string representation of the number in scientific notation.
802
803 Captures all of the information in the underlying representation.
804 """
805
Raymond Hettingere5a0a962005-06-20 09:49:42 +0000806 if self._is_special:
807 if self._isnan():
808 minus = '-'*self._sign
809 if self._int == (0,):
810 info = ''
811 else:
812 info = ''.join(map(str, self._int))
813 if self._isnan() == 2:
814 return minus + 'sNaN' + info
815 return minus + 'NaN' + info
816 if self._isinfinity():
817 minus = '-'*self._sign
818 return minus + 'Infinity'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000819
820 if context is None:
821 context = getcontext()
822
823 tmp = map(str, self._int)
824 numdigits = len(self._int)
825 leftdigits = self._exp + numdigits
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000826 if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
827 if self._exp < 0 and self._exp >= -6: #short, no need for e/E
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000828 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
829 return s
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000830 #exp is closest mult. of 3 >= self._exp
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000831 exp = ((self._exp - 1)// 3 + 1) * 3
832 if exp != self._exp:
833 s = '0.'+'0'*(exp - self._exp)
834 else:
835 s = '0'
836 if exp != 0:
837 if context.capitals:
838 s += 'E'
839 else:
840 s += 'e'
841 if exp > 0:
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000842 s += '+' #0.0e+3, not 0.0e3
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000843 s += str(exp)
844 s = '-'*self._sign + s
845 return s
846 if eng:
847 dotplace = (leftdigits-1)%3+1
848 adjexp = leftdigits -1 - (leftdigits-1)%3
849 else:
850 adjexp = leftdigits-1
851 dotplace = 1
852 if self._exp == 0:
853 pass
854 elif self._exp < 0 and adjexp >= 0:
855 tmp.insert(leftdigits, '.')
856 elif self._exp < 0 and adjexp >= -6:
857 tmp[0:0] = ['0'] * int(-leftdigits)
858 tmp.insert(0, '0.')
859 else:
860 if numdigits > dotplace:
861 tmp.insert(dotplace, '.')
862 elif numdigits < dotplace:
863 tmp.extend(['0']*(dotplace-numdigits))
864 if adjexp:
865 if not context.capitals:
866 tmp.append('e')
867 else:
868 tmp.append('E')
869 if adjexp > 0:
870 tmp.append('+')
871 tmp.append(str(adjexp))
872 if eng:
873 while tmp[0:1] == ['0']:
874 tmp[0:1] = []
875 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
876 tmp[0:0] = ['0']
877 if self._sign:
878 tmp.insert(0, '-')
879
880 return ''.join(tmp)
881
882 def to_eng_string(self, context=None):
883 """Convert to engineering-type string.
884
885 Engineering notation has an exponent which is a multiple of 3, so there
886 are up to 3 digits left of the decimal place.
887
888 Same rules for when in exponential and when as a value as in __str__.
889 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000890 return self.__str__(eng=1, context=context)
891
892 def __neg__(self, context=None):
893 """Returns a copy with the sign switched.
894
895 Rounds, if it has reason.
896 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000897 if self._is_special:
898 ans = self._check_nans(context=context)
899 if ans:
900 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000901
902 if not self:
903 # -Decimal('0') is Decimal('0'), not Decimal('-0')
904 sign = 0
905 elif self._sign:
906 sign = 0
907 else:
908 sign = 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000909
910 if context is None:
911 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000912 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000913 return Decimal((sign, self._int, self._exp))._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000914 return Decimal( (sign, self._int, self._exp))
915
916 def __pos__(self, context=None):
917 """Returns a copy, unless it is a sNaN.
918
919 Rounds the number (if more then precision digits)
920 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000921 if self._is_special:
922 ans = self._check_nans(context=context)
923 if ans:
924 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000925
926 sign = self._sign
927 if not self:
928 # + (-0) = 0
929 sign = 0
930
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000931 if context is None:
932 context = getcontext()
933
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000934 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000935 ans = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000936 else:
937 ans = Decimal(self)
938 ans._sign = sign
939 return ans
940
941 def __abs__(self, round=1, context=None):
942 """Returns the absolute value of self.
943
944 If the second argument is 0, do not round.
945 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000946 if self._is_special:
947 ans = self._check_nans(context=context)
948 if ans:
949 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000950
951 if not round:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000952 if context is None:
953 context = getcontext()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000954 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000955 context._set_rounding_decision(NEVER_ROUND)
956
957 if self._sign:
958 ans = self.__neg__(context=context)
959 else:
960 ans = self.__pos__(context=context)
961
962 return ans
963
964 def __add__(self, other, context=None):
965 """Returns self + other.
966
967 -INF + INF (or the reverse) cause InvalidOperation errors.
968 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000969 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +0000970 if other is NotImplemented:
971 return other
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000972
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000973 if context is None:
974 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000975
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000976 if self._is_special or other._is_special:
977 ans = self._check_nans(other, context)
978 if ans:
979 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000980
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000981 if self._isinfinity():
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000982 #If both INF, same sign => same as both, opposite => error.
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000983 if self._sign != other._sign and other._isinfinity():
984 return context._raise_error(InvalidOperation, '-INF + INF')
985 return Decimal(self)
986 if other._isinfinity():
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000987 return Decimal(other) #Can't both be infinity here
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000988
989 shouldround = context._rounding_decision == ALWAYS_ROUND
990
991 exp = min(self._exp, other._exp)
992 negativezero = 0
993 if context.rounding == ROUND_FLOOR and self._sign != other._sign:
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000994 #If the answer is 0, the sign should be negative, in this case.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000995 negativezero = 1
996
997 if not self and not other:
998 sign = min(self._sign, other._sign)
999 if negativezero:
1000 sign = 1
1001 return Decimal( (sign, (0,), exp))
1002 if not self:
Facundo Batista99b55482004-10-26 23:38:46 +00001003 exp = max(exp, other._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001004 ans = other._rescale(exp, watchexp=0, context=context)
1005 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001006 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001007 return ans
1008 if not other:
Facundo Batista99b55482004-10-26 23:38:46 +00001009 exp = max(exp, self._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001010 ans = self._rescale(exp, watchexp=0, context=context)
1011 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001012 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001013 return ans
1014
1015 op1 = _WorkRep(self)
1016 op2 = _WorkRep(other)
1017 op1, op2 = _normalize(op1, op2, shouldround, context.prec)
1018
1019 result = _WorkRep()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001020 if op1.sign != op2.sign:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001021 # Equal and opposite
Raymond Hettinger17931de2004-10-27 06:21:46 +00001022 if op1.int == op2.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001023 if exp < context.Etiny():
1024 exp = context.Etiny()
1025 context._raise_error(Clamped)
1026 return Decimal((negativezero, (0,), exp))
Raymond Hettinger17931de2004-10-27 06:21:46 +00001027 if op1.int < op2.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001028 op1, op2 = op2, op1
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001029 #OK, now abs(op1) > abs(op2)
Raymond Hettinger17931de2004-10-27 06:21:46 +00001030 if op1.sign == 1:
1031 result.sign = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001032 op1.sign, op2.sign = op2.sign, op1.sign
1033 else:
Raymond Hettinger17931de2004-10-27 06:21:46 +00001034 result.sign = 0
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001035 #So we know the sign, and op1 > 0.
Raymond Hettinger17931de2004-10-27 06:21:46 +00001036 elif op1.sign == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001037 result.sign = 1
Raymond Hettinger17931de2004-10-27 06:21:46 +00001038 op1.sign, op2.sign = (0, 0)
1039 else:
1040 result.sign = 0
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001041 #Now, op1 > abs(op2) > 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001042
Raymond Hettinger17931de2004-10-27 06:21:46 +00001043 if op2.sign == 0:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001044 result.int = op1.int + op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001045 else:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001046 result.int = op1.int - op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001047
1048 result.exp = op1.exp
1049 ans = Decimal(result)
1050 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001051 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001052 return ans
1053
1054 __radd__ = __add__
1055
1056 def __sub__(self, other, context=None):
1057 """Return self + (-other)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001058 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001059 if other is NotImplemented:
1060 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001061
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001062 if self._is_special or other._is_special:
1063 ans = self._check_nans(other, context=context)
1064 if ans:
1065 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001066
1067 # -Decimal(0) = Decimal(0), which we don't want since
1068 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
1069 # so we change the sign directly to a copy
1070 tmp = Decimal(other)
1071 tmp._sign = 1-tmp._sign
1072
1073 return self.__add__(tmp, context=context)
1074
1075 def __rsub__(self, other, context=None):
1076 """Return other + (-self)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001077 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001078 if other is NotImplemented:
1079 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001080
1081 tmp = Decimal(self)
1082 tmp._sign = 1 - tmp._sign
1083 return other.__add__(tmp, context=context)
1084
1085 def _increment(self, round=1, context=None):
1086 """Special case of add, adding 1eExponent
1087
1088 Since it is common, (rounding, for example) this adds
1089 (sign)*one E self._exp to the number more efficiently than add.
1090
1091 For example:
1092 Decimal('5.624e10')._increment() == Decimal('5.625e10')
1093 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001094 if self._is_special:
1095 ans = self._check_nans(context=context)
1096 if ans:
1097 return ans
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001098
1099 return Decimal(self) # Must be infinite, and incrementing makes no difference
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001100
1101 L = list(self._int)
1102 L[-1] += 1
1103 spot = len(L)-1
1104 while L[spot] == 10:
1105 L[spot] = 0
1106 if spot == 0:
1107 L[0:0] = [1]
1108 break
1109 L[spot-1] += 1
1110 spot -= 1
1111 ans = Decimal((self._sign, L, self._exp))
1112
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001113 if context is None:
1114 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001115 if round and context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001116 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001117 return ans
1118
1119 def __mul__(self, other, context=None):
1120 """Return self * other.
1121
1122 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1123 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001124 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001125 if other is NotImplemented:
1126 return other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001127
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001128 if context is None:
1129 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001130
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001131 resultsign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001132
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001133 if self._is_special or other._is_special:
1134 ans = self._check_nans(other, context)
1135 if ans:
1136 return ans
1137
1138 if self._isinfinity():
1139 if not other:
1140 return context._raise_error(InvalidOperation, '(+-)INF * 0')
1141 return Infsign[resultsign]
1142
1143 if other._isinfinity():
1144 if not self:
1145 return context._raise_error(InvalidOperation, '0 * (+-)INF')
1146 return Infsign[resultsign]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001147
1148 resultexp = self._exp + other._exp
1149 shouldround = context._rounding_decision == ALWAYS_ROUND
1150
1151 # Special case for multiplying by zero
1152 if not self or not other:
1153 ans = Decimal((resultsign, (0,), resultexp))
1154 if shouldround:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001155 #Fixing in case the exponent is out of bounds
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001156 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001157 return ans
1158
1159 # Special case for multiplying by power of 10
1160 if self._int == (1,):
1161 ans = Decimal((resultsign, other._int, resultexp))
1162 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001163 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001164 return ans
1165 if other._int == (1,):
1166 ans = Decimal((resultsign, self._int, resultexp))
1167 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001168 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001169 return ans
1170
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001171 op1 = _WorkRep(self)
1172 op2 = _WorkRep(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001173
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001174 ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001175 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001176 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001177
1178 return ans
1179 __rmul__ = __mul__
1180
1181 def __div__(self, other, context=None):
1182 """Return self / other."""
1183 return self._divide(other, context=context)
1184 __truediv__ = __div__
1185
1186 def _divide(self, other, divmod = 0, context=None):
1187 """Return a / b, to context.prec precision.
1188
1189 divmod:
1190 0 => true division
1191 1 => (a //b, a%b)
1192 2 => a //b
1193 3 => a%b
1194
1195 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1196 computing the other value are not raised.
1197 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001198 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001199 if other is NotImplemented:
1200 if divmod in (0, 1):
1201 return NotImplemented
1202 return (NotImplemented, NotImplemented)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001203
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001204 if context is None:
1205 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001206
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001207 sign = self._sign ^ other._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001208
1209 if self._is_special or other._is_special:
1210 ans = self._check_nans(other, context)
1211 if ans:
1212 if divmod:
1213 return (ans, ans)
1214 return ans
1215
1216 if self._isinfinity() and other._isinfinity():
1217 if divmod:
1218 return (context._raise_error(InvalidOperation,
1219 '(+-)INF // (+-)INF'),
1220 context._raise_error(InvalidOperation,
1221 '(+-)INF % (+-)INF'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001222 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001223
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001224 if self._isinfinity():
1225 if divmod == 1:
1226 return (Infsign[sign],
1227 context._raise_error(InvalidOperation, 'INF % x'))
1228 elif divmod == 2:
1229 return (Infsign[sign], NaN)
1230 elif divmod == 3:
1231 return (Infsign[sign],
1232 context._raise_error(InvalidOperation, 'INF % x'))
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001233 return Infsign[sign]
1234
1235 if other._isinfinity():
1236 if divmod:
1237 return (Decimal((sign, (0,), 0)), Decimal(self))
1238 context._raise_error(Clamped, 'Division by infinity')
1239 return Decimal((sign, (0,), context.Etiny()))
1240
1241 # Special cases for zeroes
1242 if not self and not other:
1243 if divmod:
1244 return context._raise_error(DivisionUndefined, '0 / 0', 1)
1245 return context._raise_error(DivisionUndefined, '0 / 0')
1246
1247 if not self:
1248 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001249 otherside = Decimal(self)
1250 otherside._exp = min(self._exp, other._exp)
1251 return (Decimal((sign, (0,), 0)), otherside)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001252 exp = self._exp - other._exp
1253 if exp < context.Etiny():
1254 exp = context.Etiny()
1255 context._raise_error(Clamped, '0e-x / y')
1256 if exp > context.Emax:
1257 exp = context.Emax
1258 context._raise_error(Clamped, '0e+x / y')
1259 return Decimal( (sign, (0,), exp) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001260
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001261 if not other:
1262 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001263 return context._raise_error(DivisionByZero, 'divmod(x,0)',
1264 sign, 1)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001265 return context._raise_error(DivisionByZero, 'x / 0', sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001266
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001267 #OK, so neither = 0, INF or NaN
1268
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001269 shouldround = context._rounding_decision == ALWAYS_ROUND
1270
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001271 #If we're dividing into ints, and self < other, stop.
1272 #self.__abs__(0) does not round.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001273 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
1274
1275 if divmod == 1 or divmod == 3:
1276 exp = min(self._exp, other._exp)
1277 ans2 = self._rescale(exp, context=context, watchexp=0)
1278 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001279 ans2 = ans2._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001280 return (Decimal( (sign, (0,), 0) ),
1281 ans2)
1282
1283 elif divmod == 2:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001284 #Don't round the mod part, if we don't need it.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001285 return (Decimal( (sign, (0,), 0) ), Decimal(self))
1286
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001287 op1 = _WorkRep(self)
1288 op2 = _WorkRep(other)
1289 op1, op2, adjust = _adjust_coefficients(op1, op2)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001290 res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001291 if divmod and res.exp > context.prec + 1:
1292 return context._raise_error(DivisionImpossible)
1293
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001294 prec_limit = 10 ** context.prec
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001295 while 1:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001296 while op2.int <= op1.int:
1297 res.int += 1
1298 op1.int -= op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001299 if res.exp == 0 and divmod:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001300 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001301 return context._raise_error(DivisionImpossible)
1302 otherside = Decimal(op1)
1303 frozen = context._ignore_all_flags()
1304
1305 exp = min(self._exp, other._exp)
Raymond Hettinger17931de2004-10-27 06:21:46 +00001306 otherside = otherside._rescale(exp, context=context, watchexp=0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001307 context._regard_flags(*frozen)
1308 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001309 otherside = otherside._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001310 return (Decimal(res), otherside)
1311
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001312 if op1.int == 0 and adjust >= 0 and not divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001313 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001314 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001315 if divmod:
1316 return context._raise_error(DivisionImpossible)
1317 shouldround=1
1318 # Really, the answer is a bit higher, so adding a one to
1319 # the end will make sure the rounding is right.
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001320 if op1.int != 0:
1321 res.int *= 10
1322 res.int += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001323 res.exp -= 1
1324
1325 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001326 res.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001327 res.exp -= 1
1328 adjust += 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001329 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001330 op1.exp -= 1
1331
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001332 if res.exp == 0 and divmod and op2.int > op1.int:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001333 #Solves an error in precision. Same as a previous block.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001334
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001335 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001336 return context._raise_error(DivisionImpossible)
1337 otherside = Decimal(op1)
1338 frozen = context._ignore_all_flags()
1339
1340 exp = min(self._exp, other._exp)
1341 otherside = otherside._rescale(exp, context=context)
1342
1343 context._regard_flags(*frozen)
1344
1345 return (Decimal(res), otherside)
1346
1347 ans = Decimal(res)
1348 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001349 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001350 return ans
1351
1352 def __rdiv__(self, other, context=None):
1353 """Swaps self/other and returns __div__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001354 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001355 if other is NotImplemented:
1356 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001357 return other.__div__(self, context=context)
1358 __rtruediv__ = __rdiv__
1359
1360 def __divmod__(self, other, context=None):
1361 """
1362 (self // other, self % other)
1363 """
1364 return self._divide(other, 1, context)
1365
1366 def __rdivmod__(self, other, context=None):
1367 """Swaps self/other and returns __divmod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001368 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001369 if other is NotImplemented:
1370 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001371 return other.__divmod__(self, context=context)
1372
1373 def __mod__(self, other, context=None):
1374 """
1375 self % other
1376 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001377 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001378 if other is NotImplemented:
1379 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001380
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001381 if self._is_special or other._is_special:
1382 ans = self._check_nans(other, context)
1383 if ans:
1384 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001385
1386 if self and not other:
1387 return context._raise_error(InvalidOperation, 'x % 0')
1388
1389 return self._divide(other, 3, context)[1]
1390
1391 def __rmod__(self, other, context=None):
1392 """Swaps self/other and returns __mod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001393 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001394 if other is NotImplemented:
1395 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001396 return other.__mod__(self, context=context)
1397
1398 def remainder_near(self, other, context=None):
1399 """
1400 Remainder nearest to 0- abs(remainder-near) <= other/2
1401 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001402 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001403 if other is NotImplemented:
1404 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001405
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001406 if self._is_special or other._is_special:
1407 ans = self._check_nans(other, context)
1408 if ans:
1409 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001410 if self and not other:
1411 return context._raise_error(InvalidOperation, 'x % 0')
1412
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001413 if context is None:
1414 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001415 # If DivisionImpossible causes an error, do not leave Rounded/Inexact
1416 # ignored in the calling function.
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001417 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001418 flags = context._ignore_flags(Rounded, Inexact)
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001419 #keep DivisionImpossible flags
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001420 (side, r) = self.__divmod__(other, context=context)
1421
1422 if r._isnan():
1423 context._regard_flags(*flags)
1424 return r
1425
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001426 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001427 rounding = context._set_rounding_decision(NEVER_ROUND)
1428
1429 if other._sign:
1430 comparison = other.__div__(Decimal(-2), context=context)
1431 else:
1432 comparison = other.__div__(Decimal(2), context=context)
1433
1434 context._set_rounding_decision(rounding)
1435 context._regard_flags(*flags)
1436
1437 s1, s2 = r._sign, comparison._sign
1438 r._sign, comparison._sign = 0, 0
1439
1440 if r < comparison:
1441 r._sign, comparison._sign = s1, s2
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001442 #Get flags now
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001443 self.__divmod__(other, context=context)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001444 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001445 r._sign, comparison._sign = s1, s2
1446
1447 rounding = context._set_rounding_decision(NEVER_ROUND)
1448
1449 (side, r) = self.__divmod__(other, context=context)
1450 context._set_rounding_decision(rounding)
1451 if r._isnan():
1452 return r
1453
1454 decrease = not side._iseven()
1455 rounding = context._set_rounding_decision(NEVER_ROUND)
1456 side = side.__abs__(context=context)
1457 context._set_rounding_decision(rounding)
1458
1459 s1, s2 = r._sign, comparison._sign
1460 r._sign, comparison._sign = 0, 0
1461 if r > comparison or decrease and r == comparison:
1462 r._sign, comparison._sign = s1, s2
1463 context.prec += 1
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001464 if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001465 context.prec -= 1
1466 return context._raise_error(DivisionImpossible)[1]
1467 context.prec -= 1
1468 if self._sign == other._sign:
1469 r = r.__sub__(other, context=context)
1470 else:
1471 r = r.__add__(other, context=context)
1472 else:
1473 r._sign, comparison._sign = s1, s2
1474
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001475 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001476
1477 def __floordiv__(self, other, context=None):
1478 """self // other"""
1479 return self._divide(other, 2, context)[0]
1480
1481 def __rfloordiv__(self, other, context=None):
1482 """Swaps self/other and returns __floordiv__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001483 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001484 if other is NotImplemented:
1485 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001486 return other.__floordiv__(self, context=context)
1487
1488 def __float__(self):
1489 """Float representation."""
1490 return float(str(self))
1491
1492 def __int__(self):
Brett Cannon46b08022005-03-01 03:12:26 +00001493 """Converts self to an int, truncating if necessary."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001494 if self._is_special:
1495 if self._isnan():
1496 context = getcontext()
1497 return context._raise_error(InvalidContext)
1498 elif self._isinfinity():
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001499 raise OverflowError, "Cannot convert infinity to long"
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001500 if self._exp >= 0:
Raymond Hettinger605ed022004-11-24 07:28:48 +00001501 s = ''.join(map(str, self._int)) + '0'*self._exp
1502 else:
1503 s = ''.join(map(str, self._int))[:self._exp]
1504 if s == '':
1505 s = '0'
1506 sign = '-'*self._sign
1507 return int(sign + s)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001508
1509 def __long__(self):
1510 """Converts to a long.
1511
1512 Equivalent to long(int(self))
1513 """
1514 return long(self.__int__())
1515
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001516 def _fix(self, context):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001517 """Round if it is necessary to keep self within prec precision.
1518
1519 Rounds and fixes the exponent. Does not raise on a sNaN.
1520
1521 Arguments:
1522 self - Decimal instance
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001523 context - context used.
1524 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001525 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001526 return self
1527 if context is None:
1528 context = getcontext()
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001529 prec = context.prec
Facundo Batista99b55482004-10-26 23:38:46 +00001530 ans = self._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001531 if len(ans._int) > prec:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001532 ans = ans._round(prec, context=context)
Facundo Batista99b55482004-10-26 23:38:46 +00001533 ans = ans._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001534 return ans
1535
Facundo Batista99b55482004-10-26 23:38:46 +00001536 def _fixexponents(self, context):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001537 """Fix the exponents and return a copy with the exponent in bounds.
1538 Only call if known to not be a special value.
1539 """
1540 folddown = context._clamp
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001541 Emin = context.Emin
Facundo Batista99b55482004-10-26 23:38:46 +00001542 ans = self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001543 ans_adjusted = ans.adjusted()
1544 if ans_adjusted < Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001545 Etiny = context.Etiny()
1546 if ans._exp < Etiny:
1547 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001548 ans = Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001549 ans._exp = Etiny
1550 context._raise_error(Clamped)
1551 return ans
1552 ans = ans._rescale(Etiny, context=context)
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001553 #It isn't zero, and exp < Emin => subnormal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001554 context._raise_error(Subnormal)
1555 if context.flags[Inexact]:
1556 context._raise_error(Underflow)
1557 else:
1558 if ans:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001559 #Only raise subnormal if non-zero.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001560 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001561 else:
1562 Etop = context.Etop()
1563 if folddown and ans._exp > Etop:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001564 context._raise_error(Clamped)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001565 ans = ans._rescale(Etop, context=context)
1566 else:
1567 Emax = context.Emax
1568 if ans_adjusted > Emax:
1569 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001570 ans = Decimal(self)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001571 ans._exp = Emax
1572 context._raise_error(Clamped)
1573 return ans
1574 context._raise_error(Inexact)
1575 context._raise_error(Rounded)
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001576 return context._raise_error(Overflow, 'above Emax', ans._sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001577 return ans
1578
1579 def _round(self, prec=None, rounding=None, context=None):
1580 """Returns a rounded version of self.
1581
1582 You can specify the precision or rounding method. Otherwise, the
1583 context determines it.
1584 """
1585
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001586 if self._is_special:
1587 ans = self._check_nans(context=context)
1588 if ans:
1589 return ans
1590
1591 if self._isinfinity():
1592 return Decimal(self)
1593
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001594 if context is None:
1595 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001596
1597 if rounding is None:
1598 rounding = context.rounding
1599 if prec is None:
1600 prec = context.prec
1601
1602 if not self:
1603 if prec <= 0:
1604 dig = (0,)
1605 exp = len(self._int) - prec + self._exp
1606 else:
1607 dig = (0,) * prec
1608 exp = len(self._int) + self._exp - prec
1609 ans = Decimal((self._sign, dig, exp))
1610 context._raise_error(Rounded)
1611 return ans
1612
1613 if prec == 0:
1614 temp = Decimal(self)
1615 temp._int = (0,)+temp._int
1616 prec = 1
1617 elif prec < 0:
1618 exp = self._exp + len(self._int) - prec - 1
1619 temp = Decimal( (self._sign, (0, 1), exp))
1620 prec = 1
1621 else:
1622 temp = Decimal(self)
1623
1624 numdigits = len(temp._int)
1625 if prec == numdigits:
1626 return temp
1627
1628 # See if we need to extend precision
1629 expdiff = prec - numdigits
1630 if expdiff > 0:
1631 tmp = list(temp._int)
1632 tmp.extend([0] * expdiff)
1633 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff))
1634 return ans
1635
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001636 #OK, but maybe all the lost digits are 0.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001637 lostdigits = self._int[expdiff:]
1638 if lostdigits == (0,) * len(lostdigits):
1639 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001640 #Rounded, but not Inexact
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001641 context._raise_error(Rounded)
1642 return ans
1643
1644 # Okay, let's round and lose data
1645
1646 this_function = getattr(temp, self._pick_rounding_function[rounding])
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001647 #Now we've got the rounding function
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001648
1649 if prec != context.prec:
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001650 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001651 context.prec = prec
1652 ans = this_function(prec, expdiff, context)
1653 context._raise_error(Rounded)
1654 context._raise_error(Inexact, 'Changed in rounding')
1655
1656 return ans
1657
1658 _pick_rounding_function = {}
1659
1660 def _round_down(self, prec, expdiff, context):
1661 """Also known as round-towards-0, truncate."""
1662 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1663
1664 def _round_half_up(self, prec, expdiff, context, tmp = None):
1665 """Rounds 5 up (away from 0)"""
1666
1667 if tmp is None:
1668 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
1669 if self._int[prec] >= 5:
1670 tmp = tmp._increment(round=0, context=context)
1671 if len(tmp._int) > prec:
1672 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1673 return tmp
1674
1675 def _round_half_even(self, prec, expdiff, context):
1676 """Round 5 to even, rest to nearest."""
1677
1678 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1679 half = (self._int[prec] == 5)
1680 if half:
1681 for digit in self._int[prec+1:]:
1682 if digit != 0:
1683 half = 0
1684 break
1685 if half:
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001686 if self._int[prec-1] & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001687 return tmp
1688 return self._round_half_up(prec, expdiff, context, tmp)
1689
1690 def _round_half_down(self, prec, expdiff, context):
1691 """Round 5 down"""
1692
1693 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1694 half = (self._int[prec] == 5)
1695 if half:
1696 for digit in self._int[prec+1:]:
1697 if digit != 0:
1698 half = 0
1699 break
1700 if half:
1701 return tmp
1702 return self._round_half_up(prec, expdiff, context, tmp)
1703
1704 def _round_up(self, prec, expdiff, context):
1705 """Rounds away from 0."""
1706 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1707 for digit in self._int[prec:]:
1708 if digit != 0:
1709 tmp = tmp._increment(round=1, context=context)
1710 if len(tmp._int) > prec:
1711 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1712 else:
1713 return tmp
1714 return tmp
1715
1716 def _round_ceiling(self, prec, expdiff, context):
1717 """Rounds up (not away from 0 if negative.)"""
1718 if self._sign:
1719 return self._round_down(prec, expdiff, context)
1720 else:
1721 return self._round_up(prec, expdiff, context)
1722
1723 def _round_floor(self, prec, expdiff, context):
1724 """Rounds down (not towards 0 if negative)"""
1725 if not self._sign:
1726 return self._round_down(prec, expdiff, context)
1727 else:
1728 return self._round_up(prec, expdiff, context)
1729
1730 def __pow__(self, n, modulo = None, context=None):
1731 """Return self ** n (mod modulo)
1732
1733 If modulo is None (default), don't take it mod modulo.
1734 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001735 n = _convert_other(n)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001736 if n is NotImplemented:
1737 return n
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001738
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001739 if context is None:
1740 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001741
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001742 if self._is_special or n._is_special or n.adjusted() > 8:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001743 #Because the spot << doesn't work with really big exponents
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001744 if n._isinfinity() or n.adjusted() > 8:
1745 return context._raise_error(InvalidOperation, 'x ** INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001746
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001747 ans = self._check_nans(n, context)
1748 if ans:
1749 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001750
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001751 if not n._isinteger():
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001752 return context._raise_error(InvalidOperation, 'x ** (non-integer)')
1753
1754 if not self and not n:
1755 return context._raise_error(InvalidOperation, '0 ** 0')
1756
1757 if not n:
1758 return Decimal(1)
1759
1760 if self == Decimal(1):
1761 return Decimal(1)
1762
1763 sign = self._sign and not n._iseven()
1764 n = int(n)
1765
1766 if self._isinfinity():
1767 if modulo:
1768 return context._raise_error(InvalidOperation, 'INF % x')
1769 if n > 0:
1770 return Infsign[sign]
1771 return Decimal( (sign, (0,), 0) )
1772
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001773 #with ludicrously large exponent, just raise an overflow and return inf.
1774 if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
1775 and self:
1776
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001777 tmp = Decimal('inf')
1778 tmp._sign = sign
1779 context._raise_error(Rounded)
1780 context._raise_error(Inexact)
1781 context._raise_error(Overflow, 'Big power', sign)
1782 return tmp
1783
1784 elength = len(str(abs(n)))
1785 firstprec = context.prec
1786
Raymond Hettinger99148e72004-07-14 19:56:56 +00001787 if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001788 return context._raise_error(Overflow, 'Too much precision.', sign)
1789
1790 mul = Decimal(self)
1791 val = Decimal(1)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001792 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001793 context.prec = firstprec + elength + 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001794 if n < 0:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001795 #n is a long now, not Decimal instance
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001796 n = -n
1797 mul = Decimal(1).__div__(mul, context=context)
1798
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001799 spot = 1
1800 while spot <= n:
1801 spot <<= 1
1802
1803 spot >>= 1
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001804 #Spot is the highest power of 2 less than n
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001805 while spot:
1806 val = val.__mul__(val, context=context)
1807 if val._isinfinity():
1808 val = Infsign[sign]
1809 break
1810 if spot & n:
1811 val = val.__mul__(mul, context=context)
1812 if modulo is not None:
1813 val = val.__mod__(modulo, context=context)
1814 spot >>= 1
1815 context.prec = firstprec
1816
Raymond Hettinger76e60d62004-10-20 06:58:28 +00001817 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001818 return val._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001819 return val
1820
1821 def __rpow__(self, other, context=None):
1822 """Swaps self/other and returns __pow__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001823 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001824 if other is NotImplemented:
1825 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001826 return other.__pow__(self, context=context)
1827
1828 def normalize(self, context=None):
1829 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001830
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001831 if self._is_special:
1832 ans = self._check_nans(context=context)
1833 if ans:
1834 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001835
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001836 dup = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001837 if dup._isinfinity():
1838 return dup
1839
1840 if not dup:
1841 return Decimal( (dup._sign, (0,), 0) )
1842 end = len(dup._int)
1843 exp = dup._exp
1844 while dup._int[end-1] == 0:
1845 exp += 1
1846 end -= 1
1847 return Decimal( (dup._sign, dup._int[:end], exp) )
1848
1849
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001850 def quantize(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001851 """Quantize self so its exponent is the same as that of exp.
1852
1853 Similar to self._rescale(exp._exp) but with error checking.
1854 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001855 if self._is_special or exp._is_special:
1856 ans = self._check_nans(exp, context)
1857 if ans:
1858 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001859
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001860 if exp._isinfinity() or self._isinfinity():
1861 if exp._isinfinity() and self._isinfinity():
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001862 return self #if both are inf, it is OK
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001863 if context is None:
1864 context = getcontext()
1865 return context._raise_error(InvalidOperation,
1866 'quantize with one INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001867 return self._rescale(exp._exp, rounding, context, watchexp)
1868
1869 def same_quantum(self, other):
1870 """Test whether self and other have the same exponent.
1871
1872 same as self._exp == other._exp, except NaN == sNaN
1873 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001874 if self._is_special or other._is_special:
1875 if self._isnan() or other._isnan():
1876 return self._isnan() and other._isnan() and True
1877 if self._isinfinity() or other._isinfinity():
1878 return self._isinfinity() and other._isinfinity() and True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001879 return self._exp == other._exp
1880
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001881 def _rescale(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001882 """Rescales so that the exponent is exp.
1883
1884 exp = exp to scale to (an integer)
1885 rounding = rounding version
1886 watchexp: if set (default) an error is returned if exp is greater
1887 than Emax or less than Etiny.
1888 """
1889 if context is None:
1890 context = getcontext()
1891
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001892 if self._is_special:
1893 if self._isinfinity():
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001894 return context._raise_error(InvalidOperation, 'rescale with an INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001895
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001896 ans = self._check_nans(context=context)
1897 if ans:
1898 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001899
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001900 if watchexp and (context.Emax < exp or context.Etiny() > exp):
1901 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1902
1903 if not self:
1904 ans = Decimal(self)
1905 ans._int = (0,)
1906 ans._exp = exp
1907 return ans
1908
1909 diff = self._exp - exp
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001910 digits = len(self._int) + diff
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001911
1912 if watchexp and digits > context.prec:
1913 return context._raise_error(InvalidOperation, 'Rescale > prec')
1914
1915 tmp = Decimal(self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001916 tmp._int = (0,) + tmp._int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001917 digits += 1
1918
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001919 if digits < 0:
1920 tmp._exp = -digits + tmp._exp
1921 tmp._int = (0,1)
1922 digits = 1
1923 tmp = tmp._round(digits, rounding, context=context)
1924
1925 if tmp._int[0] == 0 and len(tmp._int) > 1:
1926 tmp._int = tmp._int[1:]
1927 tmp._exp = exp
1928
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001929 tmp_adjusted = tmp.adjusted()
1930 if tmp and tmp_adjusted < context.Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001931 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001932 elif tmp and tmp_adjusted > context.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001933 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1934 return tmp
1935
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001936 def to_integral(self, rounding=None, context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001937 """Rounds to the nearest integer, without raising inexact, rounded."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001938 if self._is_special:
1939 ans = self._check_nans(context=context)
1940 if ans:
1941 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001942 if self._exp >= 0:
1943 return self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001944 if context is None:
1945 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001946 flags = context._ignore_flags(Rounded, Inexact)
1947 ans = self._rescale(0, rounding, context=context)
1948 context._regard_flags(flags)
1949 return ans
1950
1951 def sqrt(self, context=None):
1952 """Return the square root of self.
1953
1954 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
1955 Should quadratically approach the right answer.
1956 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001957 if self._is_special:
1958 ans = self._check_nans(context=context)
1959 if ans:
1960 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001961
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001962 if self._isinfinity() and self._sign == 0:
1963 return Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001964
1965 if not self:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001966 #exponent = self._exp / 2, using round_down.
1967 #if self._exp < 0:
1968 # exp = (self._exp+1) // 2
1969 #else:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001970 exp = (self._exp) // 2
1971 if self._sign == 1:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001972 #sqrt(-0) = -0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001973 return Decimal( (1, (0,), exp))
1974 else:
1975 return Decimal( (0, (0,), exp))
1976
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001977 if context is None:
1978 context = getcontext()
1979
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001980 if self._sign == 1:
1981 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
1982
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001983 tmp = Decimal(self)
1984
Raymond Hettinger4837a222004-09-27 14:23:40 +00001985 expadd = tmp._exp // 2
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001986 if tmp._exp & 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001987 tmp._int += (0,)
1988 tmp._exp = 0
1989 else:
1990 tmp._exp = 0
1991
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001992 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001993 flags = context._ignore_all_flags()
1994 firstprec = context.prec
1995 context.prec = 3
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001996 if tmp.adjusted() & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001997 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) )
1998 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
1999 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00002000 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002001 else:
2002 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
2003 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
2004 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00002005 ans._exp -= 1 + tmp.adjusted() // 2
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002006
2007 #ans is now a linear approximation.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002008
2009 Emax, Emin = context.Emax, context.Emin
Raymond Hettinger99148e72004-07-14 19:56:56 +00002010 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002011
2012 half = Decimal('0.5')
2013
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002014 maxp = firstprec + 2
2015 rounding = context._set_rounding(ROUND_HALF_EVEN)
2016 while 1:
2017 context.prec = min(2*context.prec - 2, maxp)
2018 ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
2019 context=context), context=context)
2020 if context.prec == maxp:
2021 break
2022
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002023 #round to the answer's precision-- the only error can be 1 ulp.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002024 context.prec = firstprec
2025 prevexp = ans.adjusted()
2026 ans = ans._round(context=context)
2027
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002028 #Now, check if the other last digits are better.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002029 context.prec = firstprec + 1
2030 # In case we rounded up another digit and we should actually go lower.
2031 if prevexp != ans.adjusted():
2032 ans._int += (0,)
2033 ans._exp -= 1
2034
2035
2036 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
2037 context._set_rounding(ROUND_UP)
2038 if lower.__mul__(lower, context=context) > (tmp):
2039 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
2040
2041 else:
2042 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
2043 context._set_rounding(ROUND_DOWN)
2044 if upper.__mul__(upper, context=context) < tmp:
2045 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
2046
2047 ans._exp += expadd
2048
2049 context.prec = firstprec
2050 context.rounding = rounding
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002051 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002052
2053 rounding = context._set_rounding_decision(NEVER_ROUND)
2054 if not ans.__mul__(ans, context=context) == self:
2055 # Only rounded/inexact if here.
2056 context._regard_flags(flags)
2057 context._raise_error(Rounded)
2058 context._raise_error(Inexact)
2059 else:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002060 #Exact answer, so let's set the exponent right.
2061 #if self._exp < 0:
2062 # exp = (self._exp +1)// 2
2063 #else:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002064 exp = self._exp // 2
2065 context.prec += ans._exp - exp
2066 ans = ans._rescale(exp, context=context)
2067 context.prec = firstprec
2068 context._regard_flags(flags)
2069 context.Emax, context.Emin = Emax, Emin
2070
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002071 return ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002072
2073 def max(self, other, context=None):
2074 """Returns the larger value.
2075
2076 like max(self, other) except if one is not a number, returns
2077 NaN (and signals if one is sNaN). Also rounds.
2078 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002079 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002080 if other is NotImplemented:
2081 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002082
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002083 if self._is_special or other._is_special:
2084 # if one operand is a quiet NaN and the other is number, then the
2085 # number is always returned
2086 sn = self._isnan()
2087 on = other._isnan()
2088 if sn or on:
2089 if on == 1 and sn != 2:
2090 return self
2091 if sn == 1 and on != 2:
2092 return other
2093 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002094
2095 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002096 c = self.__cmp__(other)
2097 if c == 0:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002098 # if both operands are finite and equal in numerical value
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002099 # then an ordering is applied:
2100 #
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002101 # if the signs differ then max returns the operand with the
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002102 # positive sign and min returns the operand with the negative sign
2103 #
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002104 # if the signs are the same then the exponent is used to select
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002105 # the result.
2106 if self._sign != other._sign:
2107 if self._sign:
2108 ans = other
2109 elif self._exp < other._exp and not self._sign:
2110 ans = other
2111 elif self._exp > other._exp and self._sign:
2112 ans = other
2113 elif c == -1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002114 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002115
2116 if context is None:
2117 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002118 if context._rounding_decision == ALWAYS_ROUND:
2119 return ans._fix(context)
2120 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002121
2122 def min(self, other, context=None):
2123 """Returns the smaller value.
2124
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002125 like min(self, other) except if one is not a number, returns
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002126 NaN (and signals if one is sNaN). Also rounds.
2127 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002128 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002129 if other is NotImplemented:
2130 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002131
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002132 if self._is_special or other._is_special:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002133 # if one operand is a quiet NaN and the other is number, then the
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002134 # number is always returned
2135 sn = self._isnan()
2136 on = other._isnan()
2137 if sn or on:
2138 if on == 1 and sn != 2:
2139 return self
2140 if sn == 1 and on != 2:
2141 return other
2142 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002143
2144 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002145 c = self.__cmp__(other)
2146 if c == 0:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002147 # if both operands are finite and equal in numerical value
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002148 # then an ordering is applied:
2149 #
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002150 # if the signs differ then max returns the operand with the
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002151 # positive sign and min returns the operand with the negative sign
2152 #
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002153 # if the signs are the same then the exponent is used to select
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002154 # the result.
2155 if self._sign != other._sign:
2156 if other._sign:
2157 ans = other
2158 elif self._exp > other._exp and not self._sign:
2159 ans = other
2160 elif self._exp < other._exp and self._sign:
2161 ans = other
2162 elif c == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002163 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002164
2165 if context is None:
2166 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002167 if context._rounding_decision == ALWAYS_ROUND:
2168 return ans._fix(context)
2169 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002170
2171 def _isinteger(self):
2172 """Returns whether self is an integer"""
2173 if self._exp >= 0:
2174 return True
2175 rest = self._int[self._exp:]
2176 return rest == (0,)*len(rest)
2177
2178 def _iseven(self):
2179 """Returns 1 if self is even. Assumes self is an integer."""
2180 if self._exp > 0:
2181 return 1
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002182 return self._int[-1+self._exp] & 1 == 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002183
2184 def adjusted(self):
2185 """Return the adjusted exponent of self"""
2186 try:
2187 return self._exp + len(self._int) - 1
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002188 #If NaN or Infinity, self._exp is string
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002189 except TypeError:
2190 return 0
2191
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002192 # support for pickling, copy, and deepcopy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002193 def __reduce__(self):
2194 return (self.__class__, (str(self),))
2195
2196 def __copy__(self):
2197 if type(self) == Decimal:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002198 return self # I'm immutable; therefore I am my own clone
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002199 return self.__class__(str(self))
2200
2201 def __deepcopy__(self, memo):
2202 if type(self) == Decimal:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002203 return self # My components are also immutable
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002204 return self.__class__(str(self))
2205
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002206##### Context class ###########################################
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002207
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002208
2209# get rounding method function:
2210rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002211for name in rounding_functions:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002212 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002213 globalname = name[1:].upper()
2214 val = globals()[globalname]
2215 Decimal._pick_rounding_function[val] = name
2216
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002217del name, val, globalname, rounding_functions
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002218
Nick Coghlanced12182006-09-02 03:54:17 +00002219class _ContextManager(object):
Nick Coghlan8b6999b2006-08-31 12:00:43 +00002220 """Context manager class to support localcontext().
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002221
Nick Coghlanced12182006-09-02 03:54:17 +00002222 Sets a copy of the supplied context in __enter__() and restores
Nick Coghlan8b6999b2006-08-31 12:00:43 +00002223 the previous decimal context in __exit__()
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002224 """
2225 def __init__(self, new_context):
Nick Coghlanced12182006-09-02 03:54:17 +00002226 self.new_context = new_context.copy()
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002227 def __enter__(self):
2228 self.saved_context = getcontext()
2229 setcontext(self.new_context)
2230 return self.new_context
2231 def __exit__(self, t, v, tb):
2232 setcontext(self.saved_context)
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002233
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002234class Context(object):
2235 """Contains the context for a Decimal instance.
2236
2237 Contains:
2238 prec - precision (for use in rounding, division, square roots..)
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002239 rounding - rounding type. (how you round)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002240 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
Raymond Hettingerbf440692004-07-10 14:14:37 +00002241 traps - If traps[exception] = 1, then the exception is
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002242 raised when it is caused. Otherwise, a value is
2243 substituted in.
2244 flags - When an exception is caused, flags[exception] is incremented.
2245 (Whether or not the trap_enabler is set)
2246 Should be reset by user of Decimal instance.
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002247 Emin - Minimum exponent
2248 Emax - Maximum exponent
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002249 capitals - If 1, 1*10^1 is printed as 1E+1.
2250 If 0, printed as 1e1
Raymond Hettingere0f15812004-07-05 05:36:39 +00002251 _clamp - If 1, change exponents if too high (Default 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002252 """
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002253
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002254 def __init__(self, prec=None, rounding=None,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002255 traps=None, flags=None,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002256 _rounding_decision=None,
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002257 Emin=None, Emax=None,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002258 capitals=None, _clamp=0,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002259 _ignored_flags=None):
2260 if flags is None:
2261 flags = []
2262 if _ignored_flags is None:
2263 _ignored_flags = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002264 if not isinstance(flags, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002265 flags = dict([(s,s in flags) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002266 del s
Raymond Hettingerbf440692004-07-10 14:14:37 +00002267 if traps is not None and not isinstance(traps, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002268 traps = dict([(s,s in traps) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002269 del s
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002270 for name, val in locals().items():
2271 if val is None:
Raymond Hettingereb260842005-06-07 18:52:34 +00002272 setattr(self, name, _copy.copy(getattr(DefaultContext, name)))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002273 else:
2274 setattr(self, name, val)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002275 del self.self
2276
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002277 def __repr__(self):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002278 """Show the current context."""
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002279 s = []
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002280 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
2281 s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
2282 s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002283 return ', '.join(s) + ')'
2284
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002285 def clear_flags(self):
2286 """Reset all flags to zero"""
2287 for flag in self.flags:
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002288 self.flags[flag] = 0
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002289
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002290 def _shallow_copy(self):
2291 """Returns a shallow copy from self."""
Raymond Hettingerbf440692004-07-10 14:14:37 +00002292 nc = Context(self.prec, self.rounding, self.traps, self.flags,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002293 self._rounding_decision, self.Emin, self.Emax,
2294 self.capitals, self._clamp, self._ignored_flags)
2295 return nc
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002296
2297 def copy(self):
2298 """Returns a deep copy from self."""
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002299 nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
2300 self._rounding_decision, self.Emin, self.Emax,
2301 self.capitals, self._clamp, self._ignored_flags)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002302 return nc
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002303 __copy__ = copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002304
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002305 def _raise_error(self, condition, explanation = None, *args):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002306 """Handles an error
2307
2308 If the flag is in _ignored_flags, returns the default response.
2309 Otherwise, it increments the flag, then, if the corresponding
2310 trap_enabler is set, it reaises the exception. Otherwise, it returns
2311 the default value after incrementing the flag.
2312 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002313 error = _condition_map.get(condition, condition)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002314 if error in self._ignored_flags:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002315 #Don't touch the flag
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002316 return error().handle(self, *args)
2317
2318 self.flags[error] += 1
Raymond Hettingerbf440692004-07-10 14:14:37 +00002319 if not self.traps[error]:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002320 #The errors define how to handle themselves.
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002321 return condition().handle(self, *args)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002322
2323 # Errors should only be risked on copies of the context
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002324 #self._ignored_flags = []
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002325 raise error, explanation
2326
2327 def _ignore_all_flags(self):
2328 """Ignore all flags, if they are raised"""
Raymond Hettingerfed52962004-07-14 15:41:57 +00002329 return self._ignore_flags(*_signals)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002330
2331 def _ignore_flags(self, *flags):
2332 """Ignore the flags, if they are raised"""
2333 # Do not mutate-- This way, copies of a context leave the original
2334 # alone.
2335 self._ignored_flags = (self._ignored_flags + list(flags))
2336 return list(flags)
2337
2338 def _regard_flags(self, *flags):
2339 """Stop ignoring the flags, if they are raised"""
2340 if flags and isinstance(flags[0], (tuple,list)):
2341 flags = flags[0]
2342 for flag in flags:
2343 self._ignored_flags.remove(flag)
2344
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002345 def __hash__(self):
2346 """A Context cannot be hashed."""
2347 # We inherit object.__hash__, so we must deny this explicitly
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002348 raise TypeError, "Cannot hash a Context."
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002349
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002350 def Etiny(self):
2351 """Returns Etiny (= Emin - prec + 1)"""
2352 return int(self.Emin - self.prec + 1)
2353
2354 def Etop(self):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002355 """Returns maximum exponent (= Emax - prec + 1)"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002356 return int(self.Emax - self.prec + 1)
2357
2358 def _set_rounding_decision(self, type):
2359 """Sets the rounding decision.
2360
2361 Sets the rounding decision, and returns the current (previous)
2362 rounding decision. Often used like:
2363
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002364 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002365 # That so you don't change the calling context
2366 # if an error occurs in the middle (say DivisionImpossible is raised).
2367
2368 rounding = context._set_rounding_decision(NEVER_ROUND)
2369 instance = instance / Decimal(2)
2370 context._set_rounding_decision(rounding)
2371
2372 This will make it not round for that operation.
2373 """
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002374
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002375 rounding = self._rounding_decision
2376 self._rounding_decision = type
2377 return rounding
2378
2379 def _set_rounding(self, type):
2380 """Sets the rounding type.
2381
2382 Sets the rounding type, and returns the current (previous)
2383 rounding type. Often used like:
2384
2385 context = context.copy()
2386 # so you don't change the calling context
2387 # if an error occurs in the middle.
2388 rounding = context._set_rounding(ROUND_UP)
2389 val = self.__sub__(other, context=context)
2390 context._set_rounding(rounding)
2391
2392 This will make it round up for that operation.
2393 """
2394 rounding = self.rounding
2395 self.rounding= type
2396 return rounding
2397
Raymond Hettingerfed52962004-07-14 15:41:57 +00002398 def create_decimal(self, num='0'):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002399 """Creates a new Decimal instance but using self as context."""
2400 d = Decimal(num, context=self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002401 return d._fix(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002402
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002403 #Methods
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002404 def abs(self, a):
2405 """Returns the absolute value of the operand.
2406
2407 If the operand is negative, the result is the same as using the minus
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002408 operation on the operand. Otherwise, the result is the same as using
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002409 the plus operation on the operand.
2410
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002411 >>> ExtendedContext.abs(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002412 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002413 >>> ExtendedContext.abs(Decimal('-100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002414 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002415 >>> ExtendedContext.abs(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002416 Decimal("101.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002417 >>> ExtendedContext.abs(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002418 Decimal("101.5")
2419 """
2420 return a.__abs__(context=self)
2421
2422 def add(self, a, b):
2423 """Return the sum of the two operands.
2424
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002425 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002426 Decimal("19.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002427 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002428 Decimal("1.02E+4")
2429 """
2430 return a.__add__(b, context=self)
2431
2432 def _apply(self, a):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002433 return str(a._fix(self))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002434
2435 def compare(self, a, b):
2436 """Compares values numerically.
2437
2438 If the signs of the operands differ, a value representing each operand
2439 ('-1' if the operand is less than zero, '0' if the operand is zero or
2440 negative zero, or '1' if the operand is greater than zero) is used in
2441 place of that operand for the comparison instead of the actual
2442 operand.
2443
2444 The comparison is then effected by subtracting the second operand from
2445 the first and then returning a value according to the result of the
2446 subtraction: '-1' if the result is less than zero, '0' if the result is
2447 zero or negative zero, or '1' if the result is greater than zero.
2448
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002449 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002450 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002451 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002452 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002453 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002454 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002455 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002456 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002457 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002458 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002459 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002460 Decimal("-1")
2461 """
2462 return a.compare(b, context=self)
2463
2464 def divide(self, a, b):
2465 """Decimal division in a specified context.
2466
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002467 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002468 Decimal("0.333333333")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002469 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002470 Decimal("0.666666667")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002471 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002472 Decimal("2.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002473 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002474 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002475 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002476 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002477 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002478 Decimal("4.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002479 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002480 Decimal("1.20")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002481 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002482 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002483 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002484 Decimal("1000")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002485 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002486 Decimal("1.20E+6")
2487 """
2488 return a.__div__(b, context=self)
2489
2490 def divide_int(self, a, b):
2491 """Divides two numbers and returns the integer part of the result.
2492
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002493 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002494 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002495 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002496 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002497 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002498 Decimal("3")
2499 """
2500 return a.__floordiv__(b, context=self)
2501
2502 def divmod(self, a, b):
2503 return a.__divmod__(b, context=self)
2504
2505 def max(self, a,b):
2506 """max compares two values numerically and returns the maximum.
2507
2508 If either operand is a NaN then the general rules apply.
2509 Otherwise, the operands are compared as as though by the compare
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002510 operation. If they are numerically equal then the left-hand operand
2511 is chosen as the result. Otherwise the maximum (closer to positive
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002512 infinity) of the two operands is chosen as the result.
2513
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002514 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002515 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002516 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002517 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002518 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002519 Decimal("1")
2520 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
2521 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002522 """
2523 return a.max(b, context=self)
2524
2525 def min(self, a,b):
2526 """min compares two values numerically and returns the minimum.
2527
2528 If either operand is a NaN then the general rules apply.
2529 Otherwise, the operands are compared as as though by the compare
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002530 operation. If they are numerically equal then the left-hand operand
2531 is chosen as the result. Otherwise the minimum (closer to negative
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002532 infinity) of the two operands is chosen as the result.
2533
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002534 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002535 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002536 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002537 Decimal("-10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002538 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002539 Decimal("1.0")
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002540 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
2541 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002542 """
2543 return a.min(b, context=self)
2544
2545 def minus(self, a):
2546 """Minus corresponds to unary prefix minus in Python.
2547
2548 The operation is evaluated using the same rules as subtract; the
2549 operation minus(a) is calculated as subtract('0', a) where the '0'
2550 has the same exponent as the operand.
2551
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002552 >>> ExtendedContext.minus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002553 Decimal("-1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002554 >>> ExtendedContext.minus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002555 Decimal("1.3")
2556 """
2557 return a.__neg__(context=self)
2558
2559 def multiply(self, a, b):
2560 """multiply multiplies two operands.
2561
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002562 If either operand is a special value then the general rules apply.
2563 Otherwise, the operands are multiplied together ('long multiplication'),
2564 resulting in a number which may be as long as the sum of the lengths
2565 of the two operands.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002566
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002567 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002568 Decimal("3.60")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002569 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002570 Decimal("21")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002571 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002572 Decimal("0.72")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002573 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002574 Decimal("-0.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002575 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002576 Decimal("4.28135971E+11")
2577 """
2578 return a.__mul__(b, context=self)
2579
2580 def normalize(self, a):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002581 """normalize reduces an operand to its simplest form.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002582
2583 Essentially a plus operation with all trailing zeros removed from the
2584 result.
2585
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002586 >>> ExtendedContext.normalize(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002587 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002588 >>> ExtendedContext.normalize(Decimal('-2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002589 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002590 >>> ExtendedContext.normalize(Decimal('1.200'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002591 Decimal("1.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002592 >>> ExtendedContext.normalize(Decimal('-120'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002593 Decimal("-1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002594 >>> ExtendedContext.normalize(Decimal('120.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002595 Decimal("1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002596 >>> ExtendedContext.normalize(Decimal('0.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002597 Decimal("0")
2598 """
2599 return a.normalize(context=self)
2600
2601 def plus(self, a):
2602 """Plus corresponds to unary prefix plus in Python.
2603
2604 The operation is evaluated using the same rules as add; the
2605 operation plus(a) is calculated as add('0', a) where the '0'
2606 has the same exponent as the operand.
2607
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002608 >>> ExtendedContext.plus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002609 Decimal("1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002610 >>> ExtendedContext.plus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002611 Decimal("-1.3")
2612 """
2613 return a.__pos__(context=self)
2614
2615 def power(self, a, b, modulo=None):
2616 """Raises a to the power of b, to modulo if given.
2617
2618 The right-hand operand must be a whole number whose integer part (after
2619 any exponent has been applied) has no more than 9 digits and whose
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002620 fractional part (if any) is all zeros before any rounding. The operand
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002621 may be positive, negative, or zero; if negative, the absolute value of
2622 the power is used, and the left-hand operand is inverted (divided into
2623 1) before use.
2624
2625 If the increased precision needed for the intermediate calculations
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002626 exceeds the capabilities of the implementation then an Invalid operation
2627 condition is raised.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002628
2629 If, when raising to a negative power, an underflow occurs during the
2630 division into 1, the operation is not halted at that point but
2631 continues.
2632
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002633 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002634 Decimal("8")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002635 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002636 Decimal("0.125")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002637 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002638 Decimal("69.7575744")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002639 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002640 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002641 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002642 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002643 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002644 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002645 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002646 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002647 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002648 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002649 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002650 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002651 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002652 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002653 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002654 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002655 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002656 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002657 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002658 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002659 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002660 Decimal("NaN")
2661 """
2662 return a.__pow__(b, modulo, context=self)
2663
2664 def quantize(self, a, b):
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002665 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002666
2667 The coefficient of the result is derived from that of the left-hand
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002668 operand. It may be rounded using the current rounding setting (if the
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002669 exponent is being increased), multiplied by a positive power of ten (if
2670 the exponent is being decreased), or is unchanged (if the exponent is
2671 already equal to that of the right-hand operand).
2672
2673 Unlike other operations, if the length of the coefficient after the
2674 quantize operation would be greater than precision then an Invalid
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002675 operation condition is raised. This guarantees that, unless there is an
2676 error condition, the exponent of the result of a quantize is always
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002677 equal to that of the right-hand operand.
2678
2679 Also unlike other operations, quantize will never raise Underflow, even
2680 if the result is subnormal and inexact.
2681
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002682 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002683 Decimal("2.170")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002684 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002685 Decimal("2.17")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002686 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002687 Decimal("2.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002688 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002689 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002690 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002691 Decimal("0E+1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002692 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002693 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002694 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002695 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002696 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002697 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002698 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002699 Decimal("-0E+5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002700 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002701 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002702 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002703 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002704 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002705 Decimal("217.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002706 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002707 Decimal("217")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002708 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002709 Decimal("2.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002710 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002711 Decimal("2E+2")
2712 """
2713 return a.quantize(b, context=self)
2714
2715 def remainder(self, a, b):
2716 """Returns the remainder from integer division.
2717
2718 The result is the residue of the dividend after the operation of
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002719 calculating integer division as described for divide-integer, rounded to
2720 precision digits if necessary. The sign of the result, if non-zero, is
2721 the same as that of the original dividend.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002722
2723 This operation will fail under the same conditions as integer division
2724 (that is, if integer division on the same two operands would fail, the
2725 remainder cannot be calculated).
2726
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002727 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002728 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002729 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002730 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002731 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002732 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002733 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002734 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002735 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002736 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002737 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002738 Decimal("1.0")
2739 """
2740 return a.__mod__(b, context=self)
2741
2742 def remainder_near(self, a, b):
2743 """Returns to be "a - b * n", where n is the integer nearest the exact
2744 value of "x / b" (if two integers are equally near then the even one
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002745 is chosen). If the result is equal to 0 then its sign will be the
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002746 sign of a.
2747
2748 This operation will fail under the same conditions as integer division
2749 (that is, if integer division on the same two operands would fail, the
2750 remainder cannot be calculated).
2751
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002752 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002753 Decimal("-0.9")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002754 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002755 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002756 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002757 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002758 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002759 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002760 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002761 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002762 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002763 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002764 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002765 Decimal("-0.3")
2766 """
2767 return a.remainder_near(b, context=self)
2768
2769 def same_quantum(self, a, b):
2770 """Returns True if the two operands have the same exponent.
2771
2772 The result is never affected by either the sign or the coefficient of
2773 either operand.
2774
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002775 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002776 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002777 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002778 True
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002779 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002780 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002781 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002782 True
2783 """
2784 return a.same_quantum(b)
2785
2786 def sqrt(self, a):
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002787 """Returns the square root of a non-negative number to context precision.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002788
2789 If the result must be inexact, it is rounded using the round-half-even
2790 algorithm.
2791
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002792 >>> ExtendedContext.sqrt(Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002793 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002794 >>> ExtendedContext.sqrt(Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002795 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002796 >>> ExtendedContext.sqrt(Decimal('0.39'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002797 Decimal("0.624499800")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002798 >>> ExtendedContext.sqrt(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002799 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002800 >>> ExtendedContext.sqrt(Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002801 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002802 >>> ExtendedContext.sqrt(Decimal('1.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002803 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002804 >>> ExtendedContext.sqrt(Decimal('1.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002805 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002806 >>> ExtendedContext.sqrt(Decimal('7'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002807 Decimal("2.64575131")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002808 >>> ExtendedContext.sqrt(Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002809 Decimal("3.16227766")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002810 >>> ExtendedContext.prec
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002811 9
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002812 """
2813 return a.sqrt(context=self)
2814
2815 def subtract(self, a, b):
Georg Brandlf33d01d2005-08-22 19:35:18 +00002816 """Return the difference between the two operands.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002817
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002818 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002819 Decimal("0.23")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002820 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002821 Decimal("0.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002822 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002823 Decimal("-0.77")
2824 """
2825 return a.__sub__(b, context=self)
2826
2827 def to_eng_string(self, a):
2828 """Converts a number to a string, using scientific notation.
2829
2830 The operation is not affected by the context.
2831 """
2832 return a.to_eng_string(context=self)
2833
2834 def to_sci_string(self, a):
2835 """Converts a number to a string, using scientific notation.
2836
2837 The operation is not affected by the context.
2838 """
2839 return a.__str__(context=self)
2840
2841 def to_integral(self, a):
2842 """Rounds to an integer.
2843
2844 When the operand has a negative exponent, the result is the same
2845 as using the quantize() operation using the given operand as the
2846 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2847 of the operand as the precision setting, except that no flags will
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002848 be set. The rounding mode is taken from the context.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002849
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002850 >>> ExtendedContext.to_integral(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002851 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002852 >>> ExtendedContext.to_integral(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002853 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002854 >>> ExtendedContext.to_integral(Decimal('100.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002855 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002856 >>> ExtendedContext.to_integral(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002857 Decimal("102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002858 >>> ExtendedContext.to_integral(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002859 Decimal("-102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002860 >>> ExtendedContext.to_integral(Decimal('10E+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002861 Decimal("1.0E+6")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002862 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002863 Decimal("7.89E+77")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002864 >>> ExtendedContext.to_integral(Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002865 Decimal("-Infinity")
2866 """
2867 return a.to_integral(context=self)
2868
2869class _WorkRep(object):
2870 __slots__ = ('sign','int','exp')
Raymond Hettinger17931de2004-10-27 06:21:46 +00002871 # sign: 0 or 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002872 # int: int or long
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002873 # exp: None, int, or string
2874
2875 def __init__(self, value=None):
2876 if value is None:
2877 self.sign = None
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002878 self.int = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002879 self.exp = None
Raymond Hettinger17931de2004-10-27 06:21:46 +00002880 elif isinstance(value, Decimal):
2881 self.sign = value._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002882 cum = 0
Raymond Hettinger17931de2004-10-27 06:21:46 +00002883 for digit in value._int:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002884 cum = cum * 10 + digit
2885 self.int = cum
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002886 self.exp = value._exp
Raymond Hettinger17931de2004-10-27 06:21:46 +00002887 else:
2888 # assert isinstance(value, tuple)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002889 self.sign = value[0]
2890 self.int = value[1]
2891 self.exp = value[2]
2892
2893 def __repr__(self):
2894 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2895
2896 __str__ = __repr__
2897
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002898
2899
2900def _normalize(op1, op2, shouldround = 0, prec = 0):
2901 """Normalizes op1, op2 to have the same exp and length of coefficient.
2902
2903 Done during addition.
2904 """
2905 # Yes, the exponent is a long, but the difference between exponents
2906 # must be an int-- otherwise you'd get a big memory problem.
2907 numdigits = int(op1.exp - op2.exp)
2908 if numdigits < 0:
2909 numdigits = -numdigits
2910 tmp = op2
2911 other = op1
2912 else:
2913 tmp = op1
2914 other = op2
2915
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002916
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002917 if shouldround and numdigits > prec + 1:
2918 # Big difference in exponents - check the adjusted exponents
2919 tmp_len = len(str(tmp.int))
2920 other_len = len(str(other.int))
2921 if numdigits > (other_len + prec + 1 - tmp_len):
2922 # If the difference in adjusted exps is > prec+1, we know
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002923 # other is insignificant, so might as well put a 1 after the precision.
2924 # (since this is only for addition.) Also stops use of massive longs.
2925
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002926 extend = prec + 2 - tmp_len
2927 if extend <= 0:
2928 extend = 1
2929 tmp.int *= 10 ** extend
2930 tmp.exp -= extend
2931 other.int = 1
2932 other.exp = tmp.exp
2933 return op1, op2
2934
2935 tmp.int *= 10 ** numdigits
2936 tmp.exp -= numdigits
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002937 return op1, op2
2938
2939def _adjust_coefficients(op1, op2):
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002940 """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002941
2942 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2943
2944 Used on _WorkRep instances during division.
2945 """
2946 adjust = 0
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002947 #If op1 is smaller, make it larger
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002948 while op2.int > op1.int:
2949 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002950 op1.exp -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002951 adjust += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002952
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002953 #If op2 is too small, make it larger
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002954 while op1.int >= (10 * op2.int):
2955 op2.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002956 op2.exp -= 1
2957 adjust -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002958
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002959 return op1, op2, adjust
2960
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002961##### Helper Functions ########################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002962
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002963def _convert_other(other):
2964 """Convert other to Decimal.
2965
2966 Verifies that it's ok to use in an implicit construction.
2967 """
2968 if isinstance(other, Decimal):
2969 return other
2970 if isinstance(other, (int, long)):
2971 return Decimal(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002972 return NotImplemented
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002973
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002974_infinity_map = {
2975 'inf' : 1,
2976 'infinity' : 1,
2977 '+inf' : 1,
2978 '+infinity' : 1,
2979 '-inf' : -1,
2980 '-infinity' : -1
2981}
2982
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002983def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002984 """Determines whether a string or float is infinity.
2985
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002986 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002987 """
2988 num = str(num).lower()
2989 return _infinity_map.get(num, 0)
2990
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002991def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002992 """Determines whether a string or float is NaN
2993
2994 (1, sign, diagnostic info as string) => NaN
2995 (2, sign, diagnostic info as string) => sNaN
2996 0 => not a NaN
2997 """
2998 num = str(num).lower()
2999 if not num:
3000 return 0
3001
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003002 #get the sign, get rid of trailing [+-]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003003 sign = 0
3004 if num[0] == '+':
3005 num = num[1:]
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003006 elif num[0] == '-': #elif avoids '+-nan'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003007 num = num[1:]
3008 sign = 1
3009
3010 if num.startswith('nan'):
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003011 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003012 return 0
3013 return (1, sign, num[3:].lstrip('0'))
3014 if num.startswith('snan'):
3015 if len(num) > 4 and not num[4:].isdigit():
3016 return 0
3017 return (2, sign, num[4:].lstrip('0'))
3018 return 0
3019
3020
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003021##### Setup Specific Contexts ################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003022
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003023# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00003024# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003025
3026DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003027 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003028 traps=[DivisionByZero, Overflow, InvalidOperation],
3029 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003030 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00003031 Emax=999999999,
3032 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00003033 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003034)
3035
3036# Pre-made alternate contexts offered by the specification
3037# Don't change these; the user should be able to select these
3038# contexts and be able to reproduce results from other implementations
3039# of the spec.
3040
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003041BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003042 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003043 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
3044 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003045)
3046
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003047ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003048 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003049 traps=[],
3050 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003051)
3052
3053
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003054##### Useful Constants (internal use only) ####################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003055
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003056#Reusable defaults
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003057Inf = Decimal('Inf')
3058negInf = Decimal('-Inf')
3059
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003060#Infsign[sign] is infinity w/ that sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003061Infsign = (Inf, negInf)
3062
3063NaN = Decimal('NaN')
3064
3065
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003066##### crud for parsing strings #################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003067import re
3068
3069# There's an optional sign at the start, and an optional exponent
3070# at the end. The exponent has an optional sign and at least one
3071# digit. In between, must have either at least one digit followed
3072# by an optional fraction, or a decimal point followed by at least
3073# one digit. Yuck.
3074
3075_parser = re.compile(r"""
3076# \s*
3077 (?P<sign>[-+])?
3078 (
3079 (?P<int>\d+) (\. (?P<frac>\d*))?
3080 |
3081 \. (?P<onlyfrac>\d+)
3082 )
3083 ([eE](?P<exp>[-+]? \d+))?
3084# \s*
3085 $
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003086""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003087
3088del re
3089
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003090# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003091
3092def _string2exact(s):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003093 m = _parser(s)
3094 if m is None:
3095 raise ValueError("invalid literal for Decimal: %r" % s)
3096
3097 if m.group('sign') == "-":
3098 sign = 1
3099 else:
3100 sign = 0
3101
3102 exp = m.group('exp')
3103 if exp is None:
3104 exp = 0
3105 else:
3106 exp = int(exp)
3107
3108 intpart = m.group('int')
3109 if intpart is None:
3110 intpart = ""
3111 fracpart = m.group('onlyfrac')
3112 else:
3113 fracpart = m.group('frac')
3114 if fracpart is None:
3115 fracpart = ""
3116
3117 exp -= len(fracpart)
3118
3119 mantissa = intpart + fracpart
3120 tmp = map(int, mantissa)
3121 backup = tmp
3122 while tmp and tmp[0] == 0:
3123 del tmp[0]
3124
3125 # It's a zero
3126 if not tmp:
3127 if backup:
3128 return (sign, tuple(backup), exp)
3129 return (sign, (0,), exp)
3130 mantissa = tuple(tmp)
3131
3132 return (sign, mantissa, exp)
3133
3134
3135if __name__ == '__main__':
3136 import doctest, sys
3137 doctest.testmod(sys.modules[__name__])