blob: cca0a442174a45a2330cd97619eb045073051957 [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
Guido van Rossumd8faa362007-04-27 19:54:29 +000032The purpose of this module is to support arithmetic using familiar
33"schoolhouse" rules and to avoid some of the 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)
Guido van Rossum7131f842007-02-09 20:13:25 +000059>>> print(dig / Decimal(3))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000600.333333333
61>>> getcontext().prec = 18
Guido van Rossum7131f842007-02-09 20:13:25 +000062>>> print(dig / Decimal(3))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000630.333333333333333333
Guido van Rossum7131f842007-02-09 20:13:25 +000064>>> print(dig.sqrt())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000651
Guido van Rossum7131f842007-02-09 20:13:25 +000066>>> print(Decimal(3).sqrt())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000671.73205080756887729
Guido van Rossum7131f842007-02-09 20:13:25 +000068>>> print(Decimal(3) ** 123)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000694.85192780976896427E+58
70>>> inf = Decimal(1) / Decimal(0)
Guido van Rossum7131f842007-02-09 20:13:25 +000071>>> print(inf)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000072Infinity
73>>> neginf = Decimal(-1) / Decimal(0)
Guido van Rossum7131f842007-02-09 20:13:25 +000074>>> print(neginf)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000075-Infinity
Guido van Rossum7131f842007-02-09 20:13:25 +000076>>> print(neginf + inf)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000077NaN
Guido van Rossum7131f842007-02-09 20:13:25 +000078>>> print(neginf * inf)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000079-Infinity
Guido van Rossum7131f842007-02-09 20:13:25 +000080>>> print(dig / 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000081Infinity
Raymond Hettingerbf440692004-07-10 14:14:37 +000082>>> getcontext().traps[DivisionByZero] = 1
Guido van Rossum7131f842007-02-09 20:13:25 +000083>>> print(dig / 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000084Traceback (most recent call last):
85 ...
86 ...
87 ...
Guido van Rossum6a2a2a02006-08-26 20:37:44 +000088decimal.DivisionByZero: x / 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000089>>> c = Context()
Raymond Hettingerbf440692004-07-10 14:14:37 +000090>>> c.traps[InvalidOperation] = 0
Guido van Rossum7131f842007-02-09 20:13:25 +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
Guido van Rossum7131f842007-02-09 20:13:25 +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
Guido van Rossum7131f842007-02-09 20:13:25 +000099>>> print(c.flags[InvalidOperation])
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001000
Guido van Rossum7131f842007-02-09 20:13:25 +0000101>>> print(c.divide(Decimal(0), Decimal(0)))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000102Traceback (most recent call last):
103 ...
104 ...
105 ...
Guido van Rossum6a2a2a02006-08-26 20:37:44 +0000106decimal.InvalidOperation: 0 / 0
Guido van Rossum7131f842007-02-09 20:13:25 +0000107>>> 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
Guido van Rossum7131f842007-02-09 20:13:25 +0000111>>> print(c.divide(Decimal(0), Decimal(0)))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000112NaN
Guido van Rossum7131f842007-02-09 20:13:25 +0000113>>> print(c.flags[InvalidOperation])
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001141
115>>>
116"""
117
118__all__ = [
119 # Two major classes
120 'Decimal', 'Context',
121
122 # Contexts
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +0000123 'DefaultContext', 'BasicContext', 'ExtendedContext',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000124
125 # Exceptions
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +0000126 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
127 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000128
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000129 # Constants for use in setting up contexts
130 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING',
131 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000132
133 # Functions for manipulating contexts
Thomas Wouters89f507f2006-12-13 04:49:30 +0000134 'setcontext', 'getcontext', 'localcontext'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000135]
136
Raymond Hettingereb260842005-06-07 18:52:34 +0000137import copy as _copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000138
Guido van Rossumd8faa362007-04-27 19:54:29 +0000139# Rounding
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000140ROUND_DOWN = 'ROUND_DOWN'
141ROUND_HALF_UP = 'ROUND_HALF_UP'
142ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
143ROUND_CEILING = 'ROUND_CEILING'
144ROUND_FLOOR = 'ROUND_FLOOR'
145ROUND_UP = 'ROUND_UP'
146ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000147
Guido van Rossumd8faa362007-04-27 19:54:29 +0000148# Rounding decision (not part of the public API)
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000149NEVER_ROUND = 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY
150ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000151
Guido van Rossumd8faa362007-04-27 19:54:29 +0000152# Errors
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000153
154class DecimalException(ArithmeticError):
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000155 """Base exception class.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000156
157 Used exceptions derive from this.
158 If an exception derives from another exception besides this (such as
159 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
160 called if the others are present. This isn't actually used for
161 anything, though.
162
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000163 handle -- Called when context._raise_error is called and the
164 trap_enabler is set. First argument is self, second is the
165 context. More arguments can be given, those being after
166 the explanation in _raise_error (For example,
167 context._raise_error(NewError, '(-x)!', self._sign) would
168 call NewError().handle(context, self._sign).)
169
170 To define a new exception, it should be sufficient to have it derive
171 from DecimalException.
172 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000173 def handle(self, context, *args):
174 pass
175
176
177class Clamped(DecimalException):
178 """Exponent of a 0 changed to fit bounds.
179
180 This occurs and signals clamped if the exponent of a result has been
181 altered in order to fit the constraints of a specific concrete
Guido van Rossumd8faa362007-04-27 19:54:29 +0000182 representation. This may occur when the exponent of a zero result would
183 be outside the bounds of a representation, or when a large normal
184 number would have an encoded exponent that cannot be represented. In
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000185 this latter case, the exponent is reduced to fit and the corresponding
186 number of zero digits are appended to the coefficient ("fold-down").
187 """
188
189
190class InvalidOperation(DecimalException):
191 """An invalid operation was performed.
192
193 Various bad things cause this:
194
195 Something creates a signaling NaN
196 -INF + INF
Guido van Rossumd8faa362007-04-27 19:54:29 +0000197 0 * (+-)INF
198 (+-)INF / (+-)INF
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000199 x % 0
200 (+-)INF % x
201 x._rescale( non-integer )
202 sqrt(-x) , x > 0
203 0 ** 0
204 x ** (non-integer)
205 x ** (+-)INF
206 An operand is invalid
207 """
208 def handle(self, context, *args):
209 if args:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000210 if args[0] == 1: # sNaN, must drop 's' but keep diagnostics
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000211 return Decimal( (args[1]._sign, args[1]._int, 'n') )
212 return NaN
213
214class ConversionSyntax(InvalidOperation):
215 """Trying to convert badly formed string.
216
217 This occurs and signals invalid-operation if an string is being
218 converted to a number and it does not conform to the numeric string
Guido van Rossumd8faa362007-04-27 19:54:29 +0000219 syntax. The result is [0,qNaN].
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000220 """
221
222 def handle(self, context, *args):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000223 return (0, (0,), 'n') # Passed to something which uses a tuple.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000224
225class DivisionByZero(DecimalException, ZeroDivisionError):
226 """Division by 0.
227
228 This occurs and signals division-by-zero if division of a finite number
229 by zero was attempted (during a divide-integer or divide operation, or a
230 power operation with negative right-hand operand), and the dividend was
231 not zero.
232
233 The result of the operation is [sign,inf], where sign is the exclusive
234 or of the signs of the operands for divide, or is 1 for an odd power of
235 -0, for power.
236 """
237
238 def handle(self, context, sign, double = None, *args):
239 if double is not None:
240 return (Infsign[sign],)*2
241 return Infsign[sign]
242
243class DivisionImpossible(InvalidOperation):
244 """Cannot perform the division adequately.
245
246 This occurs and signals invalid-operation if the integer result of a
247 divide-integer or remainder operation had too many digits (would be
Guido van Rossumd8faa362007-04-27 19:54:29 +0000248 longer than precision). The result is [0,qNaN].
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000249 """
250
251 def handle(self, context, *args):
252 return (NaN, NaN)
253
254class DivisionUndefined(InvalidOperation, ZeroDivisionError):
255 """Undefined result of division.
256
257 This occurs and signals invalid-operation if division by zero was
258 attempted (during a divide-integer, divide, or remainder operation), and
Guido van Rossumd8faa362007-04-27 19:54:29 +0000259 the dividend is also zero. The result is [0,qNaN].
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000260 """
261
262 def handle(self, context, tup=None, *args):
263 if tup is not None:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000264 return (NaN, NaN) # for 0 %0, 0 // 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000265 return NaN
266
267class Inexact(DecimalException):
268 """Had to round, losing information.
269
270 This occurs and signals inexact whenever the result of an operation is
271 not exact (that is, it needed to be rounded and any discarded digits
Guido van Rossumd8faa362007-04-27 19:54:29 +0000272 were non-zero), or if an overflow or underflow condition occurs. The
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000273 result in all cases is unchanged.
274
275 The inexact signal may be tested (or trapped) to determine if a given
276 operation (or sequence of operations) was inexact.
277 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000278 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000279
280class InvalidContext(InvalidOperation):
281 """Invalid context. Unknown rounding, for example.
282
283 This occurs and signals invalid-operation if an invalid context was
Guido van Rossumd8faa362007-04-27 19:54:29 +0000284 detected during an operation. This can occur if contexts are not checked
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000285 on creation and either the precision exceeds the capability of the
286 underlying concrete representation or an unknown or unsupported rounding
Guido van Rossumd8faa362007-04-27 19:54:29 +0000287 was specified. These aspects of the context need only be checked when
288 the values are required to be used. The result is [0,qNaN].
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000289 """
290
291 def handle(self, context, *args):
292 return NaN
293
294class Rounded(DecimalException):
295 """Number got rounded (not necessarily changed during rounding).
296
297 This occurs and signals rounded whenever the result of an operation is
298 rounded (that is, some zero or non-zero digits were discarded from the
Guido van Rossumd8faa362007-04-27 19:54:29 +0000299 coefficient), or if an overflow or underflow condition occurs. The
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000300 result in all cases is unchanged.
301
302 The rounded signal may be tested (or trapped) to determine if a given
303 operation (or sequence of operations) caused a loss of precision.
304 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000305 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000306
307class Subnormal(DecimalException):
308 """Exponent < Emin before rounding.
309
310 This occurs and signals subnormal whenever the result of a conversion or
311 operation is subnormal (that is, its adjusted exponent is less than
Guido van Rossumd8faa362007-04-27 19:54:29 +0000312 Emin, before any rounding). The result in all cases is unchanged.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000313
314 The subnormal signal may be tested (or trapped) to determine if a given
315 or operation (or sequence of operations) yielded a subnormal result.
316 """
317 pass
318
319class Overflow(Inexact, Rounded):
320 """Numerical overflow.
321
322 This occurs and signals overflow if the adjusted exponent of a result
323 (from a conversion or from an operation that is not an attempt to divide
324 by zero), after rounding, would be greater than the largest value that
325 can be handled by the implementation (the value Emax).
326
327 The result depends on the rounding mode:
328
329 For round-half-up and round-half-even (and for round-half-down and
330 round-up, if implemented), the result of the operation is [sign,inf],
Guido van Rossumd8faa362007-04-27 19:54:29 +0000331 where sign is the sign of the intermediate result. For round-down, the
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000332 result is the largest finite number that can be represented in the
Guido van Rossumd8faa362007-04-27 19:54:29 +0000333 current precision, with the sign of the intermediate result. For
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000334 round-ceiling, the result is the same as for round-down if the sign of
Guido van Rossumd8faa362007-04-27 19:54:29 +0000335 the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000336 the result is the same as for round-down if the sign of the intermediate
Guido van Rossumd8faa362007-04-27 19:54:29 +0000337 result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000338 will also be raised.
339 """
340
341 def handle(self, context, sign, *args):
342 if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
343 ROUND_HALF_DOWN, ROUND_UP):
344 return Infsign[sign]
345 if sign == 0:
346 if context.rounding == ROUND_CEILING:
347 return Infsign[sign]
348 return Decimal((sign, (9,)*context.prec,
349 context.Emax-context.prec+1))
350 if sign == 1:
351 if context.rounding == ROUND_FLOOR:
352 return Infsign[sign]
353 return Decimal( (sign, (9,)*context.prec,
354 context.Emax-context.prec+1))
355
356
357class Underflow(Inexact, Rounded, Subnormal):
358 """Numerical underflow with result rounded to 0.
359
360 This occurs and signals underflow if a result is inexact and the
361 adjusted exponent of the result would be smaller (more negative) than
362 the smallest value that can be handled by the implementation (the value
Guido van Rossumd8faa362007-04-27 19:54:29 +0000363 Emin). That is, the result is both inexact and subnormal.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000364
365 The result after an underflow will be a subnormal number rounded, if
Guido van Rossumd8faa362007-04-27 19:54:29 +0000366 necessary, so that its exponent is not less than Etiny. This may result
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000367 in 0 with the sign of the intermediate result and an exponent of Etiny.
368
369 In all cases, Inexact, Rounded, and Subnormal will also be raised.
370 """
371
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000372# List of public traps and flags
Raymond Hettingerfed52962004-07-14 15:41:57 +0000373_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000374 Underflow, InvalidOperation, Subnormal]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000375
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000376# Map conditions (per the spec) to signals
377_condition_map = {ConversionSyntax:InvalidOperation,
378 DivisionImpossible:InvalidOperation,
379 DivisionUndefined:InvalidOperation,
380 InvalidContext:InvalidOperation}
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000381
Guido van Rossumd8faa362007-04-27 19:54:29 +0000382##### Context Functions ##################################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000383
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000384# The getcontext() and setcontext() function manage access to a thread-local
385# current context. Py2.4 offers direct support for thread locals. If that
386# is not available, use threading.currentThread() which is slower but will
Raymond Hettinger7e71fa52004-12-18 19:07:19 +0000387# work for older Pythons. If threads are not part of the build, create a
388# mock threading object with threading.local() returning the module namespace.
389
390try:
391 import threading
392except ImportError:
393 # Python was compiled without threads; create a mock object instead
394 import sys
Guido van Rossumd8faa362007-04-27 19:54:29 +0000395 class MockThreading(object):
Raymond Hettinger7e71fa52004-12-18 19:07:19 +0000396 def local(self, sys=sys):
397 return sys.modules[__name__]
398 threading = MockThreading()
399 del sys, MockThreading
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000400
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000401try:
402 threading.local
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000403
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000404except AttributeError:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000405
Guido van Rossumd8faa362007-04-27 19:54:29 +0000406 # To fix reloading, force it to create a new context
407 # Old contexts have different exceptions in their dicts, making problems.
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000408 if hasattr(threading.currentThread(), '__decimal_context__'):
409 del threading.currentThread().__decimal_context__
410
411 def setcontext(context):
412 """Set this thread's context to context."""
413 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000414 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000415 context.clear_flags()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000416 threading.currentThread().__decimal_context__ = context
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000417
418 def getcontext():
419 """Returns this thread's context.
420
421 If this thread does not yet have a context, returns
422 a new context and sets this thread's context.
423 New contexts are copies of DefaultContext.
424 """
425 try:
426 return threading.currentThread().__decimal_context__
427 except AttributeError:
428 context = Context()
429 threading.currentThread().__decimal_context__ = context
430 return context
431
432else:
433
434 local = threading.local()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000435 if hasattr(local, '__decimal_context__'):
436 del local.__decimal_context__
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000437
438 def getcontext(_local=local):
439 """Returns this thread's context.
440
441 If this thread does not yet have a context, returns
442 a new context and sets this thread's context.
443 New contexts are copies of DefaultContext.
444 """
445 try:
446 return _local.__decimal_context__
447 except AttributeError:
448 context = Context()
449 _local.__decimal_context__ = context
450 return context
451
452 def setcontext(context, _local=local):
453 """Set this thread's context to context."""
454 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000455 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000456 context.clear_flags()
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000457 _local.__decimal_context__ = context
458
459 del threading, local # Don't contaminate the namespace
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000460
Thomas Wouters89f507f2006-12-13 04:49:30 +0000461def localcontext(ctx=None):
462 """Return a context manager for a copy of the supplied context
463
464 Uses a copy of the current context if no context is specified
465 The returned context manager creates a local decimal context
466 in a with statement:
467 def sin(x):
468 with localcontext() as ctx:
469 ctx.prec += 2
470 # Rest of sin calculation algorithm
471 # uses a precision 2 greater than normal
Guido van Rossumd8faa362007-04-27 19:54:29 +0000472 return +s # Convert result to normal precision
Thomas Wouters89f507f2006-12-13 04:49:30 +0000473
474 def sin(x):
475 with localcontext(ExtendedContext):
476 # Rest of sin calculation algorithm
477 # uses the Extended Context from the
478 # General Decimal Arithmetic Specification
Guido van Rossumd8faa362007-04-27 19:54:29 +0000479 return +s # Convert result to normal context
Thomas Wouters89f507f2006-12-13 04:49:30 +0000480
481 """
482 # The string below can't be included in the docstring until Python 2.6
483 # as the doctest module doesn't understand __future__ statements
484 """
485 >>> from __future__ import with_statement
Guido van Rossum7131f842007-02-09 20:13:25 +0000486 >>> print(getcontext().prec)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000487 28
488 >>> with localcontext():
489 ... ctx = getcontext()
Thomas Wouterscf297e42007-02-23 15:07:44 +0000490 ... ctx.prec += 2
Guido van Rossum7131f842007-02-09 20:13:25 +0000491 ... print(ctx.prec)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000492 ...
Thomas Wouters89f507f2006-12-13 04:49:30 +0000493 30
494 >>> with localcontext(ExtendedContext):
Guido van Rossum7131f842007-02-09 20:13:25 +0000495 ... print(getcontext().prec)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000496 ...
Thomas Wouters89f507f2006-12-13 04:49:30 +0000497 9
Guido van Rossum7131f842007-02-09 20:13:25 +0000498 >>> print(getcontext().prec)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000499 28
500 """
501 if ctx is None: ctx = getcontext()
502 return _ContextManager(ctx)
503
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000504
Guido van Rossumd8faa362007-04-27 19:54:29 +0000505##### Decimal class #######################################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000506
507class Decimal(object):
508 """Floating point class for decimal arithmetic."""
509
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000510 __slots__ = ('_exp','_int','_sign', '_is_special')
511 # Generally, the value of the Decimal instance is given by
512 # (-1)**_sign * _int * 10**_exp
513 # Special values are signified by _is_special == True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000514
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000515 # We're immutable, so use __new__ not __init__
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000516 def __new__(cls, value="0", context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000517 """Create a decimal point instance.
518
519 >>> Decimal('3.14') # string input
520 Decimal("3.14")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000521 >>> Decimal((0, (3, 1, 4), -2)) # tuple (sign, digit_tuple, exponent)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000522 Decimal("3.14")
523 >>> Decimal(314) # int or long
524 Decimal("314")
525 >>> Decimal(Decimal(314)) # another decimal instance
526 Decimal("314")
527 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000528
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000529 self = object.__new__(cls)
530 self._is_special = False
531
532 # From an internal working value
533 if isinstance(value, _WorkRep):
Raymond Hettinger17931de2004-10-27 06:21:46 +0000534 self._sign = value.sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000535 self._int = tuple(map(int, str(value.int)))
536 self._exp = int(value.exp)
537 return self
538
539 # From another decimal
540 if isinstance(value, Decimal):
541 self._exp = value._exp
542 self._sign = value._sign
543 self._int = value._int
544 self._is_special = value._is_special
545 return self
546
547 # From an integer
Guido van Rossume2a383d2007-01-15 16:59:06 +0000548 if isinstance(value, (int,int)):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000549 if value >= 0:
550 self._sign = 0
551 else:
552 self._sign = 1
553 self._exp = 0
554 self._int = tuple(map(int, str(abs(value))))
555 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000556
557 # tuple/list conversion (possibly from as_tuple())
558 if isinstance(value, (list,tuple)):
559 if len(value) != 3:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000560 raise ValueError('Invalid arguments')
Raymond Hettingerdbecd932005-02-06 06:57:08 +0000561 if value[0] not in (0,1):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000562 raise ValueError('Invalid sign')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000563 for digit in value[1]:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000564 if not isinstance(digit, (int,int)) or digit < 0:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000565 raise ValueError("The second value in the tuple must be"
566 "composed of non negative integer elements.")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000567 self._sign = value[0]
568 self._int = tuple(value[1])
569 if value[2] in ('F','n','N'):
570 self._exp = value[2]
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000571 self._is_special = True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000572 else:
573 self._exp = int(value[2])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000574 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000575
Raymond Hettingerbf440692004-07-10 14:14:37 +0000576 if isinstance(value, float):
577 raise TypeError("Cannot convert float to Decimal. " +
578 "First convert the float to a string")
579
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000580 # Other argument types may require the context during interpretation
581 if context is None:
582 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000583
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000584 # From a string
585 # REs insist on real strings, so we can too.
586 if isinstance(value, basestring):
587 if _isinfinity(value):
588 self._exp = 'F'
589 self._int = (0,)
590 self._is_special = True
591 if _isinfinity(value) == 1:
592 self._sign = 0
593 else:
594 self._sign = 1
595 return self
596 if _isnan(value):
597 sig, sign, diag = _isnan(value)
598 self._is_special = True
Guido van Rossumd8faa362007-04-27 19:54:29 +0000599 if len(diag) > context.prec: # Diagnostic info too long
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000600 self._sign, self._int, self._exp = \
601 context._raise_error(ConversionSyntax)
602 return self
603 if sig == 1:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000604 self._exp = 'n' # qNaN
605 else: # sig == 2
606 self._exp = 'N' # sNaN
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000607 self._sign = sign
Guido van Rossumd8faa362007-04-27 19:54:29 +0000608 self._int = tuple(map(int, diag)) # Diagnostic info
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000609 return self
610 try:
611 self._sign, self._int, self._exp = _string2exact(value)
612 except ValueError:
613 self._is_special = True
Guido van Rossumd8faa362007-04-27 19:54:29 +0000614 self._sign, self._int, self._exp = \
Guido van Rossumaf554a02007-08-16 23:48:43 +0000615 context._raise_error(ConversionSyntax,
616 "Invalid literal for Decimal: %r" % value)
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000617 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000618
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000619 raise TypeError("Cannot convert %r to Decimal" % value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000620
621 def _isnan(self):
622 """Returns whether the number is not actually one.
623
624 0 if a number
625 1 if NaN
626 2 if sNaN
627 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000628 if self._is_special:
629 exp = self._exp
630 if exp == 'n':
631 return 1
632 elif exp == 'N':
633 return 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000634 return 0
635
636 def _isinfinity(self):
637 """Returns whether the number is infinite
638
639 0 if finite or not a number
640 1 if +INF
641 -1 if -INF
642 """
643 if self._exp == 'F':
644 if self._sign:
645 return -1
646 return 1
647 return 0
648
649 def _check_nans(self, other = None, context=None):
650 """Returns whether the number is not actually one.
651
652 if self, other are sNaN, signal
653 if self, other are NaN return nan
654 return 0
655
656 Done before operations.
657 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000658
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000659 self_is_nan = self._isnan()
660 if other is None:
661 other_is_nan = False
662 else:
663 other_is_nan = other._isnan()
664
665 if self_is_nan or other_is_nan:
666 if context is None:
667 context = getcontext()
668
669 if self_is_nan == 2:
670 return context._raise_error(InvalidOperation, 'sNaN',
671 1, self)
672 if other_is_nan == 2:
673 return context._raise_error(InvalidOperation, 'sNaN',
674 1, other)
675 if self_is_nan:
676 return self
677
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000678 return other
679 return 0
680
Jack Diederich4dafcc42006-11-28 19:15:13 +0000681 def __bool__(self):
Jack Diederich030debb2006-11-28 22:22:22 +0000682 """return True if the number is non-zero.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000683
Jack Diederich030debb2006-11-28 22:22:22 +0000684 False if self == 0
685 True if self != 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000686 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000687 if self._is_special:
Jack Diederich4dafcc42006-11-28 19:15:13 +0000688 return True
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000689 return sum(self._int) != 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000690
691 def __cmp__(self, other, context=None):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000692 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +0000693 if other is NotImplemented:
694 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000695
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000696 if self._is_special or other._is_special:
697 ans = self._check_nans(other, context)
698 if ans:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000699 return 1 # Comparison involving NaN's always reports self > other
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000700
701 # INF = INF
702 return cmp(self._isinfinity(), other._isinfinity())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000703
704 if not self and not other:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000705 return 0 # If both 0, sign comparison isn't certain.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000706
Guido van Rossumd8faa362007-04-27 19:54:29 +0000707 # If different signs, neg one is less
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000708 if other._sign < self._sign:
709 return -1
710 if self._sign < other._sign:
711 return 1
712
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000713 self_adjusted = self.adjusted()
714 other_adjusted = other.adjusted()
715 if self_adjusted == other_adjusted and \
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000716 self._int + (0,)*(self._exp - other._exp) == \
717 other._int + (0,)*(other._exp - self._exp):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000718 return 0 # equal, except in precision. ([0]*(-x) = [])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000719 elif self_adjusted > other_adjusted and self._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000720 return (-1)**self._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000721 elif self_adjusted < other_adjusted and other._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000722 return -((-1)**self._sign)
723
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000724 # Need to round, so make sure we have a valid context
725 if context is None:
726 context = getcontext()
727
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000728 context = context._shallow_copy()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000729 rounding = context._set_rounding(ROUND_UP) # round away from 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000730
731 flags = context._ignore_all_flags()
732 res = self.__sub__(other, context=context)
733
734 context._regard_flags(*flags)
735
736 context.rounding = rounding
737
738 if not res:
739 return 0
740 elif res._sign:
741 return -1
742 return 1
743
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000744 def __eq__(self, other):
Walter Dörwaldaa97f042007-05-03 21:05:51 +0000745 if not isinstance(other, (Decimal, int)):
Raymond Hettinger267b8682005-03-27 10:47:39 +0000746 return NotImplemented
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000747 return self.__cmp__(other) == 0
748
749 def __ne__(self, other):
Walter Dörwaldaa97f042007-05-03 21:05:51 +0000750 if not isinstance(other, (Decimal, int)):
Raymond Hettinger267b8682005-03-27 10:47:39 +0000751 return NotImplemented
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000752 return self.__cmp__(other) != 0
753
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000754 def __lt__(self, other):
Walter Dörwaldaa97f042007-05-03 21:05:51 +0000755 if not isinstance(other, (Decimal, int)):
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000756 return NotImplemented
757 return self.__cmp__(other) < 0
758
759 def __le__(self, other):
Walter Dörwaldaa97f042007-05-03 21:05:51 +0000760 if not isinstance(other, (Decimal, int)):
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000761 return NotImplemented
762 return self.__cmp__(other) <= 0
763
764 def __gt__(self, other):
Walter Dörwaldaa97f042007-05-03 21:05:51 +0000765 if not isinstance(other, (Decimal, int)):
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000766 return NotImplemented
767 return self.__cmp__(other) > 0
768
769 def __ge__(self, other):
Walter Dörwaldaa97f042007-05-03 21:05:51 +0000770 if not isinstance(other, (Decimal, int)):
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000771 return NotImplemented
772 return self.__cmp__(other) >= 0
773
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000774 def compare(self, other, context=None):
775 """Compares one to another.
776
777 -1 => a < b
778 0 => a = b
779 1 => a > b
780 NaN => one is NaN
781 Like __cmp__, but returns Decimal instances.
782 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000783 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +0000784 if other is NotImplemented:
785 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000786
Guido van Rossumd8faa362007-04-27 19:54:29 +0000787 # Compare(NaN, NaN) = NaN
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000788 if (self._is_special or other and other._is_special):
789 ans = self._check_nans(other, context)
790 if ans:
791 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000792
793 return Decimal(self.__cmp__(other, context))
794
795 def __hash__(self):
796 """x.__hash__() <==> hash(x)"""
797 # Decimal integers must hash the same as the ints
798 # Non-integer decimals are normalized and hashed as strings
Thomas Wouters477c8d52006-05-27 19:21:47 +0000799 # Normalization assures that hash(100E-1) == hash(10)
Raymond Hettingerbea3f6f2005-03-15 04:59:17 +0000800 if self._is_special:
801 if self._isnan():
802 raise TypeError('Cannot hash a NaN value.')
803 return hash(str(self))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000804 i = int(self)
805 if self == Decimal(i):
806 return hash(i)
Jack Diederich4dafcc42006-11-28 19:15:13 +0000807 assert self.__bool__() # '-0' handled by integer case
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000808 return hash(str(self.normalize()))
809
810 def as_tuple(self):
811 """Represents the number as a triple tuple.
812
813 To show the internals exactly as they are.
814 """
815 return (self._sign, self._int, self._exp)
816
817 def __repr__(self):
818 """Represents the number as an instance of Decimal."""
819 # Invariant: eval(repr(d)) == d
820 return 'Decimal("%s")' % str(self)
821
822 def __str__(self, eng = 0, context=None):
823 """Return string representation of the number in scientific notation.
824
825 Captures all of the information in the underlying representation.
826 """
827
Raymond Hettingere5a0a962005-06-20 09:49:42 +0000828 if self._is_special:
829 if self._isnan():
830 minus = '-'*self._sign
831 if self._int == (0,):
832 info = ''
833 else:
834 info = ''.join(map(str, self._int))
835 if self._isnan() == 2:
836 return minus + 'sNaN' + info
837 return minus + 'NaN' + info
838 if self._isinfinity():
839 minus = '-'*self._sign
840 return minus + 'Infinity'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000841
842 if context is None:
843 context = getcontext()
844
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000845 tmp = list(map(str, self._int))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000846 numdigits = len(self._int)
847 leftdigits = self._exp + numdigits
Guido van Rossumd8faa362007-04-27 19:54:29 +0000848 if eng and not self: # self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
849 if self._exp < 0 and self._exp >= -6: # short, no need for e/E
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000850 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
851 return s
Guido van Rossumd8faa362007-04-27 19:54:29 +0000852 # exp is closest mult. of 3 >= self._exp
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000853 exp = ((self._exp - 1)// 3 + 1) * 3
854 if exp != self._exp:
855 s = '0.'+'0'*(exp - self._exp)
856 else:
857 s = '0'
858 if exp != 0:
859 if context.capitals:
860 s += 'E'
861 else:
862 s += 'e'
863 if exp > 0:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000864 s += '+' # 0.0e+3, not 0.0e3
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000865 s += str(exp)
866 s = '-'*self._sign + s
867 return s
868 if eng:
869 dotplace = (leftdigits-1)%3+1
870 adjexp = leftdigits -1 - (leftdigits-1)%3
871 else:
872 adjexp = leftdigits-1
873 dotplace = 1
874 if self._exp == 0:
875 pass
876 elif self._exp < 0 and adjexp >= 0:
877 tmp.insert(leftdigits, '.')
878 elif self._exp < 0 and adjexp >= -6:
879 tmp[0:0] = ['0'] * int(-leftdigits)
880 tmp.insert(0, '0.')
881 else:
882 if numdigits > dotplace:
883 tmp.insert(dotplace, '.')
884 elif numdigits < dotplace:
885 tmp.extend(['0']*(dotplace-numdigits))
886 if adjexp:
887 if not context.capitals:
888 tmp.append('e')
889 else:
890 tmp.append('E')
891 if adjexp > 0:
892 tmp.append('+')
893 tmp.append(str(adjexp))
894 if eng:
895 while tmp[0:1] == ['0']:
896 tmp[0:1] = []
897 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
898 tmp[0:0] = ['0']
899 if self._sign:
900 tmp.insert(0, '-')
901
902 return ''.join(tmp)
903
904 def to_eng_string(self, context=None):
905 """Convert to engineering-type string.
906
907 Engineering notation has an exponent which is a multiple of 3, so there
908 are up to 3 digits left of the decimal place.
909
910 Same rules for when in exponential and when as a value as in __str__.
911 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000912 return self.__str__(eng=1, context=context)
913
914 def __neg__(self, context=None):
915 """Returns a copy with the sign switched.
916
917 Rounds, if it has reason.
918 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000919 if self._is_special:
920 ans = self._check_nans(context=context)
921 if ans:
922 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000923
924 if not self:
925 # -Decimal('0') is Decimal('0'), not Decimal('-0')
926 sign = 0
927 elif self._sign:
928 sign = 0
929 else:
930 sign = 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000931
932 if context is None:
933 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000934 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000935 return Decimal((sign, self._int, self._exp))._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000936 return Decimal( (sign, self._int, self._exp))
937
938 def __pos__(self, context=None):
939 """Returns a copy, unless it is a sNaN.
940
941 Rounds the number (if more then precision digits)
942 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000943 if self._is_special:
944 ans = self._check_nans(context=context)
945 if ans:
946 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000947
948 sign = self._sign
949 if not self:
950 # + (-0) = 0
951 sign = 0
952
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000953 if context is None:
954 context = getcontext()
955
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000956 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000957 ans = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000958 else:
959 ans = Decimal(self)
960 ans._sign = sign
961 return ans
962
963 def __abs__(self, round=1, context=None):
964 """Returns the absolute value of self.
965
966 If the second argument is 0, do not round.
967 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000968 if self._is_special:
969 ans = self._check_nans(context=context)
970 if ans:
971 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000972
973 if not round:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000974 if context is None:
975 context = getcontext()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000976 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000977 context._set_rounding_decision(NEVER_ROUND)
978
979 if self._sign:
980 ans = self.__neg__(context=context)
981 else:
982 ans = self.__pos__(context=context)
983
984 return ans
985
986 def __add__(self, other, context=None):
987 """Returns self + other.
988
989 -INF + INF (or the reverse) cause InvalidOperation errors.
990 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000991 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +0000992 if other is NotImplemented:
993 return other
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000994
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000995 if context is None:
996 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000997
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000998 if self._is_special or other._is_special:
999 ans = self._check_nans(other, context)
1000 if ans:
1001 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001002
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001003 if self._isinfinity():
Guido van Rossumd8faa362007-04-27 19:54:29 +00001004 # If both INF, same sign => same as both, opposite => error.
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001005 if self._sign != other._sign and other._isinfinity():
1006 return context._raise_error(InvalidOperation, '-INF + INF')
1007 return Decimal(self)
1008 if other._isinfinity():
Guido van Rossumd8faa362007-04-27 19:54:29 +00001009 return Decimal(other) # Can't both be infinity here
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001010
1011 shouldround = context._rounding_decision == ALWAYS_ROUND
1012
1013 exp = min(self._exp, other._exp)
1014 negativezero = 0
1015 if context.rounding == ROUND_FLOOR and self._sign != other._sign:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001016 # If the answer is 0, the sign should be negative, in this case.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001017 negativezero = 1
1018
1019 if not self and not other:
1020 sign = min(self._sign, other._sign)
1021 if negativezero:
1022 sign = 1
1023 return Decimal( (sign, (0,), exp))
1024 if not self:
Facundo Batista99b55482004-10-26 23:38:46 +00001025 exp = max(exp, other._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001026 ans = other._rescale(exp, watchexp=0, context=context)
1027 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001028 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001029 return ans
1030 if not other:
Facundo Batista99b55482004-10-26 23:38:46 +00001031 exp = max(exp, self._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001032 ans = self._rescale(exp, watchexp=0, context=context)
1033 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001034 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001035 return ans
1036
1037 op1 = _WorkRep(self)
1038 op2 = _WorkRep(other)
1039 op1, op2 = _normalize(op1, op2, shouldround, context.prec)
1040
1041 result = _WorkRep()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001042 if op1.sign != op2.sign:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001043 # Equal and opposite
Raymond Hettinger17931de2004-10-27 06:21:46 +00001044 if op1.int == op2.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001045 if exp < context.Etiny():
1046 exp = context.Etiny()
1047 context._raise_error(Clamped)
1048 return Decimal((negativezero, (0,), exp))
Raymond Hettinger17931de2004-10-27 06:21:46 +00001049 if op1.int < op2.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001050 op1, op2 = op2, op1
Guido van Rossumd8faa362007-04-27 19:54:29 +00001051 # OK, now abs(op1) > abs(op2)
Raymond Hettinger17931de2004-10-27 06:21:46 +00001052 if op1.sign == 1:
1053 result.sign = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001054 op1.sign, op2.sign = op2.sign, op1.sign
1055 else:
Raymond Hettinger17931de2004-10-27 06:21:46 +00001056 result.sign = 0
Guido van Rossumd8faa362007-04-27 19:54:29 +00001057 # So we know the sign, and op1 > 0.
Raymond Hettinger17931de2004-10-27 06:21:46 +00001058 elif op1.sign == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001059 result.sign = 1
Raymond Hettinger17931de2004-10-27 06:21:46 +00001060 op1.sign, op2.sign = (0, 0)
1061 else:
1062 result.sign = 0
Guido van Rossumd8faa362007-04-27 19:54:29 +00001063 # Now, op1 > abs(op2) > 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001064
Raymond Hettinger17931de2004-10-27 06:21:46 +00001065 if op2.sign == 0:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001066 result.int = op1.int + op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001067 else:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001068 result.int = op1.int - op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001069
1070 result.exp = op1.exp
1071 ans = Decimal(result)
1072 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001073 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001074 return ans
1075
1076 __radd__ = __add__
1077
1078 def __sub__(self, other, context=None):
1079 """Return self + (-other)"""
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
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001084 if self._is_special or other._is_special:
1085 ans = self._check_nans(other, context=context)
1086 if ans:
1087 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001088
1089 # -Decimal(0) = Decimal(0), which we don't want since
1090 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
1091 # so we change the sign directly to a copy
1092 tmp = Decimal(other)
1093 tmp._sign = 1-tmp._sign
1094
1095 return self.__add__(tmp, context=context)
1096
1097 def __rsub__(self, other, context=None):
1098 """Return other + (-self)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001099 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001100 if other is NotImplemented:
1101 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001102
1103 tmp = Decimal(self)
1104 tmp._sign = 1 - tmp._sign
1105 return other.__add__(tmp, context=context)
1106
1107 def _increment(self, round=1, context=None):
1108 """Special case of add, adding 1eExponent
1109
1110 Since it is common, (rounding, for example) this adds
1111 (sign)*one E self._exp to the number more efficiently than add.
1112
1113 For example:
1114 Decimal('5.624e10')._increment() == Decimal('5.625e10')
1115 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001116 if self._is_special:
1117 ans = self._check_nans(context=context)
1118 if ans:
1119 return ans
1120
Guido van Rossumd8faa362007-04-27 19:54:29 +00001121 # Must be infinite, and incrementing makes no difference
1122 return Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001123
1124 L = list(self._int)
1125 L[-1] += 1
1126 spot = len(L)-1
1127 while L[spot] == 10:
1128 L[spot] = 0
1129 if spot == 0:
1130 L[0:0] = [1]
1131 break
1132 L[spot-1] += 1
1133 spot -= 1
1134 ans = Decimal((self._sign, L, self._exp))
1135
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001136 if context is None:
1137 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001138 if round and context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001139 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001140 return ans
1141
1142 def __mul__(self, other, context=None):
1143 """Return self * other.
1144
1145 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1146 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001147 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001148 if other is NotImplemented:
1149 return other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001150
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001151 if context is None:
1152 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001153
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001154 resultsign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001155
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001156 if self._is_special or other._is_special:
1157 ans = self._check_nans(other, context)
1158 if ans:
1159 return ans
1160
1161 if self._isinfinity():
1162 if not other:
1163 return context._raise_error(InvalidOperation, '(+-)INF * 0')
1164 return Infsign[resultsign]
1165
1166 if other._isinfinity():
1167 if not self:
1168 return context._raise_error(InvalidOperation, '0 * (+-)INF')
1169 return Infsign[resultsign]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001170
1171 resultexp = self._exp + other._exp
1172 shouldround = context._rounding_decision == ALWAYS_ROUND
1173
1174 # Special case for multiplying by zero
1175 if not self or not other:
1176 ans = Decimal((resultsign, (0,), resultexp))
1177 if shouldround:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001178 # Fixing in case the exponent is out of bounds
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001179 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001180 return ans
1181
1182 # Special case for multiplying by power of 10
1183 if self._int == (1,):
1184 ans = Decimal((resultsign, other._int, resultexp))
1185 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001186 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001187 return ans
1188 if other._int == (1,):
1189 ans = Decimal((resultsign, self._int, resultexp))
1190 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001191 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001192 return ans
1193
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001194 op1 = _WorkRep(self)
1195 op2 = _WorkRep(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001196
Guido van Rossumc1f779c2007-07-03 08:25:58 +00001197 ans = Decimal((resultsign,
1198 tuple(map(int, str(op1.int * op2.int))),
1199 resultexp))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001200 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001201 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001202
1203 return ans
1204 __rmul__ = __mul__
1205
Neal Norwitzbcc0db82006-03-24 08:14:36 +00001206 def __truediv__(self, other, context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001207 """Return self / other."""
1208 return self._divide(other, context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001209
1210 def _divide(self, other, divmod = 0, context=None):
1211 """Return a / b, to context.prec precision.
1212
1213 divmod:
1214 0 => true division
1215 1 => (a //b, a%b)
1216 2 => a //b
1217 3 => a%b
1218
1219 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1220 computing the other value are not raised.
1221 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001222 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001223 if other is NotImplemented:
1224 if divmod in (0, 1):
1225 return NotImplemented
1226 return (NotImplemented, NotImplemented)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001227
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001228 if context is None:
1229 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001230
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001231 sign = self._sign ^ other._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001232
1233 if self._is_special or other._is_special:
1234 ans = self._check_nans(other, context)
1235 if ans:
1236 if divmod:
1237 return (ans, ans)
1238 return ans
1239
1240 if self._isinfinity() and other._isinfinity():
1241 if divmod:
1242 return (context._raise_error(InvalidOperation,
1243 '(+-)INF // (+-)INF'),
1244 context._raise_error(InvalidOperation,
1245 '(+-)INF % (+-)INF'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001246 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001247
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001248 if self._isinfinity():
1249 if divmod == 1:
1250 return (Infsign[sign],
1251 context._raise_error(InvalidOperation, 'INF % x'))
1252 elif divmod == 2:
1253 return (Infsign[sign], NaN)
1254 elif divmod == 3:
1255 return (Infsign[sign],
1256 context._raise_error(InvalidOperation, 'INF % x'))
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001257 return Infsign[sign]
1258
1259 if other._isinfinity():
1260 if divmod:
1261 return (Decimal((sign, (0,), 0)), Decimal(self))
1262 context._raise_error(Clamped, 'Division by infinity')
1263 return Decimal((sign, (0,), context.Etiny()))
1264
1265 # Special cases for zeroes
1266 if not self and not other:
1267 if divmod:
1268 return context._raise_error(DivisionUndefined, '0 / 0', 1)
1269 return context._raise_error(DivisionUndefined, '0 / 0')
1270
1271 if not self:
1272 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001273 otherside = Decimal(self)
1274 otherside._exp = min(self._exp, other._exp)
1275 return (Decimal((sign, (0,), 0)), otherside)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001276 exp = self._exp - other._exp
1277 if exp < context.Etiny():
1278 exp = context.Etiny()
1279 context._raise_error(Clamped, '0e-x / y')
1280 if exp > context.Emax:
1281 exp = context.Emax
1282 context._raise_error(Clamped, '0e+x / y')
1283 return Decimal( (sign, (0,), exp) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001284
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001285 if not other:
1286 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001287 return context._raise_error(DivisionByZero, 'divmod(x,0)',
1288 sign, 1)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001289 return context._raise_error(DivisionByZero, 'x / 0', sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001290
Guido van Rossumd8faa362007-04-27 19:54:29 +00001291 # OK, so neither = 0, INF or NaN
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001292 shouldround = context._rounding_decision == ALWAYS_ROUND
1293
Guido van Rossumd8faa362007-04-27 19:54:29 +00001294 # If we're dividing into ints, and self < other, stop.
1295 # self.__abs__(0) does not round.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001296 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
1297
1298 if divmod == 1 or divmod == 3:
1299 exp = min(self._exp, other._exp)
1300 ans2 = self._rescale(exp, context=context, watchexp=0)
1301 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001302 ans2 = ans2._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001303 return (Decimal( (sign, (0,), 0) ),
1304 ans2)
1305
1306 elif divmod == 2:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001307 # Don't round the mod part, if we don't need it.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001308 return (Decimal( (sign, (0,), 0) ), Decimal(self))
1309
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001310 op1 = _WorkRep(self)
1311 op2 = _WorkRep(other)
1312 op1, op2, adjust = _adjust_coefficients(op1, op2)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001313 res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001314 if divmod and res.exp > context.prec + 1:
1315 return context._raise_error(DivisionImpossible)
1316
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001317 prec_limit = 10 ** context.prec
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001318 while 1:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001319 while op2.int <= op1.int:
1320 res.int += 1
1321 op1.int -= op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001322 if res.exp == 0 and divmod:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001323 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001324 return context._raise_error(DivisionImpossible)
1325 otherside = Decimal(op1)
1326 frozen = context._ignore_all_flags()
1327
1328 exp = min(self._exp, other._exp)
Raymond Hettinger17931de2004-10-27 06:21:46 +00001329 otherside = otherside._rescale(exp, context=context, watchexp=0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001330 context._regard_flags(*frozen)
1331 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001332 otherside = otherside._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001333 return (Decimal(res), otherside)
1334
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001335 if op1.int == 0 and adjust >= 0 and not divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001336 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001337 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001338 if divmod:
1339 return context._raise_error(DivisionImpossible)
1340 shouldround=1
1341 # Really, the answer is a bit higher, so adding a one to
1342 # the end will make sure the rounding is right.
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001343 if op1.int != 0:
1344 res.int *= 10
1345 res.int += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001346 res.exp -= 1
1347
1348 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001349 res.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001350 res.exp -= 1
1351 adjust += 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001352 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001353 op1.exp -= 1
1354
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001355 if res.exp == 0 and divmod and op2.int > op1.int:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001356 # Solves an error in precision. Same as a previous block.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001357
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001358 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001359 return context._raise_error(DivisionImpossible)
1360 otherside = Decimal(op1)
1361 frozen = context._ignore_all_flags()
1362
1363 exp = min(self._exp, other._exp)
1364 otherside = otherside._rescale(exp, context=context)
1365
1366 context._regard_flags(*frozen)
1367
1368 return (Decimal(res), otherside)
1369
1370 ans = Decimal(res)
1371 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001372 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001373 return ans
1374
Neal Norwitzbcc0db82006-03-24 08:14:36 +00001375 def __rtruediv__(self, other, context=None):
1376 """Swaps self/other and returns __truediv__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001377 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001378 if other is NotImplemented:
1379 return other
Neal Norwitzbcc0db82006-03-24 08:14:36 +00001380 return other.__truediv__(self, context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001381
1382 def __divmod__(self, other, context=None):
1383 """
1384 (self // other, self % other)
1385 """
1386 return self._divide(other, 1, context)
1387
1388 def __rdivmod__(self, other, context=None):
1389 """Swaps self/other and returns __divmod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001390 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001391 if other is NotImplemented:
1392 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001393 return other.__divmod__(self, context=context)
1394
1395 def __mod__(self, other, context=None):
1396 """
1397 self % other
1398 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001399 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001400 if other is NotImplemented:
1401 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001402
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001403 if self._is_special or other._is_special:
1404 ans = self._check_nans(other, context)
1405 if ans:
1406 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001407
1408 if self and not other:
1409 return context._raise_error(InvalidOperation, 'x % 0')
1410
1411 return self._divide(other, 3, context)[1]
1412
1413 def __rmod__(self, other, context=None):
1414 """Swaps self/other and returns __mod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001415 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001416 if other is NotImplemented:
1417 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001418 return other.__mod__(self, context=context)
1419
1420 def remainder_near(self, other, context=None):
1421 """
1422 Remainder nearest to 0- abs(remainder-near) <= other/2
1423 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001424 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001425 if other is NotImplemented:
1426 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001427
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001428 if self._is_special or other._is_special:
1429 ans = self._check_nans(other, context)
1430 if ans:
1431 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001432 if self and not other:
1433 return context._raise_error(InvalidOperation, 'x % 0')
1434
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001435 if context is None:
1436 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001437 # If DivisionImpossible causes an error, do not leave Rounded/Inexact
1438 # ignored in the calling function.
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001439 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001440 flags = context._ignore_flags(Rounded, Inexact)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001441 # Keep DivisionImpossible flags
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001442 (side, r) = self.__divmod__(other, context=context)
1443
1444 if r._isnan():
1445 context._regard_flags(*flags)
1446 return r
1447
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001448 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001449 rounding = context._set_rounding_decision(NEVER_ROUND)
1450
1451 if other._sign:
Neal Norwitzbcc0db82006-03-24 08:14:36 +00001452 comparison = other.__truediv__(Decimal(-2), context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001453 else:
Neal Norwitzbcc0db82006-03-24 08:14:36 +00001454 comparison = other.__truediv__(Decimal(2), context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001455
1456 context._set_rounding_decision(rounding)
1457 context._regard_flags(*flags)
1458
1459 s1, s2 = r._sign, comparison._sign
1460 r._sign, comparison._sign = 0, 0
1461
1462 if r < comparison:
1463 r._sign, comparison._sign = s1, s2
Guido van Rossumd8faa362007-04-27 19:54:29 +00001464 # Get flags now
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001465 self.__divmod__(other, context=context)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001466 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001467 r._sign, comparison._sign = s1, s2
1468
1469 rounding = context._set_rounding_decision(NEVER_ROUND)
1470
1471 (side, r) = self.__divmod__(other, context=context)
1472 context._set_rounding_decision(rounding)
1473 if r._isnan():
1474 return r
1475
1476 decrease = not side._iseven()
1477 rounding = context._set_rounding_decision(NEVER_ROUND)
1478 side = side.__abs__(context=context)
1479 context._set_rounding_decision(rounding)
1480
1481 s1, s2 = r._sign, comparison._sign
1482 r._sign, comparison._sign = 0, 0
1483 if r > comparison or decrease and r == comparison:
1484 r._sign, comparison._sign = s1, s2
1485 context.prec += 1
Guido van Rossumd8faa362007-04-27 19:54:29 +00001486 numbsquant = len(side.__add__(Decimal(1), context=context)._int)
1487 if numbsquant >= context.prec:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001488 context.prec -= 1
1489 return context._raise_error(DivisionImpossible)[1]
1490 context.prec -= 1
1491 if self._sign == other._sign:
1492 r = r.__sub__(other, context=context)
1493 else:
1494 r = r.__add__(other, context=context)
1495 else:
1496 r._sign, comparison._sign = s1, s2
1497
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001498 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001499
1500 def __floordiv__(self, other, context=None):
1501 """self // other"""
1502 return self._divide(other, 2, context)[0]
1503
1504 def __rfloordiv__(self, other, context=None):
1505 """Swaps self/other and returns __floordiv__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001506 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001507 if other is NotImplemented:
1508 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001509 return other.__floordiv__(self, context=context)
1510
1511 def __float__(self):
1512 """Float representation."""
1513 return float(str(self))
1514
1515 def __int__(self):
Brett Cannon46b08022005-03-01 03:12:26 +00001516 """Converts self to an int, truncating if necessary."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001517 if self._is_special:
1518 if self._isnan():
1519 context = getcontext()
1520 return context._raise_error(InvalidContext)
1521 elif self._isinfinity():
Guido van Rossumd8faa362007-04-27 19:54:29 +00001522 raise OverflowError("Cannot convert infinity to long")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001523 if self._exp >= 0:
Raymond Hettinger605ed022004-11-24 07:28:48 +00001524 s = ''.join(map(str, self._int)) + '0'*self._exp
1525 else:
1526 s = ''.join(map(str, self._int))[:self._exp]
1527 if s == '':
1528 s = '0'
1529 sign = '-'*self._sign
1530 return int(sign + s)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001531
1532 def __long__(self):
1533 """Converts to a long.
1534
1535 Equivalent to long(int(self))
1536 """
Guido van Rossume2a383d2007-01-15 16:59:06 +00001537 return int(self.__int__())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001538
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001539 def _fix(self, context):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001540 """Round if it is necessary to keep self within prec precision.
1541
1542 Rounds and fixes the exponent. Does not raise on a sNaN.
1543
1544 Arguments:
1545 self - Decimal instance
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001546 context - context used.
1547 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001548 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001549 return self
1550 if context is None:
1551 context = getcontext()
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001552 prec = context.prec
Facundo Batista99b55482004-10-26 23:38:46 +00001553 ans = self._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001554 if len(ans._int) > prec:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001555 ans = ans._round(prec, context=context)
Facundo Batista99b55482004-10-26 23:38:46 +00001556 ans = ans._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001557 return ans
1558
Facundo Batista99b55482004-10-26 23:38:46 +00001559 def _fixexponents(self, context):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001560 """Fix the exponents and return a copy with the exponent in bounds.
1561 Only call if known to not be a special value.
1562 """
1563 folddown = context._clamp
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001564 Emin = context.Emin
Facundo Batista99b55482004-10-26 23:38:46 +00001565 ans = self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001566 ans_adjusted = ans.adjusted()
1567 if ans_adjusted < Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001568 Etiny = context.Etiny()
1569 if ans._exp < Etiny:
1570 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001571 ans = Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001572 ans._exp = Etiny
1573 context._raise_error(Clamped)
1574 return ans
1575 ans = ans._rescale(Etiny, context=context)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001576 # It isn't zero, and exp < Emin => subnormal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001577 context._raise_error(Subnormal)
1578 if context.flags[Inexact]:
1579 context._raise_error(Underflow)
1580 else:
1581 if ans:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001582 # Only raise subnormal if non-zero.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001583 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001584 else:
1585 Etop = context.Etop()
1586 if folddown and ans._exp > Etop:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001587 context._raise_error(Clamped)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001588 ans = ans._rescale(Etop, context=context)
1589 else:
1590 Emax = context.Emax
1591 if ans_adjusted > Emax:
1592 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001593 ans = Decimal(self)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001594 ans._exp = Emax
1595 context._raise_error(Clamped)
1596 return ans
1597 context._raise_error(Inexact)
1598 context._raise_error(Rounded)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001599 c = context._raise_error(Overflow, 'above Emax', ans._sign)
1600 return c
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001601 return ans
1602
1603 def _round(self, prec=None, rounding=None, context=None):
1604 """Returns a rounded version of self.
1605
1606 You can specify the precision or rounding method. Otherwise, the
1607 context determines it.
1608 """
1609
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001610 if self._is_special:
1611 ans = self._check_nans(context=context)
1612 if ans:
1613 return ans
1614
1615 if self._isinfinity():
1616 return Decimal(self)
1617
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001618 if context is None:
1619 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001620
1621 if rounding is None:
1622 rounding = context.rounding
1623 if prec is None:
1624 prec = context.prec
1625
1626 if not self:
1627 if prec <= 0:
1628 dig = (0,)
1629 exp = len(self._int) - prec + self._exp
1630 else:
1631 dig = (0,) * prec
1632 exp = len(self._int) + self._exp - prec
1633 ans = Decimal((self._sign, dig, exp))
1634 context._raise_error(Rounded)
1635 return ans
1636
1637 if prec == 0:
1638 temp = Decimal(self)
1639 temp._int = (0,)+temp._int
1640 prec = 1
1641 elif prec < 0:
1642 exp = self._exp + len(self._int) - prec - 1
1643 temp = Decimal( (self._sign, (0, 1), exp))
1644 prec = 1
1645 else:
1646 temp = Decimal(self)
1647
1648 numdigits = len(temp._int)
1649 if prec == numdigits:
1650 return temp
1651
1652 # See if we need to extend precision
1653 expdiff = prec - numdigits
1654 if expdiff > 0:
1655 tmp = list(temp._int)
1656 tmp.extend([0] * expdiff)
1657 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff))
1658 return ans
1659
Guido van Rossumd8faa362007-04-27 19:54:29 +00001660 # OK, but maybe all the lost digits are 0.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001661 lostdigits = self._int[expdiff:]
1662 if lostdigits == (0,) * len(lostdigits):
1663 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
Guido van Rossumd8faa362007-04-27 19:54:29 +00001664 # Rounded, but not Inexact
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001665 context._raise_error(Rounded)
1666 return ans
1667
1668 # Okay, let's round and lose data
1669
1670 this_function = getattr(temp, self._pick_rounding_function[rounding])
Guido van Rossumd8faa362007-04-27 19:54:29 +00001671 # Now we've got the rounding function
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001672
1673 if prec != context.prec:
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001674 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001675 context.prec = prec
1676 ans = this_function(prec, expdiff, context)
1677 context._raise_error(Rounded)
1678 context._raise_error(Inexact, 'Changed in rounding')
1679
1680 return ans
1681
1682 _pick_rounding_function = {}
1683
1684 def _round_down(self, prec, expdiff, context):
1685 """Also known as round-towards-0, truncate."""
1686 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1687
1688 def _round_half_up(self, prec, expdiff, context, tmp = None):
1689 """Rounds 5 up (away from 0)"""
1690
1691 if tmp is None:
1692 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
1693 if self._int[prec] >= 5:
1694 tmp = tmp._increment(round=0, context=context)
1695 if len(tmp._int) > prec:
1696 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1697 return tmp
1698
1699 def _round_half_even(self, prec, expdiff, context):
1700 """Round 5 to even, rest to nearest."""
1701
1702 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1703 half = (self._int[prec] == 5)
1704 if half:
1705 for digit in self._int[prec+1:]:
1706 if digit != 0:
1707 half = 0
1708 break
1709 if half:
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001710 if self._int[prec-1] & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001711 return tmp
1712 return self._round_half_up(prec, expdiff, context, tmp)
1713
1714 def _round_half_down(self, prec, expdiff, context):
1715 """Round 5 down"""
1716
1717 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1718 half = (self._int[prec] == 5)
1719 if half:
1720 for digit in self._int[prec+1:]:
1721 if digit != 0:
1722 half = 0
1723 break
1724 if half:
1725 return tmp
1726 return self._round_half_up(prec, expdiff, context, tmp)
1727
1728 def _round_up(self, prec, expdiff, context):
1729 """Rounds away from 0."""
1730 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1731 for digit in self._int[prec:]:
1732 if digit != 0:
1733 tmp = tmp._increment(round=1, context=context)
1734 if len(tmp._int) > prec:
1735 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1736 else:
1737 return tmp
1738 return tmp
1739
1740 def _round_ceiling(self, prec, expdiff, context):
1741 """Rounds up (not away from 0 if negative.)"""
1742 if self._sign:
1743 return self._round_down(prec, expdiff, context)
1744 else:
1745 return self._round_up(prec, expdiff, context)
1746
1747 def _round_floor(self, prec, expdiff, context):
1748 """Rounds down (not towards 0 if negative)"""
1749 if not self._sign:
1750 return self._round_down(prec, expdiff, context)
1751 else:
1752 return self._round_up(prec, expdiff, context)
1753
1754 def __pow__(self, n, modulo = None, context=None):
1755 """Return self ** n (mod modulo)
1756
1757 If modulo is None (default), don't take it mod modulo.
1758 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001759 n = _convert_other(n)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001760 if n is NotImplemented:
1761 return n
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001762
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001763 if context is None:
1764 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001765
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001766 if self._is_special or n._is_special or n.adjusted() > 8:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001767 # Because the spot << doesn't work with really big exponents
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001768 if n._isinfinity() or n.adjusted() > 8:
1769 return context._raise_error(InvalidOperation, 'x ** INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001770
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001771 ans = self._check_nans(n, context)
1772 if ans:
1773 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001774
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001775 if not n._isinteger():
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001776 return context._raise_error(InvalidOperation, 'x ** (non-integer)')
1777
1778 if not self and not n:
1779 return context._raise_error(InvalidOperation, '0 ** 0')
1780
1781 if not n:
1782 return Decimal(1)
1783
1784 if self == Decimal(1):
1785 return Decimal(1)
1786
1787 sign = self._sign and not n._iseven()
1788 n = int(n)
1789
1790 if self._isinfinity():
1791 if modulo:
1792 return context._raise_error(InvalidOperation, 'INF % x')
1793 if n > 0:
1794 return Infsign[sign]
1795 return Decimal( (sign, (0,), 0) )
1796
Guido van Rossumd8faa362007-04-27 19:54:29 +00001797 # With ludicrously large exponent, just raise an overflow
1798 # and return inf.
1799 if not modulo and n > 0 and \
1800 (self._exp + len(self._int) - 1) * n > context.Emax and self:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001801
1802 tmp = Decimal('inf')
1803 tmp._sign = sign
1804 context._raise_error(Rounded)
1805 context._raise_error(Inexact)
1806 context._raise_error(Overflow, 'Big power', sign)
1807 return tmp
1808
1809 elength = len(str(abs(n)))
1810 firstprec = context.prec
1811
Raymond Hettinger99148e72004-07-14 19:56:56 +00001812 if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001813 return context._raise_error(Overflow, 'Too much precision.', sign)
1814
1815 mul = Decimal(self)
1816 val = Decimal(1)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001817 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001818 context.prec = firstprec + elength + 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001819 if n < 0:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001820 # n is a long now, not Decimal instance
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001821 n = -n
Neal Norwitzbcc0db82006-03-24 08:14:36 +00001822 mul = Decimal(1).__truediv__(mul, context=context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001823
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001824 spot = 1
1825 while spot <= n:
1826 spot <<= 1
1827
1828 spot >>= 1
Guido van Rossumd8faa362007-04-27 19:54:29 +00001829 # spot is the highest power of 2 less than n
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001830 while spot:
1831 val = val.__mul__(val, context=context)
1832 if val._isinfinity():
1833 val = Infsign[sign]
1834 break
1835 if spot & n:
1836 val = val.__mul__(mul, context=context)
1837 if modulo is not None:
1838 val = val.__mod__(modulo, context=context)
1839 spot >>= 1
1840 context.prec = firstprec
1841
Raymond Hettinger76e60d62004-10-20 06:58:28 +00001842 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001843 return val._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001844 return val
1845
1846 def __rpow__(self, other, context=None):
1847 """Swaps self/other and returns __pow__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001848 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001849 if other is NotImplemented:
1850 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001851 return other.__pow__(self, context=context)
1852
1853 def normalize(self, context=None):
1854 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001855
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001856 if self._is_special:
1857 ans = self._check_nans(context=context)
1858 if ans:
1859 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001860
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001861 dup = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001862 if dup._isinfinity():
1863 return dup
1864
1865 if not dup:
1866 return Decimal( (dup._sign, (0,), 0) )
1867 end = len(dup._int)
1868 exp = dup._exp
1869 while dup._int[end-1] == 0:
1870 exp += 1
1871 end -= 1
1872 return Decimal( (dup._sign, dup._int[:end], exp) )
1873
1874
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001875 def quantize(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001876 """Quantize self so its exponent is the same as that of exp.
1877
1878 Similar to self._rescale(exp._exp) but with error checking.
1879 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001880 if self._is_special or exp._is_special:
1881 ans = self._check_nans(exp, context)
1882 if ans:
1883 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001884
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001885 if exp._isinfinity() or self._isinfinity():
1886 if exp._isinfinity() and self._isinfinity():
Guido van Rossumd8faa362007-04-27 19:54:29 +00001887 return self # if both are inf, it is OK
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001888 if context is None:
1889 context = getcontext()
1890 return context._raise_error(InvalidOperation,
1891 'quantize with one INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001892 return self._rescale(exp._exp, rounding, context, watchexp)
1893
1894 def same_quantum(self, other):
1895 """Test whether self and other have the same exponent.
1896
1897 same as self._exp == other._exp, except NaN == sNaN
1898 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001899 if self._is_special or other._is_special:
1900 if self._isnan() or other._isnan():
1901 return self._isnan() and other._isnan() and True
1902 if self._isinfinity() or other._isinfinity():
1903 return self._isinfinity() and other._isinfinity() and True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001904 return self._exp == other._exp
1905
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001906 def _rescale(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001907 """Rescales so that the exponent is exp.
1908
1909 exp = exp to scale to (an integer)
1910 rounding = rounding version
1911 watchexp: if set (default) an error is returned if exp is greater
1912 than Emax or less than Etiny.
1913 """
1914 if context is None:
1915 context = getcontext()
1916
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001917 if self._is_special:
1918 if self._isinfinity():
1919 return context._raise_error(InvalidOperation, 'rescale with an INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001920
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001921 ans = self._check_nans(context=context)
1922 if ans:
1923 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001924
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001925 if watchexp and (context.Emax < exp or context.Etiny() > exp):
1926 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1927
1928 if not self:
1929 ans = Decimal(self)
1930 ans._int = (0,)
1931 ans._exp = exp
1932 return ans
1933
1934 diff = self._exp - exp
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001935 digits = len(self._int) + diff
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001936
1937 if watchexp and digits > context.prec:
1938 return context._raise_error(InvalidOperation, 'Rescale > prec')
1939
1940 tmp = Decimal(self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001941 tmp._int = (0,) + tmp._int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001942 digits += 1
1943
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001944 if digits < 0:
1945 tmp._exp = -digits + tmp._exp
1946 tmp._int = (0,1)
1947 digits = 1
1948 tmp = tmp._round(digits, rounding, context=context)
1949
1950 if tmp._int[0] == 0 and len(tmp._int) > 1:
1951 tmp._int = tmp._int[1:]
1952 tmp._exp = exp
1953
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001954 tmp_adjusted = tmp.adjusted()
1955 if tmp and tmp_adjusted < context.Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001956 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001957 elif tmp and tmp_adjusted > context.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001958 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1959 return tmp
1960
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001961 def to_integral(self, rounding=None, context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001962 """Rounds to the nearest integer, without raising inexact, rounded."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001963 if self._is_special:
1964 ans = self._check_nans(context=context)
1965 if ans:
1966 return ans
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001967 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001968 if self._exp >= 0:
1969 return self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001970 if context is None:
1971 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001972 flags = context._ignore_flags(Rounded, Inexact)
1973 ans = self._rescale(0, rounding, context=context)
1974 context._regard_flags(flags)
1975 return ans
1976
1977 def sqrt(self, context=None):
1978 """Return the square root of self.
1979
1980 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
1981 Should quadratically approach the right answer.
1982 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001983 if self._is_special:
1984 ans = self._check_nans(context=context)
1985 if ans:
1986 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001987
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001988 if self._isinfinity() and self._sign == 0:
1989 return Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001990
1991 if not self:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001992 # exponent = self._exp / 2, using round_down.
1993 # if self._exp < 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001994 # exp = (self._exp+1) // 2
Guido van Rossumd8faa362007-04-27 19:54:29 +00001995 # else:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001996 exp = (self._exp) // 2
1997 if self._sign == 1:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001998 # sqrt(-0) = -0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001999 return Decimal( (1, (0,), exp))
2000 else:
2001 return Decimal( (0, (0,), exp))
2002
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002003 if context is None:
2004 context = getcontext()
2005
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002006 if self._sign == 1:
2007 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
2008
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002009 tmp = Decimal(self)
2010
Raymond Hettinger4837a222004-09-27 14:23:40 +00002011 expadd = tmp._exp // 2
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002012 if tmp._exp & 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002013 tmp._int += (0,)
2014 tmp._exp = 0
2015 else:
2016 tmp._exp = 0
2017
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002018 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002019 flags = context._ignore_all_flags()
2020 firstprec = context.prec
2021 context.prec = 3
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002022 if tmp.adjusted() & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002023 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) )
2024 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
2025 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00002026 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002027 else:
2028 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
2029 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
2030 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00002031 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002032
Guido van Rossumd8faa362007-04-27 19:54:29 +00002033 # ans is now a linear approximation.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002034 Emax, Emin = context.Emax, context.Emin
Raymond Hettinger99148e72004-07-14 19:56:56 +00002035 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002036
2037 half = Decimal('0.5')
2038
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002039 maxp = firstprec + 2
2040 rounding = context._set_rounding(ROUND_HALF_EVEN)
2041 while 1:
2042 context.prec = min(2*context.prec - 2, maxp)
Neal Norwitzbcc0db82006-03-24 08:14:36 +00002043 ans = half.__mul__(ans.__add__(tmp.__truediv__(ans, context=context),
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002044 context=context), context=context)
2045 if context.prec == maxp:
2046 break
2047
Guido van Rossumd8faa362007-04-27 19:54:29 +00002048 # Round to the answer's precision-- the only error can be 1 ulp.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002049 context.prec = firstprec
2050 prevexp = ans.adjusted()
2051 ans = ans._round(context=context)
2052
Guido van Rossumd8faa362007-04-27 19:54:29 +00002053 # Now, check if the other last digits are better.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002054 context.prec = firstprec + 1
2055 # In case we rounded up another digit and we should actually go lower.
2056 if prevexp != ans.adjusted():
2057 ans._int += (0,)
2058 ans._exp -= 1
2059
2060
2061 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
2062 context._set_rounding(ROUND_UP)
2063 if lower.__mul__(lower, context=context) > (tmp):
2064 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
2065
2066 else:
2067 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
2068 context._set_rounding(ROUND_DOWN)
2069 if upper.__mul__(upper, context=context) < tmp:
2070 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
2071
2072 ans._exp += expadd
2073
2074 context.prec = firstprec
2075 context.rounding = rounding
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002076 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002077
2078 rounding = context._set_rounding_decision(NEVER_ROUND)
2079 if not ans.__mul__(ans, context=context) == self:
2080 # Only rounded/inexact if here.
2081 context._regard_flags(flags)
2082 context._raise_error(Rounded)
2083 context._raise_error(Inexact)
2084 else:
Guido van Rossumd8faa362007-04-27 19:54:29 +00002085 # Exact answer, so let's set the exponent right.
2086 # if self._exp < 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002087 # exp = (self._exp +1)// 2
Guido van Rossumd8faa362007-04-27 19:54:29 +00002088 # else:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002089 exp = self._exp // 2
2090 context.prec += ans._exp - exp
2091 ans = ans._rescale(exp, context=context)
2092 context.prec = firstprec
2093 context._regard_flags(flags)
2094 context.Emax, context.Emin = Emax, Emin
2095
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002096 return ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002097
2098 def max(self, other, context=None):
2099 """Returns the larger value.
2100
2101 like max(self, other) except if one is not a number, returns
2102 NaN (and signals if one is sNaN). Also rounds.
2103 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002104 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002105 if other is NotImplemented:
2106 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002107
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002108 if self._is_special or other._is_special:
Guido van Rossumd8faa362007-04-27 19:54:29 +00002109 # If one operand is a quiet NaN and the other is number, then the
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002110 # number is always returned
2111 sn = self._isnan()
2112 on = other._isnan()
2113 if sn or on:
2114 if on == 1 and sn != 2:
2115 return self
2116 if sn == 1 and on != 2:
2117 return other
2118 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002119
2120 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002121 c = self.__cmp__(other)
2122 if c == 0:
Guido van Rossumd8faa362007-04-27 19:54:29 +00002123 # If both operands are finite and equal in numerical value
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002124 # then an ordering is applied:
2125 #
Guido van Rossumd8faa362007-04-27 19:54:29 +00002126 # If the signs differ then max returns the operand with the
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002127 # positive sign and min returns the operand with the negative sign
2128 #
Guido van Rossumd8faa362007-04-27 19:54:29 +00002129 # If the signs are the same then the exponent is used to select
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002130 # the result.
2131 if self._sign != other._sign:
2132 if self._sign:
2133 ans = other
2134 elif self._exp < other._exp and not self._sign:
2135 ans = other
2136 elif self._exp > other._exp and self._sign:
2137 ans = other
2138 elif c == -1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002139 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002140
2141 if context is None:
2142 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002143 if context._rounding_decision == ALWAYS_ROUND:
2144 return ans._fix(context)
2145 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002146
2147 def min(self, other, context=None):
2148 """Returns the smaller value.
2149
Guido van Rossumd8faa362007-04-27 19:54:29 +00002150 Like min(self, other) except if one is not a number, returns
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002151 NaN (and signals if one is sNaN). Also rounds.
2152 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002153 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002154 if other is NotImplemented:
2155 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002156
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002157 if self._is_special or other._is_special:
Guido van Rossumd8faa362007-04-27 19:54:29 +00002158 # If one operand is a quiet NaN and the other is number, then the
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002159 # number is always returned
2160 sn = self._isnan()
2161 on = other._isnan()
2162 if sn or on:
2163 if on == 1 and sn != 2:
2164 return self
2165 if sn == 1 and on != 2:
2166 return other
2167 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002168
2169 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002170 c = self.__cmp__(other)
2171 if c == 0:
Guido van Rossumd8faa362007-04-27 19:54:29 +00002172 # If both operands are finite and equal in numerical value
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002173 # then an ordering is applied:
2174 #
Guido van Rossumd8faa362007-04-27 19:54:29 +00002175 # If the signs differ then max returns the operand with the
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002176 # positive sign and min returns the operand with the negative sign
2177 #
Guido van Rossumd8faa362007-04-27 19:54:29 +00002178 # If the signs are the same then the exponent is used to select
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002179 # the result.
2180 if self._sign != other._sign:
2181 if other._sign:
2182 ans = other
2183 elif self._exp > other._exp and not self._sign:
2184 ans = other
2185 elif self._exp < other._exp and self._sign:
2186 ans = other
2187 elif c == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002188 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002189
2190 if context is None:
2191 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002192 if context._rounding_decision == ALWAYS_ROUND:
2193 return ans._fix(context)
2194 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002195
2196 def _isinteger(self):
2197 """Returns whether self is an integer"""
2198 if self._exp >= 0:
2199 return True
2200 rest = self._int[self._exp:]
2201 return rest == (0,)*len(rest)
2202
2203 def _iseven(self):
2204 """Returns 1 if self is even. Assumes self is an integer."""
2205 if self._exp > 0:
2206 return 1
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002207 return self._int[-1+self._exp] & 1 == 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002208
2209 def adjusted(self):
2210 """Return the adjusted exponent of self"""
2211 try:
2212 return self._exp + len(self._int) - 1
Guido van Rossumd8faa362007-04-27 19:54:29 +00002213 # If NaN or Infinity, self._exp is string
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002214 except TypeError:
2215 return 0
2216
Guido van Rossumd8faa362007-04-27 19:54:29 +00002217 # Support for pickling, copy, and deepcopy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002218 def __reduce__(self):
2219 return (self.__class__, (str(self),))
2220
2221 def __copy__(self):
2222 if type(self) == Decimal:
2223 return self # I'm immutable; therefore I am my own clone
2224 return self.__class__(str(self))
2225
2226 def __deepcopy__(self, memo):
2227 if type(self) == Decimal:
2228 return self # My components are also immutable
2229 return self.__class__(str(self))
2230
Guido van Rossumd8faa362007-04-27 19:54:29 +00002231##### Context class #######################################################
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002232
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002233
2234# get rounding method function:
Guido van Rossumd8faa362007-04-27 19:54:29 +00002235rounding_functions = [name for name in Decimal.__dict__.keys()
2236 if name.startswith('_round_')]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002237for name in rounding_functions:
Guido van Rossumd8faa362007-04-27 19:54:29 +00002238 # name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002239 globalname = name[1:].upper()
2240 val = globals()[globalname]
2241 Decimal._pick_rounding_function[val] = name
2242
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002243del name, val, globalname, rounding_functions
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002244
Thomas Wouters89f507f2006-12-13 04:49:30 +00002245class _ContextManager(object):
2246 """Context manager class to support localcontext().
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002247
Thomas Wouters89f507f2006-12-13 04:49:30 +00002248 Sets a copy of the supplied context in __enter__() and restores
2249 the previous decimal context in __exit__()
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002250 """
2251 def __init__(self, new_context):
Thomas Wouters89f507f2006-12-13 04:49:30 +00002252 self.new_context = new_context.copy()
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002253 def __enter__(self):
2254 self.saved_context = getcontext()
2255 setcontext(self.new_context)
2256 return self.new_context
2257 def __exit__(self, t, v, tb):
2258 setcontext(self.saved_context)
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002259
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002260class Context(object):
2261 """Contains the context for a Decimal instance.
2262
2263 Contains:
2264 prec - precision (for use in rounding, division, square roots..)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002265 rounding - rounding type (how you round)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002266 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
Raymond Hettingerbf440692004-07-10 14:14:37 +00002267 traps - If traps[exception] = 1, then the exception is
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002268 raised when it is caused. Otherwise, a value is
2269 substituted in.
2270 flags - When an exception is caused, flags[exception] is incremented.
2271 (Whether or not the trap_enabler is set)
2272 Should be reset by user of Decimal instance.
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002273 Emin - Minimum exponent
2274 Emax - Maximum exponent
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002275 capitals - If 1, 1*10^1 is printed as 1E+1.
2276 If 0, printed as 1e1
Raymond Hettingere0f15812004-07-05 05:36:39 +00002277 _clamp - If 1, change exponents if too high (Default 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002278 """
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002279
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002280 def __init__(self, prec=None, rounding=None,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002281 traps=None, flags=None,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002282 _rounding_decision=None,
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002283 Emin=None, Emax=None,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002284 capitals=None, _clamp=0,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002285 _ignored_flags=None):
2286 if flags is None:
2287 flags = []
2288 if _ignored_flags is None:
2289 _ignored_flags = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002290 if not isinstance(flags, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002291 flags = dict([(s,s in flags) for s in _signals])
Raymond Hettingerbf440692004-07-10 14:14:37 +00002292 if traps is not None and not isinstance(traps, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002293 traps = dict([(s,s in traps) for s in _signals])
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002294 for name, val in locals().items():
2295 if val is None:
Raymond Hettingereb260842005-06-07 18:52:34 +00002296 setattr(self, name, _copy.copy(getattr(DefaultContext, name)))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002297 else:
2298 setattr(self, name, val)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002299 del self.self
2300
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002301 def __repr__(self):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002302 """Show the current context."""
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002303 s = []
Guido van Rossumd8faa362007-04-27 19:54:29 +00002304 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, '
2305 'Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d'
2306 % vars(self))
2307 names = [f.__name__ for f, v in self.flags.items() if v]
2308 s.append('flags=[' + ', '.join(names) + ']')
2309 names = [t.__name__ for t, v in self.traps.items() if v]
2310 s.append('traps=[' + ', '.join(names) + ']')
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002311 return ', '.join(s) + ')'
2312
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002313 def clear_flags(self):
2314 """Reset all flags to zero"""
2315 for flag in self.flags:
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002316 self.flags[flag] = 0
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002317
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002318 def _shallow_copy(self):
2319 """Returns a shallow copy from self."""
Raymond Hettingerbf440692004-07-10 14:14:37 +00002320 nc = Context(self.prec, self.rounding, self.traps, self.flags,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002321 self._rounding_decision, self.Emin, self.Emax,
2322 self.capitals, self._clamp, self._ignored_flags)
2323 return nc
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002324
2325 def copy(self):
2326 """Returns a deep copy from self."""
Guido van Rossumd8faa362007-04-27 19:54:29 +00002327 nc = Context(self.prec, self.rounding, self.traps.copy(),
2328 self.flags.copy(), self._rounding_decision, self.Emin,
2329 self.Emax, self.capitals, self._clamp, self._ignored_flags)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002330 return nc
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002331 __copy__ = copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002332
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002333 def _raise_error(self, condition, explanation = None, *args):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002334 """Handles an error
2335
2336 If the flag is in _ignored_flags, returns the default response.
2337 Otherwise, it increments the flag, then, if the corresponding
2338 trap_enabler is set, it reaises the exception. Otherwise, it returns
2339 the default value after incrementing the flag.
2340 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002341 error = _condition_map.get(condition, condition)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002342 if error in self._ignored_flags:
Guido van Rossumd8faa362007-04-27 19:54:29 +00002343 # Don't touch the flag
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002344 return error().handle(self, *args)
2345
2346 self.flags[error] += 1
Raymond Hettingerbf440692004-07-10 14:14:37 +00002347 if not self.traps[error]:
Guido van Rossumd8faa362007-04-27 19:54:29 +00002348 # The errors define how to handle themselves.
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002349 return condition().handle(self, *args)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002350
2351 # Errors should only be risked on copies of the context
Guido van Rossumd8faa362007-04-27 19:54:29 +00002352 # self._ignored_flags = []
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002353 raise error, explanation
2354
2355 def _ignore_all_flags(self):
2356 """Ignore all flags, if they are raised"""
Raymond Hettingerfed52962004-07-14 15:41:57 +00002357 return self._ignore_flags(*_signals)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002358
2359 def _ignore_flags(self, *flags):
2360 """Ignore the flags, if they are raised"""
2361 # Do not mutate-- This way, copies of a context leave the original
2362 # alone.
2363 self._ignored_flags = (self._ignored_flags + list(flags))
2364 return list(flags)
2365
2366 def _regard_flags(self, *flags):
2367 """Stop ignoring the flags, if they are raised"""
2368 if flags and isinstance(flags[0], (tuple,list)):
2369 flags = flags[0]
2370 for flag in flags:
2371 self._ignored_flags.remove(flag)
2372
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002373 def __hash__(self):
2374 """A Context cannot be hashed."""
2375 # We inherit object.__hash__, so we must deny this explicitly
Guido van Rossumd8faa362007-04-27 19:54:29 +00002376 raise TypeError("Cannot hash a Context.")
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002377
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002378 def Etiny(self):
2379 """Returns Etiny (= Emin - prec + 1)"""
2380 return int(self.Emin - self.prec + 1)
2381
2382 def Etop(self):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002383 """Returns maximum exponent (= Emax - prec + 1)"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002384 return int(self.Emax - self.prec + 1)
2385
2386 def _set_rounding_decision(self, type):
2387 """Sets the rounding decision.
2388
2389 Sets the rounding decision, and returns the current (previous)
2390 rounding decision. Often used like:
2391
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002392 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002393 # That so you don't change the calling context
2394 # if an error occurs in the middle (say DivisionImpossible is raised).
2395
2396 rounding = context._set_rounding_decision(NEVER_ROUND)
2397 instance = instance / Decimal(2)
2398 context._set_rounding_decision(rounding)
2399
2400 This will make it not round for that operation.
2401 """
2402
2403 rounding = self._rounding_decision
2404 self._rounding_decision = type
2405 return rounding
2406
2407 def _set_rounding(self, type):
2408 """Sets the rounding type.
2409
2410 Sets the rounding type, and returns the current (previous)
2411 rounding type. Often used like:
2412
2413 context = context.copy()
2414 # so you don't change the calling context
2415 # if an error occurs in the middle.
2416 rounding = context._set_rounding(ROUND_UP)
2417 val = self.__sub__(other, context=context)
2418 context._set_rounding(rounding)
2419
2420 This will make it round up for that operation.
2421 """
2422 rounding = self.rounding
2423 self.rounding= type
2424 return rounding
2425
Raymond Hettingerfed52962004-07-14 15:41:57 +00002426 def create_decimal(self, num='0'):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002427 """Creates a new Decimal instance but using self as context."""
2428 d = Decimal(num, context=self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002429 return d._fix(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002430
Guido van Rossumd8faa362007-04-27 19:54:29 +00002431 # Methods
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002432 def abs(self, a):
2433 """Returns the absolute value of the operand.
2434
2435 If the operand is negative, the result is the same as using the minus
Guido van Rossumd8faa362007-04-27 19:54:29 +00002436 operation on the operand. Otherwise, the result is the same as using
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002437 the plus operation on the operand.
2438
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002439 >>> ExtendedContext.abs(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002440 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002441 >>> ExtendedContext.abs(Decimal('-100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002442 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002443 >>> ExtendedContext.abs(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002444 Decimal("101.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002445 >>> ExtendedContext.abs(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002446 Decimal("101.5")
2447 """
2448 return a.__abs__(context=self)
2449
2450 def add(self, a, b):
2451 """Return the sum of the two operands.
2452
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002453 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002454 Decimal("19.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002455 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002456 Decimal("1.02E+4")
2457 """
2458 return a.__add__(b, context=self)
2459
2460 def _apply(self, a):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002461 return str(a._fix(self))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002462
2463 def compare(self, a, b):
2464 """Compares values numerically.
2465
2466 If the signs of the operands differ, a value representing each operand
2467 ('-1' if the operand is less than zero, '0' if the operand is zero or
2468 negative zero, or '1' if the operand is greater than zero) is used in
2469 place of that operand for the comparison instead of the actual
2470 operand.
2471
2472 The comparison is then effected by subtracting the second operand from
2473 the first and then returning a value according to the result of the
2474 subtraction: '-1' if the result is less than zero, '0' if the result is
2475 zero or negative zero, or '1' if the result is greater than zero.
2476
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002477 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002478 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002479 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002480 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002481 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002482 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002483 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002484 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002485 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002486 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002487 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002488 Decimal("-1")
2489 """
2490 return a.compare(b, context=self)
2491
2492 def divide(self, a, b):
2493 """Decimal division in a specified context.
2494
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002495 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002496 Decimal("0.333333333")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002497 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002498 Decimal("0.666666667")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002499 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002500 Decimal("2.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002501 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002502 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002503 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002504 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002505 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002506 Decimal("4.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002507 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002508 Decimal("1.20")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002509 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002510 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002511 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002512 Decimal("1000")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002513 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002514 Decimal("1.20E+6")
2515 """
Neal Norwitzbcc0db82006-03-24 08:14:36 +00002516 return a.__truediv__(b, context=self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002517
2518 def divide_int(self, a, b):
2519 """Divides two numbers and returns the integer part of the result.
2520
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002521 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002522 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002523 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002524 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002525 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002526 Decimal("3")
2527 """
2528 return a.__floordiv__(b, context=self)
2529
2530 def divmod(self, a, b):
2531 return a.__divmod__(b, context=self)
2532
2533 def max(self, a,b):
2534 """max compares two values numerically and returns the maximum.
2535
2536 If either operand is a NaN then the general rules apply.
2537 Otherwise, the operands are compared as as though by the compare
Guido van Rossumd8faa362007-04-27 19:54:29 +00002538 operation. If they are numerically equal then the left-hand operand
2539 is chosen as the result. Otherwise the maximum (closer to positive
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002540 infinity) of the two operands is chosen as the result.
2541
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002542 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002543 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002544 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002545 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002546 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002547 Decimal("1")
2548 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
2549 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002550 """
2551 return a.max(b, context=self)
2552
2553 def min(self, a,b):
2554 """min compares two values numerically and returns the minimum.
2555
2556 If either operand is a NaN then the general rules apply.
2557 Otherwise, the operands are compared as as though by the compare
Guido van Rossumd8faa362007-04-27 19:54:29 +00002558 operation. If they are numerically equal then the left-hand operand
2559 is chosen as the result. Otherwise the minimum (closer to negative
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002560 infinity) of the two operands is chosen as the result.
2561
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002562 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002563 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002564 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002565 Decimal("-10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002566 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002567 Decimal("1.0")
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002568 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
2569 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002570 """
2571 return a.min(b, context=self)
2572
2573 def minus(self, a):
2574 """Minus corresponds to unary prefix minus in Python.
2575
2576 The operation is evaluated using the same rules as subtract; the
2577 operation minus(a) is calculated as subtract('0', a) where the '0'
2578 has the same exponent as the operand.
2579
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002580 >>> ExtendedContext.minus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002581 Decimal("-1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002582 >>> ExtendedContext.minus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002583 Decimal("1.3")
2584 """
2585 return a.__neg__(context=self)
2586
2587 def multiply(self, a, b):
2588 """multiply multiplies two operands.
2589
2590 If either operand is a special value then the general rules apply.
2591 Otherwise, the operands are multiplied together ('long multiplication'),
2592 resulting in a number which may be as long as the sum of the lengths
2593 of the two operands.
2594
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002595 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002596 Decimal("3.60")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002597 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002598 Decimal("21")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002599 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002600 Decimal("0.72")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002601 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002602 Decimal("-0.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002603 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002604 Decimal("4.28135971E+11")
2605 """
2606 return a.__mul__(b, context=self)
2607
2608 def normalize(self, a):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002609 """normalize reduces an operand to its simplest form.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002610
2611 Essentially a plus operation with all trailing zeros removed from the
2612 result.
2613
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002614 >>> ExtendedContext.normalize(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002615 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002616 >>> ExtendedContext.normalize(Decimal('-2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002617 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002618 >>> ExtendedContext.normalize(Decimal('1.200'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002619 Decimal("1.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002620 >>> ExtendedContext.normalize(Decimal('-120'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002621 Decimal("-1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002622 >>> ExtendedContext.normalize(Decimal('120.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002623 Decimal("1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002624 >>> ExtendedContext.normalize(Decimal('0.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002625 Decimal("0")
2626 """
2627 return a.normalize(context=self)
2628
2629 def plus(self, a):
2630 """Plus corresponds to unary prefix plus in Python.
2631
2632 The operation is evaluated using the same rules as add; the
2633 operation plus(a) is calculated as add('0', a) where the '0'
2634 has the same exponent as the operand.
2635
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002636 >>> ExtendedContext.plus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002637 Decimal("1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002638 >>> ExtendedContext.plus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002639 Decimal("-1.3")
2640 """
2641 return a.__pos__(context=self)
2642
2643 def power(self, a, b, modulo=None):
2644 """Raises a to the power of b, to modulo if given.
2645
2646 The right-hand operand must be a whole number whose integer part (after
2647 any exponent has been applied) has no more than 9 digits and whose
Guido van Rossumd8faa362007-04-27 19:54:29 +00002648 fractional part (if any) is all zeros before any rounding. The operand
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002649 may be positive, negative, or zero; if negative, the absolute value of
2650 the power is used, and the left-hand operand is inverted (divided into
2651 1) before use.
2652
2653 If the increased precision needed for the intermediate calculations
Guido van Rossumd8faa362007-04-27 19:54:29 +00002654 exceeds the capabilities of the implementation then an Invalid
2655 operation condition is raised.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002656
2657 If, when raising to a negative power, an underflow occurs during the
2658 division into 1, the operation is not halted at that point but
2659 continues.
2660
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002661 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002662 Decimal("8")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002663 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002664 Decimal("0.125")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002665 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002666 Decimal("69.7575744")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002667 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002668 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002669 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002670 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002671 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002672 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002673 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002674 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002675 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002676 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002677 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002678 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002679 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002680 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002681 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002682 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002683 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002684 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002685 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002686 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002687 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002688 Decimal("NaN")
2689 """
2690 return a.__pow__(b, modulo, context=self)
2691
2692 def quantize(self, a, b):
Guido van Rossumd8faa362007-04-27 19:54:29 +00002693 """Returns a value equal to 'a' (rounded), having the exponent of 'b'.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002694
2695 The coefficient of the result is derived from that of the left-hand
Guido van Rossumd8faa362007-04-27 19:54:29 +00002696 operand. It may be rounded using the current rounding setting (if the
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002697 exponent is being increased), multiplied by a positive power of ten (if
2698 the exponent is being decreased), or is unchanged (if the exponent is
2699 already equal to that of the right-hand operand).
2700
2701 Unlike other operations, if the length of the coefficient after the
2702 quantize operation would be greater than precision then an Invalid
Guido van Rossumd8faa362007-04-27 19:54:29 +00002703 operation condition is raised. This guarantees that, unless there is
2704 an error condition, the exponent of the result of a quantize is always
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002705 equal to that of the right-hand operand.
2706
2707 Also unlike other operations, quantize will never raise Underflow, even
2708 if the result is subnormal and inexact.
2709
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002710 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002711 Decimal("2.170")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002712 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002713 Decimal("2.17")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002714 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002715 Decimal("2.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002716 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002717 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002718 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002719 Decimal("0E+1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002720 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002721 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002722 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002723 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002724 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002725 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002726 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002727 Decimal("-0E+5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002728 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002729 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002730 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002731 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002732 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002733 Decimal("217.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002734 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002735 Decimal("217")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002736 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002737 Decimal("2.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002738 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002739 Decimal("2E+2")
2740 """
2741 return a.quantize(b, context=self)
2742
2743 def remainder(self, a, b):
2744 """Returns the remainder from integer division.
2745
2746 The result is the residue of the dividend after the operation of
Guido van Rossumd8faa362007-04-27 19:54:29 +00002747 calculating integer division as described for divide-integer, rounded
2748 to precision digits if necessary. The sign of the result, if
2749 non-zero, is the same as that of the original dividend.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002750
2751 This operation will fail under the same conditions as integer division
2752 (that is, if integer division on the same two operands would fail, the
2753 remainder cannot be calculated).
2754
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002755 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002756 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002757 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002758 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002759 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002760 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002761 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002762 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002763 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002764 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002765 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002766 Decimal("1.0")
2767 """
2768 return a.__mod__(b, context=self)
2769
2770 def remainder_near(self, a, b):
2771 """Returns to be "a - b * n", where n is the integer nearest the exact
2772 value of "x / b" (if two integers are equally near then the even one
Guido van Rossumd8faa362007-04-27 19:54:29 +00002773 is chosen). If the result is equal to 0 then its sign will be the
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002774 sign of a.
2775
2776 This operation will fail under the same conditions as integer division
2777 (that is, if integer division on the same two operands would fail, the
2778 remainder cannot be calculated).
2779
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002780 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002781 Decimal("-0.9")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002782 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002783 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002784 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002785 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002786 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002787 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002788 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002789 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002790 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002791 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002792 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002793 Decimal("-0.3")
2794 """
2795 return a.remainder_near(b, context=self)
2796
2797 def same_quantum(self, a, b):
2798 """Returns True if the two operands have the same exponent.
2799
2800 The result is never affected by either the sign or the coefficient of
2801 either operand.
2802
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002803 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002804 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002805 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002806 True
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002807 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002808 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002809 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002810 True
2811 """
2812 return a.same_quantum(b)
2813
2814 def sqrt(self, a):
Guido van Rossumd8faa362007-04-27 19:54:29 +00002815 """Square root of a non-negative number to context precision.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002816
2817 If the result must be inexact, it is rounded using the round-half-even
2818 algorithm.
2819
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002820 >>> ExtendedContext.sqrt(Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002821 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002822 >>> ExtendedContext.sqrt(Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002823 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002824 >>> ExtendedContext.sqrt(Decimal('0.39'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002825 Decimal("0.624499800")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002826 >>> ExtendedContext.sqrt(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002827 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002828 >>> ExtendedContext.sqrt(Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002829 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002830 >>> ExtendedContext.sqrt(Decimal('1.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002831 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002832 >>> ExtendedContext.sqrt(Decimal('1.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002833 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002834 >>> ExtendedContext.sqrt(Decimal('7'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002835 Decimal("2.64575131")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002836 >>> ExtendedContext.sqrt(Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002837 Decimal("3.16227766")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002838 >>> ExtendedContext.prec
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002839 9
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002840 """
2841 return a.sqrt(context=self)
2842
2843 def subtract(self, a, b):
Georg Brandlf33d01d2005-08-22 19:35:18 +00002844 """Return the difference between the two operands.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002845
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002846 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002847 Decimal("0.23")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002848 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002849 Decimal("0.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002850 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002851 Decimal("-0.77")
2852 """
2853 return a.__sub__(b, context=self)
2854
2855 def to_eng_string(self, a):
2856 """Converts a number to a string, using scientific notation.
2857
2858 The operation is not affected by the context.
2859 """
2860 return a.to_eng_string(context=self)
2861
2862 def to_sci_string(self, a):
2863 """Converts a number to a string, using scientific notation.
2864
2865 The operation is not affected by the context.
2866 """
2867 return a.__str__(context=self)
2868
2869 def to_integral(self, a):
2870 """Rounds to an integer.
2871
2872 When the operand has a negative exponent, the result is the same
2873 as using the quantize() operation using the given operand as the
2874 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2875 of the operand as the precision setting, except that no flags will
Guido van Rossumd8faa362007-04-27 19:54:29 +00002876 be set. The rounding mode is taken from the context.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002877
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002878 >>> ExtendedContext.to_integral(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002879 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002880 >>> ExtendedContext.to_integral(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002881 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002882 >>> ExtendedContext.to_integral(Decimal('100.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002883 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002884 >>> ExtendedContext.to_integral(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002885 Decimal("102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002886 >>> ExtendedContext.to_integral(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002887 Decimal("-102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002888 >>> ExtendedContext.to_integral(Decimal('10E+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002889 Decimal("1.0E+6")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002890 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002891 Decimal("7.89E+77")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002892 >>> ExtendedContext.to_integral(Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002893 Decimal("-Infinity")
2894 """
2895 return a.to_integral(context=self)
2896
2897class _WorkRep(object):
2898 __slots__ = ('sign','int','exp')
Raymond Hettinger17931de2004-10-27 06:21:46 +00002899 # sign: 0 or 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002900 # int: int or long
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002901 # exp: None, int, or string
2902
2903 def __init__(self, value=None):
2904 if value is None:
2905 self.sign = None
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002906 self.int = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002907 self.exp = None
Raymond Hettinger17931de2004-10-27 06:21:46 +00002908 elif isinstance(value, Decimal):
2909 self.sign = value._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002910 cum = 0
Raymond Hettinger17931de2004-10-27 06:21:46 +00002911 for digit in value._int:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002912 cum = cum * 10 + digit
2913 self.int = cum
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002914 self.exp = value._exp
Raymond Hettinger17931de2004-10-27 06:21:46 +00002915 else:
2916 # assert isinstance(value, tuple)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002917 self.sign = value[0]
2918 self.int = value[1]
2919 self.exp = value[2]
2920
2921 def __repr__(self):
2922 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2923
2924 __str__ = __repr__
2925
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002926
2927
2928def _normalize(op1, op2, shouldround = 0, prec = 0):
2929 """Normalizes op1, op2 to have the same exp and length of coefficient.
2930
2931 Done during addition.
2932 """
2933 # Yes, the exponent is a long, but the difference between exponents
2934 # must be an int-- otherwise you'd get a big memory problem.
2935 numdigits = int(op1.exp - op2.exp)
2936 if numdigits < 0:
2937 numdigits = -numdigits
2938 tmp = op2
2939 other = op1
2940 else:
2941 tmp = op1
2942 other = op2
2943
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002944
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002945 if shouldround and numdigits > prec + 1:
2946 # Big difference in exponents - check the adjusted exponents
2947 tmp_len = len(str(tmp.int))
2948 other_len = len(str(other.int))
2949 if numdigits > (other_len + prec + 1 - tmp_len):
2950 # If the difference in adjusted exps is > prec+1, we know
Guido van Rossumd8faa362007-04-27 19:54:29 +00002951 # other is insignificant, so might as well put a 1 after the
2952 # precision (since this is only for addition). Also stops
2953 # use of massive longs.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002954
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002955 extend = prec + 2 - tmp_len
2956 if extend <= 0:
2957 extend = 1
2958 tmp.int *= 10 ** extend
2959 tmp.exp -= extend
2960 other.int = 1
2961 other.exp = tmp.exp
2962 return op1, op2
2963
2964 tmp.int *= 10 ** numdigits
2965 tmp.exp -= numdigits
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002966 return op1, op2
2967
2968def _adjust_coefficients(op1, op2):
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002969 """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002970
2971 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2972
2973 Used on _WorkRep instances during division.
2974 """
2975 adjust = 0
Guido van Rossumd8faa362007-04-27 19:54:29 +00002976 # If op1 is smaller, make it larger
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002977 while op2.int > op1.int:
2978 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002979 op1.exp -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002980 adjust += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002981
Guido van Rossumd8faa362007-04-27 19:54:29 +00002982 # If op2 is too small, make it larger
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002983 while op1.int >= (10 * op2.int):
2984 op2.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002985 op2.exp -= 1
2986 adjust -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002987
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002988 return op1, op2, adjust
2989
Guido van Rossumd8faa362007-04-27 19:54:29 +00002990##### Helper Functions ####################################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002991
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002992def _convert_other(other):
2993 """Convert other to Decimal.
2994
2995 Verifies that it's ok to use in an implicit construction.
2996 """
2997 if isinstance(other, Decimal):
2998 return other
Walter Dörwaldaa97f042007-05-03 21:05:51 +00002999 if isinstance(other, int):
Raymond Hettinger636a6b12004-09-19 01:54:09 +00003000 return Decimal(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00003001 return NotImplemented
Raymond Hettinger636a6b12004-09-19 01:54:09 +00003002
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003003_infinity_map = {
3004 'inf' : 1,
3005 'infinity' : 1,
3006 '+inf' : 1,
3007 '+infinity' : 1,
3008 '-inf' : -1,
3009 '-infinity' : -1
3010}
3011
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00003012def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003013 """Determines whether a string or float is infinity.
3014
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00003015 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003016 """
3017 num = str(num).lower()
3018 return _infinity_map.get(num, 0)
3019
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00003020def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003021 """Determines whether a string or float is NaN
3022
3023 (1, sign, diagnostic info as string) => NaN
3024 (2, sign, diagnostic info as string) => sNaN
3025 0 => not a NaN
3026 """
3027 num = str(num).lower()
3028 if not num:
3029 return 0
3030
Guido van Rossumd8faa362007-04-27 19:54:29 +00003031 # Get the sign, get rid of trailing [+-]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003032 sign = 0
3033 if num[0] == '+':
3034 num = num[1:]
Guido van Rossumd8faa362007-04-27 19:54:29 +00003035 elif num[0] == '-': # elif avoids '+-nan'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003036 num = num[1:]
3037 sign = 1
3038
3039 if num.startswith('nan'):
Guido van Rossumd8faa362007-04-27 19:54:29 +00003040 if len(num) > 3 and not num[3:].isdigit(): # diagnostic info
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003041 return 0
3042 return (1, sign, num[3:].lstrip('0'))
3043 if num.startswith('snan'):
3044 if len(num) > 4 and not num[4:].isdigit():
3045 return 0
3046 return (2, sign, num[4:].lstrip('0'))
3047 return 0
3048
3049
Guido van Rossumd8faa362007-04-27 19:54:29 +00003050##### Setup Specific Contexts ############################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003051
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003052# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00003053# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003054
3055DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003056 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003057 traps=[DivisionByZero, Overflow, InvalidOperation],
3058 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003059 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00003060 Emax=999999999,
3061 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00003062 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003063)
3064
3065# Pre-made alternate contexts offered by the specification
3066# Don't change these; the user should be able to select these
3067# contexts and be able to reproduce results from other implementations
3068# of the spec.
3069
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003070BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003071 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003072 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
3073 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003074)
3075
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003076ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003077 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003078 traps=[],
3079 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003080)
3081
3082
Guido van Rossumd8faa362007-04-27 19:54:29 +00003083##### Useful Constants (internal use only) ################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003084
Guido van Rossumd8faa362007-04-27 19:54:29 +00003085# Reusable defaults
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003086Inf = Decimal('Inf')
3087negInf = Decimal('-Inf')
3088
Guido van Rossumd8faa362007-04-27 19:54:29 +00003089# Infsign[sign] is infinity w/ that sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003090Infsign = (Inf, negInf)
3091
3092NaN = Decimal('NaN')
3093
3094
Guido van Rossumd8faa362007-04-27 19:54:29 +00003095##### crud for parsing strings #############################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003096import re
3097
3098# There's an optional sign at the start, and an optional exponent
3099# at the end. The exponent has an optional sign and at least one
3100# digit. In between, must have either at least one digit followed
3101# by an optional fraction, or a decimal point followed by at least
3102# one digit. Yuck.
3103
3104_parser = re.compile(r"""
3105# \s*
3106 (?P<sign>[-+])?
3107 (
3108 (?P<int>\d+) (\. (?P<frac>\d*))?
3109 |
3110 \. (?P<onlyfrac>\d+)
3111 )
3112 ([eE](?P<exp>[-+]? \d+))?
3113# \s*
3114 $
Guido van Rossumd8faa362007-04-27 19:54:29 +00003115""", re.VERBOSE).match # Uncomment the \s* to allow leading or trailing spaces.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003116
3117del re
3118
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003119def _string2exact(s):
Guido van Rossumd8faa362007-04-27 19:54:29 +00003120 """Return sign, n, p s.t.
3121
3122 Float string value == -1**sign * n * 10**p exactly
3123 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003124 m = _parser(s)
3125 if m is None:
3126 raise ValueError("invalid literal for Decimal: %r" % s)
3127
3128 if m.group('sign') == "-":
3129 sign = 1
3130 else:
3131 sign = 0
3132
3133 exp = m.group('exp')
3134 if exp is None:
3135 exp = 0
3136 else:
3137 exp = int(exp)
3138
3139 intpart = m.group('int')
3140 if intpart is None:
3141 intpart = ""
3142 fracpart = m.group('onlyfrac')
3143 else:
3144 fracpart = m.group('frac')
3145 if fracpart is None:
3146 fracpart = ""
3147
3148 exp -= len(fracpart)
3149
3150 mantissa = intpart + fracpart
Guido van Rossumc1f779c2007-07-03 08:25:58 +00003151 tmp = list(map(int, mantissa))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003152 backup = tmp
3153 while tmp and tmp[0] == 0:
3154 del tmp[0]
3155
3156 # It's a zero
3157 if not tmp:
3158 if backup:
3159 return (sign, tuple(backup), exp)
3160 return (sign, (0,), exp)
3161 mantissa = tuple(tmp)
3162
3163 return (sign, mantissa, exp)
3164
3165
3166if __name__ == '__main__':
3167 import doctest, sys
3168 doctest.testmod(sys.modules[__name__])