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 django.utils.copycompat 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__]) |