blob: a5176e6fe6c43d51e645685c688a430694b50b88 [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
Nick Coghlan8b6999b2006-08-31 12:00:43 +0000133 # helper for context management
134 'ContextManager',
135
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000136 # Functions for manipulating contexts
Nick Coghlan8b6999b2006-08-31 12:00:43 +0000137 'setcontext', 'getcontext', 'localcontext'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000138]
139
Raymond Hettingereb260842005-06-07 18:52:34 +0000140import copy as _copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000141
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000142#Rounding
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000143ROUND_DOWN = 'ROUND_DOWN'
144ROUND_HALF_UP = 'ROUND_HALF_UP'
145ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
146ROUND_CEILING = 'ROUND_CEILING'
147ROUND_FLOOR = 'ROUND_FLOOR'
148ROUND_UP = 'ROUND_UP'
149ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000150
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000151#Rounding decision (not part of the public API)
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000152NEVER_ROUND = 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY
153ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000154
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000155#Errors
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000156
157class DecimalException(ArithmeticError):
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000158 """Base exception class.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000159
160 Used exceptions derive from this.
161 If an exception derives from another exception besides this (such as
162 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
163 called if the others are present. This isn't actually used for
164 anything, though.
165
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000166 handle -- Called when context._raise_error is called and the
167 trap_enabler is set. First argument is self, second is the
168 context. More arguments can be given, those being after
169 the explanation in _raise_error (For example,
170 context._raise_error(NewError, '(-x)!', self._sign) would
171 call NewError().handle(context, self._sign).)
172
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000173 To define a new exception, it should be sufficient to have it derive
174 from DecimalException.
175 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000176 def handle(self, context, *args):
177 pass
178
179
180class Clamped(DecimalException):
181 """Exponent of a 0 changed to fit bounds.
182
183 This occurs and signals clamped if the exponent of a result has been
184 altered in order to fit the constraints of a specific concrete
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000185 representation. This may occur when the exponent of a zero result would
186 be outside the bounds of a representation, or when a large normal
187 number would have an encoded exponent that cannot be represented. In
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000188 this latter case, the exponent is reduced to fit and the corresponding
189 number of zero digits are appended to the coefficient ("fold-down").
190 """
191
192
193class InvalidOperation(DecimalException):
194 """An invalid operation was performed.
195
196 Various bad things cause this:
197
198 Something creates a signaling NaN
199 -INF + INF
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000200 0 * (+-)INF
201 (+-)INF / (+-)INF
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000202 x % 0
203 (+-)INF % x
204 x._rescale( non-integer )
205 sqrt(-x) , x > 0
206 0 ** 0
207 x ** (non-integer)
208 x ** (+-)INF
209 An operand is invalid
210 """
211 def handle(self, context, *args):
212 if args:
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000213 if args[0] == 1: #sNaN, must drop 's' but keep diagnostics
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000214 return Decimal( (args[1]._sign, args[1]._int, 'n') )
215 return NaN
216
217class ConversionSyntax(InvalidOperation):
218 """Trying to convert badly formed string.
219
220 This occurs and signals invalid-operation if an string is being
221 converted to a number and it does not conform to the numeric string
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000222 syntax. The result is [0,qNaN].
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000223 """
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000224
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000225 def handle(self, context, *args):
226 return (0, (0,), 'n') #Passed to something which uses a tuple.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000227
228class DivisionByZero(DecimalException, ZeroDivisionError):
229 """Division by 0.
230
231 This occurs and signals division-by-zero if division of a finite number
232 by zero was attempted (during a divide-integer or divide operation, or a
233 power operation with negative right-hand operand), and the dividend was
234 not zero.
235
236 The result of the operation is [sign,inf], where sign is the exclusive
237 or of the signs of the operands for divide, or is 1 for an odd power of
238 -0, for power.
239 """
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000240
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000241 def handle(self, context, sign, double = None, *args):
242 if double is not None:
243 return (Infsign[sign],)*2
244 return Infsign[sign]
245
246class DivisionImpossible(InvalidOperation):
247 """Cannot perform the division adequately.
248
249 This occurs and signals invalid-operation if the integer result of a
250 divide-integer or remainder operation had too many digits (would be
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000251 longer than precision). The result is [0,qNaN].
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000252 """
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000253
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000254 def handle(self, context, *args):
255 return (NaN, NaN)
256
257class DivisionUndefined(InvalidOperation, ZeroDivisionError):
258 """Undefined result of division.
259
260 This occurs and signals invalid-operation if division by zero was
261 attempted (during a divide-integer, divide, or remainder operation), and
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000262 the dividend is also zero. The result is [0,qNaN].
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000263 """
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000264
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000265 def handle(self, context, tup=None, *args):
266 if tup is not None:
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000267 return (NaN, NaN) #for 0 %0, 0 // 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000268 return NaN
269
270class Inexact(DecimalException):
271 """Had to round, losing information.
272
273 This occurs and signals inexact whenever the result of an operation is
274 not exact (that is, it needed to be rounded and any discarded digits
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000275 were non-zero), or if an overflow or underflow condition occurs. The
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000276 result in all cases is unchanged.
277
278 The inexact signal may be tested (or trapped) to determine if a given
279 operation (or sequence of operations) was inexact.
280 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000281 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000282
283class InvalidContext(InvalidOperation):
284 """Invalid context. Unknown rounding, for example.
285
286 This occurs and signals invalid-operation if an invalid context was
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000287 detected during an operation. This can occur if contexts are not checked
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000288 on creation and either the precision exceeds the capability of the
289 underlying concrete representation or an unknown or unsupported rounding
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000290 was specified. These aspects of the context need only be checked when
291 the values are required to be used. The result is [0,qNaN].
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000292 """
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000293
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000294 def handle(self, context, *args):
295 return NaN
296
297class Rounded(DecimalException):
298 """Number got rounded (not necessarily changed during rounding).
299
300 This occurs and signals rounded whenever the result of an operation is
301 rounded (that is, some zero or non-zero digits were discarded from the
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000302 coefficient), or if an overflow or underflow condition occurs. The
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000303 result in all cases is unchanged.
304
305 The rounded signal may be tested (or trapped) to determine if a given
306 operation (or sequence of operations) caused a loss of precision.
307 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000308 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000309
310class Subnormal(DecimalException):
311 """Exponent < Emin before rounding.
312
313 This occurs and signals subnormal whenever the result of a conversion or
314 operation is subnormal (that is, its adjusted exponent is less than
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000315 Emin, before any rounding). The result in all cases is unchanged.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000316
317 The subnormal signal may be tested (or trapped) to determine if a given
318 or operation (or sequence of operations) yielded a subnormal result.
319 """
320 pass
321
322class Overflow(Inexact, Rounded):
323 """Numerical overflow.
324
325 This occurs and signals overflow if the adjusted exponent of a result
326 (from a conversion or from an operation that is not an attempt to divide
327 by zero), after rounding, would be greater than the largest value that
328 can be handled by the implementation (the value Emax).
329
330 The result depends on the rounding mode:
331
332 For round-half-up and round-half-even (and for round-half-down and
333 round-up, if implemented), the result of the operation is [sign,inf],
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000334 where sign is the sign of the intermediate result. For round-down, the
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000335 result is the largest finite number that can be represented in the
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000336 current precision, with the sign of the intermediate result. For
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000337 round-ceiling, the result is the same as for round-down if the sign of
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000338 the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000339 the result is the same as for round-down if the sign of the intermediate
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000340 result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000341 will also be raised.
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000342 """
343
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000344 def handle(self, context, sign, *args):
345 if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
346 ROUND_HALF_DOWN, ROUND_UP):
347 return Infsign[sign]
348 if sign == 0:
349 if context.rounding == ROUND_CEILING:
350 return Infsign[sign]
351 return Decimal((sign, (9,)*context.prec,
352 context.Emax-context.prec+1))
353 if sign == 1:
354 if context.rounding == ROUND_FLOOR:
355 return Infsign[sign]
356 return Decimal( (sign, (9,)*context.prec,
357 context.Emax-context.prec+1))
358
359
360class Underflow(Inexact, Rounded, Subnormal):
361 """Numerical underflow with result rounded to 0.
362
363 This occurs and signals underflow if a result is inexact and the
364 adjusted exponent of the result would be smaller (more negative) than
365 the smallest value that can be handled by the implementation (the value
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000366 Emin). That is, the result is both inexact and subnormal.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000367
368 The result after an underflow will be a subnormal number rounded, if
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000369 necessary, so that its exponent is not less than Etiny. This may result
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000370 in 0 with the sign of the intermediate result and an exponent of Etiny.
371
372 In all cases, Inexact, Rounded, and Subnormal will also be raised.
373 """
374
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000375# List of public traps and flags
Raymond Hettingerfed52962004-07-14 15:41:57 +0000376_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000377 Underflow, InvalidOperation, Subnormal]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000378
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000379# Map conditions (per the spec) to signals
380_condition_map = {ConversionSyntax:InvalidOperation,
381 DivisionImpossible:InvalidOperation,
382 DivisionUndefined:InvalidOperation,
383 InvalidContext:InvalidOperation}
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000384
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000385##### Context Functions #######################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000386
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000387# The getcontext() and setcontext() function manage access to a thread-local
388# current context. Py2.4 offers direct support for thread locals. If that
389# is not available, use threading.currentThread() which is slower but will
Raymond Hettinger7e71fa52004-12-18 19:07:19 +0000390# work for older Pythons. If threads are not part of the build, create a
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000391# mock threading object with threading.local() returning the module namespace.
Raymond Hettinger7e71fa52004-12-18 19:07:19 +0000392
393try:
394 import threading
395except ImportError:
396 # Python was compiled without threads; create a mock object instead
397 import sys
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000398 class MockThreading:
Raymond Hettinger7e71fa52004-12-18 19:07:19 +0000399 def local(self, sys=sys):
400 return sys.modules[__name__]
401 threading = MockThreading()
402 del sys, MockThreading
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000403
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000404try:
405 threading.local
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000406
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000407except AttributeError:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000408
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000409 #To fix reloading, force it to create a new context
410 #Old contexts have different exceptions in their dicts, making problems.
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000411 if hasattr(threading.currentThread(), '__decimal_context__'):
412 del threading.currentThread().__decimal_context__
413
414 def setcontext(context):
415 """Set this thread's context to context."""
416 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000417 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000418 context.clear_flags()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000419 threading.currentThread().__decimal_context__ = context
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000420
421 def getcontext():
422 """Returns this thread's context.
423
424 If this thread does not yet have a context, returns
425 a new context and sets this thread's context.
426 New contexts are copies of DefaultContext.
427 """
428 try:
429 return threading.currentThread().__decimal_context__
430 except AttributeError:
431 context = Context()
432 threading.currentThread().__decimal_context__ = context
433 return context
434
435else:
436
437 local = threading.local()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000438 if hasattr(local, '__decimal_context__'):
439 del local.__decimal_context__
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000440
441 def getcontext(_local=local):
442 """Returns this thread's context.
443
444 If this thread does not yet have a context, returns
445 a new context and sets this thread's context.
446 New contexts are copies of DefaultContext.
447 """
448 try:
449 return _local.__decimal_context__
450 except AttributeError:
451 context = Context()
452 _local.__decimal_context__ = context
453 return context
454
455 def setcontext(context, _local=local):
456 """Set this thread's context to context."""
457 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000458 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000459 context.clear_flags()
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000460 _local.__decimal_context__ = context
461
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000462 del threading, local # Don't contaminate the namespace
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000463
Nick Coghlan8b6999b2006-08-31 12:00:43 +0000464def localcontext(ctx=None):
465 """Return a context manager for a copy of the supplied context
466
467 Uses a copy of the current context if no context is specified
468 The returned context manager creates a local decimal context
469 in a with statement:
470 def sin(x):
471 with localcontext() as ctx:
472 ctx.prec += 2
473 # Rest of sin calculation algorithm
474 # uses a precision 2 greater than normal
475 return +s # Convert result to normal precision
476
477 def sin(x):
478 with localcontext(ExtendedContext):
479 # Rest of sin calculation algorithm
480 # uses the Extended Context from the
481 # General Decimal Arithmetic Specification
482 return +s # Convert result to normal context
483
484 """
485 # The below can't be included in the docstring until Python 2.6
486 # as the doctest module doesn't understand __future__ statements
487 """
488 >>> from __future__ import with_statement
489 >>> print getcontext().prec
490 28
491 >>> with localcontext():
492 ... ctx = getcontext()
493 ... ctx.prec() += 2
494 ... print ctx.prec
495 ...
496 30
497 >>> with localcontext(ExtendedContext):
498 ... print getcontext().prec
499 ...
500 9
501 >>> print getcontext().prec
502 28
503 """
504 if ctx is None: ctx = getcontext().copy()
505 return ContextManager(ctx.copy())
506
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000507
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000508##### Decimal class ###########################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000509
510class Decimal(object):
511 """Floating point class for decimal arithmetic."""
512
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000513 __slots__ = ('_exp','_int','_sign', '_is_special')
514 # Generally, the value of the Decimal instance is given by
515 # (-1)**_sign * _int * 10**_exp
516 # Special values are signified by _is_special == True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000517
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000518 # We're immutable, so use __new__ not __init__
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000519 def __new__(cls, value="0", context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000520 """Create a decimal point instance.
521
522 >>> Decimal('3.14') # string input
523 Decimal("3.14")
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000524 >>> Decimal((0, (3, 1, 4), -2)) # tuple input (sign, digit_tuple, exponent)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000525 Decimal("3.14")
526 >>> Decimal(314) # int or long
527 Decimal("314")
528 >>> Decimal(Decimal(314)) # another decimal instance
529 Decimal("314")
530 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000531
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000532 self = object.__new__(cls)
533 self._is_special = False
534
535 # From an internal working value
536 if isinstance(value, _WorkRep):
Raymond Hettinger17931de2004-10-27 06:21:46 +0000537 self._sign = value.sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000538 self._int = tuple(map(int, str(value.int)))
539 self._exp = int(value.exp)
540 return self
541
542 # From another decimal
543 if isinstance(value, Decimal):
544 self._exp = value._exp
545 self._sign = value._sign
546 self._int = value._int
547 self._is_special = value._is_special
548 return self
549
550 # From an integer
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000551 if isinstance(value, (int,long)):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000552 if value >= 0:
553 self._sign = 0
554 else:
555 self._sign = 1
556 self._exp = 0
557 self._int = tuple(map(int, str(abs(value))))
558 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000559
560 # tuple/list conversion (possibly from as_tuple())
561 if isinstance(value, (list,tuple)):
562 if len(value) != 3:
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000563 raise ValueError, 'Invalid arguments'
Raymond Hettingerdbecd932005-02-06 06:57:08 +0000564 if value[0] not in (0,1):
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000565 raise ValueError, 'Invalid sign'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000566 for digit in value[1]:
567 if not isinstance(digit, (int,long)) or digit < 0:
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000568 raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000569
570 self._sign = value[0]
571 self._int = tuple(value[1])
572 if value[2] in ('F','n','N'):
573 self._exp = value[2]
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000574 self._is_special = True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000575 else:
576 self._exp = int(value[2])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000577 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000578
Raymond Hettingerbf440692004-07-10 14:14:37 +0000579 if isinstance(value, float):
580 raise TypeError("Cannot convert float to Decimal. " +
581 "First convert the float to a string")
582
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000583 # Other argument types may require the context during interpretation
584 if context is None:
585 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000586
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000587 # From a string
588 # REs insist on real strings, so we can too.
589 if isinstance(value, basestring):
590 if _isinfinity(value):
591 self._exp = 'F'
592 self._int = (0,)
593 self._is_special = True
594 if _isinfinity(value) == 1:
595 self._sign = 0
596 else:
597 self._sign = 1
598 return self
599 if _isnan(value):
600 sig, sign, diag = _isnan(value)
601 self._is_special = True
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000602 if len(diag) > context.prec: #Diagnostic info too long
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000603 self._sign, self._int, self._exp = \
604 context._raise_error(ConversionSyntax)
605 return self
606 if sig == 1:
607 self._exp = 'n' #qNaN
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000608 else: #sig == 2
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000609 self._exp = 'N' #sNaN
610 self._sign = sign
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000611 self._int = tuple(map(int, diag)) #Diagnostic info
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000612 return self
613 try:
614 self._sign, self._int, self._exp = _string2exact(value)
615 except ValueError:
616 self._is_special = True
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000617 self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000618 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000619
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000620 raise TypeError("Cannot convert %r to Decimal" % value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000621
622 def _isnan(self):
623 """Returns whether the number is not actually one.
624
625 0 if a number
626 1 if NaN
627 2 if sNaN
628 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000629 if self._is_special:
630 exp = self._exp
631 if exp == 'n':
632 return 1
633 elif exp == 'N':
634 return 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000635 return 0
636
637 def _isinfinity(self):
638 """Returns whether the number is infinite
639
640 0 if finite or not a number
641 1 if +INF
642 -1 if -INF
643 """
644 if self._exp == 'F':
645 if self._sign:
646 return -1
647 return 1
648 return 0
649
650 def _check_nans(self, other = None, context=None):
651 """Returns whether the number is not actually one.
652
653 if self, other are sNaN, signal
654 if self, other are NaN return nan
655 return 0
656
657 Done before operations.
658 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000659
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000660 self_is_nan = self._isnan()
661 if other is None:
662 other_is_nan = False
663 else:
664 other_is_nan = other._isnan()
665
666 if self_is_nan or other_is_nan:
667 if context is None:
668 context = getcontext()
669
670 if self_is_nan == 2:
671 return context._raise_error(InvalidOperation, 'sNaN',
672 1, self)
673 if other_is_nan == 2:
674 return context._raise_error(InvalidOperation, 'sNaN',
675 1, other)
676 if self_is_nan:
677 return self
678
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000679 return other
680 return 0
681
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000682 def __nonzero__(self):
683 """Is the number non-zero?
684
685 0 if self == 0
686 1 if self != 0
687 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000688 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000689 return 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000690 return sum(self._int) != 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000691
692 def __cmp__(self, other, context=None):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000693 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +0000694 if other is NotImplemented:
695 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000696
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000697 if self._is_special or other._is_special:
698 ans = self._check_nans(other, context)
699 if ans:
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000700 return 1 # Comparison involving NaN's always reports self > other
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000701
702 # INF = INF
703 return cmp(self._isinfinity(), other._isinfinity())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000704
705 if not self and not other:
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000706 return 0 #If both 0, sign comparison isn't certain.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000707
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000708 #If different signs, neg one is less
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000709 if other._sign < self._sign:
710 return -1
711 if self._sign < other._sign:
712 return 1
713
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000714 self_adjusted = self.adjusted()
715 other_adjusted = other.adjusted()
716 if self_adjusted == other_adjusted and \
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000717 self._int + (0,)*(self._exp - other._exp) == \
718 other._int + (0,)*(other._exp - self._exp):
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000719 return 0 #equal, except in precision. ([0]*(-x) = [])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000720 elif self_adjusted > other_adjusted and self._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000721 return (-1)**self._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000722 elif self_adjusted < other_adjusted and other._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000723 return -((-1)**self._sign)
724
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000725 # Need to round, so make sure we have a valid context
726 if context is None:
727 context = getcontext()
728
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000729 context = context._shallow_copy()
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000730 rounding = context._set_rounding(ROUND_UP) #round away from 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000731
732 flags = context._ignore_all_flags()
733 res = self.__sub__(other, context=context)
734
735 context._regard_flags(*flags)
736
737 context.rounding = rounding
738
739 if not res:
740 return 0
741 elif res._sign:
742 return -1
743 return 1
744
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000745 def __eq__(self, other):
746 if not isinstance(other, (Decimal, int, long)):
Raymond Hettinger267b8682005-03-27 10:47:39 +0000747 return NotImplemented
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000748 return self.__cmp__(other) == 0
749
750 def __ne__(self, other):
751 if not isinstance(other, (Decimal, int, long)):
Raymond Hettinger267b8682005-03-27 10:47:39 +0000752 return NotImplemented
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000753 return self.__cmp__(other) != 0
754
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000755 def compare(self, other, context=None):
756 """Compares one to another.
757
758 -1 => a < b
759 0 => a = b
760 1 => a > b
761 NaN => one is NaN
762 Like __cmp__, but returns Decimal instances.
763 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000764 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +0000765 if other is NotImplemented:
766 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000767
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000768 #compare(NaN, NaN) = NaN
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000769 if (self._is_special or other and other._is_special):
770 ans = self._check_nans(other, context)
771 if ans:
772 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000773
774 return Decimal(self.__cmp__(other, context))
775
776 def __hash__(self):
777 """x.__hash__() <==> hash(x)"""
778 # Decimal integers must hash the same as the ints
779 # Non-integer decimals are normalized and hashed as strings
Georg Brandl1fb9f522006-05-11 19:57:09 +0000780 # Normalization assures that hash(100E-1) == hash(10)
Raymond Hettingerbea3f6f2005-03-15 04:59:17 +0000781 if self._is_special:
782 if self._isnan():
783 raise TypeError('Cannot hash a NaN value.')
784 return hash(str(self))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000785 i = int(self)
786 if self == Decimal(i):
787 return hash(i)
788 assert self.__nonzero__() # '-0' handled by integer case
789 return hash(str(self.normalize()))
790
791 def as_tuple(self):
792 """Represents the number as a triple tuple.
793
794 To show the internals exactly as they are.
795 """
796 return (self._sign, self._int, self._exp)
797
798 def __repr__(self):
799 """Represents the number as an instance of Decimal."""
800 # Invariant: eval(repr(d)) == d
801 return 'Decimal("%s")' % str(self)
802
803 def __str__(self, eng = 0, context=None):
804 """Return string representation of the number in scientific notation.
805
806 Captures all of the information in the underlying representation.
807 """
808
Raymond Hettingere5a0a962005-06-20 09:49:42 +0000809 if self._is_special:
810 if self._isnan():
811 minus = '-'*self._sign
812 if self._int == (0,):
813 info = ''
814 else:
815 info = ''.join(map(str, self._int))
816 if self._isnan() == 2:
817 return minus + 'sNaN' + info
818 return minus + 'NaN' + info
819 if self._isinfinity():
820 minus = '-'*self._sign
821 return minus + 'Infinity'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000822
823 if context is None:
824 context = getcontext()
825
826 tmp = map(str, self._int)
827 numdigits = len(self._int)
828 leftdigits = self._exp + numdigits
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000829 if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
830 if self._exp < 0 and self._exp >= -6: #short, no need for e/E
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000831 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
832 return s
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000833 #exp is closest mult. of 3 >= self._exp
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000834 exp = ((self._exp - 1)// 3 + 1) * 3
835 if exp != self._exp:
836 s = '0.'+'0'*(exp - self._exp)
837 else:
838 s = '0'
839 if exp != 0:
840 if context.capitals:
841 s += 'E'
842 else:
843 s += 'e'
844 if exp > 0:
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000845 s += '+' #0.0e+3, not 0.0e3
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000846 s += str(exp)
847 s = '-'*self._sign + s
848 return s
849 if eng:
850 dotplace = (leftdigits-1)%3+1
851 adjexp = leftdigits -1 - (leftdigits-1)%3
852 else:
853 adjexp = leftdigits-1
854 dotplace = 1
855 if self._exp == 0:
856 pass
857 elif self._exp < 0 and adjexp >= 0:
858 tmp.insert(leftdigits, '.')
859 elif self._exp < 0 and adjexp >= -6:
860 tmp[0:0] = ['0'] * int(-leftdigits)
861 tmp.insert(0, '0.')
862 else:
863 if numdigits > dotplace:
864 tmp.insert(dotplace, '.')
865 elif numdigits < dotplace:
866 tmp.extend(['0']*(dotplace-numdigits))
867 if adjexp:
868 if not context.capitals:
869 tmp.append('e')
870 else:
871 tmp.append('E')
872 if adjexp > 0:
873 tmp.append('+')
874 tmp.append(str(adjexp))
875 if eng:
876 while tmp[0:1] == ['0']:
877 tmp[0:1] = []
878 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
879 tmp[0:0] = ['0']
880 if self._sign:
881 tmp.insert(0, '-')
882
883 return ''.join(tmp)
884
885 def to_eng_string(self, context=None):
886 """Convert to engineering-type string.
887
888 Engineering notation has an exponent which is a multiple of 3, so there
889 are up to 3 digits left of the decimal place.
890
891 Same rules for when in exponential and when as a value as in __str__.
892 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000893 return self.__str__(eng=1, context=context)
894
895 def __neg__(self, context=None):
896 """Returns a copy with the sign switched.
897
898 Rounds, if it has reason.
899 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000900 if self._is_special:
901 ans = self._check_nans(context=context)
902 if ans:
903 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000904
905 if not self:
906 # -Decimal('0') is Decimal('0'), not Decimal('-0')
907 sign = 0
908 elif self._sign:
909 sign = 0
910 else:
911 sign = 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000912
913 if context is None:
914 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000915 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000916 return Decimal((sign, self._int, self._exp))._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000917 return Decimal( (sign, self._int, self._exp))
918
919 def __pos__(self, context=None):
920 """Returns a copy, unless it is a sNaN.
921
922 Rounds the number (if more then precision digits)
923 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000924 if self._is_special:
925 ans = self._check_nans(context=context)
926 if ans:
927 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000928
929 sign = self._sign
930 if not self:
931 # + (-0) = 0
932 sign = 0
933
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000934 if context is None:
935 context = getcontext()
936
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000937 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000938 ans = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000939 else:
940 ans = Decimal(self)
941 ans._sign = sign
942 return ans
943
944 def __abs__(self, round=1, context=None):
945 """Returns the absolute value of self.
946
947 If the second argument is 0, do not round.
948 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000949 if self._is_special:
950 ans = self._check_nans(context=context)
951 if ans:
952 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000953
954 if not round:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000955 if context is None:
956 context = getcontext()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000957 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000958 context._set_rounding_decision(NEVER_ROUND)
959
960 if self._sign:
961 ans = self.__neg__(context=context)
962 else:
963 ans = self.__pos__(context=context)
964
965 return ans
966
967 def __add__(self, other, context=None):
968 """Returns self + other.
969
970 -INF + INF (or the reverse) cause InvalidOperation errors.
971 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000972 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +0000973 if other is NotImplemented:
974 return other
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000975
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000976 if context is None:
977 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000978
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000979 if self._is_special or other._is_special:
980 ans = self._check_nans(other, context)
981 if ans:
982 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000983
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000984 if self._isinfinity():
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000985 #If both INF, same sign => same as both, opposite => error.
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000986 if self._sign != other._sign and other._isinfinity():
987 return context._raise_error(InvalidOperation, '-INF + INF')
988 return Decimal(self)
989 if other._isinfinity():
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000990 return Decimal(other) #Can't both be infinity here
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000991
992 shouldround = context._rounding_decision == ALWAYS_ROUND
993
994 exp = min(self._exp, other._exp)
995 negativezero = 0
996 if context.rounding == ROUND_FLOOR and self._sign != other._sign:
Martin v. Löwiscfe31282006-07-19 17:18:32 +0000997 #If the answer is 0, the sign should be negative, in this case.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000998 negativezero = 1
999
1000 if not self and not other:
1001 sign = min(self._sign, other._sign)
1002 if negativezero:
1003 sign = 1
1004 return Decimal( (sign, (0,), exp))
1005 if not self:
Facundo Batista99b55482004-10-26 23:38:46 +00001006 exp = max(exp, other._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001007 ans = other._rescale(exp, watchexp=0, context=context)
1008 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001009 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001010 return ans
1011 if not other:
Facundo Batista99b55482004-10-26 23:38:46 +00001012 exp = max(exp, self._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001013 ans = self._rescale(exp, watchexp=0, context=context)
1014 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001015 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001016 return ans
1017
1018 op1 = _WorkRep(self)
1019 op2 = _WorkRep(other)
1020 op1, op2 = _normalize(op1, op2, shouldround, context.prec)
1021
1022 result = _WorkRep()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001023 if op1.sign != op2.sign:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001024 # Equal and opposite
Raymond Hettinger17931de2004-10-27 06:21:46 +00001025 if op1.int == op2.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001026 if exp < context.Etiny():
1027 exp = context.Etiny()
1028 context._raise_error(Clamped)
1029 return Decimal((negativezero, (0,), exp))
Raymond Hettinger17931de2004-10-27 06:21:46 +00001030 if op1.int < op2.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001031 op1, op2 = op2, op1
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001032 #OK, now abs(op1) > abs(op2)
Raymond Hettinger17931de2004-10-27 06:21:46 +00001033 if op1.sign == 1:
1034 result.sign = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001035 op1.sign, op2.sign = op2.sign, op1.sign
1036 else:
Raymond Hettinger17931de2004-10-27 06:21:46 +00001037 result.sign = 0
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001038 #So we know the sign, and op1 > 0.
Raymond Hettinger17931de2004-10-27 06:21:46 +00001039 elif op1.sign == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001040 result.sign = 1
Raymond Hettinger17931de2004-10-27 06:21:46 +00001041 op1.sign, op2.sign = (0, 0)
1042 else:
1043 result.sign = 0
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001044 #Now, op1 > abs(op2) > 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001045
Raymond Hettinger17931de2004-10-27 06:21:46 +00001046 if op2.sign == 0:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001047 result.int = op1.int + op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001048 else:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001049 result.int = op1.int - op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001050
1051 result.exp = op1.exp
1052 ans = Decimal(result)
1053 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001054 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001055 return ans
1056
1057 __radd__ = __add__
1058
1059 def __sub__(self, other, context=None):
1060 """Return self + (-other)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001061 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001062 if other is NotImplemented:
1063 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001064
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001065 if self._is_special or other._is_special:
1066 ans = self._check_nans(other, context=context)
1067 if ans:
1068 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001069
1070 # -Decimal(0) = Decimal(0), which we don't want since
1071 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
1072 # so we change the sign directly to a copy
1073 tmp = Decimal(other)
1074 tmp._sign = 1-tmp._sign
1075
1076 return self.__add__(tmp, context=context)
1077
1078 def __rsub__(self, other, context=None):
1079 """Return other + (-self)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001080 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001081 if other is NotImplemented:
1082 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001083
1084 tmp = Decimal(self)
1085 tmp._sign = 1 - tmp._sign
1086 return other.__add__(tmp, context=context)
1087
1088 def _increment(self, round=1, context=None):
1089 """Special case of add, adding 1eExponent
1090
1091 Since it is common, (rounding, for example) this adds
1092 (sign)*one E self._exp to the number more efficiently than add.
1093
1094 For example:
1095 Decimal('5.624e10')._increment() == Decimal('5.625e10')
1096 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001097 if self._is_special:
1098 ans = self._check_nans(context=context)
1099 if ans:
1100 return ans
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001101
1102 return Decimal(self) # Must be infinite, and incrementing makes no difference
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001103
1104 L = list(self._int)
1105 L[-1] += 1
1106 spot = len(L)-1
1107 while L[spot] == 10:
1108 L[spot] = 0
1109 if spot == 0:
1110 L[0:0] = [1]
1111 break
1112 L[spot-1] += 1
1113 spot -= 1
1114 ans = Decimal((self._sign, L, self._exp))
1115
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001116 if context is None:
1117 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001118 if round and context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001119 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001120 return ans
1121
1122 def __mul__(self, other, context=None):
1123 """Return self * other.
1124
1125 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1126 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001127 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001128 if other is NotImplemented:
1129 return other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001130
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001131 if context is None:
1132 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001133
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001134 resultsign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001135
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001136 if self._is_special or other._is_special:
1137 ans = self._check_nans(other, context)
1138 if ans:
1139 return ans
1140
1141 if self._isinfinity():
1142 if not other:
1143 return context._raise_error(InvalidOperation, '(+-)INF * 0')
1144 return Infsign[resultsign]
1145
1146 if other._isinfinity():
1147 if not self:
1148 return context._raise_error(InvalidOperation, '0 * (+-)INF')
1149 return Infsign[resultsign]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001150
1151 resultexp = self._exp + other._exp
1152 shouldround = context._rounding_decision == ALWAYS_ROUND
1153
1154 # Special case for multiplying by zero
1155 if not self or not other:
1156 ans = Decimal((resultsign, (0,), resultexp))
1157 if shouldround:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001158 #Fixing in case the exponent is out of bounds
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001159 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001160 return ans
1161
1162 # Special case for multiplying by power of 10
1163 if self._int == (1,):
1164 ans = Decimal((resultsign, other._int, resultexp))
1165 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001166 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001167 return ans
1168 if other._int == (1,):
1169 ans = Decimal((resultsign, self._int, resultexp))
1170 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001171 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001172 return ans
1173
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001174 op1 = _WorkRep(self)
1175 op2 = _WorkRep(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001176
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001177 ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001178 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001179 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001180
1181 return ans
1182 __rmul__ = __mul__
1183
1184 def __div__(self, other, context=None):
1185 """Return self / other."""
1186 return self._divide(other, context=context)
1187 __truediv__ = __div__
1188
1189 def _divide(self, other, divmod = 0, context=None):
1190 """Return a / b, to context.prec precision.
1191
1192 divmod:
1193 0 => true division
1194 1 => (a //b, a%b)
1195 2 => a //b
1196 3 => a%b
1197
1198 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1199 computing the other value are not raised.
1200 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001201 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001202 if other is NotImplemented:
1203 if divmod in (0, 1):
1204 return NotImplemented
1205 return (NotImplemented, NotImplemented)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001206
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001207 if context is None:
1208 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001209
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001210 sign = self._sign ^ other._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001211
1212 if self._is_special or other._is_special:
1213 ans = self._check_nans(other, context)
1214 if ans:
1215 if divmod:
1216 return (ans, ans)
1217 return ans
1218
1219 if self._isinfinity() and other._isinfinity():
1220 if divmod:
1221 return (context._raise_error(InvalidOperation,
1222 '(+-)INF // (+-)INF'),
1223 context._raise_error(InvalidOperation,
1224 '(+-)INF % (+-)INF'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001225 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001226
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001227 if self._isinfinity():
1228 if divmod == 1:
1229 return (Infsign[sign],
1230 context._raise_error(InvalidOperation, 'INF % x'))
1231 elif divmod == 2:
1232 return (Infsign[sign], NaN)
1233 elif divmod == 3:
1234 return (Infsign[sign],
1235 context._raise_error(InvalidOperation, 'INF % x'))
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001236 return Infsign[sign]
1237
1238 if other._isinfinity():
1239 if divmod:
1240 return (Decimal((sign, (0,), 0)), Decimal(self))
1241 context._raise_error(Clamped, 'Division by infinity')
1242 return Decimal((sign, (0,), context.Etiny()))
1243
1244 # Special cases for zeroes
1245 if not self and not other:
1246 if divmod:
1247 return context._raise_error(DivisionUndefined, '0 / 0', 1)
1248 return context._raise_error(DivisionUndefined, '0 / 0')
1249
1250 if not self:
1251 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001252 otherside = Decimal(self)
1253 otherside._exp = min(self._exp, other._exp)
1254 return (Decimal((sign, (0,), 0)), otherside)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001255 exp = self._exp - other._exp
1256 if exp < context.Etiny():
1257 exp = context.Etiny()
1258 context._raise_error(Clamped, '0e-x / y')
1259 if exp > context.Emax:
1260 exp = context.Emax
1261 context._raise_error(Clamped, '0e+x / y')
1262 return Decimal( (sign, (0,), exp) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001263
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001264 if not other:
1265 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001266 return context._raise_error(DivisionByZero, 'divmod(x,0)',
1267 sign, 1)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001268 return context._raise_error(DivisionByZero, 'x / 0', sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001269
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001270 #OK, so neither = 0, INF or NaN
1271
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001272 shouldround = context._rounding_decision == ALWAYS_ROUND
1273
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001274 #If we're dividing into ints, and self < other, stop.
1275 #self.__abs__(0) does not round.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001276 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
1277
1278 if divmod == 1 or divmod == 3:
1279 exp = min(self._exp, other._exp)
1280 ans2 = self._rescale(exp, context=context, watchexp=0)
1281 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001282 ans2 = ans2._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001283 return (Decimal( (sign, (0,), 0) ),
1284 ans2)
1285
1286 elif divmod == 2:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001287 #Don't round the mod part, if we don't need it.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001288 return (Decimal( (sign, (0,), 0) ), Decimal(self))
1289
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001290 op1 = _WorkRep(self)
1291 op2 = _WorkRep(other)
1292 op1, op2, adjust = _adjust_coefficients(op1, op2)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001293 res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001294 if divmod and res.exp > context.prec + 1:
1295 return context._raise_error(DivisionImpossible)
1296
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001297 prec_limit = 10 ** context.prec
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001298 while 1:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001299 while op2.int <= op1.int:
1300 res.int += 1
1301 op1.int -= op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001302 if res.exp == 0 and divmod:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001303 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001304 return context._raise_error(DivisionImpossible)
1305 otherside = Decimal(op1)
1306 frozen = context._ignore_all_flags()
1307
1308 exp = min(self._exp, other._exp)
Raymond Hettinger17931de2004-10-27 06:21:46 +00001309 otherside = otherside._rescale(exp, context=context, watchexp=0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001310 context._regard_flags(*frozen)
1311 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001312 otherside = otherside._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001313 return (Decimal(res), otherside)
1314
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001315 if op1.int == 0 and adjust >= 0 and not divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001316 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001317 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001318 if divmod:
1319 return context._raise_error(DivisionImpossible)
1320 shouldround=1
1321 # Really, the answer is a bit higher, so adding a one to
1322 # the end will make sure the rounding is right.
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001323 if op1.int != 0:
1324 res.int *= 10
1325 res.int += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001326 res.exp -= 1
1327
1328 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001329 res.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001330 res.exp -= 1
1331 adjust += 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001332 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001333 op1.exp -= 1
1334
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001335 if res.exp == 0 and divmod and op2.int > op1.int:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001336 #Solves an error in precision. Same as a previous block.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001337
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001338 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001339 return context._raise_error(DivisionImpossible)
1340 otherside = Decimal(op1)
1341 frozen = context._ignore_all_flags()
1342
1343 exp = min(self._exp, other._exp)
1344 otherside = otherside._rescale(exp, context=context)
1345
1346 context._regard_flags(*frozen)
1347
1348 return (Decimal(res), otherside)
1349
1350 ans = Decimal(res)
1351 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001352 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001353 return ans
1354
1355 def __rdiv__(self, other, context=None):
1356 """Swaps self/other and returns __div__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001357 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001358 if other is NotImplemented:
1359 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001360 return other.__div__(self, context=context)
1361 __rtruediv__ = __rdiv__
1362
1363 def __divmod__(self, other, context=None):
1364 """
1365 (self // other, self % other)
1366 """
1367 return self._divide(other, 1, context)
1368
1369 def __rdivmod__(self, other, context=None):
1370 """Swaps self/other and returns __divmod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001371 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001372 if other is NotImplemented:
1373 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001374 return other.__divmod__(self, context=context)
1375
1376 def __mod__(self, other, context=None):
1377 """
1378 self % other
1379 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001380 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001381 if other is NotImplemented:
1382 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001383
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001384 if self._is_special or other._is_special:
1385 ans = self._check_nans(other, context)
1386 if ans:
1387 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001388
1389 if self and not other:
1390 return context._raise_error(InvalidOperation, 'x % 0')
1391
1392 return self._divide(other, 3, context)[1]
1393
1394 def __rmod__(self, other, context=None):
1395 """Swaps self/other and returns __mod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001396 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001397 if other is NotImplemented:
1398 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001399 return other.__mod__(self, context=context)
1400
1401 def remainder_near(self, other, context=None):
1402 """
1403 Remainder nearest to 0- abs(remainder-near) <= other/2
1404 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001405 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001406 if other is NotImplemented:
1407 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001408
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001409 if self._is_special or other._is_special:
1410 ans = self._check_nans(other, context)
1411 if ans:
1412 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001413 if self and not other:
1414 return context._raise_error(InvalidOperation, 'x % 0')
1415
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001416 if context is None:
1417 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001418 # If DivisionImpossible causes an error, do not leave Rounded/Inexact
1419 # ignored in the calling function.
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001420 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001421 flags = context._ignore_flags(Rounded, Inexact)
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001422 #keep DivisionImpossible flags
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001423 (side, r) = self.__divmod__(other, context=context)
1424
1425 if r._isnan():
1426 context._regard_flags(*flags)
1427 return r
1428
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001429 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001430 rounding = context._set_rounding_decision(NEVER_ROUND)
1431
1432 if other._sign:
1433 comparison = other.__div__(Decimal(-2), context=context)
1434 else:
1435 comparison = other.__div__(Decimal(2), context=context)
1436
1437 context._set_rounding_decision(rounding)
1438 context._regard_flags(*flags)
1439
1440 s1, s2 = r._sign, comparison._sign
1441 r._sign, comparison._sign = 0, 0
1442
1443 if r < comparison:
1444 r._sign, comparison._sign = s1, s2
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001445 #Get flags now
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001446 self.__divmod__(other, context=context)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001447 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001448 r._sign, comparison._sign = s1, s2
1449
1450 rounding = context._set_rounding_decision(NEVER_ROUND)
1451
1452 (side, r) = self.__divmod__(other, context=context)
1453 context._set_rounding_decision(rounding)
1454 if r._isnan():
1455 return r
1456
1457 decrease = not side._iseven()
1458 rounding = context._set_rounding_decision(NEVER_ROUND)
1459 side = side.__abs__(context=context)
1460 context._set_rounding_decision(rounding)
1461
1462 s1, s2 = r._sign, comparison._sign
1463 r._sign, comparison._sign = 0, 0
1464 if r > comparison or decrease and r == comparison:
1465 r._sign, comparison._sign = s1, s2
1466 context.prec += 1
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001467 if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001468 context.prec -= 1
1469 return context._raise_error(DivisionImpossible)[1]
1470 context.prec -= 1
1471 if self._sign == other._sign:
1472 r = r.__sub__(other, context=context)
1473 else:
1474 r = r.__add__(other, context=context)
1475 else:
1476 r._sign, comparison._sign = s1, s2
1477
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001478 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001479
1480 def __floordiv__(self, other, context=None):
1481 """self // other"""
1482 return self._divide(other, 2, context)[0]
1483
1484 def __rfloordiv__(self, other, context=None):
1485 """Swaps self/other and returns __floordiv__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001486 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001487 if other is NotImplemented:
1488 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001489 return other.__floordiv__(self, context=context)
1490
1491 def __float__(self):
1492 """Float representation."""
1493 return float(str(self))
1494
1495 def __int__(self):
Brett Cannon46b08022005-03-01 03:12:26 +00001496 """Converts self to an int, truncating if necessary."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001497 if self._is_special:
1498 if self._isnan():
1499 context = getcontext()
1500 return context._raise_error(InvalidContext)
1501 elif self._isinfinity():
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001502 raise OverflowError, "Cannot convert infinity to long"
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001503 if self._exp >= 0:
Raymond Hettinger605ed022004-11-24 07:28:48 +00001504 s = ''.join(map(str, self._int)) + '0'*self._exp
1505 else:
1506 s = ''.join(map(str, self._int))[:self._exp]
1507 if s == '':
1508 s = '0'
1509 sign = '-'*self._sign
1510 return int(sign + s)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001511
1512 def __long__(self):
1513 """Converts to a long.
1514
1515 Equivalent to long(int(self))
1516 """
1517 return long(self.__int__())
1518
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001519 def _fix(self, context):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001520 """Round if it is necessary to keep self within prec precision.
1521
1522 Rounds and fixes the exponent. Does not raise on a sNaN.
1523
1524 Arguments:
1525 self - Decimal instance
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001526 context - context used.
1527 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001528 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001529 return self
1530 if context is None:
1531 context = getcontext()
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001532 prec = context.prec
Facundo Batista99b55482004-10-26 23:38:46 +00001533 ans = self._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001534 if len(ans._int) > prec:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001535 ans = ans._round(prec, context=context)
Facundo Batista99b55482004-10-26 23:38:46 +00001536 ans = ans._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001537 return ans
1538
Facundo Batista99b55482004-10-26 23:38:46 +00001539 def _fixexponents(self, context):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001540 """Fix the exponents and return a copy with the exponent in bounds.
1541 Only call if known to not be a special value.
1542 """
1543 folddown = context._clamp
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001544 Emin = context.Emin
Facundo Batista99b55482004-10-26 23:38:46 +00001545 ans = self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001546 ans_adjusted = ans.adjusted()
1547 if ans_adjusted < Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001548 Etiny = context.Etiny()
1549 if ans._exp < Etiny:
1550 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001551 ans = Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001552 ans._exp = Etiny
1553 context._raise_error(Clamped)
1554 return ans
1555 ans = ans._rescale(Etiny, context=context)
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001556 #It isn't zero, and exp < Emin => subnormal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001557 context._raise_error(Subnormal)
1558 if context.flags[Inexact]:
1559 context._raise_error(Underflow)
1560 else:
1561 if ans:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001562 #Only raise subnormal if non-zero.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001563 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001564 else:
1565 Etop = context.Etop()
1566 if folddown and ans._exp > Etop:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001567 context._raise_error(Clamped)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001568 ans = ans._rescale(Etop, context=context)
1569 else:
1570 Emax = context.Emax
1571 if ans_adjusted > Emax:
1572 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001573 ans = Decimal(self)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001574 ans._exp = Emax
1575 context._raise_error(Clamped)
1576 return ans
1577 context._raise_error(Inexact)
1578 context._raise_error(Rounded)
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001579 return context._raise_error(Overflow, 'above Emax', ans._sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001580 return ans
1581
1582 def _round(self, prec=None, rounding=None, context=None):
1583 """Returns a rounded version of self.
1584
1585 You can specify the precision or rounding method. Otherwise, the
1586 context determines it.
1587 """
1588
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001589 if self._is_special:
1590 ans = self._check_nans(context=context)
1591 if ans:
1592 return ans
1593
1594 if self._isinfinity():
1595 return Decimal(self)
1596
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001597 if context is None:
1598 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001599
1600 if rounding is None:
1601 rounding = context.rounding
1602 if prec is None:
1603 prec = context.prec
1604
1605 if not self:
1606 if prec <= 0:
1607 dig = (0,)
1608 exp = len(self._int) - prec + self._exp
1609 else:
1610 dig = (0,) * prec
1611 exp = len(self._int) + self._exp - prec
1612 ans = Decimal((self._sign, dig, exp))
1613 context._raise_error(Rounded)
1614 return ans
1615
1616 if prec == 0:
1617 temp = Decimal(self)
1618 temp._int = (0,)+temp._int
1619 prec = 1
1620 elif prec < 0:
1621 exp = self._exp + len(self._int) - prec - 1
1622 temp = Decimal( (self._sign, (0, 1), exp))
1623 prec = 1
1624 else:
1625 temp = Decimal(self)
1626
1627 numdigits = len(temp._int)
1628 if prec == numdigits:
1629 return temp
1630
1631 # See if we need to extend precision
1632 expdiff = prec - numdigits
1633 if expdiff > 0:
1634 tmp = list(temp._int)
1635 tmp.extend([0] * expdiff)
1636 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff))
1637 return ans
1638
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001639 #OK, but maybe all the lost digits are 0.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001640 lostdigits = self._int[expdiff:]
1641 if lostdigits == (0,) * len(lostdigits):
1642 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001643 #Rounded, but not Inexact
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001644 context._raise_error(Rounded)
1645 return ans
1646
1647 # Okay, let's round and lose data
1648
1649 this_function = getattr(temp, self._pick_rounding_function[rounding])
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001650 #Now we've got the rounding function
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001651
1652 if prec != context.prec:
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001653 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001654 context.prec = prec
1655 ans = this_function(prec, expdiff, context)
1656 context._raise_error(Rounded)
1657 context._raise_error(Inexact, 'Changed in rounding')
1658
1659 return ans
1660
1661 _pick_rounding_function = {}
1662
1663 def _round_down(self, prec, expdiff, context):
1664 """Also known as round-towards-0, truncate."""
1665 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1666
1667 def _round_half_up(self, prec, expdiff, context, tmp = None):
1668 """Rounds 5 up (away from 0)"""
1669
1670 if tmp is None:
1671 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
1672 if self._int[prec] >= 5:
1673 tmp = tmp._increment(round=0, context=context)
1674 if len(tmp._int) > prec:
1675 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1676 return tmp
1677
1678 def _round_half_even(self, prec, expdiff, context):
1679 """Round 5 to even, rest to nearest."""
1680
1681 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1682 half = (self._int[prec] == 5)
1683 if half:
1684 for digit in self._int[prec+1:]:
1685 if digit != 0:
1686 half = 0
1687 break
1688 if half:
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001689 if self._int[prec-1] & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001690 return tmp
1691 return self._round_half_up(prec, expdiff, context, tmp)
1692
1693 def _round_half_down(self, prec, expdiff, context):
1694 """Round 5 down"""
1695
1696 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1697 half = (self._int[prec] == 5)
1698 if half:
1699 for digit in self._int[prec+1:]:
1700 if digit != 0:
1701 half = 0
1702 break
1703 if half:
1704 return tmp
1705 return self._round_half_up(prec, expdiff, context, tmp)
1706
1707 def _round_up(self, prec, expdiff, context):
1708 """Rounds away from 0."""
1709 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1710 for digit in self._int[prec:]:
1711 if digit != 0:
1712 tmp = tmp._increment(round=1, context=context)
1713 if len(tmp._int) > prec:
1714 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1715 else:
1716 return tmp
1717 return tmp
1718
1719 def _round_ceiling(self, prec, expdiff, context):
1720 """Rounds up (not away from 0 if negative.)"""
1721 if self._sign:
1722 return self._round_down(prec, expdiff, context)
1723 else:
1724 return self._round_up(prec, expdiff, context)
1725
1726 def _round_floor(self, prec, expdiff, context):
1727 """Rounds down (not towards 0 if negative)"""
1728 if not self._sign:
1729 return self._round_down(prec, expdiff, context)
1730 else:
1731 return self._round_up(prec, expdiff, context)
1732
1733 def __pow__(self, n, modulo = None, context=None):
1734 """Return self ** n (mod modulo)
1735
1736 If modulo is None (default), don't take it mod modulo.
1737 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001738 n = _convert_other(n)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001739 if n is NotImplemented:
1740 return n
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001741
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001742 if context is None:
1743 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001744
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001745 if self._is_special or n._is_special or n.adjusted() > 8:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001746 #Because the spot << doesn't work with really big exponents
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001747 if n._isinfinity() or n.adjusted() > 8:
1748 return context._raise_error(InvalidOperation, 'x ** INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001749
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001750 ans = self._check_nans(n, context)
1751 if ans:
1752 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001753
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001754 if not n._isinteger():
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001755 return context._raise_error(InvalidOperation, 'x ** (non-integer)')
1756
1757 if not self and not n:
1758 return context._raise_error(InvalidOperation, '0 ** 0')
1759
1760 if not n:
1761 return Decimal(1)
1762
1763 if self == Decimal(1):
1764 return Decimal(1)
1765
1766 sign = self._sign and not n._iseven()
1767 n = int(n)
1768
1769 if self._isinfinity():
1770 if modulo:
1771 return context._raise_error(InvalidOperation, 'INF % x')
1772 if n > 0:
1773 return Infsign[sign]
1774 return Decimal( (sign, (0,), 0) )
1775
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001776 #with ludicrously large exponent, just raise an overflow and return inf.
1777 if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
1778 and self:
1779
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001780 tmp = Decimal('inf')
1781 tmp._sign = sign
1782 context._raise_error(Rounded)
1783 context._raise_error(Inexact)
1784 context._raise_error(Overflow, 'Big power', sign)
1785 return tmp
1786
1787 elength = len(str(abs(n)))
1788 firstprec = context.prec
1789
Raymond Hettinger99148e72004-07-14 19:56:56 +00001790 if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001791 return context._raise_error(Overflow, 'Too much precision.', sign)
1792
1793 mul = Decimal(self)
1794 val = Decimal(1)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001795 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001796 context.prec = firstprec + elength + 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001797 if n < 0:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001798 #n is a long now, not Decimal instance
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001799 n = -n
1800 mul = Decimal(1).__div__(mul, context=context)
1801
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001802 spot = 1
1803 while spot <= n:
1804 spot <<= 1
1805
1806 spot >>= 1
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001807 #Spot is the highest power of 2 less than n
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001808 while spot:
1809 val = val.__mul__(val, context=context)
1810 if val._isinfinity():
1811 val = Infsign[sign]
1812 break
1813 if spot & n:
1814 val = val.__mul__(mul, context=context)
1815 if modulo is not None:
1816 val = val.__mod__(modulo, context=context)
1817 spot >>= 1
1818 context.prec = firstprec
1819
Raymond Hettinger76e60d62004-10-20 06:58:28 +00001820 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001821 return val._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001822 return val
1823
1824 def __rpow__(self, other, context=None):
1825 """Swaps self/other and returns __pow__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001826 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001827 if other is NotImplemented:
1828 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001829 return other.__pow__(self, context=context)
1830
1831 def normalize(self, context=None):
1832 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001833
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001834 if self._is_special:
1835 ans = self._check_nans(context=context)
1836 if ans:
1837 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001838
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001839 dup = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001840 if dup._isinfinity():
1841 return dup
1842
1843 if not dup:
1844 return Decimal( (dup._sign, (0,), 0) )
1845 end = len(dup._int)
1846 exp = dup._exp
1847 while dup._int[end-1] == 0:
1848 exp += 1
1849 end -= 1
1850 return Decimal( (dup._sign, dup._int[:end], exp) )
1851
1852
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001853 def quantize(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001854 """Quantize self so its exponent is the same as that of exp.
1855
1856 Similar to self._rescale(exp._exp) but with error checking.
1857 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001858 if self._is_special or exp._is_special:
1859 ans = self._check_nans(exp, context)
1860 if ans:
1861 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001862
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001863 if exp._isinfinity() or self._isinfinity():
1864 if exp._isinfinity() and self._isinfinity():
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001865 return self #if both are inf, it is OK
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001866 if context is None:
1867 context = getcontext()
1868 return context._raise_error(InvalidOperation,
1869 'quantize with one INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001870 return self._rescale(exp._exp, rounding, context, watchexp)
1871
1872 def same_quantum(self, other):
1873 """Test whether self and other have the same exponent.
1874
1875 same as self._exp == other._exp, except NaN == sNaN
1876 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001877 if self._is_special or other._is_special:
1878 if self._isnan() or other._isnan():
1879 return self._isnan() and other._isnan() and True
1880 if self._isinfinity() or other._isinfinity():
1881 return self._isinfinity() and other._isinfinity() and True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001882 return self._exp == other._exp
1883
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001884 def _rescale(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001885 """Rescales so that the exponent is exp.
1886
1887 exp = exp to scale to (an integer)
1888 rounding = rounding version
1889 watchexp: if set (default) an error is returned if exp is greater
1890 than Emax or less than Etiny.
1891 """
1892 if context is None:
1893 context = getcontext()
1894
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001895 if self._is_special:
1896 if self._isinfinity():
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001897 return context._raise_error(InvalidOperation, 'rescale with an INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001898
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001899 ans = self._check_nans(context=context)
1900 if ans:
1901 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001902
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001903 if watchexp and (context.Emax < exp or context.Etiny() > exp):
1904 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1905
1906 if not self:
1907 ans = Decimal(self)
1908 ans._int = (0,)
1909 ans._exp = exp
1910 return ans
1911
1912 diff = self._exp - exp
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001913 digits = len(self._int) + diff
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001914
1915 if watchexp and digits > context.prec:
1916 return context._raise_error(InvalidOperation, 'Rescale > prec')
1917
1918 tmp = Decimal(self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001919 tmp._int = (0,) + tmp._int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001920 digits += 1
1921
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001922 if digits < 0:
1923 tmp._exp = -digits + tmp._exp
1924 tmp._int = (0,1)
1925 digits = 1
1926 tmp = tmp._round(digits, rounding, context=context)
1927
1928 if tmp._int[0] == 0 and len(tmp._int) > 1:
1929 tmp._int = tmp._int[1:]
1930 tmp._exp = exp
1931
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001932 tmp_adjusted = tmp.adjusted()
1933 if tmp and tmp_adjusted < context.Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001934 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001935 elif tmp and tmp_adjusted > context.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001936 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1937 return tmp
1938
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001939 def to_integral(self, rounding=None, context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001940 """Rounds to the nearest integer, without raising inexact, rounded."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001941 if self._is_special:
1942 ans = self._check_nans(context=context)
1943 if ans:
1944 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001945 if self._exp >= 0:
1946 return self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001947 if context is None:
1948 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001949 flags = context._ignore_flags(Rounded, Inexact)
1950 ans = self._rescale(0, rounding, context=context)
1951 context._regard_flags(flags)
1952 return ans
1953
1954 def sqrt(self, context=None):
1955 """Return the square root of self.
1956
1957 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
1958 Should quadratically approach the right answer.
1959 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001960 if self._is_special:
1961 ans = self._check_nans(context=context)
1962 if ans:
1963 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001964
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001965 if self._isinfinity() and self._sign == 0:
1966 return Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001967
1968 if not self:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001969 #exponent = self._exp / 2, using round_down.
1970 #if self._exp < 0:
1971 # exp = (self._exp+1) // 2
1972 #else:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001973 exp = (self._exp) // 2
1974 if self._sign == 1:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00001975 #sqrt(-0) = -0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001976 return Decimal( (1, (0,), exp))
1977 else:
1978 return Decimal( (0, (0,), exp))
1979
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001980 if context is None:
1981 context = getcontext()
1982
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001983 if self._sign == 1:
1984 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
1985
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001986 tmp = Decimal(self)
1987
Raymond Hettinger4837a222004-09-27 14:23:40 +00001988 expadd = tmp._exp // 2
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001989 if tmp._exp & 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001990 tmp._int += (0,)
1991 tmp._exp = 0
1992 else:
1993 tmp._exp = 0
1994
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001995 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001996 flags = context._ignore_all_flags()
1997 firstprec = context.prec
1998 context.prec = 3
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001999 if tmp.adjusted() & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002000 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) )
2001 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
2002 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00002003 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002004 else:
2005 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
2006 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
2007 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00002008 ans._exp -= 1 + tmp.adjusted() // 2
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002009
2010 #ans is now a linear approximation.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002011
2012 Emax, Emin = context.Emax, context.Emin
Raymond Hettinger99148e72004-07-14 19:56:56 +00002013 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002014
2015 half = Decimal('0.5')
2016
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002017 maxp = firstprec + 2
2018 rounding = context._set_rounding(ROUND_HALF_EVEN)
2019 while 1:
2020 context.prec = min(2*context.prec - 2, maxp)
2021 ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
2022 context=context), context=context)
2023 if context.prec == maxp:
2024 break
2025
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002026 #round to the answer's precision-- the only error can be 1 ulp.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002027 context.prec = firstprec
2028 prevexp = ans.adjusted()
2029 ans = ans._round(context=context)
2030
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002031 #Now, check if the other last digits are better.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002032 context.prec = firstprec + 1
2033 # In case we rounded up another digit and we should actually go lower.
2034 if prevexp != ans.adjusted():
2035 ans._int += (0,)
2036 ans._exp -= 1
2037
2038
2039 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
2040 context._set_rounding(ROUND_UP)
2041 if lower.__mul__(lower, context=context) > (tmp):
2042 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
2043
2044 else:
2045 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
2046 context._set_rounding(ROUND_DOWN)
2047 if upper.__mul__(upper, context=context) < tmp:
2048 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
2049
2050 ans._exp += expadd
2051
2052 context.prec = firstprec
2053 context.rounding = rounding
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002054 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002055
2056 rounding = context._set_rounding_decision(NEVER_ROUND)
2057 if not ans.__mul__(ans, context=context) == self:
2058 # Only rounded/inexact if here.
2059 context._regard_flags(flags)
2060 context._raise_error(Rounded)
2061 context._raise_error(Inexact)
2062 else:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002063 #Exact answer, so let's set the exponent right.
2064 #if self._exp < 0:
2065 # exp = (self._exp +1)// 2
2066 #else:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002067 exp = self._exp // 2
2068 context.prec += ans._exp - exp
2069 ans = ans._rescale(exp, context=context)
2070 context.prec = firstprec
2071 context._regard_flags(flags)
2072 context.Emax, context.Emin = Emax, Emin
2073
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002074 return ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002075
2076 def max(self, other, context=None):
2077 """Returns the larger value.
2078
2079 like max(self, other) except if one is not a number, returns
2080 NaN (and signals if one is sNaN). Also rounds.
2081 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002082 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002083 if other is NotImplemented:
2084 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002085
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002086 if self._is_special or other._is_special:
2087 # if one operand is a quiet NaN and the other is number, then the
2088 # number is always returned
2089 sn = self._isnan()
2090 on = other._isnan()
2091 if sn or on:
2092 if on == 1 and sn != 2:
2093 return self
2094 if sn == 1 and on != 2:
2095 return other
2096 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002097
2098 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002099 c = self.__cmp__(other)
2100 if c == 0:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002101 # if both operands are finite and equal in numerical value
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002102 # then an ordering is applied:
2103 #
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002104 # if the signs differ then max returns the operand with the
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002105 # positive sign and min returns the operand with the negative sign
2106 #
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002107 # if the signs are the same then the exponent is used to select
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002108 # the result.
2109 if self._sign != other._sign:
2110 if self._sign:
2111 ans = other
2112 elif self._exp < other._exp and not self._sign:
2113 ans = other
2114 elif self._exp > other._exp and self._sign:
2115 ans = other
2116 elif c == -1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002117 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002118
2119 if context is None:
2120 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002121 if context._rounding_decision == ALWAYS_ROUND:
2122 return ans._fix(context)
2123 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002124
2125 def min(self, other, context=None):
2126 """Returns the smaller value.
2127
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002128 like min(self, other) except if one is not a number, returns
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002129 NaN (and signals if one is sNaN). Also rounds.
2130 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002131 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002132 if other is NotImplemented:
2133 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002134
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002135 if self._is_special or other._is_special:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002136 # if one operand is a quiet NaN and the other is number, then the
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002137 # number is always returned
2138 sn = self._isnan()
2139 on = other._isnan()
2140 if sn or on:
2141 if on == 1 and sn != 2:
2142 return self
2143 if sn == 1 and on != 2:
2144 return other
2145 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002146
2147 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002148 c = self.__cmp__(other)
2149 if c == 0:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002150 # if both operands are finite and equal in numerical value
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002151 # then an ordering is applied:
2152 #
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002153 # if the signs differ then max returns the operand with the
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002154 # positive sign and min returns the operand with the negative sign
2155 #
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002156 # if the signs are the same then the exponent is used to select
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002157 # the result.
2158 if self._sign != other._sign:
2159 if other._sign:
2160 ans = other
2161 elif self._exp > other._exp and not self._sign:
2162 ans = other
2163 elif self._exp < other._exp and self._sign:
2164 ans = other
2165 elif c == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002166 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002167
2168 if context is None:
2169 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002170 if context._rounding_decision == ALWAYS_ROUND:
2171 return ans._fix(context)
2172 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002173
2174 def _isinteger(self):
2175 """Returns whether self is an integer"""
2176 if self._exp >= 0:
2177 return True
2178 rest = self._int[self._exp:]
2179 return rest == (0,)*len(rest)
2180
2181 def _iseven(self):
2182 """Returns 1 if self is even. Assumes self is an integer."""
2183 if self._exp > 0:
2184 return 1
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002185 return self._int[-1+self._exp] & 1 == 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002186
2187 def adjusted(self):
2188 """Return the adjusted exponent of self"""
2189 try:
2190 return self._exp + len(self._int) - 1
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002191 #If NaN or Infinity, self._exp is string
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002192 except TypeError:
2193 return 0
2194
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002195 # support for pickling, copy, and deepcopy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002196 def __reduce__(self):
2197 return (self.__class__, (str(self),))
2198
2199 def __copy__(self):
2200 if type(self) == Decimal:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002201 return self # I'm immutable; therefore I am my own clone
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002202 return self.__class__(str(self))
2203
2204 def __deepcopy__(self, memo):
2205 if type(self) == Decimal:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002206 return self # My components are also immutable
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002207 return self.__class__(str(self))
2208
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002209##### Context class ###########################################
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002210
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002211
2212# get rounding method function:
2213rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002214for name in rounding_functions:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002215 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002216 globalname = name[1:].upper()
2217 val = globals()[globalname]
2218 Decimal._pick_rounding_function[val] = name
2219
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002220del name, val, globalname, rounding_functions
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002221
Nick Coghlanafd5e632006-05-03 13:02:47 +00002222class ContextManager(object):
Nick Coghlan8b6999b2006-08-31 12:00:43 +00002223 """Context manager class to support localcontext().
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002224
Nick Coghlan8b6999b2006-08-31 12:00:43 +00002225 Sets the supplied context in __enter__() and restores
2226 the previous decimal context in __exit__()
2227
2228 """
2229 # The below can't be included in the docstring until Python 2.6
2230 # as the doctest module doesn't understand __future__ statements
2231 """
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002232 Sample usage:
Nick Coghlan8b6999b2006-08-31 12:00:43 +00002233 >>> from __future__ import with_statement
2234 >>> print getcontext().prec
2235 28
2236 >>> ctx = Context(prec=15)
2237 >>> with ContextManager(ctx):
2238 ... print getcontext().prec
2239 ...
2240 15
2241 >>> print getcontext().prec
2242 28
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002243 """
2244 def __init__(self, new_context):
2245 self.new_context = new_context
2246 def __enter__(self):
2247 self.saved_context = getcontext()
2248 setcontext(self.new_context)
2249 return self.new_context
2250 def __exit__(self, t, v, tb):
2251 setcontext(self.saved_context)
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002252
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002253class Context(object):
2254 """Contains the context for a Decimal instance.
2255
2256 Contains:
2257 prec - precision (for use in rounding, division, square roots..)
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002258 rounding - rounding type. (how you round)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002259 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
Raymond Hettingerbf440692004-07-10 14:14:37 +00002260 traps - If traps[exception] = 1, then the exception is
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002261 raised when it is caused. Otherwise, a value is
2262 substituted in.
2263 flags - When an exception is caused, flags[exception] is incremented.
2264 (Whether or not the trap_enabler is set)
2265 Should be reset by user of Decimal instance.
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002266 Emin - Minimum exponent
2267 Emax - Maximum exponent
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002268 capitals - If 1, 1*10^1 is printed as 1E+1.
2269 If 0, printed as 1e1
Raymond Hettingere0f15812004-07-05 05:36:39 +00002270 _clamp - If 1, change exponents if too high (Default 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002271 """
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002272
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002273 def __init__(self, prec=None, rounding=None,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002274 traps=None, flags=None,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002275 _rounding_decision=None,
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002276 Emin=None, Emax=None,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002277 capitals=None, _clamp=0,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002278 _ignored_flags=None):
2279 if flags is None:
2280 flags = []
2281 if _ignored_flags is None:
2282 _ignored_flags = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002283 if not isinstance(flags, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002284 flags = dict([(s,s in flags) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002285 del s
Raymond Hettingerbf440692004-07-10 14:14:37 +00002286 if traps is not None and not isinstance(traps, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002287 traps = dict([(s,s in traps) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002288 del s
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002289 for name, val in locals().items():
2290 if val is None:
Raymond Hettingereb260842005-06-07 18:52:34 +00002291 setattr(self, name, _copy.copy(getattr(DefaultContext, name)))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002292 else:
2293 setattr(self, name, val)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002294 del self.self
2295
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002296 def __repr__(self):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002297 """Show the current context."""
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002298 s = []
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002299 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
2300 s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
2301 s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002302 return ', '.join(s) + ')'
2303
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002304 def clear_flags(self):
2305 """Reset all flags to zero"""
2306 for flag in self.flags:
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002307 self.flags[flag] = 0
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002308
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002309 def _shallow_copy(self):
2310 """Returns a shallow copy from self."""
Raymond Hettingerbf440692004-07-10 14:14:37 +00002311 nc = Context(self.prec, self.rounding, self.traps, self.flags,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002312 self._rounding_decision, self.Emin, self.Emax,
2313 self.capitals, self._clamp, self._ignored_flags)
2314 return nc
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002315
2316 def copy(self):
2317 """Returns a deep copy from self."""
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002318 nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
2319 self._rounding_decision, self.Emin, self.Emax,
2320 self.capitals, self._clamp, self._ignored_flags)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002321 return nc
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002322 __copy__ = copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002323
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002324 def _raise_error(self, condition, explanation = None, *args):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002325 """Handles an error
2326
2327 If the flag is in _ignored_flags, returns the default response.
2328 Otherwise, it increments the flag, then, if the corresponding
2329 trap_enabler is set, it reaises the exception. Otherwise, it returns
2330 the default value after incrementing the flag.
2331 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002332 error = _condition_map.get(condition, condition)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002333 if error in self._ignored_flags:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002334 #Don't touch the flag
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002335 return error().handle(self, *args)
2336
2337 self.flags[error] += 1
Raymond Hettingerbf440692004-07-10 14:14:37 +00002338 if not self.traps[error]:
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002339 #The errors define how to handle themselves.
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002340 return condition().handle(self, *args)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002341
2342 # Errors should only be risked on copies of the context
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002343 #self._ignored_flags = []
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002344 raise error, explanation
2345
2346 def _ignore_all_flags(self):
2347 """Ignore all flags, if they are raised"""
Raymond Hettingerfed52962004-07-14 15:41:57 +00002348 return self._ignore_flags(*_signals)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002349
2350 def _ignore_flags(self, *flags):
2351 """Ignore the flags, if they are raised"""
2352 # Do not mutate-- This way, copies of a context leave the original
2353 # alone.
2354 self._ignored_flags = (self._ignored_flags + list(flags))
2355 return list(flags)
2356
2357 def _regard_flags(self, *flags):
2358 """Stop ignoring the flags, if they are raised"""
2359 if flags and isinstance(flags[0], (tuple,list)):
2360 flags = flags[0]
2361 for flag in flags:
2362 self._ignored_flags.remove(flag)
2363
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002364 def __hash__(self):
2365 """A Context cannot be hashed."""
2366 # We inherit object.__hash__, so we must deny this explicitly
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002367 raise TypeError, "Cannot hash a Context."
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002368
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002369 def Etiny(self):
2370 """Returns Etiny (= Emin - prec + 1)"""
2371 return int(self.Emin - self.prec + 1)
2372
2373 def Etop(self):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002374 """Returns maximum exponent (= Emax - prec + 1)"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002375 return int(self.Emax - self.prec + 1)
2376
2377 def _set_rounding_decision(self, type):
2378 """Sets the rounding decision.
2379
2380 Sets the rounding decision, and returns the current (previous)
2381 rounding decision. Often used like:
2382
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002383 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002384 # That so you don't change the calling context
2385 # if an error occurs in the middle (say DivisionImpossible is raised).
2386
2387 rounding = context._set_rounding_decision(NEVER_ROUND)
2388 instance = instance / Decimal(2)
2389 context._set_rounding_decision(rounding)
2390
2391 This will make it not round for that operation.
2392 """
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002393
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002394 rounding = self._rounding_decision
2395 self._rounding_decision = type
2396 return rounding
2397
2398 def _set_rounding(self, type):
2399 """Sets the rounding type.
2400
2401 Sets the rounding type, and returns the current (previous)
2402 rounding type. Often used like:
2403
2404 context = context.copy()
2405 # so you don't change the calling context
2406 # if an error occurs in the middle.
2407 rounding = context._set_rounding(ROUND_UP)
2408 val = self.__sub__(other, context=context)
2409 context._set_rounding(rounding)
2410
2411 This will make it round up for that operation.
2412 """
2413 rounding = self.rounding
2414 self.rounding= type
2415 return rounding
2416
Raymond Hettingerfed52962004-07-14 15:41:57 +00002417 def create_decimal(self, num='0'):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002418 """Creates a new Decimal instance but using self as context."""
2419 d = Decimal(num, context=self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002420 return d._fix(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002421
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002422 #Methods
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002423 def abs(self, a):
2424 """Returns the absolute value of the operand.
2425
2426 If the operand is negative, the result is the same as using the minus
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002427 operation on the operand. Otherwise, the result is the same as using
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002428 the plus operation on the operand.
2429
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002430 >>> ExtendedContext.abs(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002431 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002432 >>> ExtendedContext.abs(Decimal('-100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002433 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002434 >>> ExtendedContext.abs(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002435 Decimal("101.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002436 >>> ExtendedContext.abs(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002437 Decimal("101.5")
2438 """
2439 return a.__abs__(context=self)
2440
2441 def add(self, a, b):
2442 """Return the sum of the two operands.
2443
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002444 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002445 Decimal("19.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002446 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002447 Decimal("1.02E+4")
2448 """
2449 return a.__add__(b, context=self)
2450
2451 def _apply(self, a):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002452 return str(a._fix(self))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002453
2454 def compare(self, a, b):
2455 """Compares values numerically.
2456
2457 If the signs of the operands differ, a value representing each operand
2458 ('-1' if the operand is less than zero, '0' if the operand is zero or
2459 negative zero, or '1' if the operand is greater than zero) is used in
2460 place of that operand for the comparison instead of the actual
2461 operand.
2462
2463 The comparison is then effected by subtracting the second operand from
2464 the first and then returning a value according to the result of the
2465 subtraction: '-1' if the result is less than zero, '0' if the result is
2466 zero or negative zero, or '1' if the result is greater than zero.
2467
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002468 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002469 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002470 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002471 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002472 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002473 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002474 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002475 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002476 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002477 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002478 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002479 Decimal("-1")
2480 """
2481 return a.compare(b, context=self)
2482
2483 def divide(self, a, b):
2484 """Decimal division in a specified context.
2485
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002486 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002487 Decimal("0.333333333")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002488 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002489 Decimal("0.666666667")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002490 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002491 Decimal("2.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002492 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002493 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002494 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002495 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002496 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002497 Decimal("4.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002498 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002499 Decimal("1.20")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002500 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002501 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002502 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002503 Decimal("1000")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002504 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002505 Decimal("1.20E+6")
2506 """
2507 return a.__div__(b, context=self)
2508
2509 def divide_int(self, a, b):
2510 """Divides two numbers and returns the integer part of the result.
2511
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002512 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002513 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002514 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002515 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002516 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002517 Decimal("3")
2518 """
2519 return a.__floordiv__(b, context=self)
2520
2521 def divmod(self, a, b):
2522 return a.__divmod__(b, context=self)
2523
2524 def max(self, a,b):
2525 """max compares two values numerically and returns the maximum.
2526
2527 If either operand is a NaN then the general rules apply.
2528 Otherwise, the operands are compared as as though by the compare
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002529 operation. If they are numerically equal then the left-hand operand
2530 is chosen as the result. Otherwise the maximum (closer to positive
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002531 infinity) of the two operands is chosen as the result.
2532
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002533 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002534 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002535 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002536 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002537 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002538 Decimal("1")
2539 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
2540 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002541 """
2542 return a.max(b, context=self)
2543
2544 def min(self, a,b):
2545 """min compares two values numerically and returns the minimum.
2546
2547 If either operand is a NaN then the general rules apply.
2548 Otherwise, the operands are compared as as though by the compare
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002549 operation. If they are numerically equal then the left-hand operand
2550 is chosen as the result. Otherwise the minimum (closer to negative
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002551 infinity) of the two operands is chosen as the result.
2552
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002553 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002554 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002555 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002556 Decimal("-10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002557 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002558 Decimal("1.0")
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002559 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
2560 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002561 """
2562 return a.min(b, context=self)
2563
2564 def minus(self, a):
2565 """Minus corresponds to unary prefix minus in Python.
2566
2567 The operation is evaluated using the same rules as subtract; the
2568 operation minus(a) is calculated as subtract('0', a) where the '0'
2569 has the same exponent as the operand.
2570
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002571 >>> ExtendedContext.minus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002572 Decimal("-1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002573 >>> ExtendedContext.minus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002574 Decimal("1.3")
2575 """
2576 return a.__neg__(context=self)
2577
2578 def multiply(self, a, b):
2579 """multiply multiplies two operands.
2580
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002581 If either operand is a special value then the general rules apply.
2582 Otherwise, the operands are multiplied together ('long multiplication'),
2583 resulting in a number which may be as long as the sum of the lengths
2584 of the two operands.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002585
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002586 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002587 Decimal("3.60")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002588 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002589 Decimal("21")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002590 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002591 Decimal("0.72")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002592 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002593 Decimal("-0.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002594 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002595 Decimal("4.28135971E+11")
2596 """
2597 return a.__mul__(b, context=self)
2598
2599 def normalize(self, a):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002600 """normalize reduces an operand to its simplest form.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002601
2602 Essentially a plus operation with all trailing zeros removed from the
2603 result.
2604
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002605 >>> ExtendedContext.normalize(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002606 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002607 >>> ExtendedContext.normalize(Decimal('-2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002608 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002609 >>> ExtendedContext.normalize(Decimal('1.200'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002610 Decimal("1.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002611 >>> ExtendedContext.normalize(Decimal('-120'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002612 Decimal("-1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002613 >>> ExtendedContext.normalize(Decimal('120.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002614 Decimal("1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002615 >>> ExtendedContext.normalize(Decimal('0.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002616 Decimal("0")
2617 """
2618 return a.normalize(context=self)
2619
2620 def plus(self, a):
2621 """Plus corresponds to unary prefix plus in Python.
2622
2623 The operation is evaluated using the same rules as add; the
2624 operation plus(a) is calculated as add('0', a) where the '0'
2625 has the same exponent as the operand.
2626
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002627 >>> ExtendedContext.plus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002628 Decimal("1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002629 >>> ExtendedContext.plus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002630 Decimal("-1.3")
2631 """
2632 return a.__pos__(context=self)
2633
2634 def power(self, a, b, modulo=None):
2635 """Raises a to the power of b, to modulo if given.
2636
2637 The right-hand operand must be a whole number whose integer part (after
2638 any exponent has been applied) has no more than 9 digits and whose
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002639 fractional part (if any) is all zeros before any rounding. The operand
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002640 may be positive, negative, or zero; if negative, the absolute value of
2641 the power is used, and the left-hand operand is inverted (divided into
2642 1) before use.
2643
2644 If the increased precision needed for the intermediate calculations
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002645 exceeds the capabilities of the implementation then an Invalid operation
2646 condition is raised.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002647
2648 If, when raising to a negative power, an underflow occurs during the
2649 division into 1, the operation is not halted at that point but
2650 continues.
2651
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002652 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002653 Decimal("8")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002654 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002655 Decimal("0.125")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002656 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002657 Decimal("69.7575744")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002658 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002659 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002660 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002661 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002662 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002663 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002664 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002665 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002666 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002667 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002668 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002669 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002670 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002671 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002672 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002673 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002674 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002675 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002676 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002677 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002678 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002679 Decimal("NaN")
2680 """
2681 return a.__pow__(b, modulo, context=self)
2682
2683 def quantize(self, a, b):
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002684 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002685
2686 The coefficient of the result is derived from that of the left-hand
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002687 operand. It may be rounded using the current rounding setting (if the
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002688 exponent is being increased), multiplied by a positive power of ten (if
2689 the exponent is being decreased), or is unchanged (if the exponent is
2690 already equal to that of the right-hand operand).
2691
2692 Unlike other operations, if the length of the coefficient after the
2693 quantize operation would be greater than precision then an Invalid
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002694 operation condition is raised. This guarantees that, unless there is an
2695 error condition, the exponent of the result of a quantize is always
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002696 equal to that of the right-hand operand.
2697
2698 Also unlike other operations, quantize will never raise Underflow, even
2699 if the result is subnormal and inexact.
2700
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002701 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002702 Decimal("2.170")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002703 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002704 Decimal("2.17")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002705 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002706 Decimal("2.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002707 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002708 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002709 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002710 Decimal("0E+1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002711 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002712 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002713 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002714 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002715 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002716 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002717 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002718 Decimal("-0E+5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002719 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002720 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002721 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002722 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002723 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002724 Decimal("217.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002725 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002726 Decimal("217")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002727 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002728 Decimal("2.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002729 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002730 Decimal("2E+2")
2731 """
2732 return a.quantize(b, context=self)
2733
2734 def remainder(self, a, b):
2735 """Returns the remainder from integer division.
2736
2737 The result is the residue of the dividend after the operation of
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002738 calculating integer division as described for divide-integer, rounded to
2739 precision digits if necessary. The sign of the result, if non-zero, is
2740 the same as that of the original dividend.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002741
2742 This operation will fail under the same conditions as integer division
2743 (that is, if integer division on the same two operands would fail, the
2744 remainder cannot be calculated).
2745
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002746 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002747 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002748 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002749 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002750 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002751 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002752 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002753 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002754 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002755 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002756 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002757 Decimal("1.0")
2758 """
2759 return a.__mod__(b, context=self)
2760
2761 def remainder_near(self, a, b):
2762 """Returns to be "a - b * n", where n is the integer nearest the exact
2763 value of "x / b" (if two integers are equally near then the even one
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002764 is chosen). If the result is equal to 0 then its sign will be the
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002765 sign of a.
2766
2767 This operation will fail under the same conditions as integer division
2768 (that is, if integer division on the same two operands would fail, the
2769 remainder cannot be calculated).
2770
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002771 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002772 Decimal("-0.9")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002773 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002774 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002775 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002776 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002777 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002778 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002779 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002780 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002781 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002782 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002783 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002784 Decimal("-0.3")
2785 """
2786 return a.remainder_near(b, context=self)
2787
2788 def same_quantum(self, a, b):
2789 """Returns True if the two operands have the same exponent.
2790
2791 The result is never affected by either the sign or the coefficient of
2792 either operand.
2793
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002794 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002795 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002796 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002797 True
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002798 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002799 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002800 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002801 True
2802 """
2803 return a.same_quantum(b)
2804
2805 def sqrt(self, a):
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002806 """Returns the square root of a non-negative number to context precision.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002807
2808 If the result must be inexact, it is rounded using the round-half-even
2809 algorithm.
2810
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002811 >>> ExtendedContext.sqrt(Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002812 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002813 >>> ExtendedContext.sqrt(Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002814 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002815 >>> ExtendedContext.sqrt(Decimal('0.39'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002816 Decimal("0.624499800")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002817 >>> ExtendedContext.sqrt(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002818 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002819 >>> ExtendedContext.sqrt(Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002820 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002821 >>> ExtendedContext.sqrt(Decimal('1.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002822 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002823 >>> ExtendedContext.sqrt(Decimal('1.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002824 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002825 >>> ExtendedContext.sqrt(Decimal('7'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002826 Decimal("2.64575131")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002827 >>> ExtendedContext.sqrt(Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002828 Decimal("3.16227766")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002829 >>> ExtendedContext.prec
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002830 9
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002831 """
2832 return a.sqrt(context=self)
2833
2834 def subtract(self, a, b):
Georg Brandlf33d01d2005-08-22 19:35:18 +00002835 """Return the difference between the two operands.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002836
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002837 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002838 Decimal("0.23")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002839 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002840 Decimal("0.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002841 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002842 Decimal("-0.77")
2843 """
2844 return a.__sub__(b, context=self)
2845
2846 def to_eng_string(self, a):
2847 """Converts a number to a string, using scientific notation.
2848
2849 The operation is not affected by the context.
2850 """
2851 return a.to_eng_string(context=self)
2852
2853 def to_sci_string(self, a):
2854 """Converts a number to a string, using scientific notation.
2855
2856 The operation is not affected by the context.
2857 """
2858 return a.__str__(context=self)
2859
2860 def to_integral(self, a):
2861 """Rounds to an integer.
2862
2863 When the operand has a negative exponent, the result is the same
2864 as using the quantize() operation using the given operand as the
2865 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2866 of the operand as the precision setting, except that no flags will
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002867 be set. The rounding mode is taken from the context.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002868
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002869 >>> ExtendedContext.to_integral(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002870 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002871 >>> ExtendedContext.to_integral(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002872 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002873 >>> ExtendedContext.to_integral(Decimal('100.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002874 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002875 >>> ExtendedContext.to_integral(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002876 Decimal("102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002877 >>> ExtendedContext.to_integral(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002878 Decimal("-102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002879 >>> ExtendedContext.to_integral(Decimal('10E+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002880 Decimal("1.0E+6")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002881 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002882 Decimal("7.89E+77")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002883 >>> ExtendedContext.to_integral(Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002884 Decimal("-Infinity")
2885 """
2886 return a.to_integral(context=self)
2887
2888class _WorkRep(object):
2889 __slots__ = ('sign','int','exp')
Raymond Hettinger17931de2004-10-27 06:21:46 +00002890 # sign: 0 or 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002891 # int: int or long
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002892 # exp: None, int, or string
2893
2894 def __init__(self, value=None):
2895 if value is None:
2896 self.sign = None
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002897 self.int = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002898 self.exp = None
Raymond Hettinger17931de2004-10-27 06:21:46 +00002899 elif isinstance(value, Decimal):
2900 self.sign = value._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002901 cum = 0
Raymond Hettinger17931de2004-10-27 06:21:46 +00002902 for digit in value._int:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002903 cum = cum * 10 + digit
2904 self.int = cum
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002905 self.exp = value._exp
Raymond Hettinger17931de2004-10-27 06:21:46 +00002906 else:
2907 # assert isinstance(value, tuple)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002908 self.sign = value[0]
2909 self.int = value[1]
2910 self.exp = value[2]
2911
2912 def __repr__(self):
2913 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2914
2915 __str__ = __repr__
2916
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002917
2918
2919def _normalize(op1, op2, shouldround = 0, prec = 0):
2920 """Normalizes op1, op2 to have the same exp and length of coefficient.
2921
2922 Done during addition.
2923 """
2924 # Yes, the exponent is a long, but the difference between exponents
2925 # must be an int-- otherwise you'd get a big memory problem.
2926 numdigits = int(op1.exp - op2.exp)
2927 if numdigits < 0:
2928 numdigits = -numdigits
2929 tmp = op2
2930 other = op1
2931 else:
2932 tmp = op1
2933 other = op2
2934
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002935
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002936 if shouldround and numdigits > prec + 1:
2937 # Big difference in exponents - check the adjusted exponents
2938 tmp_len = len(str(tmp.int))
2939 other_len = len(str(other.int))
2940 if numdigits > (other_len + prec + 1 - tmp_len):
2941 # If the difference in adjusted exps is > prec+1, we know
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002942 # other is insignificant, so might as well put a 1 after the precision.
2943 # (since this is only for addition.) Also stops use of massive longs.
2944
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002945 extend = prec + 2 - tmp_len
2946 if extend <= 0:
2947 extend = 1
2948 tmp.int *= 10 ** extend
2949 tmp.exp -= extend
2950 other.int = 1
2951 other.exp = tmp.exp
2952 return op1, op2
2953
2954 tmp.int *= 10 ** numdigits
2955 tmp.exp -= numdigits
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002956 return op1, op2
2957
2958def _adjust_coefficients(op1, op2):
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002959 """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002960
2961 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2962
2963 Used on _WorkRep instances during division.
2964 """
2965 adjust = 0
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002966 #If op1 is smaller, make it larger
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002967 while op2.int > op1.int:
2968 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002969 op1.exp -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002970 adjust += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002971
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002972 #If op2 is too small, make it larger
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002973 while op1.int >= (10 * op2.int):
2974 op2.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002975 op2.exp -= 1
2976 adjust -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002977
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002978 return op1, op2, adjust
2979
Martin v. Löwiscfe31282006-07-19 17:18:32 +00002980##### Helper Functions ########################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002981
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002982def _convert_other(other):
2983 """Convert other to Decimal.
2984
2985 Verifies that it's ok to use in an implicit construction.
2986 """
2987 if isinstance(other, Decimal):
2988 return other
2989 if isinstance(other, (int, long)):
2990 return Decimal(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002991 return NotImplemented
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002992
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002993_infinity_map = {
2994 'inf' : 1,
2995 'infinity' : 1,
2996 '+inf' : 1,
2997 '+infinity' : 1,
2998 '-inf' : -1,
2999 '-infinity' : -1
3000}
3001
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00003002def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003003 """Determines whether a string or float is infinity.
3004
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00003005 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003006 """
3007 num = str(num).lower()
3008 return _infinity_map.get(num, 0)
3009
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00003010def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003011 """Determines whether a string or float is NaN
3012
3013 (1, sign, diagnostic info as string) => NaN
3014 (2, sign, diagnostic info as string) => sNaN
3015 0 => not a NaN
3016 """
3017 num = str(num).lower()
3018 if not num:
3019 return 0
3020
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003021 #get the sign, get rid of trailing [+-]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003022 sign = 0
3023 if num[0] == '+':
3024 num = num[1:]
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003025 elif num[0] == '-': #elif avoids '+-nan'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003026 num = num[1:]
3027 sign = 1
3028
3029 if num.startswith('nan'):
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003030 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003031 return 0
3032 return (1, sign, num[3:].lstrip('0'))
3033 if num.startswith('snan'):
3034 if len(num) > 4 and not num[4:].isdigit():
3035 return 0
3036 return (2, sign, num[4:].lstrip('0'))
3037 return 0
3038
3039
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003040##### Setup Specific Contexts ################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003041
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003042# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00003043# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003044
3045DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003046 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003047 traps=[DivisionByZero, Overflow, InvalidOperation],
3048 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003049 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00003050 Emax=999999999,
3051 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00003052 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003053)
3054
3055# Pre-made alternate contexts offered by the specification
3056# Don't change these; the user should be able to select these
3057# contexts and be able to reproduce results from other implementations
3058# of the spec.
3059
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003060BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003061 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003062 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
3063 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003064)
3065
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003066ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003067 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003068 traps=[],
3069 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003070)
3071
3072
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003073##### Useful Constants (internal use only) ####################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003074
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003075#Reusable defaults
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003076Inf = Decimal('Inf')
3077negInf = Decimal('-Inf')
3078
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003079#Infsign[sign] is infinity w/ that sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003080Infsign = (Inf, negInf)
3081
3082NaN = Decimal('NaN')
3083
3084
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003085##### crud for parsing strings #################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003086import re
3087
3088# There's an optional sign at the start, and an optional exponent
3089# at the end. The exponent has an optional sign and at least one
3090# digit. In between, must have either at least one digit followed
3091# by an optional fraction, or a decimal point followed by at least
3092# one digit. Yuck.
3093
3094_parser = re.compile(r"""
3095# \s*
3096 (?P<sign>[-+])?
3097 (
3098 (?P<int>\d+) (\. (?P<frac>\d*))?
3099 |
3100 \. (?P<onlyfrac>\d+)
3101 )
3102 ([eE](?P<exp>[-+]? \d+))?
3103# \s*
3104 $
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003105""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003106
3107del re
3108
Martin v. Löwiscfe31282006-07-19 17:18:32 +00003109# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003110
3111def _string2exact(s):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003112 m = _parser(s)
3113 if m is None:
3114 raise ValueError("invalid literal for Decimal: %r" % s)
3115
3116 if m.group('sign') == "-":
3117 sign = 1
3118 else:
3119 sign = 0
3120
3121 exp = m.group('exp')
3122 if exp is None:
3123 exp = 0
3124 else:
3125 exp = int(exp)
3126
3127 intpart = m.group('int')
3128 if intpart is None:
3129 intpart = ""
3130 fracpart = m.group('onlyfrac')
3131 else:
3132 fracpart = m.group('frac')
3133 if fracpart is None:
3134 fracpart = ""
3135
3136 exp -= len(fracpart)
3137
3138 mantissa = intpart + fracpart
3139 tmp = map(int, mantissa)
3140 backup = tmp
3141 while tmp and tmp[0] == 0:
3142 del tmp[0]
3143
3144 # It's a zero
3145 if not tmp:
3146 if backup:
3147 return (sign, tuple(backup), exp)
3148 return (sign, (0,), exp)
3149 mantissa = tuple(tmp)
3150
3151 return (sign, mantissa, exp)
3152
3153
3154if __name__ == '__main__':
3155 import doctest, sys
3156 doctest.testmod(sys.modules[__name__])