blob: 71e2ad73e109a64effaa7612267e9912d978a65b [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
Facundo Batistaac4ae4b2006-07-18 12:16:13 +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)
59>>> print dig / Decimal(3)
600.333333333
61>>> getcontext().prec = 18
62>>> print dig / Decimal(3)
630.333333333333333333
64>>> print dig.sqrt()
651
66>>> print Decimal(3).sqrt()
671.73205080756887729
68>>> print Decimal(3) ** 123
694.85192780976896427E+58
70>>> inf = Decimal(1) / Decimal(0)
71>>> print inf
72Infinity
73>>> neginf = Decimal(-1) / Decimal(0)
74>>> print neginf
75-Infinity
76>>> print neginf + inf
77NaN
78>>> print neginf * inf
79-Infinity
80>>> print dig / 0
81Infinity
Raymond Hettingerbf440692004-07-10 14:14:37 +000082>>> getcontext().traps[DivisionByZero] = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000083>>> print dig / 0
84Traceback (most recent call last):
85 ...
86 ...
87 ...
88DivisionByZero: x / 0
89>>> c = Context()
Raymond Hettingerbf440692004-07-10 14:14:37 +000090>>> c.traps[InvalidOperation] = 0
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000091>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000920
93>>> c.divide(Decimal(0), Decimal(0))
94Decimal("NaN")
Raymond Hettingerbf440692004-07-10 14:14:37 +000095>>> c.traps[InvalidOperation] = 1
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000096>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000971
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000098>>> c.flags[InvalidOperation] = 0
99>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001000
101>>> print c.divide(Decimal(0), Decimal(0))
102Traceback (most recent call last):
103 ...
104 ...
105 ...
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000106InvalidOperation: 0 / 0
107>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001081
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000109>>> c.flags[InvalidOperation] = 0
Raymond Hettingerbf440692004-07-10 14:14:37 +0000110>>> c.traps[InvalidOperation] = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000111>>> print c.divide(Decimal(0), Decimal(0))
112NaN
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000113>>> print c.flags[InvalidOperation]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001141
115>>>
116"""
117
118__all__ = [
119 # Two major classes
120 'Decimal', 'Context',
121
122 # Contexts
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +0000123 'DefaultContext', 'BasicContext', 'ExtendedContext',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000124
125 # Exceptions
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +0000126 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
127 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000128
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000129 # Constants for use in setting up contexts
130 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING',
131 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000132
133 # Functions for manipulating contexts
Raymond Hettinger0ea241e2004-07-04 13:53:24 +0000134 'setcontext', 'getcontext'
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
Facundo Batistaac4ae4b2006-07-18 12:16:13 +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
Facundo Batistaac4ae4b2006-07-18 12:16:13 +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
Facundo Batistaac4ae4b2006-07-18 12:16:13 +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 To define a new exception, it should be sufficient to have it derive
164 from DecimalException.
165 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000166 def handle(self, context, *args):
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000167 """Called when context._raise_error is called and trap_enabler is set.
Tim Peters73a9ead2006-07-18 21:55:15 +0000168
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000169 First argument is self, second is the context. More arguments can
170 be given, those being after the explanation in _raise_error (For
171 example, context._raise_error(NewError, '(-x)!', self._sign) would
172 call NewError().handle(context, self._sign).)
173 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000174 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
Facundo Batistaac4ae4b2006-07-18 12:16:13 +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 """
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000188 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000189
190
191class InvalidOperation(DecimalException):
192 """An invalid operation was performed.
193
194 Various bad things cause this:
195
196 Something creates a signaling NaN
197 -INF + INF
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000198 0 * (+-)INF
199 (+-)INF / (+-)INF
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000200 x % 0
201 (+-)INF % x
202 x._rescale( non-integer )
203 sqrt(-x) , x > 0
204 0 ** 0
205 x ** (non-integer)
206 x ** (+-)INF
207 An operand is invalid
208 """
209 def handle(self, context, *args):
210 if args:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000211 if args[0] == 1: # sNaN, must drop 's' but keep diagnostics
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000212 return Decimal( (args[1]._sign, args[1]._int, 'n') )
213 return NaN
214
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000215
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000216class ConversionSyntax(InvalidOperation):
217 """Trying to convert badly formed string.
218
219 This occurs and signals invalid-operation if an string is being
220 converted to a number and it does not conform to the numeric string
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000221 syntax. The result is [0,qNaN].
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000222 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000223 def handle(self, context, *args):
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000224 return (0, (0,), 'n') # Passed to something which uses a tuple.
225
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000226
227class DivisionByZero(DecimalException, ZeroDivisionError):
228 """Division by 0.
229
230 This occurs and signals division-by-zero if division of a finite number
231 by zero was attempted (during a divide-integer or divide operation, or a
232 power operation with negative right-hand operand), and the dividend was
233 not zero.
234
235 The result of the operation is [sign,inf], where sign is the exclusive
236 or of the signs of the operands for divide, or is 1 for an odd power of
237 -0, for power.
238 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000239 def handle(self, context, sign, double = None, *args):
240 if double is not None:
241 return (Infsign[sign],)*2
242 return Infsign[sign]
243
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000244
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000245class DivisionImpossible(InvalidOperation):
246 """Cannot perform the division adequately.
247
248 This occurs and signals invalid-operation if the integer result of a
249 divide-integer or remainder operation had too many digits (would be
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000250 longer than precision). The result is [0,qNaN].
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000251 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000252 def handle(self, context, *args):
253 return (NaN, NaN)
254
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000255
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000256class DivisionUndefined(InvalidOperation, ZeroDivisionError):
257 """Undefined result of division.
258
259 This occurs and signals invalid-operation if division by zero was
260 attempted (during a divide-integer, divide, or remainder operation), and
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000261 the dividend is also zero. The result is [0,qNaN].
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000262 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000263 def handle(self, context, tup=None, *args):
264 if tup is not None:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000265 return (NaN, NaN) # For 0 %0, 0 // 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000266 return NaN
267
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000268
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000269class Inexact(DecimalException):
270 """Had to round, losing information.
271
272 This occurs and signals inexact whenever the result of an operation is
273 not exact (that is, it needed to be rounded and any discarded digits
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000274 were non-zero), or if an overflow or underflow condition occurs. The
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000275 result in all cases is unchanged.
276
277 The inexact signal may be tested (or trapped) to determine if a given
278 operation (or sequence of operations) was inexact.
279 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000280 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000281
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000282
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000283class InvalidContext(InvalidOperation):
284 """Invalid context. Unknown rounding, for example.
285
286 This occurs and signals invalid-operation if an invalid context was
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000287 detected during an operation. This can occur if contexts are not checked
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000288 on creation and either the precision exceeds the capability of the
289 underlying concrete representation or an unknown or unsupported rounding
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000290 was specified. These aspects of the context need only be checked when
291 the values are required to be used. The result is [0,qNaN].
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000292 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000293 def handle(self, context, *args):
294 return NaN
295
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000296
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000297class Rounded(DecimalException):
298 """Number got rounded (not necessarily changed during rounding).
299
300 This occurs and signals rounded whenever the result of an operation is
301 rounded (that is, some zero or non-zero digits were discarded from the
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000302 coefficient), or if an overflow or underflow condition occurs. The
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000303 result in all cases is unchanged.
304
305 The rounded signal may be tested (or trapped) to determine if a given
306 operation (or sequence of operations) caused a loss of precision.
307 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000308 pass
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000309
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000310
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000311class Subnormal(DecimalException):
312 """Exponent < Emin before rounding.
313
314 This occurs and signals subnormal whenever the result of a conversion or
315 operation is subnormal (that is, its adjusted exponent is less than
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000316 Emin, before any rounding). The result in all cases is unchanged.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000317
318 The subnormal signal may be tested (or trapped) to determine if a given
319 or operation (or sequence of operations) yielded a subnormal result.
320 """
321 pass
322
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000323
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000324class Overflow(Inexact, Rounded):
325 """Numerical overflow.
326
327 This occurs and signals overflow if the adjusted exponent of a result
328 (from a conversion or from an operation that is not an attempt to divide
329 by zero), after rounding, would be greater than the largest value that
330 can be handled by the implementation (the value Emax).
331
332 The result depends on the rounding mode:
333
334 For round-half-up and round-half-even (and for round-half-down and
335 round-up, if implemented), the result of the operation is [sign,inf],
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000336 where sign is the sign of the intermediate result. For round-down, the
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000337 result is the largest finite number that can be represented in the
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000338 current precision, with the sign of the intermediate result. For
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000339 round-ceiling, the result is the same as for round-down if the sign of
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000340 the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000341 the result is the same as for round-down if the sign of the intermediate
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000342 result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000343 will also be raised.
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000344 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000345 def handle(self, context, sign, *args):
346 if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
347 ROUND_HALF_DOWN, ROUND_UP):
348 return Infsign[sign]
349 if sign == 0:
350 if context.rounding == ROUND_CEILING:
351 return Infsign[sign]
352 return Decimal((sign, (9,)*context.prec,
353 context.Emax-context.prec+1))
354 if sign == 1:
355 if context.rounding == ROUND_FLOOR:
356 return Infsign[sign]
357 return Decimal( (sign, (9,)*context.prec,
358 context.Emax-context.prec+1))
359
360
361class Underflow(Inexact, Rounded, Subnormal):
362 """Numerical underflow with result rounded to 0.
363
364 This occurs and signals underflow if a result is inexact and the
365 adjusted exponent of the result would be smaller (more negative) than
366 the smallest value that can be handled by the implementation (the value
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000367 Emin). That is, the result is both inexact and subnormal.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000368
369 The result after an underflow will be a subnormal number rounded, if
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000370 necessary, so that its exponent is not less than Etiny. This may result
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000371 in 0 with the sign of the intermediate result and an exponent of Etiny.
372
373 In all cases, Inexact, Rounded, and Subnormal will also be raised.
374 """
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000375 pass
376
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000377
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000378# List of public traps and flags
Raymond Hettingerfed52962004-07-14 15:41:57 +0000379_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000380 Underflow, InvalidOperation, Subnormal]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000381
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000382# Map conditions (per the spec) to signals
383_condition_map = {ConversionSyntax:InvalidOperation,
384 DivisionImpossible:InvalidOperation,
385 DivisionUndefined:InvalidOperation,
386 InvalidContext:InvalidOperation}
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000387
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000388##### Context Functions #####################################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000389
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000390# The getcontext() and setcontext() function manage access to a thread-local
391# current context. Py2.4 offers direct support for thread locals. If that
392# is not available, use threading.currentThread() which is slower but will
Raymond Hettinger7e71fa52004-12-18 19:07:19 +0000393# work for older Pythons. If threads are not part of the build, create a
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000394# mock threading object with threading.local() returning the module
395# namespace.
Raymond Hettinger7e71fa52004-12-18 19:07:19 +0000396
397try:
398 import threading
399except ImportError:
400 # Python was compiled without threads; create a mock object instead
401 import sys
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000402 class MockThreading(object):
Raymond Hettinger7e71fa52004-12-18 19:07:19 +0000403 def local(self, sys=sys):
404 return sys.modules[__name__]
405 threading = MockThreading()
406 del sys, MockThreading
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000407
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000408
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000409try:
410 threading.local
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000411
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000412except AttributeError:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000413
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000414 # To fix reloading, force it to create a new context
415 # Old contexts have different exceptions in their dicts, making problems.
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000416 if hasattr(threading.currentThread(), '__decimal_context__'):
417 del threading.currentThread().__decimal_context__
418
419 def setcontext(context):
420 """Set this thread's context to context."""
421 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000422 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000423 context.clear_flags()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000424 threading.currentThread().__decimal_context__ = context
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000425
426 def getcontext():
427 """Returns this thread's context.
428
429 If this thread does not yet have a context, returns
430 a new context and sets this thread's context.
431 New contexts are copies of DefaultContext.
432 """
433 try:
434 return threading.currentThread().__decimal_context__
435 except AttributeError:
436 context = Context()
437 threading.currentThread().__decimal_context__ = context
438 return context
439
440else:
441
442 local = threading.local()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000443 if hasattr(local, '__decimal_context__'):
444 del local.__decimal_context__
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000445
446 def getcontext(_local=local):
447 """Returns this thread's context.
448
449 If this thread does not yet have a context, returns
450 a new context and sets this thread's context.
451 New contexts are copies of DefaultContext.
452 """
453 try:
454 return _local.__decimal_context__
455 except AttributeError:
456 context = Context()
457 _local.__decimal_context__ = context
458 return context
459
460 def setcontext(context, _local=local):
461 """Set this thread's context to context."""
462 if context in (DefaultContext, BasicContext, ExtendedContext):
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000463 context = context.copy()
Raymond Hettinger61992ef2004-08-06 23:42:16 +0000464 context.clear_flags()
Raymond Hettingeref66deb2004-07-14 21:04:27 +0000465 _local.__decimal_context__ = context
466
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000467 del threading, local # Don't contaminate the namespace
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000468
469
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000470##### Decimal class ##########################################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000471
472class Decimal(object):
473 """Floating point class for decimal arithmetic."""
474
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000475 __slots__ = ('_exp','_int','_sign', '_is_special')
476 # Generally, the value of the Decimal instance is given by
477 # (-1)**_sign * _int * 10**_exp
478 # Special values are signified by _is_special == True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000479
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000480 # We're immutable, so use __new__ not __init__
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000481 def __new__(cls, value="0", context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000482 """Create a decimal point instance.
483
484 >>> Decimal('3.14') # string input
485 Decimal("3.14")
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000486 >>> Decimal((0, (3, 1, 4), -2)) # tuple (sign, digit_tuple, exponent)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000487 Decimal("3.14")
488 >>> Decimal(314) # int or long
489 Decimal("314")
490 >>> Decimal(Decimal(314)) # another decimal instance
491 Decimal("314")
492 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000493
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000494 self = object.__new__(cls)
495 self._is_special = False
496
497 # From an internal working value
498 if isinstance(value, _WorkRep):
Raymond Hettinger17931de2004-10-27 06:21:46 +0000499 self._sign = value.sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000500 self._int = tuple(map(int, str(value.int)))
501 self._exp = int(value.exp)
502 return self
503
504 # From another decimal
505 if isinstance(value, Decimal):
506 self._exp = value._exp
507 self._sign = value._sign
508 self._int = value._int
509 self._is_special = value._is_special
510 return self
511
512 # From an integer
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000513 if isinstance(value, (int,long)):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000514 if value >= 0:
515 self._sign = 0
516 else:
517 self._sign = 1
518 self._exp = 0
519 self._int = tuple(map(int, str(abs(value))))
520 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000521
522 # tuple/list conversion (possibly from as_tuple())
523 if isinstance(value, (list,tuple)):
524 if len(value) != 3:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000525 raise ValueError('Invalid arguments')
Raymond Hettingerdbecd932005-02-06 06:57:08 +0000526 if value[0] not in (0,1):
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000527 raise ValueError('Invalid sign')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000528 for digit in value[1]:
529 if not isinstance(digit, (int,long)) or digit < 0:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000530 raise ValueError("The second value in the tuple must be "+
531 "composed of non negative integer elements.")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000532
533 self._sign = value[0]
534 self._int = tuple(value[1])
535 if value[2] in ('F','n','N'):
536 self._exp = value[2]
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000537 self._is_special = True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000538 else:
539 self._exp = int(value[2])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000540 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000541
Raymond Hettingerbf440692004-07-10 14:14:37 +0000542 if isinstance(value, float):
543 raise TypeError("Cannot convert float to Decimal. " +
544 "First convert the float to a string")
545
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000546 # Other argument types may require the context during interpretation
547 if context is None:
548 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000549
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000550 # From a string
551 # REs insist on real strings, so we can too.
552 if isinstance(value, basestring):
553 if _isinfinity(value):
554 self._exp = 'F'
555 self._int = (0,)
556 self._is_special = True
557 if _isinfinity(value) == 1:
558 self._sign = 0
559 else:
560 self._sign = 1
561 return self
562 if _isnan(value):
563 sig, sign, diag = _isnan(value)
564 self._is_special = True
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000565 if len(diag) > context.prec: # Diagnostic info too long
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000566 self._sign, self._int, self._exp = \
567 context._raise_error(ConversionSyntax)
568 return self
569 if sig == 1:
570 self._exp = 'n' #qNaN
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000571 else: # sig == 2
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000572 self._exp = 'N' #sNaN
573 self._sign = sign
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000574 self._int = tuple(map(int, diag)) # Diagnostic info
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000575 return self
576 try:
577 self._sign, self._int, self._exp = _string2exact(value)
578 except ValueError:
579 self._is_special = True
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000580 self._sign, self._int, self._exp = \
581 context._raise_error(ConversionSyntax)
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000582 return self
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000583
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000584 raise TypeError("Cannot convert %r to Decimal" % value)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000585
586 def _isnan(self):
587 """Returns whether the number is not actually one.
588
589 0 if a number
590 1 if NaN
591 2 if sNaN
592 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000593 if self._is_special:
594 exp = self._exp
595 if exp == 'n':
596 return 1
597 elif exp == 'N':
598 return 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000599 return 0
600
601 def _isinfinity(self):
602 """Returns whether the number is infinite
603
604 0 if finite or not a number
605 1 if +INF
606 -1 if -INF
607 """
608 if self._exp == 'F':
609 if self._sign:
610 return -1
611 return 1
612 return 0
613
614 def _check_nans(self, other = None, context=None):
615 """Returns whether the number is not actually one.
616
617 if self, other are sNaN, signal
618 if self, other are NaN return nan
619 return 0
620
621 Done before operations.
622 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000623
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000624 self_is_nan = self._isnan()
625 if other is None:
626 other_is_nan = False
627 else:
628 other_is_nan = other._isnan()
629
630 if self_is_nan or other_is_nan:
631 if context is None:
632 context = getcontext()
633
634 if self_is_nan == 2:
635 return context._raise_error(InvalidOperation, 'sNaN',
636 1, self)
637 if other_is_nan == 2:
638 return context._raise_error(InvalidOperation, 'sNaN',
639 1, other)
640 if self_is_nan:
641 return self
642
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000643 return other
644 return 0
645
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000646 def __nonzero__(self):
647 """Is the number non-zero?
648
649 0 if self == 0
650 1 if self != 0
651 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000652 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000653 return 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000654 return sum(self._int) != 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000655
656 def __cmp__(self, other, context=None):
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000657 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +0000658 if other is NotImplemented:
659 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000660
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000661 if self._is_special or other._is_special:
662 ans = self._check_nans(other, context)
663 if ans:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000664 return 1 # Comparison involving NaN's always reports self > other
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000665
666 # INF = INF
667 return cmp(self._isinfinity(), other._isinfinity())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000668
669 if not self and not other:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000670 return 0 # If both 0, sign comparison isn't certain.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000671
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000672 # If different signs, neg one is less
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000673 if other._sign < self._sign:
674 return -1
675 if self._sign < other._sign:
676 return 1
677
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000678 self_adjusted = self.adjusted()
679 other_adjusted = other.adjusted()
680 if self_adjusted == other_adjusted and \
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000681 self._int + (0,)*(self._exp - other._exp) == \
682 other._int + (0,)*(other._exp - self._exp):
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000683 return 0 # Equal, except in precision. ([0]*(-x) = [])
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000684 elif self_adjusted > other_adjusted and self._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000685 return (-1)**self._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000686 elif self_adjusted < other_adjusted and other._int[0] != 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000687 return -((-1)**self._sign)
688
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000689 # Need to round, so make sure we have a valid context
690 if context is None:
691 context = getcontext()
692
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000693 context = context._shallow_copy()
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000694 rounding = context._set_rounding(ROUND_UP) # Round away from 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000695
696 flags = context._ignore_all_flags()
697 res = self.__sub__(other, context=context)
698
699 context._regard_flags(*flags)
700
701 context.rounding = rounding
702
703 if not res:
704 return 0
705 elif res._sign:
706 return -1
707 return 1
708
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000709 def __eq__(self, other):
710 if not isinstance(other, (Decimal, int, long)):
Raymond Hettinger267b8682005-03-27 10:47:39 +0000711 return NotImplemented
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000712 return self.__cmp__(other) == 0
713
714 def __ne__(self, other):
715 if not isinstance(other, (Decimal, int, long)):
Raymond Hettinger267b8682005-03-27 10:47:39 +0000716 return NotImplemented
Raymond Hettinger0aeac102004-07-05 22:53:03 +0000717 return self.__cmp__(other) != 0
718
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000719 def compare(self, other, context=None):
720 """Compares one to another.
721
722 -1 => a < b
723 0 => a = b
724 1 => a > b
725 NaN => one is NaN
726 Like __cmp__, but returns Decimal instances.
727 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000728 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +0000729 if other is NotImplemented:
730 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000731
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000732 # Compare(NaN, NaN) = NaN
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000733 if (self._is_special or other and other._is_special):
734 ans = self._check_nans(other, context)
735 if ans:
736 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000737
738 return Decimal(self.__cmp__(other, context))
739
740 def __hash__(self):
741 """x.__hash__() <==> hash(x)"""
742 # Decimal integers must hash the same as the ints
743 # Non-integer decimals are normalized and hashed as strings
Georg Brandl1fb9f522006-05-11 19:57:09 +0000744 # Normalization assures that hash(100E-1) == hash(10)
Raymond Hettingerbea3f6f2005-03-15 04:59:17 +0000745 if self._is_special:
746 if self._isnan():
747 raise TypeError('Cannot hash a NaN value.')
748 return hash(str(self))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000749 i = int(self)
750 if self == Decimal(i):
751 return hash(i)
752 assert self.__nonzero__() # '-0' handled by integer case
753 return hash(str(self.normalize()))
754
755 def as_tuple(self):
756 """Represents the number as a triple tuple.
757
758 To show the internals exactly as they are.
759 """
760 return (self._sign, self._int, self._exp)
761
762 def __repr__(self):
763 """Represents the number as an instance of Decimal."""
764 # Invariant: eval(repr(d)) == d
765 return 'Decimal("%s")' % str(self)
766
767 def __str__(self, eng = 0, context=None):
768 """Return string representation of the number in scientific notation.
769
770 Captures all of the information in the underlying representation.
771 """
772
Raymond Hettingere5a0a962005-06-20 09:49:42 +0000773 if self._is_special:
774 if self._isnan():
775 minus = '-'*self._sign
776 if self._int == (0,):
777 info = ''
778 else:
779 info = ''.join(map(str, self._int))
780 if self._isnan() == 2:
781 return minus + 'sNaN' + info
782 return minus + 'NaN' + info
783 if self._isinfinity():
784 minus = '-'*self._sign
785 return minus + 'Infinity'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000786
787 if context is None:
788 context = getcontext()
789
790 tmp = map(str, self._int)
791 numdigits = len(self._int)
792 leftdigits = self._exp + numdigits
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000793 if eng and not self: # self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
794 if self._exp < 0 and self._exp >= -6: # short, no need for e/E
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000795 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
796 return s
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000797 # exp is closest mult. of 3 >= self._exp
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000798 exp = ((self._exp - 1)// 3 + 1) * 3
799 if exp != self._exp:
800 s = '0.'+'0'*(exp - self._exp)
801 else:
802 s = '0'
803 if exp != 0:
804 if context.capitals:
805 s += 'E'
806 else:
807 s += 'e'
808 if exp > 0:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000809 s += '+' # 0.0e+3, not 0.0e3
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000810 s += str(exp)
811 s = '-'*self._sign + s
812 return s
813 if eng:
814 dotplace = (leftdigits-1)%3+1
815 adjexp = leftdigits -1 - (leftdigits-1)%3
816 else:
817 adjexp = leftdigits-1
818 dotplace = 1
819 if self._exp == 0:
820 pass
821 elif self._exp < 0 and adjexp >= 0:
822 tmp.insert(leftdigits, '.')
823 elif self._exp < 0 and adjexp >= -6:
824 tmp[0:0] = ['0'] * int(-leftdigits)
825 tmp.insert(0, '0.')
826 else:
827 if numdigits > dotplace:
828 tmp.insert(dotplace, '.')
829 elif numdigits < dotplace:
830 tmp.extend(['0']*(dotplace-numdigits))
831 if adjexp:
832 if not context.capitals:
833 tmp.append('e')
834 else:
835 tmp.append('E')
836 if adjexp > 0:
837 tmp.append('+')
838 tmp.append(str(adjexp))
839 if eng:
840 while tmp[0:1] == ['0']:
841 tmp[0:1] = []
842 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
843 tmp[0:0] = ['0']
844 if self._sign:
845 tmp.insert(0, '-')
846
847 return ''.join(tmp)
848
849 def to_eng_string(self, context=None):
850 """Convert to engineering-type string.
851
852 Engineering notation has an exponent which is a multiple of 3, so there
853 are up to 3 digits left of the decimal place.
854
855 Same rules for when in exponential and when as a value as in __str__.
856 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000857 return self.__str__(eng=1, context=context)
858
859 def __neg__(self, context=None):
860 """Returns a copy with the sign switched.
861
862 Rounds, if it has reason.
863 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000864 if self._is_special:
865 ans = self._check_nans(context=context)
866 if ans:
867 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000868
869 if not self:
870 # -Decimal('0') is Decimal('0'), not Decimal('-0')
871 sign = 0
872 elif self._sign:
873 sign = 0
874 else:
875 sign = 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000876
877 if context is None:
878 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000879 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000880 return Decimal((sign, self._int, self._exp))._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000881 return Decimal( (sign, self._int, self._exp))
882
883 def __pos__(self, context=None):
884 """Returns a copy, unless it is a sNaN.
885
886 Rounds the number (if more then precision digits)
887 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000888 if self._is_special:
889 ans = self._check_nans(context=context)
890 if ans:
891 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000892
893 sign = self._sign
894 if not self:
895 # + (-0) = 0
896 sign = 0
897
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000898 if context is None:
899 context = getcontext()
900
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000901 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000902 ans = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000903 else:
904 ans = Decimal(self)
905 ans._sign = sign
906 return ans
907
908 def __abs__(self, round=1, context=None):
909 """Returns the absolute value of self.
910
911 If the second argument is 0, do not round.
912 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000913 if self._is_special:
914 ans = self._check_nans(context=context)
915 if ans:
916 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000917
918 if not round:
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000919 if context is None:
920 context = getcontext()
Raymond Hettinger9fce44b2004-08-08 04:03:24 +0000921 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000922 context._set_rounding_decision(NEVER_ROUND)
923
924 if self._sign:
925 ans = self.__neg__(context=context)
926 else:
927 ans = self.__pos__(context=context)
928
929 return ans
930
931 def __add__(self, other, context=None):
932 """Returns self + other.
933
934 -INF + INF (or the reverse) cause InvalidOperation errors.
935 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000936 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +0000937 if other is NotImplemented:
938 return other
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000939
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000940 if context is None:
941 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000942
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000943 if self._is_special or other._is_special:
944 ans = self._check_nans(other, context)
945 if ans:
946 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000947
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000948 if self._isinfinity():
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000949 # If both INF, same sign => same as both, opposite => error.
Raymond Hettinger636a6b12004-09-19 01:54:09 +0000950 if self._sign != other._sign and other._isinfinity():
951 return context._raise_error(InvalidOperation, '-INF + INF')
952 return Decimal(self)
953 if other._isinfinity():
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000954 return Decimal(other) # Can't both be infinity here
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000955
956 shouldround = context._rounding_decision == ALWAYS_ROUND
957
958 exp = min(self._exp, other._exp)
959 negativezero = 0
960 if context.rounding == ROUND_FLOOR and self._sign != other._sign:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000961 # If the answer is 0, the sign should be negative, in this case.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000962 negativezero = 1
963
964 if not self and not other:
965 sign = min(self._sign, other._sign)
966 if negativezero:
967 sign = 1
968 return Decimal( (sign, (0,), exp))
969 if not self:
Facundo Batista99b55482004-10-26 23:38:46 +0000970 exp = max(exp, other._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000971 ans = other._rescale(exp, watchexp=0, context=context)
972 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000973 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000974 return ans
975 if not other:
Facundo Batista99b55482004-10-26 23:38:46 +0000976 exp = max(exp, self._exp - context.prec-1)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000977 ans = self._rescale(exp, watchexp=0, context=context)
978 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +0000979 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000980 return ans
981
982 op1 = _WorkRep(self)
983 op2 = _WorkRep(other)
984 op1, op2 = _normalize(op1, op2, shouldround, context.prec)
985
986 result = _WorkRep()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000987 if op1.sign != op2.sign:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000988 # Equal and opposite
Raymond Hettinger17931de2004-10-27 06:21:46 +0000989 if op1.int == op2.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000990 if exp < context.Etiny():
991 exp = context.Etiny()
992 context._raise_error(Clamped)
993 return Decimal((negativezero, (0,), exp))
Raymond Hettinger17931de2004-10-27 06:21:46 +0000994 if op1.int < op2.int:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000995 op1, op2 = op2, op1
Facundo Batistaac4ae4b2006-07-18 12:16:13 +0000996 # OK, now abs(op1) > abs(op2)
Raymond Hettinger17931de2004-10-27 06:21:46 +0000997 if op1.sign == 1:
998 result.sign = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000999 op1.sign, op2.sign = op2.sign, op1.sign
1000 else:
Raymond Hettinger17931de2004-10-27 06:21:46 +00001001 result.sign = 0
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001002 # So we know the sign, and op1 > 0.
Raymond Hettinger17931de2004-10-27 06:21:46 +00001003 elif op1.sign == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001004 result.sign = 1
Raymond Hettinger17931de2004-10-27 06:21:46 +00001005 op1.sign, op2.sign = (0, 0)
1006 else:
1007 result.sign = 0
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001008 # Now, op1 > abs(op2) > 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001009
Raymond Hettinger17931de2004-10-27 06:21:46 +00001010 if op2.sign == 0:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001011 result.int = op1.int + op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001012 else:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001013 result.int = op1.int - op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001014
1015 result.exp = op1.exp
1016 ans = Decimal(result)
1017 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001018 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001019 return ans
1020
1021 __radd__ = __add__
1022
1023 def __sub__(self, other, context=None):
1024 """Return self + (-other)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001025 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001026 if other is NotImplemented:
1027 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001028
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001029 if self._is_special or other._is_special:
1030 ans = self._check_nans(other, context=context)
1031 if ans:
1032 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001033
1034 # -Decimal(0) = Decimal(0), which we don't want since
1035 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
1036 # so we change the sign directly to a copy
1037 tmp = Decimal(other)
1038 tmp._sign = 1-tmp._sign
1039
1040 return self.__add__(tmp, context=context)
1041
1042 def __rsub__(self, other, context=None):
1043 """Return other + (-self)"""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001044 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001045 if other is NotImplemented:
1046 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001047
1048 tmp = Decimal(self)
1049 tmp._sign = 1 - tmp._sign
1050 return other.__add__(tmp, context=context)
1051
1052 def _increment(self, round=1, context=None):
1053 """Special case of add, adding 1eExponent
1054
1055 Since it is common, (rounding, for example) this adds
1056 (sign)*one E self._exp to the number more efficiently than add.
1057
1058 For example:
1059 Decimal('5.624e10')._increment() == Decimal('5.625e10')
1060 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001061 if self._is_special:
1062 ans = self._check_nans(context=context)
1063 if ans:
1064 return ans
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001065 # Must be infinite, and incrementing makes no difference
1066 return Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001067
1068 L = list(self._int)
1069 L[-1] += 1
1070 spot = len(L)-1
1071 while L[spot] == 10:
1072 L[spot] = 0
1073 if spot == 0:
1074 L[0:0] = [1]
1075 break
1076 L[spot-1] += 1
1077 spot -= 1
1078 ans = Decimal((self._sign, L, self._exp))
1079
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001080 if context is None:
1081 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001082 if round and context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001083 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001084 return ans
1085
1086 def __mul__(self, other, context=None):
1087 """Return self * other.
1088
1089 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1090 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001091 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001092 if other is NotImplemented:
1093 return other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001094
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001095 if context is None:
1096 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001097
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001098 resultsign = self._sign ^ other._sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001099
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001100 if self._is_special or other._is_special:
1101 ans = self._check_nans(other, context)
1102 if ans:
1103 return ans
1104
1105 if self._isinfinity():
1106 if not other:
1107 return context._raise_error(InvalidOperation, '(+-)INF * 0')
1108 return Infsign[resultsign]
1109
1110 if other._isinfinity():
1111 if not self:
1112 return context._raise_error(InvalidOperation, '0 * (+-)INF')
1113 return Infsign[resultsign]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001114
1115 resultexp = self._exp + other._exp
1116 shouldround = context._rounding_decision == ALWAYS_ROUND
1117
1118 # Special case for multiplying by zero
1119 if not self or not other:
1120 ans = Decimal((resultsign, (0,), resultexp))
1121 if shouldround:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001122 # Fixing in case the exponent is out of bounds
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001123 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001124 return ans
1125
1126 # Special case for multiplying by power of 10
1127 if self._int == (1,):
1128 ans = Decimal((resultsign, other._int, resultexp))
1129 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001130 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001131 return ans
1132 if other._int == (1,):
1133 ans = Decimal((resultsign, self._int, resultexp))
1134 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001135 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001136 return ans
1137
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001138 op1 = _WorkRep(self)
1139 op2 = _WorkRep(other)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001140
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001141 ans = Decimal((resultsign, map(int, str(op1.int * op2.int)), resultexp))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001142 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001143 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001144
1145 return ans
1146 __rmul__ = __mul__
1147
1148 def __div__(self, other, context=None):
1149 """Return self / other."""
1150 return self._divide(other, context=context)
1151 __truediv__ = __div__
1152
1153 def _divide(self, other, divmod = 0, context=None):
1154 """Return a / b, to context.prec precision.
1155
1156 divmod:
1157 0 => true division
1158 1 => (a //b, a%b)
1159 2 => a //b
1160 3 => a%b
1161
1162 Actually, if divmod is 2 or 3 a tuple is returned, but errors for
1163 computing the other value are not raised.
1164 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001165 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001166 if other is NotImplemented:
1167 if divmod in (0, 1):
1168 return NotImplemented
1169 return (NotImplemented, NotImplemented)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001170
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001171 if context is None:
1172 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001173
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +00001174 sign = self._sign ^ other._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001175
1176 if self._is_special or other._is_special:
1177 ans = self._check_nans(other, context)
1178 if ans:
1179 if divmod:
1180 return (ans, ans)
1181 return ans
1182
1183 if self._isinfinity() and other._isinfinity():
1184 if divmod:
1185 return (context._raise_error(InvalidOperation,
1186 '(+-)INF // (+-)INF'),
1187 context._raise_error(InvalidOperation,
1188 '(+-)INF % (+-)INF'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001189 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001190
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001191 if self._isinfinity():
1192 if divmod == 1:
1193 return (Infsign[sign],
1194 context._raise_error(InvalidOperation, 'INF % x'))
1195 elif divmod == 2:
1196 return (Infsign[sign], NaN)
1197 elif divmod == 3:
1198 return (Infsign[sign],
1199 context._raise_error(InvalidOperation, 'INF % x'))
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001200 return Infsign[sign]
1201
1202 if other._isinfinity():
1203 if divmod:
1204 return (Decimal((sign, (0,), 0)), Decimal(self))
1205 context._raise_error(Clamped, 'Division by infinity')
1206 return Decimal((sign, (0,), context.Etiny()))
1207
1208 # Special cases for zeroes
1209 if not self and not other:
1210 if divmod:
1211 return context._raise_error(DivisionUndefined, '0 / 0', 1)
1212 return context._raise_error(DivisionUndefined, '0 / 0')
1213
1214 if not self:
1215 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001216 otherside = Decimal(self)
1217 otherside._exp = min(self._exp, other._exp)
1218 return (Decimal((sign, (0,), 0)), otherside)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001219 exp = self._exp - other._exp
1220 if exp < context.Etiny():
1221 exp = context.Etiny()
1222 context._raise_error(Clamped, '0e-x / y')
1223 if exp > context.Emax:
1224 exp = context.Emax
1225 context._raise_error(Clamped, '0e+x / y')
1226 return Decimal( (sign, (0,), exp) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001227
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001228 if not other:
1229 if divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001230 return context._raise_error(DivisionByZero, 'divmod(x,0)',
1231 sign, 1)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001232 return context._raise_error(DivisionByZero, 'x / 0', sign)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001233
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001234 # OK, so neither = 0, INF or NaN
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001235 shouldround = context._rounding_decision == ALWAYS_ROUND
1236
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001237 # If we're dividing into ints, and self < other, stop.
1238 # self.__abs__(0) does not round.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001239 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
1240
1241 if divmod == 1 or divmod == 3:
1242 exp = min(self._exp, other._exp)
1243 ans2 = self._rescale(exp, context=context, watchexp=0)
1244 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001245 ans2 = ans2._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001246 return (Decimal( (sign, (0,), 0) ),
1247 ans2)
1248
1249 elif divmod == 2:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001250 # Don't round the mod part, if we don't need it.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001251 return (Decimal( (sign, (0,), 0) ), Decimal(self))
1252
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001253 op1 = _WorkRep(self)
1254 op2 = _WorkRep(other)
1255 op1, op2, adjust = _adjust_coefficients(op1, op2)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001256 res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001257 if divmod and res.exp > context.prec + 1:
1258 return context._raise_error(DivisionImpossible)
1259
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001260 prec_limit = 10 ** context.prec
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001261 while 1:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001262 while op2.int <= op1.int:
1263 res.int += 1
1264 op1.int -= op2.int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001265 if res.exp == 0 and divmod:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001266 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001267 return context._raise_error(DivisionImpossible)
1268 otherside = Decimal(op1)
1269 frozen = context._ignore_all_flags()
1270
1271 exp = min(self._exp, other._exp)
Raymond Hettinger17931de2004-10-27 06:21:46 +00001272 otherside = otherside._rescale(exp, context=context, watchexp=0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001273 context._regard_flags(*frozen)
1274 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001275 otherside = otherside._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001276 return (Decimal(res), otherside)
1277
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001278 if op1.int == 0 and adjust >= 0 and not divmod:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001279 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001280 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001281 if divmod:
1282 return context._raise_error(DivisionImpossible)
1283 shouldround=1
1284 # Really, the answer is a bit higher, so adding a one to
1285 # the end will make sure the rounding is right.
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001286 if op1.int != 0:
1287 res.int *= 10
1288 res.int += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001289 res.exp -= 1
1290
1291 break
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001292 res.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001293 res.exp -= 1
1294 adjust += 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001295 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001296 op1.exp -= 1
1297
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001298 if res.exp == 0 and divmod and op2.int > op1.int:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001299 # Solves an error in precision. Same as a previous block.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001300
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001301 if res.int >= prec_limit and shouldround:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001302 return context._raise_error(DivisionImpossible)
1303 otherside = Decimal(op1)
1304 frozen = context._ignore_all_flags()
1305
1306 exp = min(self._exp, other._exp)
1307 otherside = otherside._rescale(exp, context=context)
1308
1309 context._regard_flags(*frozen)
1310
1311 return (Decimal(res), otherside)
1312
1313 ans = Decimal(res)
1314 if shouldround:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001315 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001316 return ans
1317
1318 def __rdiv__(self, other, context=None):
1319 """Swaps self/other and returns __div__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001320 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001321 if other is NotImplemented:
1322 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001323 return other.__div__(self, context=context)
1324 __rtruediv__ = __rdiv__
1325
1326 def __divmod__(self, other, context=None):
1327 """
1328 (self // other, self % other)
1329 """
1330 return self._divide(other, 1, context)
1331
1332 def __rdivmod__(self, other, context=None):
1333 """Swaps self/other and returns __divmod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001334 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001335 if other is NotImplemented:
1336 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001337 return other.__divmod__(self, context=context)
1338
1339 def __mod__(self, other, context=None):
1340 """
1341 self % other
1342 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001343 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001344 if other is NotImplemented:
1345 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001346
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001347 if self._is_special or other._is_special:
1348 ans = self._check_nans(other, context)
1349 if ans:
1350 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001351
1352 if self and not other:
1353 return context._raise_error(InvalidOperation, 'x % 0')
1354
1355 return self._divide(other, 3, context)[1]
1356
1357 def __rmod__(self, other, context=None):
1358 """Swaps self/other and returns __mod__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001359 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001360 if other is NotImplemented:
1361 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001362 return other.__mod__(self, context=context)
1363
1364 def remainder_near(self, other, context=None):
1365 """
1366 Remainder nearest to 0- abs(remainder-near) <= other/2
1367 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001368 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001369 if other is NotImplemented:
1370 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001371
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001372 if self._is_special or other._is_special:
1373 ans = self._check_nans(other, context)
1374 if ans:
1375 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001376 if self and not other:
1377 return context._raise_error(InvalidOperation, 'x % 0')
1378
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001379 if context is None:
1380 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001381 # If DivisionImpossible causes an error, do not leave Rounded/Inexact
1382 # ignored in the calling function.
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001383 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001384 flags = context._ignore_flags(Rounded, Inexact)
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001385 # Keep DivisionImpossible flags
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001386 (side, r) = self.__divmod__(other, context=context)
1387
1388 if r._isnan():
1389 context._regard_flags(*flags)
1390 return r
1391
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001392 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001393 rounding = context._set_rounding_decision(NEVER_ROUND)
1394
1395 if other._sign:
1396 comparison = other.__div__(Decimal(-2), context=context)
1397 else:
1398 comparison = other.__div__(Decimal(2), context=context)
1399
1400 context._set_rounding_decision(rounding)
1401 context._regard_flags(*flags)
1402
1403 s1, s2 = r._sign, comparison._sign
1404 r._sign, comparison._sign = 0, 0
1405
1406 if r < comparison:
1407 r._sign, comparison._sign = s1, s2
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001408 # Get flags now
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001409 self.__divmod__(other, context=context)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001410 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001411 r._sign, comparison._sign = s1, s2
1412
1413 rounding = context._set_rounding_decision(NEVER_ROUND)
1414
1415 (side, r) = self.__divmod__(other, context=context)
1416 context._set_rounding_decision(rounding)
1417 if r._isnan():
1418 return r
1419
1420 decrease = not side._iseven()
1421 rounding = context._set_rounding_decision(NEVER_ROUND)
1422 side = side.__abs__(context=context)
1423 context._set_rounding_decision(rounding)
1424
1425 s1, s2 = r._sign, comparison._sign
1426 r._sign, comparison._sign = 0, 0
1427 if r > comparison or decrease and r == comparison:
1428 r._sign, comparison._sign = s1, s2
1429 context.prec += 1
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001430 numbsquant = len(side.__add__(Decimal(1), context=context)._int)
1431 if numbsquant >= context.prec:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001432 context.prec -= 1
1433 return context._raise_error(DivisionImpossible)[1]
1434 context.prec -= 1
1435 if self._sign == other._sign:
1436 r = r.__sub__(other, context=context)
1437 else:
1438 r = r.__add__(other, context=context)
1439 else:
1440 r._sign, comparison._sign = s1, s2
1441
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001442 return r._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001443
1444 def __floordiv__(self, other, context=None):
1445 """self // other"""
1446 return self._divide(other, 2, context)[0]
1447
1448 def __rfloordiv__(self, other, context=None):
1449 """Swaps self/other and returns __floordiv__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001450 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001451 if other is NotImplemented:
1452 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001453 return other.__floordiv__(self, context=context)
1454
1455 def __float__(self):
1456 """Float representation."""
1457 return float(str(self))
1458
1459 def __int__(self):
Brett Cannon46b08022005-03-01 03:12:26 +00001460 """Converts self to an int, truncating if necessary."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001461 if self._is_special:
1462 if self._isnan():
1463 context = getcontext()
1464 return context._raise_error(InvalidContext)
1465 elif self._isinfinity():
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001466 raise OverflowError("Cannot convert infinity to long")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001467 if self._exp >= 0:
Raymond Hettinger605ed022004-11-24 07:28:48 +00001468 s = ''.join(map(str, self._int)) + '0'*self._exp
1469 else:
1470 s = ''.join(map(str, self._int))[:self._exp]
1471 if s == '':
1472 s = '0'
1473 sign = '-'*self._sign
1474 return int(sign + s)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001475
1476 def __long__(self):
1477 """Converts to a long.
1478
1479 Equivalent to long(int(self))
1480 """
1481 return long(self.__int__())
1482
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001483 def _fix(self, context):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001484 """Round if it is necessary to keep self within prec precision.
1485
1486 Rounds and fixes the exponent. Does not raise on a sNaN.
1487
1488 Arguments:
1489 self - Decimal instance
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001490 context - context used.
1491 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001492 if self._is_special:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001493 return self
1494 if context is None:
1495 context = getcontext()
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001496 prec = context.prec
Facundo Batista99b55482004-10-26 23:38:46 +00001497 ans = self._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001498 if len(ans._int) > prec:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001499 ans = ans._round(prec, context=context)
Facundo Batista99b55482004-10-26 23:38:46 +00001500 ans = ans._fixexponents(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001501 return ans
1502
Facundo Batista99b55482004-10-26 23:38:46 +00001503 def _fixexponents(self, context):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001504 """Fix the exponents and return a copy with the exponent in bounds.
1505 Only call if known to not be a special value.
1506 """
1507 folddown = context._clamp
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001508 Emin = context.Emin
Facundo Batista99b55482004-10-26 23:38:46 +00001509 ans = self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001510 ans_adjusted = ans.adjusted()
1511 if ans_adjusted < Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001512 Etiny = context.Etiny()
1513 if ans._exp < Etiny:
1514 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001515 ans = Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001516 ans._exp = Etiny
1517 context._raise_error(Clamped)
1518 return ans
1519 ans = ans._rescale(Etiny, context=context)
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001520 # It isn't zero, and exp < Emin => subnormal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001521 context._raise_error(Subnormal)
1522 if context.flags[Inexact]:
1523 context._raise_error(Underflow)
1524 else:
1525 if ans:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001526 # Only raise subnormal if non-zero.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001527 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001528 else:
1529 Etop = context.Etop()
1530 if folddown and ans._exp > Etop:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001531 context._raise_error(Clamped)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001532 ans = ans._rescale(Etop, context=context)
1533 else:
1534 Emax = context.Emax
1535 if ans_adjusted > Emax:
1536 if not ans:
Facundo Batista99b55482004-10-26 23:38:46 +00001537 ans = Decimal(self)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001538 ans._exp = Emax
1539 context._raise_error(Clamped)
1540 return ans
1541 context._raise_error(Inexact)
1542 context._raise_error(Rounded)
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001543 c = context._raise_error(Overflow, 'above Emax', ans._sign)
1544 return c
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001545 return ans
1546
1547 def _round(self, prec=None, rounding=None, context=None):
1548 """Returns a rounded version of self.
1549
1550 You can specify the precision or rounding method. Otherwise, the
1551 context determines it.
1552 """
1553
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001554 if self._is_special:
1555 ans = self._check_nans(context=context)
1556 if ans:
1557 return ans
1558
1559 if self._isinfinity():
1560 return Decimal(self)
1561
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001562 if context is None:
1563 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001564
1565 if rounding is None:
1566 rounding = context.rounding
1567 if prec is None:
1568 prec = context.prec
1569
1570 if not self:
1571 if prec <= 0:
1572 dig = (0,)
1573 exp = len(self._int) - prec + self._exp
1574 else:
1575 dig = (0,) * prec
1576 exp = len(self._int) + self._exp - prec
1577 ans = Decimal((self._sign, dig, exp))
1578 context._raise_error(Rounded)
1579 return ans
1580
1581 if prec == 0:
1582 temp = Decimal(self)
1583 temp._int = (0,)+temp._int
1584 prec = 1
1585 elif prec < 0:
1586 exp = self._exp + len(self._int) - prec - 1
1587 temp = Decimal( (self._sign, (0, 1), exp))
1588 prec = 1
1589 else:
1590 temp = Decimal(self)
1591
1592 numdigits = len(temp._int)
1593 if prec == numdigits:
1594 return temp
1595
1596 # See if we need to extend precision
1597 expdiff = prec - numdigits
1598 if expdiff > 0:
1599 tmp = list(temp._int)
1600 tmp.extend([0] * expdiff)
1601 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff))
1602 return ans
1603
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001604 # OK, but maybe all the lost digits are 0.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001605 lostdigits = self._int[expdiff:]
1606 if lostdigits == (0,) * len(lostdigits):
1607 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001608 # Rounded, but not Inexact
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001609 context._raise_error(Rounded)
1610 return ans
1611
1612 # Okay, let's round and lose data
1613
1614 this_function = getattr(temp, self._pick_rounding_function[rounding])
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001615 # Now we've got the rounding function
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001616
1617 if prec != context.prec:
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001618 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001619 context.prec = prec
1620 ans = this_function(prec, expdiff, context)
1621 context._raise_error(Rounded)
1622 context._raise_error(Inexact, 'Changed in rounding')
1623
1624 return ans
1625
1626 _pick_rounding_function = {}
1627
1628 def _round_down(self, prec, expdiff, context):
1629 """Also known as round-towards-0, truncate."""
1630 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1631
1632 def _round_half_up(self, prec, expdiff, context, tmp = None):
1633 """Rounds 5 up (away from 0)"""
1634
1635 if tmp is None:
1636 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
1637 if self._int[prec] >= 5:
1638 tmp = tmp._increment(round=0, context=context)
1639 if len(tmp._int) > prec:
1640 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1641 return tmp
1642
1643 def _round_half_even(self, prec, expdiff, context):
1644 """Round 5 to even, rest to nearest."""
1645
1646 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1647 half = (self._int[prec] == 5)
1648 if half:
1649 for digit in self._int[prec+1:]:
1650 if digit != 0:
1651 half = 0
1652 break
1653 if half:
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001654 if self._int[prec-1] & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001655 return tmp
1656 return self._round_half_up(prec, expdiff, context, tmp)
1657
1658 def _round_half_down(self, prec, expdiff, context):
1659 """Round 5 down"""
1660
1661 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
1662 half = (self._int[prec] == 5)
1663 if half:
1664 for digit in self._int[prec+1:]:
1665 if digit != 0:
1666 half = 0
1667 break
1668 if half:
1669 return tmp
1670 return self._round_half_up(prec, expdiff, context, tmp)
1671
1672 def _round_up(self, prec, expdiff, context):
1673 """Rounds away from 0."""
1674 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
1675 for digit in self._int[prec:]:
1676 if digit != 0:
1677 tmp = tmp._increment(round=1, context=context)
1678 if len(tmp._int) > prec:
1679 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
1680 else:
1681 return tmp
1682 return tmp
1683
1684 def _round_ceiling(self, prec, expdiff, context):
1685 """Rounds up (not away from 0 if negative.)"""
1686 if self._sign:
1687 return self._round_down(prec, expdiff, context)
1688 else:
1689 return self._round_up(prec, expdiff, context)
1690
1691 def _round_floor(self, prec, expdiff, context):
1692 """Rounds down (not towards 0 if negative)"""
1693 if not self._sign:
1694 return self._round_down(prec, expdiff, context)
1695 else:
1696 return self._round_up(prec, expdiff, context)
1697
1698 def __pow__(self, n, modulo = None, context=None):
1699 """Return self ** n (mod modulo)
1700
1701 If modulo is None (default), don't take it mod modulo.
1702 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001703 n = _convert_other(n)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001704 if n is NotImplemented:
1705 return n
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001706
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001707 if context is None:
1708 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001709
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001710 if self._is_special or n._is_special or n.adjusted() > 8:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001711 # Because the spot << doesn't work with really big exponents
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001712 if n._isinfinity() or n.adjusted() > 8:
1713 return context._raise_error(InvalidOperation, 'x ** INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001714
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001715 ans = self._check_nans(n, context)
1716 if ans:
1717 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001718
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001719 if not n._isinteger():
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001720 return context._raise_error(InvalidOperation, 'x ** (non-integer)')
1721
1722 if not self and not n:
1723 return context._raise_error(InvalidOperation, '0 ** 0')
1724
1725 if not n:
1726 return Decimal(1)
1727
1728 if self == Decimal(1):
1729 return Decimal(1)
1730
1731 sign = self._sign and not n._iseven()
1732 n = int(n)
1733
1734 if self._isinfinity():
1735 if modulo:
1736 return context._raise_error(InvalidOperation, 'INF % x')
1737 if n > 0:
1738 return Infsign[sign]
1739 return Decimal( (sign, (0,), 0) )
1740
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001741 # With ludicrously large exponent, just raise an overflow and return inf.
1742 if not modulo and n > 0 \
1743 and (self._exp + len(self._int) - 1) * n > context.Emax and self:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001744 tmp = Decimal('inf')
1745 tmp._sign = sign
1746 context._raise_error(Rounded)
1747 context._raise_error(Inexact)
1748 context._raise_error(Overflow, 'Big power', sign)
1749 return tmp
1750
1751 elength = len(str(abs(n)))
1752 firstprec = context.prec
1753
Raymond Hettinger99148e72004-07-14 19:56:56 +00001754 if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001755 return context._raise_error(Overflow, 'Too much precision.', sign)
1756
1757 mul = Decimal(self)
1758 val = Decimal(1)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001759 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001760 context.prec = firstprec + elength + 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001761 if n < 0:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001762 # n is a long now, not Decimal instance
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001763 n = -n
1764 mul = Decimal(1).__div__(mul, context=context)
1765
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001766 spot = 1
1767 while spot <= n:
1768 spot <<= 1
1769
1770 spot >>= 1
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001771 # Spot is the highest power of 2 less than n
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001772 while spot:
1773 val = val.__mul__(val, context=context)
1774 if val._isinfinity():
1775 val = Infsign[sign]
1776 break
1777 if spot & n:
1778 val = val.__mul__(mul, context=context)
1779 if modulo is not None:
1780 val = val.__mod__(modulo, context=context)
1781 spot >>= 1
1782 context.prec = firstprec
1783
Raymond Hettinger76e60d62004-10-20 06:58:28 +00001784 if context._rounding_decision == ALWAYS_ROUND:
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001785 return val._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001786 return val
1787
1788 def __rpow__(self, other, context=None):
1789 """Swaps self/other and returns __pow__."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001790 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00001791 if other is NotImplemented:
1792 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001793 return other.__pow__(self, context=context)
1794
1795 def normalize(self, context=None):
1796 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001797
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001798 if self._is_special:
1799 ans = self._check_nans(context=context)
1800 if ans:
1801 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001802
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001803 dup = self._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001804 if dup._isinfinity():
1805 return dup
1806
1807 if not dup:
1808 return Decimal( (dup._sign, (0,), 0) )
1809 end = len(dup._int)
1810 exp = dup._exp
1811 while dup._int[end-1] == 0:
1812 exp += 1
1813 end -= 1
1814 return Decimal( (dup._sign, dup._int[:end], exp) )
1815
1816
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001817 def quantize(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001818 """Quantize self so its exponent is the same as that of exp.
1819
1820 Similar to self._rescale(exp._exp) but with error checking.
1821 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001822 if self._is_special or exp._is_special:
1823 ans = self._check_nans(exp, context)
1824 if ans:
1825 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001826
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001827 if exp._isinfinity() or self._isinfinity():
1828 if exp._isinfinity() and self._isinfinity():
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001829 return self # If both are inf, it is OK
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001830 if context is None:
1831 context = getcontext()
1832 return context._raise_error(InvalidOperation,
1833 'quantize with one INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001834 return self._rescale(exp._exp, rounding, context, watchexp)
1835
1836 def same_quantum(self, other):
1837 """Test whether self and other have the same exponent.
1838
1839 same as self._exp == other._exp, except NaN == sNaN
1840 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001841 if self._is_special or other._is_special:
1842 if self._isnan() or other._isnan():
1843 return self._isnan() and other._isnan() and True
1844 if self._isinfinity() or other._isinfinity():
1845 return self._isinfinity() and other._isinfinity() and True
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001846 return self._exp == other._exp
1847
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001848 def _rescale(self, exp, rounding=None, context=None, watchexp=1):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001849 """Rescales so that the exponent is exp.
1850
1851 exp = exp to scale to (an integer)
1852 rounding = rounding version
1853 watchexp: if set (default) an error is returned if exp is greater
1854 than Emax or less than Etiny.
1855 """
1856 if context is None:
1857 context = getcontext()
1858
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001859 if self._is_special:
1860 if self._isinfinity():
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001861 return context._raise_error(InvalidOperation,
1862 'rescale with an INF')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001863
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001864 ans = self._check_nans(context=context)
1865 if ans:
1866 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001867
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001868 if watchexp and (context.Emax < exp or context.Etiny() > exp):
1869 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1870
1871 if not self:
1872 ans = Decimal(self)
1873 ans._int = (0,)
1874 ans._exp = exp
1875 return ans
1876
1877 diff = self._exp - exp
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001878 digits = len(self._int) + diff
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001879
1880 if watchexp and digits > context.prec:
1881 return context._raise_error(InvalidOperation, 'Rescale > prec')
1882
1883 tmp = Decimal(self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001884 tmp._int = (0,) + tmp._int
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001885 digits += 1
1886
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001887 if digits < 0:
1888 tmp._exp = -digits + tmp._exp
1889 tmp._int = (0,1)
1890 digits = 1
1891 tmp = tmp._round(digits, rounding, context=context)
1892
1893 if tmp._int[0] == 0 and len(tmp._int) > 1:
1894 tmp._int = tmp._int[1:]
1895 tmp._exp = exp
1896
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001897 tmp_adjusted = tmp.adjusted()
1898 if tmp and tmp_adjusted < context.Emin:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001899 context._raise_error(Subnormal)
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001900 elif tmp and tmp_adjusted > context.Emax:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001901 return context._raise_error(InvalidOperation, 'rescale(a, INF)')
1902 return tmp
1903
Raymond Hettingerdab988d2004-10-09 07:10:44 +00001904 def to_integral(self, rounding=None, context=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001905 """Rounds to the nearest integer, without raising inexact, rounded."""
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001906 if self._is_special:
1907 ans = self._check_nans(context=context)
1908 if ans:
1909 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001910 if self._exp >= 0:
1911 return self
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001912 if context is None:
1913 context = getcontext()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001914 flags = context._ignore_flags(Rounded, Inexact)
1915 ans = self._rescale(0, rounding, context=context)
1916 context._regard_flags(flags)
1917 return ans
1918
1919 def sqrt(self, context=None):
1920 """Return the square root of self.
1921
1922 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
1923 Should quadratically approach the right answer.
1924 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001925 if self._is_special:
1926 ans = self._check_nans(context=context)
1927 if ans:
1928 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001929
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001930 if self._isinfinity() and self._sign == 0:
1931 return Decimal(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001932
1933 if not self:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001934 # exponent = self._exp / 2, using round_down.
1935 # if self._exp < 0:
1936 # exp = (self._exp+1) // 2
1937 # else:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001938 exp = (self._exp) // 2
1939 if self._sign == 1:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001940 # sqrt(-0) = -0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001941 return Decimal( (1, (0,), exp))
1942 else:
1943 return Decimal( (0, (0,), exp))
1944
Raymond Hettinger636a6b12004-09-19 01:54:09 +00001945 if context is None:
1946 context = getcontext()
1947
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001948 if self._sign == 1:
1949 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
1950
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001951 tmp = Decimal(self)
1952
Raymond Hettinger4837a222004-09-27 14:23:40 +00001953 expadd = tmp._exp // 2
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001954 if tmp._exp & 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001955 tmp._int += (0,)
1956 tmp._exp = 0
1957 else:
1958 tmp._exp = 0
1959
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00001960 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001961 flags = context._ignore_all_flags()
1962 firstprec = context.prec
1963 context.prec = 3
Raymond Hettinger61992ef2004-08-06 23:42:16 +00001964 if tmp.adjusted() & 1 == 0:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001965 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) )
1966 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
1967 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00001968 ans._exp -= 1 + tmp.adjusted() // 2
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001969 else:
1970 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
1971 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
1972 context=context), context=context)
Raymond Hettinger4837a222004-09-27 14:23:40 +00001973 ans._exp -= 1 + tmp.adjusted() // 2
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001974 # ans is now a linear approximation.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001975
1976 Emax, Emin = context.Emax, context.Emin
Raymond Hettinger99148e72004-07-14 19:56:56 +00001977 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001978
1979 half = Decimal('0.5')
1980
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001981 maxp = firstprec + 2
1982 rounding = context._set_rounding(ROUND_HALF_EVEN)
1983 while 1:
1984 context.prec = min(2*context.prec - 2, maxp)
1985 ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
1986 context=context), context=context)
1987 if context.prec == maxp:
1988 break
1989
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001990 # Round to the answer's precision-- the only error can be 1 ulp.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001991 context.prec = firstprec
1992 prevexp = ans.adjusted()
1993 ans = ans._round(context=context)
1994
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00001995 # Now, check if the other last digits are better.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001996 context.prec = firstprec + 1
1997 # In case we rounded up another digit and we should actually go lower.
1998 if prevexp != ans.adjusted():
1999 ans._int += (0,)
2000 ans._exp -= 1
2001
2002
2003 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
2004 context._set_rounding(ROUND_UP)
2005 if lower.__mul__(lower, context=context) > (tmp):
2006 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
2007
2008 else:
2009 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
2010 context._set_rounding(ROUND_DOWN)
2011 if upper.__mul__(upper, context=context) < tmp:
2012 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
2013
2014 ans._exp += expadd
2015
2016 context.prec = firstprec
2017 context.rounding = rounding
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002018 ans = ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002019
2020 rounding = context._set_rounding_decision(NEVER_ROUND)
2021 if not ans.__mul__(ans, context=context) == self:
2022 # Only rounded/inexact if here.
2023 context._regard_flags(flags)
2024 context._raise_error(Rounded)
2025 context._raise_error(Inexact)
2026 else:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002027 # Exact answer, so let's set the exponent right.
2028 # if self._exp < 0:
2029 # exp = (self._exp +1)// 2
2030 # else:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002031 exp = self._exp // 2
2032 context.prec += ans._exp - exp
2033 ans = ans._rescale(exp, context=context)
2034 context.prec = firstprec
2035 context._regard_flags(flags)
2036 context.Emax, context.Emin = Emax, Emin
2037
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002038 return ans._fix(context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002039
2040 def max(self, other, context=None):
2041 """Returns the larger value.
2042
2043 like max(self, other) except if one is not a number, returns
2044 NaN (and signals if one is sNaN). Also rounds.
2045 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002046 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002047 if other is NotImplemented:
2048 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002049
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002050 if self._is_special or other._is_special:
2051 # if one operand is a quiet NaN and the other is number, then the
2052 # number is always returned
2053 sn = self._isnan()
2054 on = other._isnan()
2055 if sn or on:
2056 if on == 1 and sn != 2:
2057 return self
2058 if sn == 1 and on != 2:
2059 return other
2060 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002061
2062 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002063 c = self.__cmp__(other)
2064 if c == 0:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002065 # If both operands are finite and equal in numerical value
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002066 # then an ordering is applied:
2067 #
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002068 # If the signs differ then max returns the operand with the
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002069 # positive sign and min returns the operand with the negative sign
2070 #
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002071 # If the signs are the same then the exponent is used to select
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002072 # the result.
2073 if self._sign != other._sign:
2074 if self._sign:
2075 ans = other
2076 elif self._exp < other._exp and not self._sign:
2077 ans = other
2078 elif self._exp > other._exp and self._sign:
2079 ans = other
2080 elif c == -1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002081 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002082
2083 if context is None:
2084 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002085 if context._rounding_decision == ALWAYS_ROUND:
2086 return ans._fix(context)
2087 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002088
2089 def min(self, other, context=None):
2090 """Returns the smaller value.
2091
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002092 Like min(self, other) except if one is not a number, returns
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002093 NaN (and signals if one is sNaN). Also rounds.
2094 """
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002095 other = _convert_other(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002096 if other is NotImplemented:
2097 return other
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002098
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002099 if self._is_special or other._is_special:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002100 # If one operand is a quiet NaN and the other is number, then the
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002101 # number is always returned
2102 sn = self._isnan()
2103 on = other._isnan()
2104 if sn or on:
2105 if on == 1 and sn != 2:
2106 return self
2107 if sn == 1 and on != 2:
2108 return other
2109 return self._check_nans(other, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002110
2111 ans = self
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002112 c = self.__cmp__(other)
2113 if c == 0:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002114 # If both operands are finite and equal in numerical value
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002115 # then an ordering is applied:
2116 #
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002117 # If the signs differ then max returns the operand with the
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002118 # positive sign and min returns the operand with the negative sign
2119 #
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002120 # If the signs are the same then the exponent is used to select
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002121 # the result.
2122 if self._sign != other._sign:
2123 if other._sign:
2124 ans = other
2125 elif self._exp > other._exp and not self._sign:
2126 ans = other
2127 elif self._exp < other._exp and self._sign:
2128 ans = other
2129 elif c == 1:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002130 ans = other
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002131
2132 if context is None:
2133 context = getcontext()
Raymond Hettinger76e60d62004-10-20 06:58:28 +00002134 if context._rounding_decision == ALWAYS_ROUND:
2135 return ans._fix(context)
2136 return ans
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002137
2138 def _isinteger(self):
2139 """Returns whether self is an integer"""
2140 if self._exp >= 0:
2141 return True
2142 rest = self._int[self._exp:]
2143 return rest == (0,)*len(rest)
2144
2145 def _iseven(self):
2146 """Returns 1 if self is even. Assumes self is an integer."""
2147 if self._exp > 0:
2148 return 1
Raymond Hettinger61992ef2004-08-06 23:42:16 +00002149 return self._int[-1+self._exp] & 1 == 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002150
2151 def adjusted(self):
2152 """Return the adjusted exponent of self"""
2153 try:
2154 return self._exp + len(self._int) - 1
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002155 # If NaN or Infinity, self._exp is string
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002156 except TypeError:
2157 return 0
2158
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002159 # Support for pickling, copy, and deepcopy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002160 def __reduce__(self):
2161 return (self.__class__, (str(self),))
2162
2163 def __copy__(self):
2164 if type(self) == Decimal:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002165 return self # I'm immutable; therefore I am my own clone
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002166 return self.__class__(str(self))
2167
2168 def __deepcopy__(self, memo):
2169 if type(self) == Decimal:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002170 return self # My components are also immutable
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002171 return self.__class__(str(self))
2172
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002173##### Context class ##########################################################
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002174
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002175# Get rounding method function:
2176rounding_functions = [name for name in Decimal.__dict__.keys()
2177 if name.startswith('_round_')]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002178for name in rounding_functions:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002179 # Name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002180 globalname = name[1:].upper()
2181 val = globals()[globalname]
2182 Decimal._pick_rounding_function[val] = name
2183
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002184del name, val, globalname, rounding_functions
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002185
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002186
Nick Coghlanafd5e632006-05-03 13:02:47 +00002187class ContextManager(object):
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002188 """Helper class to simplify Context management.
2189
2190 Sample usage:
2191
2192 with decimal.ExtendedContext:
2193 s = ...
2194 return +s # Convert result to normal precision
2195
2196 with decimal.getcontext() as ctx:
2197 ctx.prec += 2
2198 s = ...
2199 return +s
2200
2201 """
2202 def __init__(self, new_context):
2203 self.new_context = new_context
2204 def __enter__(self):
2205 self.saved_context = getcontext()
2206 setcontext(self.new_context)
2207 return self.new_context
2208 def __exit__(self, t, v, tb):
2209 setcontext(self.saved_context)
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002210
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002211
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002212class Context(object):
2213 """Contains the context for a Decimal instance.
2214
2215 Contains:
2216 prec - precision (for use in rounding, division, square roots..)
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002217 rounding - rounding type (how you round).
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002218 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
Raymond Hettingerbf440692004-07-10 14:14:37 +00002219 traps - If traps[exception] = 1, then the exception is
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002220 raised when it is caused. Otherwise, a value is
2221 substituted in.
2222 flags - When an exception is caused, flags[exception] is incremented.
2223 (Whether or not the trap_enabler is set)
2224 Should be reset by user of Decimal instance.
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002225 Emin - Minimum exponent
2226 Emax - Maximum exponent
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002227 capitals - If 1, 1*10^1 is printed as 1E+1.
2228 If 0, printed as 1e1
Raymond Hettingere0f15812004-07-05 05:36:39 +00002229 _clamp - If 1, change exponents if too high (Default 0)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002230 """
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002231
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002232 def __init__(self, prec=None, rounding=None,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002233 traps=None, flags=None,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002234 _rounding_decision=None,
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002235 Emin=None, Emax=None,
Raymond Hettingere0f15812004-07-05 05:36:39 +00002236 capitals=None, _clamp=0,
Raymond Hettingerabf8a562004-10-12 09:12:16 +00002237 _ignored_flags=None):
2238 if flags is None:
2239 flags = []
2240 if _ignored_flags is None:
2241 _ignored_flags = []
Raymond Hettingerbf440692004-07-10 14:14:37 +00002242 if not isinstance(flags, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002243 flags = dict([(s,s in flags) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002244 del s
Raymond Hettingerbf440692004-07-10 14:14:37 +00002245 if traps is not None and not isinstance(traps, dict):
Raymond Hettingerfed52962004-07-14 15:41:57 +00002246 traps = dict([(s,s in traps) for s in _signals])
Raymond Hettingerb91af522004-07-14 16:35:30 +00002247 del s
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002248 for name, val in locals().items():
2249 if val is None:
Raymond Hettingereb260842005-06-07 18:52:34 +00002250 setattr(self, name, _copy.copy(getattr(DefaultContext, name)))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002251 else:
2252 setattr(self, name, val)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002253 del self.self
2254
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002255 def __repr__(self):
Raymond Hettingerbf440692004-07-10 14:14:37 +00002256 """Show the current context."""
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002257 s = []
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002258 s.append(
2259 'Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d'
2260 % vars(self))
Tim Peters73a9ead2006-07-18 21:55:15 +00002261 s.append('flags=[' + ', '.join([f.__name__ for f, v
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002262 in self.flags.items() if v]) + ']')
Tim Peters73a9ead2006-07-18 21:55:15 +00002263 s.append('traps=[' + ', '.join([t.__name__ for t, v
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002264 in self.traps.items() if v]) + ']')
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002265 return ', '.join(s) + ')'
2266
Nick Coghlanafd5e632006-05-03 13:02:47 +00002267 def get_manager(self):
2268 return ContextManager(self.copy())
Guido van Rossum1a5e21e2006-02-28 21:57:43 +00002269
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002270 def clear_flags(self):
2271 """Reset all flags to zero"""
2272 for flag in self.flags:
Raymond Hettingerb1b605e2004-07-04 01:55:39 +00002273 self.flags[flag] = 0
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00002274
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002275 def _shallow_copy(self):
2276 """Returns a shallow copy from self."""
Raymond Hettingerbf440692004-07-10 14:14:37 +00002277 nc = Context(self.prec, self.rounding, self.traps, self.flags,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002278 self._rounding_decision, self.Emin, self.Emax,
2279 self.capitals, self._clamp, self._ignored_flags)
2280 return nc
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002281
2282 def copy(self):
2283 """Returns a deep copy from self."""
Tim Peters73a9ead2006-07-18 21:55:15 +00002284 nc = Context(self.prec, self.rounding, self.traps.copy(),
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002285 self.flags.copy(), self._rounding_decision,
2286 self.Emin, self.Emax, self.capitals,
2287 self._clamp, self._ignored_flags)
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002288 return nc
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002289 __copy__ = copy
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002290
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002291 def _raise_error(self, condition, explanation = None, *args):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002292 """Handles an error
2293
2294 If the flag is in _ignored_flags, returns the default response.
2295 Otherwise, it increments the flag, then, if the corresponding
2296 trap_enabler is set, it reaises the exception. Otherwise, it returns
2297 the default value after incrementing the flag.
2298 """
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002299 error = _condition_map.get(condition, condition)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002300 if error in self._ignored_flags:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002301 # Don't touch the flag
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002302 return error().handle(self, *args)
2303
2304 self.flags[error] += 1
Raymond Hettingerbf440692004-07-10 14:14:37 +00002305 if not self.traps[error]:
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002306 # The errors define how to handle themselves.
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002307 return condition().handle(self, *args)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002308
2309 # Errors should only be risked on copies of the context
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002310 # self._ignored_flags = []
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002311 raise error, explanation
2312
2313 def _ignore_all_flags(self):
2314 """Ignore all flags, if they are raised"""
Raymond Hettingerfed52962004-07-14 15:41:57 +00002315 return self._ignore_flags(*_signals)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002316
2317 def _ignore_flags(self, *flags):
2318 """Ignore the flags, if they are raised"""
2319 # Do not mutate-- This way, copies of a context leave the original
2320 # alone.
2321 self._ignored_flags = (self._ignored_flags + list(flags))
2322 return list(flags)
2323
2324 def _regard_flags(self, *flags):
2325 """Stop ignoring the flags, if they are raised"""
2326 if flags and isinstance(flags[0], (tuple,list)):
2327 flags = flags[0]
2328 for flag in flags:
2329 self._ignored_flags.remove(flag)
2330
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002331 def __hash__(self):
2332 """A Context cannot be hashed."""
2333 # We inherit object.__hash__, so we must deny this explicitly
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002334 raise TypeError("Cannot hash a Context.")
Raymond Hettinger5aa478b2004-07-09 10:02:53 +00002335
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002336 def Etiny(self):
2337 """Returns Etiny (= Emin - prec + 1)"""
2338 return int(self.Emin - self.prec + 1)
2339
2340 def Etop(self):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002341 """Returns maximum exponent (= Emax - prec + 1)"""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002342 return int(self.Emax - self.prec + 1)
2343
2344 def _set_rounding_decision(self, type):
2345 """Sets the rounding decision.
2346
2347 Sets the rounding decision, and returns the current (previous)
2348 rounding decision. Often used like:
2349
Raymond Hettinger9fce44b2004-08-08 04:03:24 +00002350 context = context._shallow_copy()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002351 # That so you don't change the calling context
2352 # if an error occurs in the middle (say DivisionImpossible is raised).
2353
2354 rounding = context._set_rounding_decision(NEVER_ROUND)
2355 instance = instance / Decimal(2)
2356 context._set_rounding_decision(rounding)
2357
2358 This will make it not round for that operation.
2359 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002360 rounding = self._rounding_decision
2361 self._rounding_decision = type
2362 return rounding
2363
2364 def _set_rounding(self, type):
2365 """Sets the rounding type.
2366
2367 Sets the rounding type, and returns the current (previous)
2368 rounding type. Often used like:
2369
2370 context = context.copy()
2371 # so you don't change the calling context
2372 # if an error occurs in the middle.
2373 rounding = context._set_rounding(ROUND_UP)
2374 val = self.__sub__(other, context=context)
2375 context._set_rounding(rounding)
2376
2377 This will make it round up for that operation.
2378 """
2379 rounding = self.rounding
2380 self.rounding= type
2381 return rounding
2382
Raymond Hettingerfed52962004-07-14 15:41:57 +00002383 def create_decimal(self, num='0'):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002384 """Creates a new Decimal instance but using self as context."""
2385 d = Decimal(num, context=self)
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002386 return d._fix(self)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002387
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002388 # Methods
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002389 def abs(self, a):
2390 """Returns the absolute value of the operand.
2391
2392 If the operand is negative, the result is the same as using the minus
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002393 operation on the operand. Otherwise, the result is the same as using
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002394 the plus operation on the operand.
2395
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002396 >>> ExtendedContext.abs(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002397 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002398 >>> ExtendedContext.abs(Decimal('-100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002399 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002400 >>> ExtendedContext.abs(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002401 Decimal("101.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002402 >>> ExtendedContext.abs(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002403 Decimal("101.5")
2404 """
2405 return a.__abs__(context=self)
2406
2407 def add(self, a, b):
2408 """Return the sum of the two operands.
2409
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002410 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002411 Decimal("19.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002412 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002413 Decimal("1.02E+4")
2414 """
2415 return a.__add__(b, context=self)
2416
2417 def _apply(self, a):
Raymond Hettingerdab988d2004-10-09 07:10:44 +00002418 return str(a._fix(self))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002419
2420 def compare(self, a, b):
2421 """Compares values numerically.
2422
2423 If the signs of the operands differ, a value representing each operand
2424 ('-1' if the operand is less than zero, '0' if the operand is zero or
2425 negative zero, or '1' if the operand is greater than zero) is used in
2426 place of that operand for the comparison instead of the actual
2427 operand.
2428
2429 The comparison is then effected by subtracting the second operand from
2430 the first and then returning a value according to the result of the
2431 subtraction: '-1' if the result is less than zero, '0' if the result is
2432 zero or negative zero, or '1' if the result is greater than zero.
2433
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002434 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002435 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002436 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002437 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002438 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002439 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002440 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002441 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002442 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002443 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002444 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002445 Decimal("-1")
2446 """
2447 return a.compare(b, context=self)
2448
2449 def divide(self, a, b):
2450 """Decimal division in a specified context.
2451
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002452 >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002453 Decimal("0.333333333")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002454 >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002455 Decimal("0.666666667")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002456 >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002457 Decimal("2.5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002458 >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002459 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002460 >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002461 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002462 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002463 Decimal("4.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002464 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002465 Decimal("1.20")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002466 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002467 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002468 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002469 Decimal("1000")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002470 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002471 Decimal("1.20E+6")
2472 """
2473 return a.__div__(b, context=self)
2474
2475 def divide_int(self, a, b):
2476 """Divides two numbers and returns the integer part of the result.
2477
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002478 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002479 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002480 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002481 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002482 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002483 Decimal("3")
2484 """
2485 return a.__floordiv__(b, context=self)
2486
2487 def divmod(self, a, b):
2488 return a.__divmod__(b, context=self)
2489
2490 def max(self, a,b):
2491 """max compares two values numerically and returns the maximum.
2492
2493 If either operand is a NaN then the general rules apply.
2494 Otherwise, the operands are compared as as though by the compare
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002495 operation. If they are numerically equal then the left-hand operand
2496 is chosen as the result. Otherwise the maximum (closer to positive
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002497 infinity) of the two operands is chosen as the result.
2498
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002499 >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002500 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002501 >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002502 Decimal("3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002503 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002504 Decimal("1")
2505 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
2506 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002507 """
2508 return a.max(b, context=self)
2509
2510 def min(self, a,b):
2511 """min compares two values numerically and returns the minimum.
2512
2513 If either operand is a NaN then the general rules apply.
2514 Otherwise, the operands are compared as as though by the compare
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002515 operation. If they are numerically equal then the left-hand operand
2516 is chosen as the result. Otherwise the minimum (closer to negative
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002517 infinity) of the two operands is chosen as the result.
2518
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002519 >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002520 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002521 >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002522 Decimal("-10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002523 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002524 Decimal("1.0")
Raymond Hettingerd6c700a2004-08-17 06:39:37 +00002525 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
2526 Decimal("7")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002527 """
2528 return a.min(b, context=self)
2529
2530 def minus(self, a):
2531 """Minus corresponds to unary prefix minus in Python.
2532
2533 The operation is evaluated using the same rules as subtract; the
2534 operation minus(a) is calculated as subtract('0', a) where the '0'
2535 has the same exponent as the operand.
2536
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002537 >>> ExtendedContext.minus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002538 Decimal("-1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002539 >>> ExtendedContext.minus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002540 Decimal("1.3")
2541 """
2542 return a.__neg__(context=self)
2543
2544 def multiply(self, a, b):
2545 """multiply multiplies two operands.
2546
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002547 If either operand is a special value then the general rules
2548 apply. Otherwise, the operands are multiplied together
2549 ('long multiplication'), resulting in a number which may be
2550 as long as the sum of the lengths of the two operands.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002551
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002552 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002553 Decimal("3.60")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002554 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002555 Decimal("21")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002556 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002557 Decimal("0.72")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002558 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002559 Decimal("-0.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002560 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002561 Decimal("4.28135971E+11")
2562 """
2563 return a.__mul__(b, context=self)
2564
2565 def normalize(self, a):
Raymond Hettingere0f15812004-07-05 05:36:39 +00002566 """normalize reduces an operand to its simplest form.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002567
2568 Essentially a plus operation with all trailing zeros removed from the
2569 result.
2570
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002571 >>> ExtendedContext.normalize(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002572 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002573 >>> ExtendedContext.normalize(Decimal('-2.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002574 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002575 >>> ExtendedContext.normalize(Decimal('1.200'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002576 Decimal("1.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002577 >>> ExtendedContext.normalize(Decimal('-120'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002578 Decimal("-1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002579 >>> ExtendedContext.normalize(Decimal('120.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002580 Decimal("1.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002581 >>> ExtendedContext.normalize(Decimal('0.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002582 Decimal("0")
2583 """
2584 return a.normalize(context=self)
2585
2586 def plus(self, a):
2587 """Plus corresponds to unary prefix plus in Python.
2588
2589 The operation is evaluated using the same rules as add; the
2590 operation plus(a) is calculated as add('0', a) where the '0'
2591 has the same exponent as the operand.
2592
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002593 >>> ExtendedContext.plus(Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002594 Decimal("1.3")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002595 >>> ExtendedContext.plus(Decimal('-1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002596 Decimal("-1.3")
2597 """
2598 return a.__pos__(context=self)
2599
2600 def power(self, a, b, modulo=None):
2601 """Raises a to the power of b, to modulo if given.
2602
2603 The right-hand operand must be a whole number whose integer part (after
2604 any exponent has been applied) has no more than 9 digits and whose
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002605 fractional part (if any) is all zeros before any rounding. The operand
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002606 may be positive, negative, or zero; if negative, the absolute value of
2607 the power is used, and the left-hand operand is inverted (divided into
2608 1) before use.
2609
2610 If the increased precision needed for the intermediate calculations
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002611 exceeds the capabilities of the implementation then an Invalid
2612 operation condition is raised.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002613
2614 If, when raising to a negative power, an underflow occurs during the
2615 division into 1, the operation is not halted at that point but
2616 continues.
2617
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002618 >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002619 Decimal("8")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002620 >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002621 Decimal("0.125")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002622 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002623 Decimal("69.7575744")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002624 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002625 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002626 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002627 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002628 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002629 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002630 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002631 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002632 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002633 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002634 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002635 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002636 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002637 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002638 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002639 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002640 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002641 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002642 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002643 Decimal("Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002644 >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002645 Decimal("NaN")
2646 """
2647 return a.__pow__(b, modulo, context=self)
2648
2649 def quantize(self, a, b):
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002650 """Returns a value equal to 'a' (rounded), having the exponent of 'b'.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002651
2652 The coefficient of the result is derived from that of the left-hand
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002653 operand. It may be rounded using the current rounding setting (if the
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002654 exponent is being increased), multiplied by a positive power of ten (if
2655 the exponent is being decreased), or is unchanged (if the exponent is
2656 already equal to that of the right-hand operand).
2657
2658 Unlike other operations, if the length of the coefficient after the
2659 quantize operation would be greater than precision then an Invalid
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002660 operation condition is raised. This guarantees that, unless there is
2661 an error condition, the exponent of the result of a quantize is always
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002662 equal to that of the right-hand operand.
2663
2664 Also unlike other operations, quantize will never raise Underflow, even
2665 if the result is subnormal and inexact.
2666
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002667 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002668 Decimal("2.170")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002669 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002670 Decimal("2.17")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002671 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002672 Decimal("2.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002673 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002674 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002675 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002676 Decimal("0E+1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002677 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002678 Decimal("-Infinity")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002679 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002680 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002681 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002682 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002683 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002684 Decimal("-0E+5")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002685 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002686 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002687 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002688 Decimal("NaN")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002689 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002690 Decimal("217.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002691 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002692 Decimal("217")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002693 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002694 Decimal("2.2E+2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002695 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002696 Decimal("2E+2")
2697 """
2698 return a.quantize(b, context=self)
2699
2700 def remainder(self, a, b):
2701 """Returns the remainder from integer division.
2702
2703 The result is the residue of the dividend after the operation of
Tim Peters73a9ead2006-07-18 21:55:15 +00002704 calculating integer division as described for divide-integer, rounded
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002705 to precision digits if necessary. The sign of the result, if non-zero,
2706 is the same as that of the original dividend.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002707
2708 This operation will fail under the same conditions as integer division
2709 (that is, if integer division on the same two operands would fail, the
2710 remainder cannot be calculated).
2711
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002712 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002713 Decimal("2.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002714 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002715 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002716 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002717 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002718 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002719 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002720 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002721 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002722 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002723 Decimal("1.0")
2724 """
2725 return a.__mod__(b, context=self)
2726
2727 def remainder_near(self, a, b):
2728 """Returns to be "a - b * n", where n is the integer nearest the exact
2729 value of "x / b" (if two integers are equally near then the even one
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002730 is chosen). If the result is equal to 0 then its sign will be the
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002731 sign of a.
2732
2733 This operation will fail under the same conditions as integer division
2734 (that is, if integer division on the same two operands would fail, the
2735 remainder cannot be calculated).
2736
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002737 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002738 Decimal("-0.9")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002739 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002740 Decimal("-2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002741 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002742 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002743 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002744 Decimal("-1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002745 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002746 Decimal("0.2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002747 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002748 Decimal("0.1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002749 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002750 Decimal("-0.3")
2751 """
2752 return a.remainder_near(b, context=self)
2753
2754 def same_quantum(self, a, b):
2755 """Returns True if the two operands have the same exponent.
2756
2757 The result is never affected by either the sign or the coefficient of
2758 either operand.
2759
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002760 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002761 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002762 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002763 True
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002764 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002765 False
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002766 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002767 True
2768 """
2769 return a.same_quantum(b)
2770
2771 def sqrt(self, a):
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002772 """Square root of a non-negative number to context precision.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002773
2774 If the result must be inexact, it is rounded using the round-half-even
2775 algorithm.
2776
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002777 >>> ExtendedContext.sqrt(Decimal('0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002778 Decimal("0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002779 >>> ExtendedContext.sqrt(Decimal('-0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002780 Decimal("-0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002781 >>> ExtendedContext.sqrt(Decimal('0.39'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002782 Decimal("0.624499800")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002783 >>> ExtendedContext.sqrt(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002784 Decimal("10")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002785 >>> ExtendedContext.sqrt(Decimal('1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002786 Decimal("1")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002787 >>> ExtendedContext.sqrt(Decimal('1.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002788 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002789 >>> ExtendedContext.sqrt(Decimal('1.00'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002790 Decimal("1.0")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002791 >>> ExtendedContext.sqrt(Decimal('7'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002792 Decimal("2.64575131")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002793 >>> ExtendedContext.sqrt(Decimal('10'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002794 Decimal("3.16227766")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002795 >>> ExtendedContext.prec
Raymond Hettinger6ea48452004-07-03 12:26:21 +00002796 9
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002797 """
2798 return a.sqrt(context=self)
2799
2800 def subtract(self, a, b):
Georg Brandlf33d01d2005-08-22 19:35:18 +00002801 """Return the difference between the two operands.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002802
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002803 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002804 Decimal("0.23")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002805 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002806 Decimal("0.00")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002807 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002808 Decimal("-0.77")
2809 """
2810 return a.__sub__(b, context=self)
2811
2812 def to_eng_string(self, a):
2813 """Converts a number to a string, using scientific notation.
2814
2815 The operation is not affected by the context.
2816 """
2817 return a.to_eng_string(context=self)
2818
2819 def to_sci_string(self, a):
2820 """Converts a number to a string, using scientific notation.
2821
2822 The operation is not affected by the context.
2823 """
2824 return a.__str__(context=self)
2825
2826 def to_integral(self, a):
2827 """Rounds to an integer.
2828
2829 When the operand has a negative exponent, the result is the same
2830 as using the quantize() operation using the given operand as the
2831 left-hand-operand, 1E+0 as the right-hand-operand, and the precision
2832 of the operand as the precision setting, except that no flags will
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002833 be set. The rounding mode is taken from the context.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002834
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002835 >>> ExtendedContext.to_integral(Decimal('2.1'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002836 Decimal("2")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002837 >>> ExtendedContext.to_integral(Decimal('100'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002838 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002839 >>> ExtendedContext.to_integral(Decimal('100.0'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002840 Decimal("100")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002841 >>> ExtendedContext.to_integral(Decimal('101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002842 Decimal("102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002843 >>> ExtendedContext.to_integral(Decimal('-101.5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002844 Decimal("-102")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002845 >>> ExtendedContext.to_integral(Decimal('10E+5'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002846 Decimal("1.0E+6")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002847 >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002848 Decimal("7.89E+77")
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00002849 >>> ExtendedContext.to_integral(Decimal('-Inf'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002850 Decimal("-Infinity")
2851 """
2852 return a.to_integral(context=self)
2853
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002854
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002855class _WorkRep(object):
2856 __slots__ = ('sign','int','exp')
Raymond Hettinger17931de2004-10-27 06:21:46 +00002857 # sign: 0 or 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002858 # int: int or long
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002859 # exp: None, int, or string
2860
2861 def __init__(self, value=None):
2862 if value is None:
2863 self.sign = None
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002864 self.int = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002865 self.exp = None
Raymond Hettinger17931de2004-10-27 06:21:46 +00002866 elif isinstance(value, Decimal):
2867 self.sign = value._sign
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002868 cum = 0
Raymond Hettinger17931de2004-10-27 06:21:46 +00002869 for digit in value._int:
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002870 cum = cum * 10 + digit
2871 self.int = cum
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002872 self.exp = value._exp
Raymond Hettinger17931de2004-10-27 06:21:46 +00002873 else:
2874 # assert isinstance(value, tuple)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002875 self.sign = value[0]
2876 self.int = value[1]
2877 self.exp = value[2]
2878
2879 def __repr__(self):
2880 return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
2881
2882 __str__ = __repr__
2883
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002884
2885
2886def _normalize(op1, op2, shouldround = 0, prec = 0):
2887 """Normalizes op1, op2 to have the same exp and length of coefficient.
2888
2889 Done during addition.
2890 """
2891 # Yes, the exponent is a long, but the difference between exponents
2892 # must be an int-- otherwise you'd get a big memory problem.
2893 numdigits = int(op1.exp - op2.exp)
2894 if numdigits < 0:
2895 numdigits = -numdigits
2896 tmp = op2
2897 other = op1
2898 else:
2899 tmp = op1
2900 other = op2
2901
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002902
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002903 if shouldround and numdigits > prec + 1:
2904 # Big difference in exponents - check the adjusted exponents
2905 tmp_len = len(str(tmp.int))
2906 other_len = len(str(other.int))
2907 if numdigits > (other_len + prec + 1 - tmp_len):
2908 # If the difference in adjusted exps is > prec+1, we know
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002909 # other is insignificant, so might as well put a 1 after the
2910 # precision (since this is only for addition). Also stops
2911 # use of massive longs.
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002912 extend = prec + 2 - tmp_len
2913 if extend <= 0:
2914 extend = 1
2915 tmp.int *= 10 ** extend
2916 tmp.exp -= extend
2917 other.int = 1
2918 other.exp = tmp.exp
2919 return op1, op2
2920
2921 tmp.int *= 10 ** numdigits
2922 tmp.exp -= numdigits
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002923 return op1, op2
2924
2925def _adjust_coefficients(op1, op2):
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002926 """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002927
2928 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
2929
2930 Used on _WorkRep instances during division.
2931 """
2932 adjust = 0
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002933 # If op1 is smaller, make it larger
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002934 while op2.int > op1.int:
2935 op1.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002936 op1.exp -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002937 adjust += 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002938
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002939 # If op2 is too small, make it larger
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002940 while op1.int >= (10 * op2.int):
2941 op2.int *= 10
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002942 op2.exp -= 1
2943 adjust -= 1
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002944
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002945 return op1, op2, adjust
2946
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002947
2948##### Helper Functions #######################################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002949
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002950def _convert_other(other):
2951 """Convert other to Decimal.
2952
2953 Verifies that it's ok to use in an implicit construction.
2954 """
2955 if isinstance(other, Decimal):
2956 return other
2957 if isinstance(other, (int, long)):
2958 return Decimal(other)
Raymond Hettinger267b8682005-03-27 10:47:39 +00002959 return NotImplemented
Raymond Hettinger636a6b12004-09-19 01:54:09 +00002960
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002961_infinity_map = {
2962 'inf' : 1,
2963 'infinity' : 1,
2964 '+inf' : 1,
2965 '+infinity' : 1,
2966 '-inf' : -1,
2967 '-infinity' : -1
2968}
2969
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002970def _isinfinity(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002971 """Determines whether a string or float is infinity.
2972
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002973 +1 for negative infinity; 0 for finite ; +1 for positive infinity
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002974 """
2975 num = str(num).lower()
2976 return _infinity_map.get(num, 0)
2977
Raymond Hettinger0ea241e2004-07-04 13:53:24 +00002978def _isnan(num):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002979 """Determines whether a string or float is NaN
2980
2981 (1, sign, diagnostic info as string) => NaN
2982 (2, sign, diagnostic info as string) => sNaN
2983 0 => not a NaN
2984 """
2985 num = str(num).lower()
2986 if not num:
2987 return 0
2988
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002989 # get the sign, get rid of trailing [+-]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002990 sign = 0
2991 if num[0] == '+':
2992 num = num[1:]
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002993 elif num[0] == '-': # elif avoids '+-nan'
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002994 num = num[1:]
2995 sign = 1
2996
2997 if num.startswith('nan'):
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00002998 if len(num) > 3 and not num[3:].isdigit(): # diagnostic info
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002999 return 0
3000 return (1, sign, num[3:].lstrip('0'))
3001 if num.startswith('snan'):
3002 if len(num) > 4 and not num[4:].isdigit():
3003 return 0
3004 return (2, sign, num[4:].lstrip('0'))
3005 return 0
3006
3007
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00003008##### Setup Specific Contexts ################################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003009
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003010# The default context prototype used by Context()
Raymond Hettingerfed52962004-07-14 15:41:57 +00003011# Is mutable, so that new contexts can have different default values
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003012
3013DefaultContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003014 prec=28, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003015 traps=[DivisionByZero, Overflow, InvalidOperation],
3016 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003017 _rounding_decision=ALWAYS_ROUND,
Raymond Hettinger99148e72004-07-14 19:56:56 +00003018 Emax=999999999,
3019 Emin=-999999999,
Raymond Hettingere0f15812004-07-05 05:36:39 +00003020 capitals=1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003021)
3022
3023# Pre-made alternate contexts offered by the specification
3024# Don't change these; the user should be able to select these
3025# contexts and be able to reproduce results from other implementations
3026# of the spec.
3027
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003028BasicContext = Context(
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003029 prec=9, rounding=ROUND_HALF_UP,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003030 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
3031 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003032)
3033
Raymond Hettinger9ec3e3b2004-07-03 13:48:56 +00003034ExtendedContext = Context(
Raymond Hettinger6ea48452004-07-03 12:26:21 +00003035 prec=9, rounding=ROUND_HALF_EVEN,
Raymond Hettingerbf440692004-07-10 14:14:37 +00003036 traps=[],
3037 flags=[],
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003038)
3039
3040
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00003041##### Useful Constants (internal use only) ###################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003042
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00003043# Reusable defaults
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003044Inf = Decimal('Inf')
3045negInf = Decimal('-Inf')
3046
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00003047# Infsign[sign] is infinity w/ that sign
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003048Infsign = (Inf, negInf)
3049
3050NaN = Decimal('NaN')
3051
3052
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00003053##### crud for parsing strings ################################################
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003054import re
3055
3056# There's an optional sign at the start, and an optional exponent
3057# at the end. The exponent has an optional sign and at least one
3058# digit. In between, must have either at least one digit followed
3059# by an optional fraction, or a decimal point followed by at least
3060# one digit. Yuck.
3061
3062_parser = re.compile(r"""
3063# \s*
3064 (?P<sign>[-+])?
3065 (
3066 (?P<int>\d+) (\. (?P<frac>\d*))?
3067 |
3068 \. (?P<onlyfrac>\d+)
3069 )
3070 ([eE](?P<exp>[-+]? \d+))?
3071# \s*
3072 $
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00003073""", re.VERBOSE).match # Uncomment the \s* to allow leading/trailing spaces
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003074
3075del re
3076
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003077
3078def _string2exact(s):
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00003079 """Return sign, n, p s.t.
Tim Peters73a9ead2006-07-18 21:55:15 +00003080
Facundo Batistaac4ae4b2006-07-18 12:16:13 +00003081 Float string value == -1**sign * n * 10**p exactly
3082 """
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00003083 m = _parser(s)
3084 if m is None:
3085 raise ValueError("invalid literal for Decimal: %r" % s)
3086
3087 if m.group('sign') == "-":
3088 sign = 1
3089 else:
3090 sign = 0
3091
3092 exp = m.group('exp')
3093 if exp is None:
3094 exp = 0
3095 else:
3096 exp = int(exp)
3097
3098 intpart = m.group('int')
3099 if intpart is None:
3100 intpart = ""
3101 fracpart = m.group('onlyfrac')
3102 else:
3103 fracpart = m.group('frac')
3104 if fracpart is None:
3105 fracpart = ""
3106
3107 exp -= len(fracpart)
3108
3109 mantissa = intpart + fracpart
3110 tmp = map(int, mantissa)
3111 backup = tmp
3112 while tmp and tmp[0] == 0:
3113 del tmp[0]
3114
3115 # It's a zero
3116 if not tmp:
3117 if backup:
3118 return (sign, tuple(backup), exp)
3119 return (sign, (0,), exp)
3120 mantissa = tuple(tmp)
3121
3122 return (sign, mantissa, exp)
3123
3124
3125if __name__ == '__main__':
3126 import doctest, sys
3127 doctest.testmod(sys.modules[__name__])