|
1 # 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> |
|
7 # and Aahz <aahz at pobox.com> |
|
8 # and Tim Peters |
|
9 |
|
10 # 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. |
|
19 |
|
20 """ |
|
21 This is a Py2.3 implementation of decimal floating point arithmetic based on |
|
22 the General Decimal Arithmetic Specification: |
|
23 |
|
24 www2.hursley.ibm.com/decimal/decarith.html |
|
25 |
|
26 and IEEE standard 854-1987: |
|
27 |
|
28 www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html |
|
29 |
|
30 Decimal floating point has finite precision with arbitrarily large bounds. |
|
31 |
|
32 The purpose of the module is to support arithmetic using familiar |
|
33 "schoolhouse" rules and to avoid the some of tricky representation |
|
34 issues associated with binary floating point. The package is especially |
|
35 useful for financial applications or for contexts where users have |
|
36 expectations that are at odds with binary floating point (for instance, |
|
37 in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead |
|
38 of the expected Decimal("0.00") returned by decimal floating point). |
|
39 |
|
40 Here are some examples of using the decimal module: |
|
41 |
|
42 >>> from decimal import * |
|
43 >>> setcontext(ExtendedContext) |
|
44 >>> Decimal(0) |
|
45 Decimal("0") |
|
46 >>> Decimal("1") |
|
47 Decimal("1") |
|
48 >>> Decimal("-.0123") |
|
49 Decimal("-0.0123") |
|
50 >>> Decimal(123456) |
|
51 Decimal("123456") |
|
52 >>> Decimal("123.45e12345678901234567890") |
|
53 Decimal("1.2345E+12345678901234567892") |
|
54 >>> Decimal("1.33") + Decimal("1.27") |
|
55 Decimal("2.60") |
|
56 >>> Decimal("12.34") + Decimal("3.87") - Decimal("18.41") |
|
57 Decimal("-2.20") |
|
58 >>> dig = Decimal(1) |
|
59 >>> print dig / Decimal(3) |
|
60 0.333333333 |
|
61 >>> getcontext().prec = 18 |
|
62 >>> print dig / Decimal(3) |
|
63 0.333333333333333333 |
|
64 >>> print dig.sqrt() |
|
65 1 |
|
66 >>> print Decimal(3).sqrt() |
|
67 1.73205080756887729 |
|
68 >>> print Decimal(3) ** 123 |
|
69 4.85192780976896427E+58 |
|
70 >>> inf = Decimal(1) / Decimal(0) |
|
71 >>> print inf |
|
72 Infinity |
|
73 >>> neginf = Decimal(-1) / Decimal(0) |
|
74 >>> print neginf |
|
75 -Infinity |
|
76 >>> print neginf + inf |
|
77 NaN |
|
78 >>> print neginf * inf |
|
79 -Infinity |
|
80 >>> print dig / 0 |
|
81 Infinity |
|
82 >>> getcontext().traps[DivisionByZero] = 1 |
|
83 >>> print dig / 0 |
|
84 Traceback (most recent call last): |
|
85 ... |
|
86 ... |
|
87 ... |
|
88 DivisionByZero: x / 0 |
|
89 >>> c = Context() |
|
90 >>> c.traps[InvalidOperation] = 0 |
|
91 >>> print c.flags[InvalidOperation] |
|
92 0 |
|
93 >>> c.divide(Decimal(0), Decimal(0)) |
|
94 Decimal("NaN") |
|
95 >>> c.traps[InvalidOperation] = 1 |
|
96 >>> print c.flags[InvalidOperation] |
|
97 1 |
|
98 >>> c.flags[InvalidOperation] = 0 |
|
99 >>> print c.flags[InvalidOperation] |
|
100 0 |
|
101 >>> print c.divide(Decimal(0), Decimal(0)) |
|
102 Traceback (most recent call last): |
|
103 ... |
|
104 ... |
|
105 ... |
|
106 InvalidOperation: 0 / 0 |
|
107 >>> print c.flags[InvalidOperation] |
|
108 1 |
|
109 >>> c.flags[InvalidOperation] = 0 |
|
110 >>> c.traps[InvalidOperation] = 0 |
|
111 >>> print c.divide(Decimal(0), Decimal(0)) |
|
112 NaN |
|
113 >>> print c.flags[InvalidOperation] |
|
114 1 |
|
115 >>> |
|
116 """ |
|
117 |
|
118 __all__ = [ |
|
119 # Two major classes |
|
120 'Decimal', 'Context', |
|
121 |
|
122 # Contexts |
|
123 'DefaultContext', 'BasicContext', 'ExtendedContext', |
|
124 |
|
125 # Exceptions |
|
126 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero', |
|
127 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow', |
|
128 |
|
129 # 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', |
|
132 |
|
133 # Functions for manipulating contexts |
|
134 'setcontext', 'getcontext' |
|
135 ] |
|
136 |
|
137 import copy as _copy |
|
138 |
|
139 #Rounding |
|
140 ROUND_DOWN = 'ROUND_DOWN' |
|
141 ROUND_HALF_UP = 'ROUND_HALF_UP' |
|
142 ROUND_HALF_EVEN = 'ROUND_HALF_EVEN' |
|
143 ROUND_CEILING = 'ROUND_CEILING' |
|
144 ROUND_FLOOR = 'ROUND_FLOOR' |
|
145 ROUND_UP = 'ROUND_UP' |
|
146 ROUND_HALF_DOWN = 'ROUND_HALF_DOWN' |
|
147 |
|
148 #Rounding decision (not part of the public API) |
|
149 NEVER_ROUND = 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY |
|
150 ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end. |
|
151 |
|
152 #Errors |
|
153 |
|
154 class DecimalException(ArithmeticError): |
|
155 """Base exception class. |
|
156 |
|
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 |
|
163 handle -- Called when context._raise_error is called and the |
|
164 trap_enabler is set. First argument is self, second is the |
|
165 context. More arguments can be given, those being after |
|
166 the explanation in _raise_error (For example, |
|
167 context._raise_error(NewError, '(-x)!', self._sign) would |
|
168 call NewError().handle(context, self._sign).) |
|
169 |
|
170 To define a new exception, it should be sufficient to have it derive |
|
171 from DecimalException. |
|
172 """ |
|
173 def handle(self, context, *args): |
|
174 pass |
|
175 |
|
176 |
|
177 class 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 |
|
182 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 |
|
185 this latter case, the exponent is reduced to fit and the corresponding |
|
186 number of zero digits are appended to the coefficient ("fold-down"). |
|
187 """ |
|
188 |
|
189 |
|
190 class InvalidOperation(DecimalException): |
|
191 """An invalid operation was performed. |
|
192 |
|
193 Various bad things cause this: |
|
194 |
|
195 Something creates a signaling NaN |
|
196 -INF + INF |
|
197 0 * (+-)INF |
|
198 (+-)INF / (+-)INF |
|
199 x % 0 |
|
200 (+-)INF % x |
|
201 x._rescale( non-integer ) |
|
202 sqrt(-x) , x > 0 |
|
203 0 ** 0 |
|
204 x ** (non-integer) |
|
205 x ** (+-)INF |
|
206 An operand is invalid |
|
207 """ |
|
208 def handle(self, context, *args): |
|
209 if args: |
|
210 if args[0] == 1: #sNaN, must drop 's' but keep diagnostics |
|
211 return Decimal( (args[1]._sign, args[1]._int, 'n') ) |
|
212 return NaN |
|
213 |
|
214 class ConversionSyntax(InvalidOperation): |
|
215 """Trying to convert badly formed string. |
|
216 |
|
217 This occurs and signals invalid-operation if an string is being |
|
218 converted to a number and it does not conform to the numeric string |
|
219 syntax. The result is [0,qNaN]. |
|
220 """ |
|
221 |
|
222 def handle(self, context, *args): |
|
223 return (0, (0,), 'n') #Passed to something which uses a tuple. |
|
224 |
|
225 class DivisionByZero(DecimalException, ZeroDivisionError): |
|
226 """Division by 0. |
|
227 |
|
228 This occurs and signals division-by-zero if division of a finite number |
|
229 by zero was attempted (during a divide-integer or divide operation, or a |
|
230 power operation with negative right-hand operand), and the dividend was |
|
231 not zero. |
|
232 |
|
233 The result of the operation is [sign,inf], where sign is the exclusive |
|
234 or of the signs of the operands for divide, or is 1 for an odd power of |
|
235 -0, for power. |
|
236 """ |
|
237 |
|
238 def handle(self, context, sign, double = None, *args): |
|
239 if double is not None: |
|
240 return (Infsign[sign],)*2 |
|
241 return Infsign[sign] |
|
242 |
|
243 class DivisionImpossible(InvalidOperation): |
|
244 """Cannot perform the division adequately. |
|
245 |
|
246 This occurs and signals invalid-operation if the integer result of a |
|
247 divide-integer or remainder operation had too many digits (would be |
|
248 longer than precision). The result is [0,qNaN]. |
|
249 """ |
|
250 |
|
251 def handle(self, context, *args): |
|
252 return (NaN, NaN) |
|
253 |
|
254 class DivisionUndefined(InvalidOperation, ZeroDivisionError): |
|
255 """Undefined result of division. |
|
256 |
|
257 This occurs and signals invalid-operation if division by zero was |
|
258 attempted (during a divide-integer, divide, or remainder operation), and |
|
259 the dividend is also zero. The result is [0,qNaN]. |
|
260 """ |
|
261 |
|
262 def handle(self, context, tup=None, *args): |
|
263 if tup is not None: |
|
264 return (NaN, NaN) #for 0 %0, 0 // 0 |
|
265 return NaN |
|
266 |
|
267 class Inexact(DecimalException): |
|
268 """Had to round, losing information. |
|
269 |
|
270 This occurs and signals inexact whenever the result of an operation is |
|
271 not exact (that is, it needed to be rounded and any discarded digits |
|
272 were non-zero), or if an overflow or underflow condition occurs. The |
|
273 result in all cases is unchanged. |
|
274 |
|
275 The inexact signal may be tested (or trapped) to determine if a given |
|
276 operation (or sequence of operations) was inexact. |
|
277 """ |
|
278 pass |
|
279 |
|
280 class InvalidContext(InvalidOperation): |
|
281 """Invalid context. Unknown rounding, for example. |
|
282 |
|
283 This occurs and signals invalid-operation if an invalid context was |
|
284 detected during an operation. This can occur if contexts are not checked |
|
285 on creation and either the precision exceeds the capability of the |
|
286 underlying concrete representation or an unknown or unsupported rounding |
|
287 was specified. These aspects of the context need only be checked when |
|
288 the values are required to be used. The result is [0,qNaN]. |
|
289 """ |
|
290 |
|
291 def handle(self, context, *args): |
|
292 return NaN |
|
293 |
|
294 class Rounded(DecimalException): |
|
295 """Number got rounded (not necessarily changed during rounding). |
|
296 |
|
297 This occurs and signals rounded whenever the result of an operation is |
|
298 rounded (that is, some zero or non-zero digits were discarded from the |
|
299 coefficient), or if an overflow or underflow condition occurs. The |
|
300 result in all cases is unchanged. |
|
301 |
|
302 The rounded signal may be tested (or trapped) to determine if a given |
|
303 operation (or sequence of operations) caused a loss of precision. |
|
304 """ |
|
305 pass |
|
306 |
|
307 class Subnormal(DecimalException): |
|
308 """Exponent < Emin before rounding. |
|
309 |
|
310 This occurs and signals subnormal whenever the result of a conversion or |
|
311 operation is subnormal (that is, its adjusted exponent is less than |
|
312 Emin, before any rounding). The result in all cases is unchanged. |
|
313 |
|
314 The subnormal signal may be tested (or trapped) to determine if a given |
|
315 or operation (or sequence of operations) yielded a subnormal result. |
|
316 """ |
|
317 pass |
|
318 |
|
319 class Overflow(Inexact, Rounded): |
|
320 """Numerical overflow. |
|
321 |
|
322 This occurs and signals overflow if the adjusted exponent of a result |
|
323 (from a conversion or from an operation that is not an attempt to divide |
|
324 by zero), after rounding, would be greater than the largest value that |
|
325 can be handled by the implementation (the value Emax). |
|
326 |
|
327 The result depends on the rounding mode: |
|
328 |
|
329 For round-half-up and round-half-even (and for round-half-down and |
|
330 round-up, if implemented), the result of the operation is [sign,inf], |
|
331 where sign is the sign of the intermediate result. For round-down, the |
|
332 result is the largest finite number that can be represented in the |
|
333 current precision, with the sign of the intermediate result. For |
|
334 round-ceiling, the result is the same as for round-down if the sign of |
|
335 the intermediate result is 1, or is [0,inf] otherwise. For round-floor, |
|
336 the result is the same as for round-down if the sign of the intermediate |
|
337 result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded |
|
338 will also be raised. |
|
339 """ |
|
340 |
|
341 def handle(self, context, sign, *args): |
|
342 if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN, |
|
343 ROUND_HALF_DOWN, ROUND_UP): |
|
344 return Infsign[sign] |
|
345 if sign == 0: |
|
346 if context.rounding == ROUND_CEILING: |
|
347 return Infsign[sign] |
|
348 return Decimal((sign, (9,)*context.prec, |
|
349 context.Emax-context.prec+1)) |
|
350 if sign == 1: |
|
351 if context.rounding == ROUND_FLOOR: |
|
352 return Infsign[sign] |
|
353 return Decimal( (sign, (9,)*context.prec, |
|
354 context.Emax-context.prec+1)) |
|
355 |
|
356 |
|
357 class Underflow(Inexact, Rounded, Subnormal): |
|
358 """Numerical underflow with result rounded to 0. |
|
359 |
|
360 This occurs and signals underflow if a result is inexact and the |
|
361 adjusted exponent of the result would be smaller (more negative) than |
|
362 the smallest value that can be handled by the implementation (the value |
|
363 Emin). That is, the result is both inexact and subnormal. |
|
364 |
|
365 The result after an underflow will be a subnormal number rounded, if |
|
366 necessary, so that its exponent is not less than Etiny. This may result |
|
367 in 0 with the sign of the intermediate result and an exponent of Etiny. |
|
368 |
|
369 In all cases, Inexact, Rounded, and Subnormal will also be raised. |
|
370 """ |
|
371 |
|
372 # List of public traps and flags |
|
373 _signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded, |
|
374 Underflow, InvalidOperation, Subnormal] |
|
375 |
|
376 # Map conditions (per the spec) to signals |
|
377 _condition_map = {ConversionSyntax:InvalidOperation, |
|
378 DivisionImpossible:InvalidOperation, |
|
379 DivisionUndefined:InvalidOperation, |
|
380 InvalidContext:InvalidOperation} |
|
381 |
|
382 ##### Context Functions ####################################### |
|
383 |
|
384 # The getcontext() and setcontext() function manage access to a thread-local |
|
385 # current context. Py2.4 offers direct support for thread locals. If that |
|
386 # is not available, use threading.currentThread() which is slower but will |
|
387 # work for older Pythons. If threads are not part of the build, create a |
|
388 # mock threading object with threading.local() returning the module namespace. |
|
389 |
|
390 try: |
|
391 import threading |
|
392 except ImportError: |
|
393 # Python was compiled without threads; create a mock object instead |
|
394 import sys |
|
395 class MockThreading: |
|
396 def local(self, sys=sys): |
|
397 return sys.modules[__name__] |
|
398 threading = MockThreading() |
|
399 del sys, MockThreading |
|
400 |
|
401 try: |
|
402 threading.local |
|
403 |
|
404 except AttributeError: |
|
405 |
|
406 #To fix reloading, force it to create a new context |
|
407 #Old contexts have different exceptions in their dicts, making problems. |
|
408 if hasattr(threading.currentThread(), '__decimal_context__'): |
|
409 del threading.currentThread().__decimal_context__ |
|
410 |
|
411 def setcontext(context): |
|
412 """Set this thread's context to context.""" |
|
413 if context in (DefaultContext, BasicContext, ExtendedContext): |
|
414 context = context.copy() |
|
415 context.clear_flags() |
|
416 threading.currentThread().__decimal_context__ = context |
|
417 |
|
418 def getcontext(): |
|
419 """Returns this thread's context. |
|
420 |
|
421 If this thread does not yet have a context, returns |
|
422 a new context and sets this thread's context. |
|
423 New contexts are copies of DefaultContext. |
|
424 """ |
|
425 try: |
|
426 return threading.currentThread().__decimal_context__ |
|
427 except AttributeError: |
|
428 context = Context() |
|
429 threading.currentThread().__decimal_context__ = context |
|
430 return context |
|
431 |
|
432 else: |
|
433 |
|
434 local = threading.local() |
|
435 if hasattr(local, '__decimal_context__'): |
|
436 del local.__decimal_context__ |
|
437 |
|
438 def getcontext(_local=local): |
|
439 """Returns this thread's context. |
|
440 |
|
441 If this thread does not yet have a context, returns |
|
442 a new context and sets this thread's context. |
|
443 New contexts are copies of DefaultContext. |
|
444 """ |
|
445 try: |
|
446 return _local.__decimal_context__ |
|
447 except AttributeError: |
|
448 context = Context() |
|
449 _local.__decimal_context__ = context |
|
450 return context |
|
451 |
|
452 def setcontext(context, _local=local): |
|
453 """Set this thread's context to context.""" |
|
454 if context in (DefaultContext, BasicContext, ExtendedContext): |
|
455 context = context.copy() |
|
456 context.clear_flags() |
|
457 _local.__decimal_context__ = context |
|
458 |
|
459 del threading, local # Don't contaminate the namespace |
|
460 |
|
461 |
|
462 ##### Decimal class ########################################### |
|
463 |
|
464 class Decimal(object): |
|
465 """Floating point class for decimal arithmetic.""" |
|
466 |
|
467 __slots__ = ('_exp','_int','_sign', '_is_special') |
|
468 # Generally, the value of the Decimal instance is given by |
|
469 # (-1)**_sign * _int * 10**_exp |
|
470 # Special values are signified by _is_special == True |
|
471 |
|
472 # We're immutable, so use __new__ not __init__ |
|
473 def __new__(cls, value="0", context=None): |
|
474 """Create a decimal point instance. |
|
475 |
|
476 >>> Decimal('3.14') # string input |
|
477 Decimal("3.14") |
|
478 >>> Decimal((0, (3, 1, 4), -2)) # tuple input (sign, digit_tuple, exponent) |
|
479 Decimal("3.14") |
|
480 >>> Decimal(314) # int or long |
|
481 Decimal("314") |
|
482 >>> Decimal(Decimal(314)) # another decimal instance |
|
483 Decimal("314") |
|
484 """ |
|
485 |
|
486 self = object.__new__(cls) |
|
487 self._is_special = False |
|
488 |
|
489 # From an internal working value |
|
490 if isinstance(value, _WorkRep): |
|
491 self._sign = value.sign |
|
492 self._int = tuple(map(int, str(value.int))) |
|
493 self._exp = int(value.exp) |
|
494 return self |
|
495 |
|
496 # From another decimal |
|
497 if isinstance(value, Decimal): |
|
498 self._exp = value._exp |
|
499 self._sign = value._sign |
|
500 self._int = value._int |
|
501 self._is_special = value._is_special |
|
502 return self |
|
503 |
|
504 # From an integer |
|
505 if isinstance(value, (int,long)): |
|
506 if value >= 0: |
|
507 self._sign = 0 |
|
508 else: |
|
509 self._sign = 1 |
|
510 self._exp = 0 |
|
511 self._int = tuple(map(int, str(abs(value)))) |
|
512 return self |
|
513 |
|
514 # tuple/list conversion (possibly from as_tuple()) |
|
515 if isinstance(value, (list,tuple)): |
|
516 if len(value) != 3: |
|
517 raise ValueError, 'Invalid arguments' |
|
518 if value[0] not in (0,1): |
|
519 raise ValueError, 'Invalid sign' |
|
520 for digit in value[1]: |
|
521 if not isinstance(digit, (int,long)) or digit < 0: |
|
522 raise ValueError, "The second value in the tuple must be composed of non negative integer elements." |
|
523 |
|
524 self._sign = value[0] |
|
525 self._int = tuple(value[1]) |
|
526 if value[2] in ('F','n','N'): |
|
527 self._exp = value[2] |
|
528 self._is_special = True |
|
529 else: |
|
530 self._exp = int(value[2]) |
|
531 return self |
|
532 |
|
533 if isinstance(value, float): |
|
534 raise TypeError("Cannot convert float to Decimal. " + |
|
535 "First convert the float to a string") |
|
536 |
|
537 # Other argument types may require the context during interpretation |
|
538 if context is None: |
|
539 context = getcontext() |
|
540 |
|
541 # From a string |
|
542 # REs insist on real strings, so we can too. |
|
543 if isinstance(value, basestring): |
|
544 if _isinfinity(value): |
|
545 self._exp = 'F' |
|
546 self._int = (0,) |
|
547 self._is_special = True |
|
548 if _isinfinity(value) == 1: |
|
549 self._sign = 0 |
|
550 else: |
|
551 self._sign = 1 |
|
552 return self |
|
553 if _isnan(value): |
|
554 sig, sign, diag = _isnan(value) |
|
555 self._is_special = True |
|
556 if len(diag) > context.prec: #Diagnostic info too long |
|
557 self._sign, self._int, self._exp = \ |
|
558 context._raise_error(ConversionSyntax) |
|
559 return self |
|
560 if sig == 1: |
|
561 self._exp = 'n' #qNaN |
|
562 else: #sig == 2 |
|
563 self._exp = 'N' #sNaN |
|
564 self._sign = sign |
|
565 self._int = tuple(map(int, diag)) #Diagnostic info |
|
566 return self |
|
567 try: |
|
568 self._sign, self._int, self._exp = _string2exact(value) |
|
569 except ValueError: |
|
570 self._is_special = True |
|
571 self._sign, self._int, self._exp = context._raise_error(ConversionSyntax) |
|
572 return self |
|
573 |
|
574 raise TypeError("Cannot convert %r to Decimal" % value) |
|
575 |
|
576 def _isnan(self): |
|
577 """Returns whether the number is not actually one. |
|
578 |
|
579 0 if a number |
|
580 1 if NaN |
|
581 2 if sNaN |
|
582 """ |
|
583 if self._is_special: |
|
584 exp = self._exp |
|
585 if exp == 'n': |
|
586 return 1 |
|
587 elif exp == 'N': |
|
588 return 2 |
|
589 return 0 |
|
590 |
|
591 def _isinfinity(self): |
|
592 """Returns whether the number is infinite |
|
593 |
|
594 0 if finite or not a number |
|
595 1 if +INF |
|
596 -1 if -INF |
|
597 """ |
|
598 if self._exp == 'F': |
|
599 if self._sign: |
|
600 return -1 |
|
601 return 1 |
|
602 return 0 |
|
603 |
|
604 def _check_nans(self, other = None, context=None): |
|
605 """Returns whether the number is not actually one. |
|
606 |
|
607 if self, other are sNaN, signal |
|
608 if self, other are NaN return nan |
|
609 return 0 |
|
610 |
|
611 Done before operations. |
|
612 """ |
|
613 |
|
614 self_is_nan = self._isnan() |
|
615 if other is None: |
|
616 other_is_nan = False |
|
617 else: |
|
618 other_is_nan = other._isnan() |
|
619 |
|
620 if self_is_nan or other_is_nan: |
|
621 if context is None: |
|
622 context = getcontext() |
|
623 |
|
624 if self_is_nan == 2: |
|
625 return context._raise_error(InvalidOperation, 'sNaN', |
|
626 1, self) |
|
627 if other_is_nan == 2: |
|
628 return context._raise_error(InvalidOperation, 'sNaN', |
|
629 1, other) |
|
630 if self_is_nan: |
|
631 return self |
|
632 |
|
633 return other |
|
634 return 0 |
|
635 |
|
636 def __nonzero__(self): |
|
637 """Is the number non-zero? |
|
638 |
|
639 0 if self == 0 |
|
640 1 if self != 0 |
|
641 """ |
|
642 if self._is_special: |
|
643 return 1 |
|
644 return sum(self._int) != 0 |
|
645 |
|
646 def __cmp__(self, other, context=None): |
|
647 other = _convert_other(other) |
|
648 if other is NotImplemented: |
|
649 return other |
|
650 |
|
651 if self._is_special or other._is_special: |
|
652 ans = self._check_nans(other, context) |
|
653 if ans: |
|
654 return 1 # Comparison involving NaN's always reports self > other |
|
655 |
|
656 # INF = INF |
|
657 return cmp(self._isinfinity(), other._isinfinity()) |
|
658 |
|
659 if not self and not other: |
|
660 return 0 #If both 0, sign comparison isn't certain. |
|
661 |
|
662 #If different signs, neg one is less |
|
663 if other._sign < self._sign: |
|
664 return -1 |
|
665 if self._sign < other._sign: |
|
666 return 1 |
|
667 |
|
668 self_adjusted = self.adjusted() |
|
669 other_adjusted = other.adjusted() |
|
670 if self_adjusted == other_adjusted and \ |
|
671 self._int + (0,)*(self._exp - other._exp) == \ |
|
672 other._int + (0,)*(other._exp - self._exp): |
|
673 return 0 #equal, except in precision. ([0]*(-x) = []) |
|
674 elif self_adjusted > other_adjusted and self._int[0] != 0: |
|
675 return (-1)**self._sign |
|
676 elif self_adjusted < other_adjusted and other._int[0] != 0: |
|
677 return -((-1)**self._sign) |
|
678 |
|
679 # Need to round, so make sure we have a valid context |
|
680 if context is None: |
|
681 context = getcontext() |
|
682 |
|
683 context = context._shallow_copy() |
|
684 rounding = context._set_rounding(ROUND_UP) #round away from 0 |
|
685 |
|
686 flags = context._ignore_all_flags() |
|
687 res = self.__sub__(other, context=context) |
|
688 |
|
689 context._regard_flags(*flags) |
|
690 |
|
691 context.rounding = rounding |
|
692 |
|
693 if not res: |
|
694 return 0 |
|
695 elif res._sign: |
|
696 return -1 |
|
697 return 1 |
|
698 |
|
699 def __eq__(self, other): |
|
700 if not isinstance(other, (Decimal, int, long)): |
|
701 return NotImplemented |
|
702 return self.__cmp__(other) == 0 |
|
703 |
|
704 def __ne__(self, other): |
|
705 if not isinstance(other, (Decimal, int, long)): |
|
706 return NotImplemented |
|
707 return self.__cmp__(other) != 0 |
|
708 |
|
709 def compare(self, other, context=None): |
|
710 """Compares one to another. |
|
711 |
|
712 -1 => a < b |
|
713 0 => a = b |
|
714 1 => a > b |
|
715 NaN => one is NaN |
|
716 Like __cmp__, but returns Decimal instances. |
|
717 """ |
|
718 other = _convert_other(other) |
|
719 if other is NotImplemented: |
|
720 return other |
|
721 |
|
722 #compare(NaN, NaN) = NaN |
|
723 if (self._is_special or other and other._is_special): |
|
724 ans = self._check_nans(other, context) |
|
725 if ans: |
|
726 return ans |
|
727 |
|
728 return Decimal(self.__cmp__(other, context)) |
|
729 |
|
730 def __hash__(self): |
|
731 """x.__hash__() <==> hash(x)""" |
|
732 # Decimal integers must hash the same as the ints |
|
733 # Non-integer decimals are normalized and hashed as strings |
|
734 # Normalization assures that hast(100E-1) == hash(10) |
|
735 if self._is_special: |
|
736 if self._isnan(): |
|
737 raise TypeError('Cannot hash a NaN value.') |
|
738 return hash(str(self)) |
|
739 i = int(self) |
|
740 if self == Decimal(i): |
|
741 return hash(i) |
|
742 assert self.__nonzero__() # '-0' handled by integer case |
|
743 return hash(str(self.normalize())) |
|
744 |
|
745 def as_tuple(self): |
|
746 """Represents the number as a triple tuple. |
|
747 |
|
748 To show the internals exactly as they are. |
|
749 """ |
|
750 return (self._sign, self._int, self._exp) |
|
751 |
|
752 def __repr__(self): |
|
753 """Represents the number as an instance of Decimal.""" |
|
754 # Invariant: eval(repr(d)) == d |
|
755 return 'Decimal("%s")' % str(self) |
|
756 |
|
757 def __str__(self, eng = 0, context=None): |
|
758 """Return string representation of the number in scientific notation. |
|
759 |
|
760 Captures all of the information in the underlying representation. |
|
761 """ |
|
762 |
|
763 if self._is_special: |
|
764 if self._isnan(): |
|
765 minus = '-'*self._sign |
|
766 if self._int == (0,): |
|
767 info = '' |
|
768 else: |
|
769 info = ''.join(map(str, self._int)) |
|
770 if self._isnan() == 2: |
|
771 return minus + 'sNaN' + info |
|
772 return minus + 'NaN' + info |
|
773 if self._isinfinity(): |
|
774 minus = '-'*self._sign |
|
775 return minus + 'Infinity' |
|
776 |
|
777 if context is None: |
|
778 context = getcontext() |
|
779 |
|
780 tmp = map(str, self._int) |
|
781 numdigits = len(self._int) |
|
782 leftdigits = self._exp + numdigits |
|
783 if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY |
|
784 if self._exp < 0 and self._exp >= -6: #short, no need for e/E |
|
785 s = '-'*self._sign + '0.' + '0'*(abs(self._exp)) |
|
786 return s |
|
787 #exp is closest mult. of 3 >= self._exp |
|
788 exp = ((self._exp - 1)// 3 + 1) * 3 |
|
789 if exp != self._exp: |
|
790 s = '0.'+'0'*(exp - self._exp) |
|
791 else: |
|
792 s = '0' |
|
793 if exp != 0: |
|
794 if context.capitals: |
|
795 s += 'E' |
|
796 else: |
|
797 s += 'e' |
|
798 if exp > 0: |
|
799 s += '+' #0.0e+3, not 0.0e3 |
|
800 s += str(exp) |
|
801 s = '-'*self._sign + s |
|
802 return s |
|
803 if eng: |
|
804 dotplace = (leftdigits-1)%3+1 |
|
805 adjexp = leftdigits -1 - (leftdigits-1)%3 |
|
806 else: |
|
807 adjexp = leftdigits-1 |
|
808 dotplace = 1 |
|
809 if self._exp == 0: |
|
810 pass |
|
811 elif self._exp < 0 and adjexp >= 0: |
|
812 tmp.insert(leftdigits, '.') |
|
813 elif self._exp < 0 and adjexp >= -6: |
|
814 tmp[0:0] = ['0'] * int(-leftdigits) |
|
815 tmp.insert(0, '0.') |
|
816 else: |
|
817 if numdigits > dotplace: |
|
818 tmp.insert(dotplace, '.') |
|
819 elif numdigits < dotplace: |
|
820 tmp.extend(['0']*(dotplace-numdigits)) |
|
821 if adjexp: |
|
822 if not context.capitals: |
|
823 tmp.append('e') |
|
824 else: |
|
825 tmp.append('E') |
|
826 if adjexp > 0: |
|
827 tmp.append('+') |
|
828 tmp.append(str(adjexp)) |
|
829 if eng: |
|
830 while tmp[0:1] == ['0']: |
|
831 tmp[0:1] = [] |
|
832 if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e': |
|
833 tmp[0:0] = ['0'] |
|
834 if self._sign: |
|
835 tmp.insert(0, '-') |
|
836 |
|
837 return ''.join(tmp) |
|
838 |
|
839 def to_eng_string(self, context=None): |
|
840 """Convert to engineering-type string. |
|
841 |
|
842 Engineering notation has an exponent which is a multiple of 3, so there |
|
843 are up to 3 digits left of the decimal place. |
|
844 |
|
845 Same rules for when in exponential and when as a value as in __str__. |
|
846 """ |
|
847 return self.__str__(eng=1, context=context) |
|
848 |
|
849 def __neg__(self, context=None): |
|
850 """Returns a copy with the sign switched. |
|
851 |
|
852 Rounds, if it has reason. |
|
853 """ |
|
854 if self._is_special: |
|
855 ans = self._check_nans(context=context) |
|
856 if ans: |
|
857 return ans |
|
858 |
|
859 if not self: |
|
860 # -Decimal('0') is Decimal('0'), not Decimal('-0') |
|
861 sign = 0 |
|
862 elif self._sign: |
|
863 sign = 0 |
|
864 else: |
|
865 sign = 1 |
|
866 |
|
867 if context is None: |
|
868 context = getcontext() |
|
869 if context._rounding_decision == ALWAYS_ROUND: |
|
870 return Decimal((sign, self._int, self._exp))._fix(context) |
|
871 return Decimal( (sign, self._int, self._exp)) |
|
872 |
|
873 def __pos__(self, context=None): |
|
874 """Returns a copy, unless it is a sNaN. |
|
875 |
|
876 Rounds the number (if more then precision digits) |
|
877 """ |
|
878 if self._is_special: |
|
879 ans = self._check_nans(context=context) |
|
880 if ans: |
|
881 return ans |
|
882 |
|
883 sign = self._sign |
|
884 if not self: |
|
885 # + (-0) = 0 |
|
886 sign = 0 |
|
887 |
|
888 if context is None: |
|
889 context = getcontext() |
|
890 |
|
891 if context._rounding_decision == ALWAYS_ROUND: |
|
892 ans = self._fix(context) |
|
893 else: |
|
894 ans = Decimal(self) |
|
895 ans._sign = sign |
|
896 return ans |
|
897 |
|
898 def __abs__(self, round=1, context=None): |
|
899 """Returns the absolute value of self. |
|
900 |
|
901 If the second argument is 0, do not round. |
|
902 """ |
|
903 if self._is_special: |
|
904 ans = self._check_nans(context=context) |
|
905 if ans: |
|
906 return ans |
|
907 |
|
908 if not round: |
|
909 if context is None: |
|
910 context = getcontext() |
|
911 context = context._shallow_copy() |
|
912 context._set_rounding_decision(NEVER_ROUND) |
|
913 |
|
914 if self._sign: |
|
915 ans = self.__neg__(context=context) |
|
916 else: |
|
917 ans = self.__pos__(context=context) |
|
918 |
|
919 return ans |
|
920 |
|
921 def __add__(self, other, context=None): |
|
922 """Returns self + other. |
|
923 |
|
924 -INF + INF (or the reverse) cause InvalidOperation errors. |
|
925 """ |
|
926 other = _convert_other(other) |
|
927 if other is NotImplemented: |
|
928 return other |
|
929 |
|
930 if context is None: |
|
931 context = getcontext() |
|
932 |
|
933 if self._is_special or other._is_special: |
|
934 ans = self._check_nans(other, context) |
|
935 if ans: |
|
936 return ans |
|
937 |
|
938 if self._isinfinity(): |
|
939 #If both INF, same sign => same as both, opposite => error. |
|
940 if self._sign != other._sign and other._isinfinity(): |
|
941 return context._raise_error(InvalidOperation, '-INF + INF') |
|
942 return Decimal(self) |
|
943 if other._isinfinity(): |
|
944 return Decimal(other) #Can't both be infinity here |
|
945 |
|
946 shouldround = context._rounding_decision == ALWAYS_ROUND |
|
947 |
|
948 exp = min(self._exp, other._exp) |
|
949 negativezero = 0 |
|
950 if context.rounding == ROUND_FLOOR and self._sign != other._sign: |
|
951 #If the answer is 0, the sign should be negative, in this case. |
|
952 negativezero = 1 |
|
953 |
|
954 if not self and not other: |
|
955 sign = min(self._sign, other._sign) |
|
956 if negativezero: |
|
957 sign = 1 |
|
958 return Decimal( (sign, (0,), exp)) |
|
959 if not self: |
|
960 exp = max(exp, other._exp - context.prec-1) |
|
961 ans = other._rescale(exp, watchexp=0, context=context) |
|
962 if shouldround: |
|
963 ans = ans._fix(context) |
|
964 return ans |
|
965 if not other: |
|
966 exp = max(exp, self._exp - context.prec-1) |
|
967 ans = self._rescale(exp, watchexp=0, context=context) |
|
968 if shouldround: |
|
969 ans = ans._fix(context) |
|
970 return ans |
|
971 |
|
972 op1 = _WorkRep(self) |
|
973 op2 = _WorkRep(other) |
|
974 op1, op2 = _normalize(op1, op2, shouldround, context.prec) |
|
975 |
|
976 result = _WorkRep() |
|
977 if op1.sign != op2.sign: |
|
978 # Equal and opposite |
|
979 if op1.int == op2.int: |
|
980 if exp < context.Etiny(): |
|
981 exp = context.Etiny() |
|
982 context._raise_error(Clamped) |
|
983 return Decimal((negativezero, (0,), exp)) |
|
984 if op1.int < op2.int: |
|
985 op1, op2 = op2, op1 |
|
986 #OK, now abs(op1) > abs(op2) |
|
987 if op1.sign == 1: |
|
988 result.sign = 1 |
|
989 op1.sign, op2.sign = op2.sign, op1.sign |
|
990 else: |
|
991 result.sign = 0 |
|
992 #So we know the sign, and op1 > 0. |
|
993 elif op1.sign == 1: |
|
994 result.sign = 1 |
|
995 op1.sign, op2.sign = (0, 0) |
|
996 else: |
|
997 result.sign = 0 |
|
998 #Now, op1 > abs(op2) > 0 |
|
999 |
|
1000 if op2.sign == 0: |
|
1001 result.int = op1.int + op2.int |
|
1002 else: |
|
1003 result.int = op1.int - op2.int |
|
1004 |
|
1005 result.exp = op1.exp |
|
1006 ans = Decimal(result) |
|
1007 if shouldround: |
|
1008 ans = ans._fix(context) |
|
1009 return ans |
|
1010 |
|
1011 __radd__ = __add__ |
|
1012 |
|
1013 def __sub__(self, other, context=None): |
|
1014 """Return self + (-other)""" |
|
1015 other = _convert_other(other) |
|
1016 if other is NotImplemented: |
|
1017 return other |
|
1018 |
|
1019 if self._is_special or other._is_special: |
|
1020 ans = self._check_nans(other, context=context) |
|
1021 if ans: |
|
1022 return ans |
|
1023 |
|
1024 # -Decimal(0) = Decimal(0), which we don't want since |
|
1025 # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.) |
|
1026 # so we change the sign directly to a copy |
|
1027 tmp = Decimal(other) |
|
1028 tmp._sign = 1-tmp._sign |
|
1029 |
|
1030 return self.__add__(tmp, context=context) |
|
1031 |
|
1032 def __rsub__(self, other, context=None): |
|
1033 """Return other + (-self)""" |
|
1034 other = _convert_other(other) |
|
1035 if other is NotImplemented: |
|
1036 return other |
|
1037 |
|
1038 tmp = Decimal(self) |
|
1039 tmp._sign = 1 - tmp._sign |
|
1040 return other.__add__(tmp, context=context) |
|
1041 |
|
1042 def _increment(self, round=1, context=None): |
|
1043 """Special case of add, adding 1eExponent |
|
1044 |
|
1045 Since it is common, (rounding, for example) this adds |
|
1046 (sign)*one E self._exp to the number more efficiently than add. |
|
1047 |
|
1048 For example: |
|
1049 Decimal('5.624e10')._increment() == Decimal('5.625e10') |
|
1050 """ |
|
1051 if self._is_special: |
|
1052 ans = self._check_nans(context=context) |
|
1053 if ans: |
|
1054 return ans |
|
1055 |
|
1056 return Decimal(self) # Must be infinite, and incrementing makes no difference |
|
1057 |
|
1058 L = list(self._int) |
|
1059 L[-1] += 1 |
|
1060 spot = len(L)-1 |
|
1061 while L[spot] == 10: |
|
1062 L[spot] = 0 |
|
1063 if spot == 0: |
|
1064 L[0:0] = [1] |
|
1065 break |
|
1066 L[spot-1] += 1 |
|
1067 spot -= 1 |
|
1068 ans = Decimal((self._sign, L, self._exp)) |
|
1069 |
|
1070 if context is None: |
|
1071 context = getcontext() |
|
1072 if round and context._rounding_decision == ALWAYS_ROUND: |
|
1073 ans = ans._fix(context) |
|
1074 return ans |
|
1075 |
|
1076 def __mul__(self, other, context=None): |
|
1077 """Return self * other. |
|
1078 |
|
1079 (+-) INF * 0 (or its reverse) raise InvalidOperation. |
|
1080 """ |
|
1081 other = _convert_other(other) |
|
1082 if other is NotImplemented: |
|
1083 return other |
|
1084 |
|
1085 if context is None: |
|
1086 context = getcontext() |
|
1087 |
|
1088 resultsign = self._sign ^ other._sign |
|
1089 |
|
1090 if self._is_special or other._is_special: |
|
1091 ans = self._check_nans(other, context) |
|
1092 if ans: |
|
1093 return ans |
|
1094 |
|
1095 if self._isinfinity(): |
|
1096 if not other: |
|
1097 return context._raise_error(InvalidOperation, '(+-)INF * 0') |
|
1098 return Infsign[resultsign] |
|
1099 |
|
1100 if other._isinfinity(): |
|
1101 if not self: |
|
1102 return context._raise_error(InvalidOperation, '0 * (+-)INF') |
|
1103 return Infsign[resultsign] |
|
1104 |
|
1105 resultexp = self._exp + other._exp |
|
1106 shouldround = context._rounding_decision == ALWAYS_ROUND |
|
1107 |
|
1108 # Special case for multiplying by zero |
|
1109 if not self or not other: |
|
1110 ans = Decimal((resultsign, (0,), resultexp)) |
|
1111 if shouldround: |
|
1112 #Fixing in case the exponent is out of bounds |
|
1113 ans = ans._fix(context) |
|
1114 return ans |
|
1115 |
|
1116 # Special case for multiplying by power of 10 |
|
1117 if self._int == (1,): |
|
1118 ans = Decimal((resultsign, other._int, resultexp)) |
|
1119 if shouldround: |
|
1120 ans = ans._fix(context) |
|
1121 return ans |
|
1122 if other._int == (1,): |
|
1123 ans = Decimal((resultsign, self._int, resultexp)) |
|
1124 if shouldround: |
|
1125 ans = ans._fix(context) |
|
1126 return ans |
|
1127 |
|
1128 op1 = _WorkRep(self) |
|
1129 op2 = _WorkRep(other) |
|
1130 |
|
1131 ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp)) |
|
1132 if shouldround: |
|
1133 ans = ans._fix(context) |
|
1134 |
|
1135 return ans |
|
1136 __rmul__ = __mul__ |
|
1137 |
|
1138 def __div__(self, other, context=None): |
|
1139 """Return self / other.""" |
|
1140 return self._divide(other, context=context) |
|
1141 __truediv__ = __div__ |
|
1142 |
|
1143 def _divide(self, other, divmod = 0, context=None): |
|
1144 """Return a / b, to context.prec precision. |
|
1145 |
|
1146 divmod: |
|
1147 0 => true division |
|
1148 1 => (a //b, a%b) |
|
1149 2 => a //b |
|
1150 3 => a%b |
|
1151 |
|
1152 Actually, if divmod is 2 or 3 a tuple is returned, but errors for |
|
1153 computing the other value are not raised. |
|
1154 """ |
|
1155 other = _convert_other(other) |
|
1156 if other is NotImplemented: |
|
1157 if divmod in (0, 1): |
|
1158 return NotImplemented |
|
1159 return (NotImplemented, NotImplemented) |
|
1160 |
|
1161 if context is None: |
|
1162 context = getcontext() |
|
1163 |
|
1164 sign = self._sign ^ other._sign |
|
1165 |
|
1166 if self._is_special or other._is_special: |
|
1167 ans = self._check_nans(other, context) |
|
1168 if ans: |
|
1169 if divmod: |
|
1170 return (ans, ans) |
|
1171 return ans |
|
1172 |
|
1173 if self._isinfinity() and other._isinfinity(): |
|
1174 if divmod: |
|
1175 return (context._raise_error(InvalidOperation, |
|
1176 '(+-)INF // (+-)INF'), |
|
1177 context._raise_error(InvalidOperation, |
|
1178 '(+-)INF % (+-)INF')) |
|
1179 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF') |
|
1180 |
|
1181 if self._isinfinity(): |
|
1182 if divmod == 1: |
|
1183 return (Infsign[sign], |
|
1184 context._raise_error(InvalidOperation, 'INF % x')) |
|
1185 elif divmod == 2: |
|
1186 return (Infsign[sign], NaN) |
|
1187 elif divmod == 3: |
|
1188 return (Infsign[sign], |
|
1189 context._raise_error(InvalidOperation, 'INF % x')) |
|
1190 return Infsign[sign] |
|
1191 |
|
1192 if other._isinfinity(): |
|
1193 if divmod: |
|
1194 return (Decimal((sign, (0,), 0)), Decimal(self)) |
|
1195 context._raise_error(Clamped, 'Division by infinity') |
|
1196 return Decimal((sign, (0,), context.Etiny())) |
|
1197 |
|
1198 # Special cases for zeroes |
|
1199 if not self and not other: |
|
1200 if divmod: |
|
1201 return context._raise_error(DivisionUndefined, '0 / 0', 1) |
|
1202 return context._raise_error(DivisionUndefined, '0 / 0') |
|
1203 |
|
1204 if not self: |
|
1205 if divmod: |
|
1206 otherside = Decimal(self) |
|
1207 otherside._exp = min(self._exp, other._exp) |
|
1208 return (Decimal((sign, (0,), 0)), otherside) |
|
1209 exp = self._exp - other._exp |
|
1210 if exp < context.Etiny(): |
|
1211 exp = context.Etiny() |
|
1212 context._raise_error(Clamped, '0e-x / y') |
|
1213 if exp > context.Emax: |
|
1214 exp = context.Emax |
|
1215 context._raise_error(Clamped, '0e+x / y') |
|
1216 return Decimal( (sign, (0,), exp) ) |
|
1217 |
|
1218 if not other: |
|
1219 if divmod: |
|
1220 return context._raise_error(DivisionByZero, 'divmod(x,0)', |
|
1221 sign, 1) |
|
1222 return context._raise_error(DivisionByZero, 'x / 0', sign) |
|
1223 |
|
1224 #OK, so neither = 0, INF or NaN |
|
1225 |
|
1226 shouldround = context._rounding_decision == ALWAYS_ROUND |
|
1227 |
|
1228 #If we're dividing into ints, and self < other, stop. |
|
1229 #self.__abs__(0) does not round. |
|
1230 if divmod and (self.__abs__(0, context) < other.__abs__(0, context)): |
|
1231 |
|
1232 if divmod == 1 or divmod == 3: |
|
1233 exp = min(self._exp, other._exp) |
|
1234 ans2 = self._rescale(exp, context=context, watchexp=0) |
|
1235 if shouldround: |
|
1236 ans2 = ans2._fix(context) |
|
1237 return (Decimal( (sign, (0,), 0) ), |
|
1238 ans2) |
|
1239 |
|
1240 elif divmod == 2: |
|
1241 #Don't round the mod part, if we don't need it. |
|
1242 return (Decimal( (sign, (0,), 0) ), Decimal(self)) |
|
1243 |
|
1244 op1 = _WorkRep(self) |
|
1245 op2 = _WorkRep(other) |
|
1246 op1, op2, adjust = _adjust_coefficients(op1, op2) |
|
1247 res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) ) |
|
1248 if divmod and res.exp > context.prec + 1: |
|
1249 return context._raise_error(DivisionImpossible) |
|
1250 |
|
1251 prec_limit = 10 ** context.prec |
|
1252 while 1: |
|
1253 while op2.int <= op1.int: |
|
1254 res.int += 1 |
|
1255 op1.int -= op2.int |
|
1256 if res.exp == 0 and divmod: |
|
1257 if res.int >= prec_limit and shouldround: |
|
1258 return context._raise_error(DivisionImpossible) |
|
1259 otherside = Decimal(op1) |
|
1260 frozen = context._ignore_all_flags() |
|
1261 |
|
1262 exp = min(self._exp, other._exp) |
|
1263 otherside = otherside._rescale(exp, context=context, watchexp=0) |
|
1264 context._regard_flags(*frozen) |
|
1265 if shouldround: |
|
1266 otherside = otherside._fix(context) |
|
1267 return (Decimal(res), otherside) |
|
1268 |
|
1269 if op1.int == 0 and adjust >= 0 and not divmod: |
|
1270 break |
|
1271 if res.int >= prec_limit and shouldround: |
|
1272 if divmod: |
|
1273 return context._raise_error(DivisionImpossible) |
|
1274 shouldround=1 |
|
1275 # Really, the answer is a bit higher, so adding a one to |
|
1276 # the end will make sure the rounding is right. |
|
1277 if op1.int != 0: |
|
1278 res.int *= 10 |
|
1279 res.int += 1 |
|
1280 res.exp -= 1 |
|
1281 |
|
1282 break |
|
1283 res.int *= 10 |
|
1284 res.exp -= 1 |
|
1285 adjust += 1 |
|
1286 op1.int *= 10 |
|
1287 op1.exp -= 1 |
|
1288 |
|
1289 if res.exp == 0 and divmod and op2.int > op1.int: |
|
1290 #Solves an error in precision. Same as a previous block. |
|
1291 |
|
1292 if res.int >= prec_limit and shouldround: |
|
1293 return context._raise_error(DivisionImpossible) |
|
1294 otherside = Decimal(op1) |
|
1295 frozen = context._ignore_all_flags() |
|
1296 |
|
1297 exp = min(self._exp, other._exp) |
|
1298 otherside = otherside._rescale(exp, context=context) |
|
1299 |
|
1300 context._regard_flags(*frozen) |
|
1301 |
|
1302 return (Decimal(res), otherside) |
|
1303 |
|
1304 ans = Decimal(res) |
|
1305 if shouldround: |
|
1306 ans = ans._fix(context) |
|
1307 return ans |
|
1308 |
|
1309 def __rdiv__(self, other, context=None): |
|
1310 """Swaps self/other and returns __div__.""" |
|
1311 other = _convert_other(other) |
|
1312 if other is NotImplemented: |
|
1313 return other |
|
1314 return other.__div__(self, context=context) |
|
1315 __rtruediv__ = __rdiv__ |
|
1316 |
|
1317 def __divmod__(self, other, context=None): |
|
1318 """ |
|
1319 (self // other, self % other) |
|
1320 """ |
|
1321 return self._divide(other, 1, context) |
|
1322 |
|
1323 def __rdivmod__(self, other, context=None): |
|
1324 """Swaps self/other and returns __divmod__.""" |
|
1325 other = _convert_other(other) |
|
1326 if other is NotImplemented: |
|
1327 return other |
|
1328 return other.__divmod__(self, context=context) |
|
1329 |
|
1330 def __mod__(self, other, context=None): |
|
1331 """ |
|
1332 self % other |
|
1333 """ |
|
1334 other = _convert_other(other) |
|
1335 if other is NotImplemented: |
|
1336 return other |
|
1337 |
|
1338 if self._is_special or other._is_special: |
|
1339 ans = self._check_nans(other, context) |
|
1340 if ans: |
|
1341 return ans |
|
1342 |
|
1343 if self and not other: |
|
1344 return context._raise_error(InvalidOperation, 'x % 0') |
|
1345 |
|
1346 return self._divide(other, 3, context)[1] |
|
1347 |
|
1348 def __rmod__(self, other, context=None): |
|
1349 """Swaps self/other and returns __mod__.""" |
|
1350 other = _convert_other(other) |
|
1351 if other is NotImplemented: |
|
1352 return other |
|
1353 return other.__mod__(self, context=context) |
|
1354 |
|
1355 def remainder_near(self, other, context=None): |
|
1356 """ |
|
1357 Remainder nearest to 0- abs(remainder-near) <= other/2 |
|
1358 """ |
|
1359 other = _convert_other(other) |
|
1360 if other is NotImplemented: |
|
1361 return other |
|
1362 |
|
1363 if self._is_special or other._is_special: |
|
1364 ans = self._check_nans(other, context) |
|
1365 if ans: |
|
1366 return ans |
|
1367 if self and not other: |
|
1368 return context._raise_error(InvalidOperation, 'x % 0') |
|
1369 |
|
1370 if context is None: |
|
1371 context = getcontext() |
|
1372 # If DivisionImpossible causes an error, do not leave Rounded/Inexact |
|
1373 # ignored in the calling function. |
|
1374 context = context._shallow_copy() |
|
1375 flags = context._ignore_flags(Rounded, Inexact) |
|
1376 #keep DivisionImpossible flags |
|
1377 (side, r) = self.__divmod__(other, context=context) |
|
1378 |
|
1379 if r._isnan(): |
|
1380 context._regard_flags(*flags) |
|
1381 return r |
|
1382 |
|
1383 context = context._shallow_copy() |
|
1384 rounding = context._set_rounding_decision(NEVER_ROUND) |
|
1385 |
|
1386 if other._sign: |
|
1387 comparison = other.__div__(Decimal(-2), context=context) |
|
1388 else: |
|
1389 comparison = other.__div__(Decimal(2), context=context) |
|
1390 |
|
1391 context._set_rounding_decision(rounding) |
|
1392 context._regard_flags(*flags) |
|
1393 |
|
1394 s1, s2 = r._sign, comparison._sign |
|
1395 r._sign, comparison._sign = 0, 0 |
|
1396 |
|
1397 if r < comparison: |
|
1398 r._sign, comparison._sign = s1, s2 |
|
1399 #Get flags now |
|
1400 self.__divmod__(other, context=context) |
|
1401 return r._fix(context) |
|
1402 r._sign, comparison._sign = s1, s2 |
|
1403 |
|
1404 rounding = context._set_rounding_decision(NEVER_ROUND) |
|
1405 |
|
1406 (side, r) = self.__divmod__(other, context=context) |
|
1407 context._set_rounding_decision(rounding) |
|
1408 if r._isnan(): |
|
1409 return r |
|
1410 |
|
1411 decrease = not side._iseven() |
|
1412 rounding = context._set_rounding_decision(NEVER_ROUND) |
|
1413 side = side.__abs__(context=context) |
|
1414 context._set_rounding_decision(rounding) |
|
1415 |
|
1416 s1, s2 = r._sign, comparison._sign |
|
1417 r._sign, comparison._sign = 0, 0 |
|
1418 if r > comparison or decrease and r == comparison: |
|
1419 r._sign, comparison._sign = s1, s2 |
|
1420 context.prec += 1 |
|
1421 if len(side.__add__(Decimal(1), context=context)._int) >= context.prec: |
|
1422 context.prec -= 1 |
|
1423 return context._raise_error(DivisionImpossible)[1] |
|
1424 context.prec -= 1 |
|
1425 if self._sign == other._sign: |
|
1426 r = r.__sub__(other, context=context) |
|
1427 else: |
|
1428 r = r.__add__(other, context=context) |
|
1429 else: |
|
1430 r._sign, comparison._sign = s1, s2 |
|
1431 |
|
1432 return r._fix(context) |
|
1433 |
|
1434 def __floordiv__(self, other, context=None): |
|
1435 """self // other""" |
|
1436 return self._divide(other, 2, context)[0] |
|
1437 |
|
1438 def __rfloordiv__(self, other, context=None): |
|
1439 """Swaps self/other and returns __floordiv__.""" |
|
1440 other = _convert_other(other) |
|
1441 if other is NotImplemented: |
|
1442 return other |
|
1443 return other.__floordiv__(self, context=context) |
|
1444 |
|
1445 def __float__(self): |
|
1446 """Float representation.""" |
|
1447 return float(str(self)) |
|
1448 |
|
1449 def __int__(self): |
|
1450 """Converts self to an int, truncating if necessary.""" |
|
1451 if self._is_special: |
|
1452 if self._isnan(): |
|
1453 context = getcontext() |
|
1454 return context._raise_error(InvalidContext) |
|
1455 elif self._isinfinity(): |
|
1456 raise OverflowError, "Cannot convert infinity to long" |
|
1457 if self._exp >= 0: |
|
1458 s = ''.join(map(str, self._int)) + '0'*self._exp |
|
1459 else: |
|
1460 s = ''.join(map(str, self._int))[:self._exp] |
|
1461 if s == '': |
|
1462 s = '0' |
|
1463 sign = '-'*self._sign |
|
1464 return int(sign + s) |
|
1465 |
|
1466 def __long__(self): |
|
1467 """Converts to a long. |
|
1468 |
|
1469 Equivalent to long(int(self)) |
|
1470 """ |
|
1471 return long(self.__int__()) |
|
1472 |
|
1473 def _fix(self, context): |
|
1474 """Round if it is necessary to keep self within prec precision. |
|
1475 |
|
1476 Rounds and fixes the exponent. Does not raise on a sNaN. |
|
1477 |
|
1478 Arguments: |
|
1479 self - Decimal instance |
|
1480 context - context used. |
|
1481 """ |
|
1482 if self._is_special: |
|
1483 return self |
|
1484 if context is None: |
|
1485 context = getcontext() |
|
1486 prec = context.prec |
|
1487 ans = self._fixexponents(context) |
|
1488 if len(ans._int) > prec: |
|
1489 ans = ans._round(prec, context=context) |
|
1490 ans = ans._fixexponents(context) |
|
1491 return ans |
|
1492 |
|
1493 def _fixexponents(self, context): |
|
1494 """Fix the exponents and return a copy with the exponent in bounds. |
|
1495 Only call if known to not be a special value. |
|
1496 """ |
|
1497 folddown = context._clamp |
|
1498 Emin = context.Emin |
|
1499 ans = self |
|
1500 ans_adjusted = ans.adjusted() |
|
1501 if ans_adjusted < Emin: |
|
1502 Etiny = context.Etiny() |
|
1503 if ans._exp < Etiny: |
|
1504 if not ans: |
|
1505 ans = Decimal(self) |
|
1506 ans._exp = Etiny |
|
1507 context._raise_error(Clamped) |
|
1508 return ans |
|
1509 ans = ans._rescale(Etiny, context=context) |
|
1510 #It isn't zero, and exp < Emin => subnormal |
|
1511 context._raise_error(Subnormal) |
|
1512 if context.flags[Inexact]: |
|
1513 context._raise_error(Underflow) |
|
1514 else: |
|
1515 if ans: |
|
1516 #Only raise subnormal if non-zero. |
|
1517 context._raise_error(Subnormal) |
|
1518 else: |
|
1519 Etop = context.Etop() |
|
1520 if folddown and ans._exp > Etop: |
|
1521 context._raise_error(Clamped) |
|
1522 ans = ans._rescale(Etop, context=context) |
|
1523 else: |
|
1524 Emax = context.Emax |
|
1525 if ans_adjusted > Emax: |
|
1526 if not ans: |
|
1527 ans = Decimal(self) |
|
1528 ans._exp = Emax |
|
1529 context._raise_error(Clamped) |
|
1530 return ans |
|
1531 context._raise_error(Inexact) |
|
1532 context._raise_error(Rounded) |
|
1533 return context._raise_error(Overflow, 'above Emax', ans._sign) |
|
1534 return ans |
|
1535 |
|
1536 def _round(self, prec=None, rounding=None, context=None): |
|
1537 """Returns a rounded version of self. |
|
1538 |
|
1539 You can specify the precision or rounding method. Otherwise, the |
|
1540 context determines it. |
|
1541 """ |
|
1542 |
|
1543 if self._is_special: |
|
1544 ans = self._check_nans(context=context) |
|
1545 if ans: |
|
1546 return ans |
|
1547 |
|
1548 if self._isinfinity(): |
|
1549 return Decimal(self) |
|
1550 |
|
1551 if context is None: |
|
1552 context = getcontext() |
|
1553 |
|
1554 if rounding is None: |
|
1555 rounding = context.rounding |
|
1556 if prec is None: |
|
1557 prec = context.prec |
|
1558 |
|
1559 if not self: |
|
1560 if prec <= 0: |
|
1561 dig = (0,) |
|
1562 exp = len(self._int) - prec + self._exp |
|
1563 else: |
|
1564 dig = (0,) * prec |
|
1565 exp = len(self._int) + self._exp - prec |
|
1566 ans = Decimal((self._sign, dig, exp)) |
|
1567 context._raise_error(Rounded) |
|
1568 return ans |
|
1569 |
|
1570 if prec == 0: |
|
1571 temp = Decimal(self) |
|
1572 temp._int = (0,)+temp._int |
|
1573 prec = 1 |
|
1574 elif prec < 0: |
|
1575 exp = self._exp + len(self._int) - prec - 1 |
|
1576 temp = Decimal( (self._sign, (0, 1), exp)) |
|
1577 prec = 1 |
|
1578 else: |
|
1579 temp = Decimal(self) |
|
1580 |
|
1581 numdigits = len(temp._int) |
|
1582 if prec == numdigits: |
|
1583 return temp |
|
1584 |
|
1585 # See if we need to extend precision |
|
1586 expdiff = prec - numdigits |
|
1587 if expdiff > 0: |
|
1588 tmp = list(temp._int) |
|
1589 tmp.extend([0] * expdiff) |
|
1590 ans = Decimal( (temp._sign, tmp, temp._exp - expdiff)) |
|
1591 return ans |
|
1592 |
|
1593 #OK, but maybe all the lost digits are 0. |
|
1594 lostdigits = self._int[expdiff:] |
|
1595 if lostdigits == (0,) * len(lostdigits): |
|
1596 ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff)) |
|
1597 #Rounded, but not Inexact |
|
1598 context._raise_error(Rounded) |
|
1599 return ans |
|
1600 |
|
1601 # Okay, let's round and lose data |
|
1602 |
|
1603 this_function = getattr(temp, self._pick_rounding_function[rounding]) |
|
1604 #Now we've got the rounding function |
|
1605 |
|
1606 if prec != context.prec: |
|
1607 context = context._shallow_copy() |
|
1608 context.prec = prec |
|
1609 ans = this_function(prec, expdiff, context) |
|
1610 context._raise_error(Rounded) |
|
1611 context._raise_error(Inexact, 'Changed in rounding') |
|
1612 |
|
1613 return ans |
|
1614 |
|
1615 _pick_rounding_function = {} |
|
1616 |
|
1617 def _round_down(self, prec, expdiff, context): |
|
1618 """Also known as round-towards-0, truncate.""" |
|
1619 return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) ) |
|
1620 |
|
1621 def _round_half_up(self, prec, expdiff, context, tmp = None): |
|
1622 """Rounds 5 up (away from 0)""" |
|
1623 |
|
1624 if tmp is None: |
|
1625 tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff)) |
|
1626 if self._int[prec] >= 5: |
|
1627 tmp = tmp._increment(round=0, context=context) |
|
1628 if len(tmp._int) > prec: |
|
1629 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1)) |
|
1630 return tmp |
|
1631 |
|
1632 def _round_half_even(self, prec, expdiff, context): |
|
1633 """Round 5 to even, rest to nearest.""" |
|
1634 |
|
1635 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff)) |
|
1636 half = (self._int[prec] == 5) |
|
1637 if half: |
|
1638 for digit in self._int[prec+1:]: |
|
1639 if digit != 0: |
|
1640 half = 0 |
|
1641 break |
|
1642 if half: |
|
1643 if self._int[prec-1] & 1 == 0: |
|
1644 return tmp |
|
1645 return self._round_half_up(prec, expdiff, context, tmp) |
|
1646 |
|
1647 def _round_half_down(self, prec, expdiff, context): |
|
1648 """Round 5 down""" |
|
1649 |
|
1650 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff)) |
|
1651 half = (self._int[prec] == 5) |
|
1652 if half: |
|
1653 for digit in self._int[prec+1:]: |
|
1654 if digit != 0: |
|
1655 half = 0 |
|
1656 break |
|
1657 if half: |
|
1658 return tmp |
|
1659 return self._round_half_up(prec, expdiff, context, tmp) |
|
1660 |
|
1661 def _round_up(self, prec, expdiff, context): |
|
1662 """Rounds away from 0.""" |
|
1663 tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) ) |
|
1664 for digit in self._int[prec:]: |
|
1665 if digit != 0: |
|
1666 tmp = tmp._increment(round=1, context=context) |
|
1667 if len(tmp._int) > prec: |
|
1668 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1)) |
|
1669 else: |
|
1670 return tmp |
|
1671 return tmp |
|
1672 |
|
1673 def _round_ceiling(self, prec, expdiff, context): |
|
1674 """Rounds up (not away from 0 if negative.)""" |
|
1675 if self._sign: |
|
1676 return self._round_down(prec, expdiff, context) |
|
1677 else: |
|
1678 return self._round_up(prec, expdiff, context) |
|
1679 |
|
1680 def _round_floor(self, prec, expdiff, context): |
|
1681 """Rounds down (not towards 0 if negative)""" |
|
1682 if not self._sign: |
|
1683 return self._round_down(prec, expdiff, context) |
|
1684 else: |
|
1685 return self._round_up(prec, expdiff, context) |
|
1686 |
|
1687 def __pow__(self, n, modulo = None, context=None): |
|
1688 """Return self ** n (mod modulo) |
|
1689 |
|
1690 If modulo is None (default), don't take it mod modulo. |
|
1691 """ |
|
1692 n = _convert_other(n) |
|
1693 if n is NotImplemented: |
|
1694 return n |
|
1695 |
|
1696 if context is None: |
|
1697 context = getcontext() |
|
1698 |
|
1699 if self._is_special or n._is_special or n.adjusted() > 8: |
|
1700 #Because the spot << doesn't work with really big exponents |
|
1701 if n._isinfinity() or n.adjusted() > 8: |
|
1702 return context._raise_error(InvalidOperation, 'x ** INF') |
|
1703 |
|
1704 ans = self._check_nans(n, context) |
|
1705 if ans: |
|
1706 return ans |
|
1707 |
|
1708 if not n._isinteger(): |
|
1709 return context._raise_error(InvalidOperation, 'x ** (non-integer)') |
|
1710 |
|
1711 if not self and not n: |
|
1712 return context._raise_error(InvalidOperation, '0 ** 0') |
|
1713 |
|
1714 if not n: |
|
1715 return Decimal(1) |
|
1716 |
|
1717 if self == Decimal(1): |
|
1718 return Decimal(1) |
|
1719 |
|
1720 sign = self._sign and not n._iseven() |
|
1721 n = int(n) |
|
1722 |
|
1723 if self._isinfinity(): |
|
1724 if modulo: |
|
1725 return context._raise_error(InvalidOperation, 'INF % x') |
|
1726 if n > 0: |
|
1727 return Infsign[sign] |
|
1728 return Decimal( (sign, (0,), 0) ) |
|
1729 |
|
1730 #with ludicrously large exponent, just raise an overflow and return inf. |
|
1731 if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \ |
|
1732 and self: |
|
1733 |
|
1734 tmp = Decimal('inf') |
|
1735 tmp._sign = sign |
|
1736 context._raise_error(Rounded) |
|
1737 context._raise_error(Inexact) |
|
1738 context._raise_error(Overflow, 'Big power', sign) |
|
1739 return tmp |
|
1740 |
|
1741 elength = len(str(abs(n))) |
|
1742 firstprec = context.prec |
|
1743 |
|
1744 if not modulo and firstprec + elength + 1 > DefaultContext.Emax: |
|
1745 return context._raise_error(Overflow, 'Too much precision.', sign) |
|
1746 |
|
1747 mul = Decimal(self) |
|
1748 val = Decimal(1) |
|
1749 context = context._shallow_copy() |
|
1750 context.prec = firstprec + elength + 1 |
|
1751 if n < 0: |
|
1752 #n is a long now, not Decimal instance |
|
1753 n = -n |
|
1754 mul = Decimal(1).__div__(mul, context=context) |
|
1755 |
|
1756 spot = 1 |
|
1757 while spot <= n: |
|
1758 spot <<= 1 |
|
1759 |
|
1760 spot >>= 1 |
|
1761 #Spot is the highest power of 2 less than n |
|
1762 while spot: |
|
1763 val = val.__mul__(val, context=context) |
|
1764 if val._isinfinity(): |
|
1765 val = Infsign[sign] |
|
1766 break |
|
1767 if spot & n: |
|
1768 val = val.__mul__(mul, context=context) |
|
1769 if modulo is not None: |
|
1770 val = val.__mod__(modulo, context=context) |
|
1771 spot >>= 1 |
|
1772 context.prec = firstprec |
|
1773 |
|
1774 if context._rounding_decision == ALWAYS_ROUND: |
|
1775 return val._fix(context) |
|
1776 return val |
|
1777 |
|
1778 def __rpow__(self, other, context=None): |
|
1779 """Swaps self/other and returns __pow__.""" |
|
1780 other = _convert_other(other) |
|
1781 if other is NotImplemented: |
|
1782 return other |
|
1783 return other.__pow__(self, context=context) |
|
1784 |
|
1785 def normalize(self, context=None): |
|
1786 """Normalize- strip trailing 0s, change anything equal to 0 to 0e0""" |
|
1787 |
|
1788 if self._is_special: |
|
1789 ans = self._check_nans(context=context) |
|
1790 if ans: |
|
1791 return ans |
|
1792 |
|
1793 dup = self._fix(context) |
|
1794 if dup._isinfinity(): |
|
1795 return dup |
|
1796 |
|
1797 if not dup: |
|
1798 return Decimal( (dup._sign, (0,), 0) ) |
|
1799 end = len(dup._int) |
|
1800 exp = dup._exp |
|
1801 while dup._int[end-1] == 0: |
|
1802 exp += 1 |
|
1803 end -= 1 |
|
1804 return Decimal( (dup._sign, dup._int[:end], exp) ) |
|
1805 |
|
1806 |
|
1807 def quantize(self, exp, rounding=None, context=None, watchexp=1): |
|
1808 """Quantize self so its exponent is the same as that of exp. |
|
1809 |
|
1810 Similar to self._rescale(exp._exp) but with error checking. |
|
1811 """ |
|
1812 if self._is_special or exp._is_special: |
|
1813 ans = self._check_nans(exp, context) |
|
1814 if ans: |
|
1815 return ans |
|
1816 |
|
1817 if exp._isinfinity() or self._isinfinity(): |
|
1818 if exp._isinfinity() and self._isinfinity(): |
|
1819 return self #if both are inf, it is OK |
|
1820 if context is None: |
|
1821 context = getcontext() |
|
1822 return context._raise_error(InvalidOperation, |
|
1823 'quantize with one INF') |
|
1824 return self._rescale(exp._exp, rounding, context, watchexp) |
|
1825 |
|
1826 def same_quantum(self, other): |
|
1827 """Test whether self and other have the same exponent. |
|
1828 |
|
1829 same as self._exp == other._exp, except NaN == sNaN |
|
1830 """ |
|
1831 if self._is_special or other._is_special: |
|
1832 if self._isnan() or other._isnan(): |
|
1833 return self._isnan() and other._isnan() and True |
|
1834 if self._isinfinity() or other._isinfinity(): |
|
1835 return self._isinfinity() and other._isinfinity() and True |
|
1836 return self._exp == other._exp |
|
1837 |
|
1838 def _rescale(self, exp, rounding=None, context=None, watchexp=1): |
|
1839 """Rescales so that the exponent is exp. |
|
1840 |
|
1841 exp = exp to scale to (an integer) |
|
1842 rounding = rounding version |
|
1843 watchexp: if set (default) an error is returned if exp is greater |
|
1844 than Emax or less than Etiny. |
|
1845 """ |
|
1846 if context is None: |
|
1847 context = getcontext() |
|
1848 |
|
1849 if self._is_special: |
|
1850 if self._isinfinity(): |
|
1851 return context._raise_error(InvalidOperation, 'rescale with an INF') |
|
1852 |
|
1853 ans = self._check_nans(context=context) |
|
1854 if ans: |
|
1855 return ans |
|
1856 |
|
1857 if watchexp and (context.Emax < exp or context.Etiny() > exp): |
|
1858 return context._raise_error(InvalidOperation, 'rescale(a, INF)') |
|
1859 |
|
1860 if not self: |
|
1861 ans = Decimal(self) |
|
1862 ans._int = (0,) |
|
1863 ans._exp = exp |
|
1864 return ans |
|
1865 |
|
1866 diff = self._exp - exp |
|
1867 digits = len(self._int) + diff |
|
1868 |
|
1869 if watchexp and digits > context.prec: |
|
1870 return context._raise_error(InvalidOperation, 'Rescale > prec') |
|
1871 |
|
1872 tmp = Decimal(self) |
|
1873 tmp._int = (0,) + tmp._int |
|
1874 digits += 1 |
|
1875 |
|
1876 if digits < 0: |
|
1877 tmp._exp = -digits + tmp._exp |
|
1878 tmp._int = (0,1) |
|
1879 digits = 1 |
|
1880 tmp = tmp._round(digits, rounding, context=context) |
|
1881 |
|
1882 if tmp._int[0] == 0 and len(tmp._int) > 1: |
|
1883 tmp._int = tmp._int[1:] |
|
1884 tmp._exp = exp |
|
1885 |
|
1886 tmp_adjusted = tmp.adjusted() |
|
1887 if tmp and tmp_adjusted < context.Emin: |
|
1888 context._raise_error(Subnormal) |
|
1889 elif tmp and tmp_adjusted > context.Emax: |
|
1890 return context._raise_error(InvalidOperation, 'rescale(a, INF)') |
|
1891 return tmp |
|
1892 |
|
1893 def to_integral(self, rounding=None, context=None): |
|
1894 """Rounds to the nearest integer, without raising inexact, rounded.""" |
|
1895 if self._is_special: |
|
1896 ans = self._check_nans(context=context) |
|
1897 if ans: |
|
1898 return ans |
|
1899 if self._exp >= 0: |
|
1900 return self |
|
1901 if context is None: |
|
1902 context = getcontext() |
|
1903 flags = context._ignore_flags(Rounded, Inexact) |
|
1904 ans = self._rescale(0, rounding, context=context) |
|
1905 context._regard_flags(flags) |
|
1906 return ans |
|
1907 |
|
1908 def sqrt(self, context=None): |
|
1909 """Return the square root of self. |
|
1910 |
|
1911 Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn)) |
|
1912 Should quadratically approach the right answer. |
|
1913 """ |
|
1914 if self._is_special: |
|
1915 ans = self._check_nans(context=context) |
|
1916 if ans: |
|
1917 return ans |
|
1918 |
|
1919 if self._isinfinity() and self._sign == 0: |
|
1920 return Decimal(self) |
|
1921 |
|
1922 if not self: |
|
1923 #exponent = self._exp / 2, using round_down. |
|
1924 #if self._exp < 0: |
|
1925 # exp = (self._exp+1) // 2 |
|
1926 #else: |
|
1927 exp = (self._exp) // 2 |
|
1928 if self._sign == 1: |
|
1929 #sqrt(-0) = -0 |
|
1930 return Decimal( (1, (0,), exp)) |
|
1931 else: |
|
1932 return Decimal( (0, (0,), exp)) |
|
1933 |
|
1934 if context is None: |
|
1935 context = getcontext() |
|
1936 |
|
1937 if self._sign == 1: |
|
1938 return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0') |
|
1939 |
|
1940 tmp = Decimal(self) |
|
1941 |
|
1942 expadd = tmp._exp // 2 |
|
1943 if tmp._exp & 1: |
|
1944 tmp._int += (0,) |
|
1945 tmp._exp = 0 |
|
1946 else: |
|
1947 tmp._exp = 0 |
|
1948 |
|
1949 context = context._shallow_copy() |
|
1950 flags = context._ignore_all_flags() |
|
1951 firstprec = context.prec |
|
1952 context.prec = 3 |
|
1953 if tmp.adjusted() & 1 == 0: |
|
1954 ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) ) |
|
1955 ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)), |
|
1956 context=context), context=context) |
|
1957 ans._exp -= 1 + tmp.adjusted() // 2 |
|
1958 else: |
|
1959 ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) ) |
|
1960 ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)), |
|
1961 context=context), context=context) |
|
1962 ans._exp -= 1 + tmp.adjusted() // 2 |
|
1963 |
|
1964 #ans is now a linear approximation. |
|
1965 |
|
1966 Emax, Emin = context.Emax, context.Emin |
|
1967 context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin |
|
1968 |
|
1969 half = Decimal('0.5') |
|
1970 |
|
1971 maxp = firstprec + 2 |
|
1972 rounding = context._set_rounding(ROUND_HALF_EVEN) |
|
1973 while 1: |
|
1974 context.prec = min(2*context.prec - 2, maxp) |
|
1975 ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context), |
|
1976 context=context), context=context) |
|
1977 if context.prec == maxp: |
|
1978 break |
|
1979 |
|
1980 #round to the answer's precision-- the only error can be 1 ulp. |
|
1981 context.prec = firstprec |
|
1982 prevexp = ans.adjusted() |
|
1983 ans = ans._round(context=context) |
|
1984 |
|
1985 #Now, check if the other last digits are better. |
|
1986 context.prec = firstprec + 1 |
|
1987 # In case we rounded up another digit and we should actually go lower. |
|
1988 if prevexp != ans.adjusted(): |
|
1989 ans._int += (0,) |
|
1990 ans._exp -= 1 |
|
1991 |
|
1992 |
|
1993 lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context) |
|
1994 context._set_rounding(ROUND_UP) |
|
1995 if lower.__mul__(lower, context=context) > (tmp): |
|
1996 ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context) |
|
1997 |
|
1998 else: |
|
1999 upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context) |
|
2000 context._set_rounding(ROUND_DOWN) |
|
2001 if upper.__mul__(upper, context=context) < tmp: |
|
2002 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context) |
|
2003 |
|
2004 ans._exp += expadd |
|
2005 |
|
2006 context.prec = firstprec |
|
2007 context.rounding = rounding |
|
2008 ans = ans._fix(context) |
|
2009 |
|
2010 rounding = context._set_rounding_decision(NEVER_ROUND) |
|
2011 if not ans.__mul__(ans, context=context) == self: |
|
2012 # Only rounded/inexact if here. |
|
2013 context._regard_flags(flags) |
|
2014 context._raise_error(Rounded) |
|
2015 context._raise_error(Inexact) |
|
2016 else: |
|
2017 #Exact answer, so let's set the exponent right. |
|
2018 #if self._exp < 0: |
|
2019 # exp = (self._exp +1)// 2 |
|
2020 #else: |
|
2021 exp = self._exp // 2 |
|
2022 context.prec += ans._exp - exp |
|
2023 ans = ans._rescale(exp, context=context) |
|
2024 context.prec = firstprec |
|
2025 context._regard_flags(flags) |
|
2026 context.Emax, context.Emin = Emax, Emin |
|
2027 |
|
2028 return ans._fix(context) |
|
2029 |
|
2030 def max(self, other, context=None): |
|
2031 """Returns the larger value. |
|
2032 |
|
2033 like max(self, other) except if one is not a number, returns |
|
2034 NaN (and signals if one is sNaN). Also rounds. |
|
2035 """ |
|
2036 other = _convert_other(other) |
|
2037 if other is NotImplemented: |
|
2038 return other |
|
2039 |
|
2040 if self._is_special or other._is_special: |
|
2041 # if one operand is a quiet NaN and the other is number, then the |
|
2042 # number is always returned |
|
2043 sn = self._isnan() |
|
2044 on = other._isnan() |
|
2045 if sn or on: |
|
2046 if on == 1 and sn != 2: |
|
2047 return self |
|
2048 if sn == 1 and on != 2: |
|
2049 return other |
|
2050 return self._check_nans(other, context) |
|
2051 |
|
2052 ans = self |
|
2053 c = self.__cmp__(other) |
|
2054 if c == 0: |
|
2055 # if both operands are finite and equal in numerical value |
|
2056 # then an ordering is applied: |
|
2057 # |
|
2058 # if the signs differ then max returns the operand with the |
|
2059 # positive sign and min returns the operand with the negative sign |
|
2060 # |
|
2061 # if the signs are the same then the exponent is used to select |
|
2062 # the result. |
|
2063 if self._sign != other._sign: |
|
2064 if self._sign: |
|
2065 ans = other |
|
2066 elif self._exp < other._exp and not self._sign: |
|
2067 ans = other |
|
2068 elif self._exp > other._exp and self._sign: |
|
2069 ans = other |
|
2070 elif c == -1: |
|
2071 ans = other |
|
2072 |
|
2073 if context is None: |
|
2074 context = getcontext() |
|
2075 if context._rounding_decision == ALWAYS_ROUND: |
|
2076 return ans._fix(context) |
|
2077 return ans |
|
2078 |
|
2079 def min(self, other, context=None): |
|
2080 """Returns the smaller value. |
|
2081 |
|
2082 like min(self, other) except if one is not a number, returns |
|
2083 NaN (and signals if one is sNaN). Also rounds. |
|
2084 """ |
|
2085 other = _convert_other(other) |
|
2086 if other is NotImplemented: |
|
2087 return other |
|
2088 |
|
2089 if self._is_special or other._is_special: |
|
2090 # if one operand is a quiet NaN and the other is number, then the |
|
2091 # number is always returned |
|
2092 sn = self._isnan() |
|
2093 on = other._isnan() |
|
2094 if sn or on: |
|
2095 if on == 1 and sn != 2: |
|
2096 return self |
|
2097 if sn == 1 and on != 2: |
|
2098 return other |
|
2099 return self._check_nans(other, context) |
|
2100 |
|
2101 ans = self |
|
2102 c = self.__cmp__(other) |
|
2103 if c == 0: |
|
2104 # if both operands are finite and equal in numerical value |
|
2105 # then an ordering is applied: |
|
2106 # |
|
2107 # if the signs differ then max returns the operand with the |
|
2108 # positive sign and min returns the operand with the negative sign |
|
2109 # |
|
2110 # if the signs are the same then the exponent is used to select |
|
2111 # the result. |
|
2112 if self._sign != other._sign: |
|
2113 if other._sign: |
|
2114 ans = other |
|
2115 elif self._exp > other._exp and not self._sign: |
|
2116 ans = other |
|
2117 elif self._exp < other._exp and self._sign: |
|
2118 ans = other |
|
2119 elif c == 1: |
|
2120 ans = other |
|
2121 |
|
2122 if context is None: |
|
2123 context = getcontext() |
|
2124 if context._rounding_decision == ALWAYS_ROUND: |
|
2125 return ans._fix(context) |
|
2126 return ans |
|
2127 |
|
2128 def _isinteger(self): |
|
2129 """Returns whether self is an integer""" |
|
2130 if self._exp >= 0: |
|
2131 return True |
|
2132 rest = self._int[self._exp:] |
|
2133 return rest == (0,)*len(rest) |
|
2134 |
|
2135 def _iseven(self): |
|
2136 """Returns 1 if self is even. Assumes self is an integer.""" |
|
2137 if self._exp > 0: |
|
2138 return 1 |
|
2139 return self._int[-1+self._exp] & 1 == 0 |
|
2140 |
|
2141 def adjusted(self): |
|
2142 """Return the adjusted exponent of self""" |
|
2143 try: |
|
2144 return self._exp + len(self._int) - 1 |
|
2145 #If NaN or Infinity, self._exp is string |
|
2146 except TypeError: |
|
2147 return 0 |
|
2148 |
|
2149 # support for pickling, copy, and deepcopy |
|
2150 def __reduce__(self): |
|
2151 return (self.__class__, (str(self),)) |
|
2152 |
|
2153 def __copy__(self): |
|
2154 if type(self) == Decimal: |
|
2155 return self # I'm immutable; therefore I am my own clone |
|
2156 return self.__class__(str(self)) |
|
2157 |
|
2158 def __deepcopy__(self, memo): |
|
2159 if type(self) == Decimal: |
|
2160 return self # My components are also immutable |
|
2161 return self.__class__(str(self)) |
|
2162 |
|
2163 ##### Context class ########################################### |
|
2164 |
|
2165 |
|
2166 # get rounding method function: |
|
2167 rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')] |
|
2168 for name in rounding_functions: |
|
2169 #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value. |
|
2170 globalname = name[1:].upper() |
|
2171 val = globals()[globalname] |
|
2172 Decimal._pick_rounding_function[val] = name |
|
2173 |
|
2174 del name, val, globalname, rounding_functions |
|
2175 |
|
2176 class Context(object): |
|
2177 """Contains the context for a Decimal instance. |
|
2178 |
|
2179 Contains: |
|
2180 prec - precision (for use in rounding, division, square roots..) |
|
2181 rounding - rounding type. (how you round) |
|
2182 _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round? |
|
2183 traps - If traps[exception] = 1, then the exception is |
|
2184 raised when it is caused. Otherwise, a value is |
|
2185 substituted in. |
|
2186 flags - When an exception is caused, flags[exception] is incremented. |
|
2187 (Whether or not the trap_enabler is set) |
|
2188 Should be reset by user of Decimal instance. |
|
2189 Emin - Minimum exponent |
|
2190 Emax - Maximum exponent |
|
2191 capitals - If 1, 1*10^1 is printed as 1E+1. |
|
2192 If 0, printed as 1e1 |
|
2193 _clamp - If 1, change exponents if too high (Default 0) |
|
2194 """ |
|
2195 |
|
2196 def __init__(self, prec=None, rounding=None, |
|
2197 traps=None, flags=None, |
|
2198 _rounding_decision=None, |
|
2199 Emin=None, Emax=None, |
|
2200 capitals=None, _clamp=0, |
|
2201 _ignored_flags=None): |
|
2202 if flags is None: |
|
2203 flags = [] |
|
2204 if _ignored_flags is None: |
|
2205 _ignored_flags = [] |
|
2206 if not isinstance(flags, dict): |
|
2207 flags = dict([(s,s in flags) for s in _signals]) |
|
2208 del s |
|
2209 if traps is not None and not isinstance(traps, dict): |
|
2210 traps = dict([(s,s in traps) for s in _signals]) |
|
2211 del s |
|
2212 for name, val in locals().items(): |
|
2213 if val is None: |
|
2214 setattr(self, name, _copy.copy(getattr(DefaultContext, name))) |
|
2215 else: |
|
2216 setattr(self, name, val) |
|
2217 del self.self |
|
2218 |
|
2219 def __repr__(self): |
|
2220 """Show the current context.""" |
|
2221 s = [] |
|
2222 s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self)) |
|
2223 s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']') |
|
2224 s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']') |
|
2225 return ', '.join(s) + ')' |
|
2226 |
|
2227 def clear_flags(self): |
|
2228 """Reset all flags to zero""" |
|
2229 for flag in self.flags: |
|
2230 self.flags[flag] = 0 |
|
2231 |
|
2232 def _shallow_copy(self): |
|
2233 """Returns a shallow copy from self.""" |
|
2234 nc = Context(self.prec, self.rounding, self.traps, self.flags, |
|
2235 self._rounding_decision, self.Emin, self.Emax, |
|
2236 self.capitals, self._clamp, self._ignored_flags) |
|
2237 return nc |
|
2238 |
|
2239 def copy(self): |
|
2240 """Returns a deep copy from self.""" |
|
2241 nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(), |
|
2242 self._rounding_decision, self.Emin, self.Emax, |
|
2243 self.capitals, self._clamp, self._ignored_flags) |
|
2244 return nc |
|
2245 __copy__ = copy |
|
2246 |
|
2247 def _raise_error(self, condition, explanation = None, *args): |
|
2248 """Handles an error |
|
2249 |
|
2250 If the flag is in _ignored_flags, returns the default response. |
|
2251 Otherwise, it increments the flag, then, if the corresponding |
|
2252 trap_enabler is set, it reaises the exception. Otherwise, it returns |
|
2253 the default value after incrementing the flag. |
|
2254 """ |
|
2255 error = _condition_map.get(condition, condition) |
|
2256 if error in self._ignored_flags: |
|
2257 #Don't touch the flag |
|
2258 return error().handle(self, *args) |
|
2259 |
|
2260 self.flags[error] += 1 |
|
2261 if not self.traps[error]: |
|
2262 #The errors define how to handle themselves. |
|
2263 return condition().handle(self, *args) |
|
2264 |
|
2265 # Errors should only be risked on copies of the context |
|
2266 #self._ignored_flags = [] |
|
2267 raise error, explanation |
|
2268 |
|
2269 def _ignore_all_flags(self): |
|
2270 """Ignore all flags, if they are raised""" |
|
2271 return self._ignore_flags(*_signals) |
|
2272 |
|
2273 def _ignore_flags(self, *flags): |
|
2274 """Ignore the flags, if they are raised""" |
|
2275 # Do not mutate-- This way, copies of a context leave the original |
|
2276 # alone. |
|
2277 self._ignored_flags = (self._ignored_flags + list(flags)) |
|
2278 return list(flags) |
|
2279 |
|
2280 def _regard_flags(self, *flags): |
|
2281 """Stop ignoring the flags, if they are raised""" |
|
2282 if flags and isinstance(flags[0], (tuple,list)): |
|
2283 flags = flags[0] |
|
2284 for flag in flags: |
|
2285 self._ignored_flags.remove(flag) |
|
2286 |
|
2287 def __hash__(self): |
|
2288 """A Context cannot be hashed.""" |
|
2289 # We inherit object.__hash__, so we must deny this explicitly |
|
2290 raise TypeError, "Cannot hash a Context." |
|
2291 |
|
2292 def Etiny(self): |
|
2293 """Returns Etiny (= Emin - prec + 1)""" |
|
2294 return int(self.Emin - self.prec + 1) |
|
2295 |
|
2296 def Etop(self): |
|
2297 """Returns maximum exponent (= Emax - prec + 1)""" |
|
2298 return int(self.Emax - self.prec + 1) |
|
2299 |
|
2300 def _set_rounding_decision(self, type): |
|
2301 """Sets the rounding decision. |
|
2302 |
|
2303 Sets the rounding decision, and returns the current (previous) |
|
2304 rounding decision. Often used like: |
|
2305 |
|
2306 context = context._shallow_copy() |
|
2307 # That so you don't change the calling context |
|
2308 # if an error occurs in the middle (say DivisionImpossible is raised). |
|
2309 |
|
2310 rounding = context._set_rounding_decision(NEVER_ROUND) |
|
2311 instance = instance / Decimal(2) |
|
2312 context._set_rounding_decision(rounding) |
|
2313 |
|
2314 This will make it not round for that operation. |
|
2315 """ |
|
2316 |
|
2317 rounding = self._rounding_decision |
|
2318 self._rounding_decision = type |
|
2319 return rounding |
|
2320 |
|
2321 def _set_rounding(self, type): |
|
2322 """Sets the rounding type. |
|
2323 |
|
2324 Sets the rounding type, and returns the current (previous) |
|
2325 rounding type. Often used like: |
|
2326 |
|
2327 context = context.copy() |
|
2328 # so you don't change the calling context |
|
2329 # if an error occurs in the middle. |
|
2330 rounding = context._set_rounding(ROUND_UP) |
|
2331 val = self.__sub__(other, context=context) |
|
2332 context._set_rounding(rounding) |
|
2333 |
|
2334 This will make it round up for that operation. |
|
2335 """ |
|
2336 rounding = self.rounding |
|
2337 self.rounding= type |
|
2338 return rounding |
|
2339 |
|
2340 def create_decimal(self, num='0'): |
|
2341 """Creates a new Decimal instance but using self as context.""" |
|
2342 d = Decimal(num, context=self) |
|
2343 return d._fix(self) |
|
2344 |
|
2345 #Methods |
|
2346 def abs(self, a): |
|
2347 """Returns the absolute value of the operand. |
|
2348 |
|
2349 If the operand is negative, the result is the same as using the minus |
|
2350 operation on the operand. Otherwise, the result is the same as using |
|
2351 the plus operation on the operand. |
|
2352 |
|
2353 >>> ExtendedContext.abs(Decimal('2.1')) |
|
2354 Decimal("2.1") |
|
2355 >>> ExtendedContext.abs(Decimal('-100')) |
|
2356 Decimal("100") |
|
2357 >>> ExtendedContext.abs(Decimal('101.5')) |
|
2358 Decimal("101.5") |
|
2359 >>> ExtendedContext.abs(Decimal('-101.5')) |
|
2360 Decimal("101.5") |
|
2361 """ |
|
2362 return a.__abs__(context=self) |
|
2363 |
|
2364 def add(self, a, b): |
|
2365 """Return the sum of the two operands. |
|
2366 |
|
2367 >>> ExtendedContext.add(Decimal('12'), Decimal('7.00')) |
|
2368 Decimal("19.00") |
|
2369 >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4')) |
|
2370 Decimal("1.02E+4") |
|
2371 """ |
|
2372 return a.__add__(b, context=self) |
|
2373 |
|
2374 def _apply(self, a): |
|
2375 return str(a._fix(self)) |
|
2376 |
|
2377 def compare(self, a, b): |
|
2378 """Compares values numerically. |
|
2379 |
|
2380 If the signs of the operands differ, a value representing each operand |
|
2381 ('-1' if the operand is less than zero, '0' if the operand is zero or |
|
2382 negative zero, or '1' if the operand is greater than zero) is used in |
|
2383 place of that operand for the comparison instead of the actual |
|
2384 operand. |
|
2385 |
|
2386 The comparison is then effected by subtracting the second operand from |
|
2387 the first and then returning a value according to the result of the |
|
2388 subtraction: '-1' if the result is less than zero, '0' if the result is |
|
2389 zero or negative zero, or '1' if the result is greater than zero. |
|
2390 |
|
2391 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3')) |
|
2392 Decimal("-1") |
|
2393 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1')) |
|
2394 Decimal("0") |
|
2395 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10')) |
|
2396 Decimal("0") |
|
2397 >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1')) |
|
2398 Decimal("1") |
|
2399 >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3')) |
|
2400 Decimal("1") |
|
2401 >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1')) |
|
2402 Decimal("-1") |
|
2403 """ |
|
2404 return a.compare(b, context=self) |
|
2405 |
|
2406 def divide(self, a, b): |
|
2407 """Decimal division in a specified context. |
|
2408 |
|
2409 >>> ExtendedContext.divide(Decimal('1'), Decimal('3')) |
|
2410 Decimal("0.333333333") |
|
2411 >>> ExtendedContext.divide(Decimal('2'), Decimal('3')) |
|
2412 Decimal("0.666666667") |
|
2413 >>> ExtendedContext.divide(Decimal('5'), Decimal('2')) |
|
2414 Decimal("2.5") |
|
2415 >>> ExtendedContext.divide(Decimal('1'), Decimal('10')) |
|
2416 Decimal("0.1") |
|
2417 >>> ExtendedContext.divide(Decimal('12'), Decimal('12')) |
|
2418 Decimal("1") |
|
2419 >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2')) |
|
2420 Decimal("4.00") |
|
2421 >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0')) |
|
2422 Decimal("1.20") |
|
2423 >>> ExtendedContext.divide(Decimal('1000'), Decimal('100')) |
|
2424 Decimal("10") |
|
2425 >>> ExtendedContext.divide(Decimal('1000'), Decimal('1')) |
|
2426 Decimal("1000") |
|
2427 >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2')) |
|
2428 Decimal("1.20E+6") |
|
2429 """ |
|
2430 return a.__div__(b, context=self) |
|
2431 |
|
2432 def divide_int(self, a, b): |
|
2433 """Divides two numbers and returns the integer part of the result. |
|
2434 |
|
2435 >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3')) |
|
2436 Decimal("0") |
|
2437 >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3')) |
|
2438 Decimal("3") |
|
2439 >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3')) |
|
2440 Decimal("3") |
|
2441 """ |
|
2442 return a.__floordiv__(b, context=self) |
|
2443 |
|
2444 def divmod(self, a, b): |
|
2445 return a.__divmod__(b, context=self) |
|
2446 |
|
2447 def max(self, a,b): |
|
2448 """max compares two values numerically and returns the maximum. |
|
2449 |
|
2450 If either operand is a NaN then the general rules apply. |
|
2451 Otherwise, the operands are compared as as though by the compare |
|
2452 operation. If they are numerically equal then the left-hand operand |
|
2453 is chosen as the result. Otherwise the maximum (closer to positive |
|
2454 infinity) of the two operands is chosen as the result. |
|
2455 |
|
2456 >>> ExtendedContext.max(Decimal('3'), Decimal('2')) |
|
2457 Decimal("3") |
|
2458 >>> ExtendedContext.max(Decimal('-10'), Decimal('3')) |
|
2459 Decimal("3") |
|
2460 >>> ExtendedContext.max(Decimal('1.0'), Decimal('1')) |
|
2461 Decimal("1") |
|
2462 >>> ExtendedContext.max(Decimal('7'), Decimal('NaN')) |
|
2463 Decimal("7") |
|
2464 """ |
|
2465 return a.max(b, context=self) |
|
2466 |
|
2467 def min(self, a,b): |
|
2468 """min compares two values numerically and returns the minimum. |
|
2469 |
|
2470 If either operand is a NaN then the general rules apply. |
|
2471 Otherwise, the operands are compared as as though by the compare |
|
2472 operation. If they are numerically equal then the left-hand operand |
|
2473 is chosen as the result. Otherwise the minimum (closer to negative |
|
2474 infinity) of the two operands is chosen as the result. |
|
2475 |
|
2476 >>> ExtendedContext.min(Decimal('3'), Decimal('2')) |
|
2477 Decimal("2") |
|
2478 >>> ExtendedContext.min(Decimal('-10'), Decimal('3')) |
|
2479 Decimal("-10") |
|
2480 >>> ExtendedContext.min(Decimal('1.0'), Decimal('1')) |
|
2481 Decimal("1.0") |
|
2482 >>> ExtendedContext.min(Decimal('7'), Decimal('NaN')) |
|
2483 Decimal("7") |
|
2484 """ |
|
2485 return a.min(b, context=self) |
|
2486 |
|
2487 def minus(self, a): |
|
2488 """Minus corresponds to unary prefix minus in Python. |
|
2489 |
|
2490 The operation is evaluated using the same rules as subtract; the |
|
2491 operation minus(a) is calculated as subtract('0', a) where the '0' |
|
2492 has the same exponent as the operand. |
|
2493 |
|
2494 >>> ExtendedContext.minus(Decimal('1.3')) |
|
2495 Decimal("-1.3") |
|
2496 >>> ExtendedContext.minus(Decimal('-1.3')) |
|
2497 Decimal("1.3") |
|
2498 """ |
|
2499 return a.__neg__(context=self) |
|
2500 |
|
2501 def multiply(self, a, b): |
|
2502 """multiply multiplies two operands. |
|
2503 |
|
2504 If either operand is a special value then the general rules apply. |
|
2505 Otherwise, the operands are multiplied together ('long multiplication'), |
|
2506 resulting in a number which may be as long as the sum of the lengths |
|
2507 of the two operands. |
|
2508 |
|
2509 >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3')) |
|
2510 Decimal("3.60") |
|
2511 >>> ExtendedContext.multiply(Decimal('7'), Decimal('3')) |
|
2512 Decimal("21") |
|
2513 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8')) |
|
2514 Decimal("0.72") |
|
2515 >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0')) |
|
2516 Decimal("-0.0") |
|
2517 >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321')) |
|
2518 Decimal("4.28135971E+11") |
|
2519 """ |
|
2520 return a.__mul__(b, context=self) |
|
2521 |
|
2522 def normalize(self, a): |
|
2523 """normalize reduces an operand to its simplest form. |
|
2524 |
|
2525 Essentially a plus operation with all trailing zeros removed from the |
|
2526 result. |
|
2527 |
|
2528 >>> ExtendedContext.normalize(Decimal('2.1')) |
|
2529 Decimal("2.1") |
|
2530 >>> ExtendedContext.normalize(Decimal('-2.0')) |
|
2531 Decimal("-2") |
|
2532 >>> ExtendedContext.normalize(Decimal('1.200')) |
|
2533 Decimal("1.2") |
|
2534 >>> ExtendedContext.normalize(Decimal('-120')) |
|
2535 Decimal("-1.2E+2") |
|
2536 >>> ExtendedContext.normalize(Decimal('120.00')) |
|
2537 Decimal("1.2E+2") |
|
2538 >>> ExtendedContext.normalize(Decimal('0.00')) |
|
2539 Decimal("0") |
|
2540 """ |
|
2541 return a.normalize(context=self) |
|
2542 |
|
2543 def plus(self, a): |
|
2544 """Plus corresponds to unary prefix plus in Python. |
|
2545 |
|
2546 The operation is evaluated using the same rules as add; the |
|
2547 operation plus(a) is calculated as add('0', a) where the '0' |
|
2548 has the same exponent as the operand. |
|
2549 |
|
2550 >>> ExtendedContext.plus(Decimal('1.3')) |
|
2551 Decimal("1.3") |
|
2552 >>> ExtendedContext.plus(Decimal('-1.3')) |
|
2553 Decimal("-1.3") |
|
2554 """ |
|
2555 return a.__pos__(context=self) |
|
2556 |
|
2557 def power(self, a, b, modulo=None): |
|
2558 """Raises a to the power of b, to modulo if given. |
|
2559 |
|
2560 The right-hand operand must be a whole number whose integer part (after |
|
2561 any exponent has been applied) has no more than 9 digits and whose |
|
2562 fractional part (if any) is all zeros before any rounding. The operand |
|
2563 may be positive, negative, or zero; if negative, the absolute value of |
|
2564 the power is used, and the left-hand operand is inverted (divided into |
|
2565 1) before use. |
|
2566 |
|
2567 If the increased precision needed for the intermediate calculations |
|
2568 exceeds the capabilities of the implementation then an Invalid operation |
|
2569 condition is raised. |
|
2570 |
|
2571 If, when raising to a negative power, an underflow occurs during the |
|
2572 division into 1, the operation is not halted at that point but |
|
2573 continues. |
|
2574 |
|
2575 >>> ExtendedContext.power(Decimal('2'), Decimal('3')) |
|
2576 Decimal("8") |
|
2577 >>> ExtendedContext.power(Decimal('2'), Decimal('-3')) |
|
2578 Decimal("0.125") |
|
2579 >>> ExtendedContext.power(Decimal('1.7'), Decimal('8')) |
|
2580 Decimal("69.7575744") |
|
2581 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2')) |
|
2582 Decimal("0") |
|
2583 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1')) |
|
2584 Decimal("0") |
|
2585 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0')) |
|
2586 Decimal("1") |
|
2587 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1')) |
|
2588 Decimal("Infinity") |
|
2589 >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2')) |
|
2590 Decimal("Infinity") |
|
2591 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2')) |
|
2592 Decimal("0") |
|
2593 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1')) |
|
2594 Decimal("-0") |
|
2595 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0')) |
|
2596 Decimal("1") |
|
2597 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1')) |
|
2598 Decimal("-Infinity") |
|
2599 >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2')) |
|
2600 Decimal("Infinity") |
|
2601 >>> ExtendedContext.power(Decimal('0'), Decimal('0')) |
|
2602 Decimal("NaN") |
|
2603 """ |
|
2604 return a.__pow__(b, modulo, context=self) |
|
2605 |
|
2606 def quantize(self, a, b): |
|
2607 """Returns a value equal to 'a' (rounded) and having the exponent of 'b'. |
|
2608 |
|
2609 The coefficient of the result is derived from that of the left-hand |
|
2610 operand. It may be rounded using the current rounding setting (if the |
|
2611 exponent is being increased), multiplied by a positive power of ten (if |
|
2612 the exponent is being decreased), or is unchanged (if the exponent is |
|
2613 already equal to that of the right-hand operand). |
|
2614 |
|
2615 Unlike other operations, if the length of the coefficient after the |
|
2616 quantize operation would be greater than precision then an Invalid |
|
2617 operation condition is raised. This guarantees that, unless there is an |
|
2618 error condition, the exponent of the result of a quantize is always |
|
2619 equal to that of the right-hand operand. |
|
2620 |
|
2621 Also unlike other operations, quantize will never raise Underflow, even |
|
2622 if the result is subnormal and inexact. |
|
2623 |
|
2624 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001')) |
|
2625 Decimal("2.170") |
|
2626 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01')) |
|
2627 Decimal("2.17") |
|
2628 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1')) |
|
2629 Decimal("2.2") |
|
2630 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0')) |
|
2631 Decimal("2") |
|
2632 >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1')) |
|
2633 Decimal("0E+1") |
|
2634 >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity')) |
|
2635 Decimal("-Infinity") |
|
2636 >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity')) |
|
2637 Decimal("NaN") |
|
2638 >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1')) |
|
2639 Decimal("-0") |
|
2640 >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5')) |
|
2641 Decimal("-0E+5") |
|
2642 >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2')) |
|
2643 Decimal("NaN") |
|
2644 >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2')) |
|
2645 Decimal("NaN") |
|
2646 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1')) |
|
2647 Decimal("217.0") |
|
2648 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0')) |
|
2649 Decimal("217") |
|
2650 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1')) |
|
2651 Decimal("2.2E+2") |
|
2652 >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2')) |
|
2653 Decimal("2E+2") |
|
2654 """ |
|
2655 return a.quantize(b, context=self) |
|
2656 |
|
2657 def remainder(self, a, b): |
|
2658 """Returns the remainder from integer division. |
|
2659 |
|
2660 The result is the residue of the dividend after the operation of |
|
2661 calculating integer division as described for divide-integer, rounded to |
|
2662 precision digits if necessary. The sign of the result, if non-zero, is |
|
2663 the same as that of the original dividend. |
|
2664 |
|
2665 This operation will fail under the same conditions as integer division |
|
2666 (that is, if integer division on the same two operands would fail, the |
|
2667 remainder cannot be calculated). |
|
2668 |
|
2669 >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3')) |
|
2670 Decimal("2.1") |
|
2671 >>> ExtendedContext.remainder(Decimal('10'), Decimal('3')) |
|
2672 Decimal("1") |
|
2673 >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3')) |
|
2674 Decimal("-1") |
|
2675 >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1')) |
|
2676 Decimal("0.2") |
|
2677 >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3')) |
|
2678 Decimal("0.1") |
|
2679 >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3')) |
|
2680 Decimal("1.0") |
|
2681 """ |
|
2682 return a.__mod__(b, context=self) |
|
2683 |
|
2684 def remainder_near(self, a, b): |
|
2685 """Returns to be "a - b * n", where n is the integer nearest the exact |
|
2686 value of "x / b" (if two integers are equally near then the even one |
|
2687 is chosen). If the result is equal to 0 then its sign will be the |
|
2688 sign of a. |
|
2689 |
|
2690 This operation will fail under the same conditions as integer division |
|
2691 (that is, if integer division on the same two operands would fail, the |
|
2692 remainder cannot be calculated). |
|
2693 |
|
2694 >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3')) |
|
2695 Decimal("-0.9") |
|
2696 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6')) |
|
2697 Decimal("-2") |
|
2698 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3')) |
|
2699 Decimal("1") |
|
2700 >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3')) |
|
2701 Decimal("-1") |
|
2702 >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1')) |
|
2703 Decimal("0.2") |
|
2704 >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3')) |
|
2705 Decimal("0.1") |
|
2706 >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3')) |
|
2707 Decimal("-0.3") |
|
2708 """ |
|
2709 return a.remainder_near(b, context=self) |
|
2710 |
|
2711 def same_quantum(self, a, b): |
|
2712 """Returns True if the two operands have the same exponent. |
|
2713 |
|
2714 The result is never affected by either the sign or the coefficient of |
|
2715 either operand. |
|
2716 |
|
2717 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001')) |
|
2718 False |
|
2719 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01')) |
|
2720 True |
|
2721 >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1')) |
|
2722 False |
|
2723 >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf')) |
|
2724 True |
|
2725 """ |
|
2726 return a.same_quantum(b) |
|
2727 |
|
2728 def sqrt(self, a): |
|
2729 """Returns the square root of a non-negative number to context precision. |
|
2730 |
|
2731 If the result must be inexact, it is rounded using the round-half-even |
|
2732 algorithm. |
|
2733 |
|
2734 >>> ExtendedContext.sqrt(Decimal('0')) |
|
2735 Decimal("0") |
|
2736 >>> ExtendedContext.sqrt(Decimal('-0')) |
|
2737 Decimal("-0") |
|
2738 >>> ExtendedContext.sqrt(Decimal('0.39')) |
|
2739 Decimal("0.624499800") |
|
2740 >>> ExtendedContext.sqrt(Decimal('100')) |
|
2741 Decimal("10") |
|
2742 >>> ExtendedContext.sqrt(Decimal('1')) |
|
2743 Decimal("1") |
|
2744 >>> ExtendedContext.sqrt(Decimal('1.0')) |
|
2745 Decimal("1.0") |
|
2746 >>> ExtendedContext.sqrt(Decimal('1.00')) |
|
2747 Decimal("1.0") |
|
2748 >>> ExtendedContext.sqrt(Decimal('7')) |
|
2749 Decimal("2.64575131") |
|
2750 >>> ExtendedContext.sqrt(Decimal('10')) |
|
2751 Decimal("3.16227766") |
|
2752 >>> ExtendedContext.prec |
|
2753 9 |
|
2754 """ |
|
2755 return a.sqrt(context=self) |
|
2756 |
|
2757 def subtract(self, a, b): |
|
2758 """Return the difference between the two operands. |
|
2759 |
|
2760 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07')) |
|
2761 Decimal("0.23") |
|
2762 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30')) |
|
2763 Decimal("0.00") |
|
2764 >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07')) |
|
2765 Decimal("-0.77") |
|
2766 """ |
|
2767 return a.__sub__(b, context=self) |
|
2768 |
|
2769 def to_eng_string(self, a): |
|
2770 """Converts a number to a string, using scientific notation. |
|
2771 |
|
2772 The operation is not affected by the context. |
|
2773 """ |
|
2774 return a.to_eng_string(context=self) |
|
2775 |
|
2776 def to_sci_string(self, a): |
|
2777 """Converts a number to a string, using scientific notation. |
|
2778 |
|
2779 The operation is not affected by the context. |
|
2780 """ |
|
2781 return a.__str__(context=self) |
|
2782 |
|
2783 def to_integral(self, a): |
|
2784 """Rounds to an integer. |
|
2785 |
|
2786 When the operand has a negative exponent, the result is the same |
|
2787 as using the quantize() operation using the given operand as the |
|
2788 left-hand-operand, 1E+0 as the right-hand-operand, and the precision |
|
2789 of the operand as the precision setting, except that no flags will |
|
2790 be set. The rounding mode is taken from the context. |
|
2791 |
|
2792 >>> ExtendedContext.to_integral(Decimal('2.1')) |
|
2793 Decimal("2") |
|
2794 >>> ExtendedContext.to_integral(Decimal('100')) |
|
2795 Decimal("100") |
|
2796 >>> ExtendedContext.to_integral(Decimal('100.0')) |
|
2797 Decimal("100") |
|
2798 >>> ExtendedContext.to_integral(Decimal('101.5')) |
|
2799 Decimal("102") |
|
2800 >>> ExtendedContext.to_integral(Decimal('-101.5')) |
|
2801 Decimal("-102") |
|
2802 >>> ExtendedContext.to_integral(Decimal('10E+5')) |
|
2803 Decimal("1.0E+6") |
|
2804 >>> ExtendedContext.to_integral(Decimal('7.89E+77')) |
|
2805 Decimal("7.89E+77") |
|
2806 >>> ExtendedContext.to_integral(Decimal('-Inf')) |
|
2807 Decimal("-Infinity") |
|
2808 """ |
|
2809 return a.to_integral(context=self) |
|
2810 |
|
2811 class _WorkRep(object): |
|
2812 __slots__ = ('sign','int','exp') |
|
2813 # sign: 0 or 1 |
|
2814 # int: int or long |
|
2815 # exp: None, int, or string |
|
2816 |
|
2817 def __init__(self, value=None): |
|
2818 if value is None: |
|
2819 self.sign = None |
|
2820 self.int = 0 |
|
2821 self.exp = None |
|
2822 elif isinstance(value, Decimal): |
|
2823 self.sign = value._sign |
|
2824 cum = 0 |
|
2825 for digit in value._int: |
|
2826 cum = cum * 10 + digit |
|
2827 self.int = cum |
|
2828 self.exp = value._exp |
|
2829 else: |
|
2830 # assert isinstance(value, tuple) |
|
2831 self.sign = value[0] |
|
2832 self.int = value[1] |
|
2833 self.exp = value[2] |
|
2834 |
|
2835 def __repr__(self): |
|
2836 return "(%r, %r, %r)" % (self.sign, self.int, self.exp) |
|
2837 |
|
2838 __str__ = __repr__ |
|
2839 |
|
2840 |
|
2841 |
|
2842 def _normalize(op1, op2, shouldround = 0, prec = 0): |
|
2843 """Normalizes op1, op2 to have the same exp and length of coefficient. |
|
2844 |
|
2845 Done during addition. |
|
2846 """ |
|
2847 # Yes, the exponent is a long, but the difference between exponents |
|
2848 # must be an int-- otherwise you'd get a big memory problem. |
|
2849 numdigits = int(op1.exp - op2.exp) |
|
2850 if numdigits < 0: |
|
2851 numdigits = -numdigits |
|
2852 tmp = op2 |
|
2853 other = op1 |
|
2854 else: |
|
2855 tmp = op1 |
|
2856 other = op2 |
|
2857 |
|
2858 |
|
2859 if shouldround and numdigits > prec + 1: |
|
2860 # Big difference in exponents - check the adjusted exponents |
|
2861 tmp_len = len(str(tmp.int)) |
|
2862 other_len = len(str(other.int)) |
|
2863 if numdigits > (other_len + prec + 1 - tmp_len): |
|
2864 # If the difference in adjusted exps is > prec+1, we know |
|
2865 # other is insignificant, so might as well put a 1 after the precision. |
|
2866 # (since this is only for addition.) Also stops use of massive longs. |
|
2867 |
|
2868 extend = prec + 2 - tmp_len |
|
2869 if extend <= 0: |
|
2870 extend = 1 |
|
2871 tmp.int *= 10 ** extend |
|
2872 tmp.exp -= extend |
|
2873 other.int = 1 |
|
2874 other.exp = tmp.exp |
|
2875 return op1, op2 |
|
2876 |
|
2877 tmp.int *= 10 ** numdigits |
|
2878 tmp.exp -= numdigits |
|
2879 return op1, op2 |
|
2880 |
|
2881 def _adjust_coefficients(op1, op2): |
|
2882 """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int. |
|
2883 |
|
2884 Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp. |
|
2885 |
|
2886 Used on _WorkRep instances during division. |
|
2887 """ |
|
2888 adjust = 0 |
|
2889 #If op1 is smaller, make it larger |
|
2890 while op2.int > op1.int: |
|
2891 op1.int *= 10 |
|
2892 op1.exp -= 1 |
|
2893 adjust += 1 |
|
2894 |
|
2895 #If op2 is too small, make it larger |
|
2896 while op1.int >= (10 * op2.int): |
|
2897 op2.int *= 10 |
|
2898 op2.exp -= 1 |
|
2899 adjust -= 1 |
|
2900 |
|
2901 return op1, op2, adjust |
|
2902 |
|
2903 ##### Helper Functions ######################################## |
|
2904 |
|
2905 def _convert_other(other): |
|
2906 """Convert other to Decimal. |
|
2907 |
|
2908 Verifies that it's ok to use in an implicit construction. |
|
2909 """ |
|
2910 if isinstance(other, Decimal): |
|
2911 return other |
|
2912 if isinstance(other, (int, long)): |
|
2913 return Decimal(other) |
|
2914 return NotImplemented |
|
2915 |
|
2916 _infinity_map = { |
|
2917 'inf' : 1, |
|
2918 'infinity' : 1, |
|
2919 '+inf' : 1, |
|
2920 '+infinity' : 1, |
|
2921 '-inf' : -1, |
|
2922 '-infinity' : -1 |
|
2923 } |
|
2924 |
|
2925 def _isinfinity(num): |
|
2926 """Determines whether a string or float is infinity. |
|
2927 |
|
2928 +1 for negative infinity; 0 for finite ; +1 for positive infinity |
|
2929 """ |
|
2930 num = str(num).lower() |
|
2931 return _infinity_map.get(num, 0) |
|
2932 |
|
2933 def _isnan(num): |
|
2934 """Determines whether a string or float is NaN |
|
2935 |
|
2936 (1, sign, diagnostic info as string) => NaN |
|
2937 (2, sign, diagnostic info as string) => sNaN |
|
2938 0 => not a NaN |
|
2939 """ |
|
2940 num = str(num).lower() |
|
2941 if not num: |
|
2942 return 0 |
|
2943 |
|
2944 #get the sign, get rid of trailing [+-] |
|
2945 sign = 0 |
|
2946 if num[0] == '+': |
|
2947 num = num[1:] |
|
2948 elif num[0] == '-': #elif avoids '+-nan' |
|
2949 num = num[1:] |
|
2950 sign = 1 |
|
2951 |
|
2952 if num.startswith('nan'): |
|
2953 if len(num) > 3 and not num[3:].isdigit(): #diagnostic info |
|
2954 return 0 |
|
2955 return (1, sign, num[3:].lstrip('0')) |
|
2956 if num.startswith('snan'): |
|
2957 if len(num) > 4 and not num[4:].isdigit(): |
|
2958 return 0 |
|
2959 return (2, sign, num[4:].lstrip('0')) |
|
2960 return 0 |
|
2961 |
|
2962 |
|
2963 ##### Setup Specific Contexts ################################ |
|
2964 |
|
2965 # The default context prototype used by Context() |
|
2966 # Is mutable, so that new contexts can have different default values |
|
2967 |
|
2968 DefaultContext = Context( |
|
2969 prec=28, rounding=ROUND_HALF_EVEN, |
|
2970 traps=[DivisionByZero, Overflow, InvalidOperation], |
|
2971 flags=[], |
|
2972 _rounding_decision=ALWAYS_ROUND, |
|
2973 Emax=999999999, |
|
2974 Emin=-999999999, |
|
2975 capitals=1 |
|
2976 ) |
|
2977 |
|
2978 # Pre-made alternate contexts offered by the specification |
|
2979 # Don't change these; the user should be able to select these |
|
2980 # contexts and be able to reproduce results from other implementations |
|
2981 # of the spec. |
|
2982 |
|
2983 BasicContext = Context( |
|
2984 prec=9, rounding=ROUND_HALF_UP, |
|
2985 traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow], |
|
2986 flags=[], |
|
2987 ) |
|
2988 |
|
2989 ExtendedContext = Context( |
|
2990 prec=9, rounding=ROUND_HALF_EVEN, |
|
2991 traps=[], |
|
2992 flags=[], |
|
2993 ) |
|
2994 |
|
2995 |
|
2996 ##### Useful Constants (internal use only) #################### |
|
2997 |
|
2998 #Reusable defaults |
|
2999 Inf = Decimal('Inf') |
|
3000 negInf = Decimal('-Inf') |
|
3001 |
|
3002 #Infsign[sign] is infinity w/ that sign |
|
3003 Infsign = (Inf, negInf) |
|
3004 |
|
3005 NaN = Decimal('NaN') |
|
3006 |
|
3007 |
|
3008 ##### crud for parsing strings ################################# |
|
3009 import re |
|
3010 |
|
3011 # There's an optional sign at the start, and an optional exponent |
|
3012 # at the end. The exponent has an optional sign and at least one |
|
3013 # digit. In between, must have either at least one digit followed |
|
3014 # by an optional fraction, or a decimal point followed by at least |
|
3015 # one digit. Yuck. |
|
3016 |
|
3017 _parser = re.compile(r""" |
|
3018 # \s* |
|
3019 (?P<sign>[-+])? |
|
3020 ( |
|
3021 (?P<int>\d+) (\. (?P<frac>\d*))? |
|
3022 | |
|
3023 \. (?P<onlyfrac>\d+) |
|
3024 ) |
|
3025 ([eE](?P<exp>[-+]? \d+))? |
|
3026 # \s* |
|
3027 $ |
|
3028 """, re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces. |
|
3029 |
|
3030 del re |
|
3031 |
|
3032 # return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly |
|
3033 |
|
3034 def _string2exact(s): |
|
3035 m = _parser(s) |
|
3036 if m is None: |
|
3037 raise ValueError("invalid literal for Decimal: %r" % s) |
|
3038 |
|
3039 if m.group('sign') == "-": |
|
3040 sign = 1 |
|
3041 else: |
|
3042 sign = 0 |
|
3043 |
|
3044 exp = m.group('exp') |
|
3045 if exp is None: |
|
3046 exp = 0 |
|
3047 else: |
|
3048 exp = int(exp) |
|
3049 |
|
3050 intpart = m.group('int') |
|
3051 if intpart is None: |
|
3052 intpart = "" |
|
3053 fracpart = m.group('onlyfrac') |
|
3054 else: |
|
3055 fracpart = m.group('frac') |
|
3056 if fracpart is None: |
|
3057 fracpart = "" |
|
3058 |
|
3059 exp -= len(fracpart) |
|
3060 |
|
3061 mantissa = intpart + fracpart |
|
3062 tmp = map(int, mantissa) |
|
3063 backup = tmp |
|
3064 while tmp and tmp[0] == 0: |
|
3065 del tmp[0] |
|
3066 |
|
3067 # It's a zero |
|
3068 if not tmp: |
|
3069 if backup: |
|
3070 return (sign, tuple(backup), exp) |
|
3071 return (sign, (0,), exp) |
|
3072 mantissa = tuple(tmp) |
|
3073 |
|
3074 return (sign, mantissa, exp) |
|
3075 |
|
3076 |
|
3077 if __name__ == '__main__': |
|
3078 import doctest, sys |
|
3079 doctest.testmod(sys.modules[__name__]) |