1edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Copyright (c) 2004 Python Software Foundation.
2edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# All rights reserved.
3edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Written by Eric Price <eprice at tjhsst.edu>
5edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#    and Facundo Batista <facundo at taniquetil.com.ar>
6edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#    and Raymond Hettinger <python at rcn.com>
7edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#    and Aahz <aahz at pobox.com>
8edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#    and Tim Peters
9edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
10edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# This module is currently Py2.3 compatible and should be kept that way
11edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# unless a major compelling advantage arises.  IOW, 2.3 compatibility is
12edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# strongly preferred, but not guaranteed.
13edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
14edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Also, this module should be kept in sync with the latest updates of
15edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# the IBM specification as it evolves.  Those updates will be treated
16edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# as bug fixes (deviation from the spec is a compatibility, usability
17edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# bug) and will be backported.  At this point the spec is stabilizing
18edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# and the updates are becoming fewer, smaller, and less significant.
19edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
20edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep"""
21edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepThis is a Py2.3 implementation of decimal floating point arithmetic based on
22edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepthe General Decimal Arithmetic Specification:
23edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
24edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    http://speleotrove.com/decimal/decarith.html
25edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
26edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepand IEEE standard 854-1987:
27edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
28edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html
29edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
30edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal floating point has finite precision with arbitrarily large bounds.
31edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
32edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepThe purpose of this module is to support arithmetic using familiar
33edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep"schoolhouse" rules and to avoid some of the tricky representation
34edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepissues associated with binary floating point.  The package is especially
35edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepuseful for financial applications or for contexts where users have
36edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepexpectations that are at odds with binary floating point (for instance,
37edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepin binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead
38edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepof the expected Decimal('0.00') returned by decimal floating point).
39edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
40edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepHere are some examples of using the decimal module:
41edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
42edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> from decimal import *
43edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> setcontext(ExtendedContext)
44edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> Decimal(0)
45edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal('0')
46edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> Decimal('1')
47edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal('1')
48edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> Decimal('-.0123')
49edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal('-0.0123')
50edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> Decimal(123456)
51edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal('123456')
52edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> Decimal('123.45e12345678901234567890')
53edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal('1.2345E+12345678901234567892')
54edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> Decimal('1.33') + Decimal('1.27')
55edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal('2.60')
56edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> Decimal('12.34') + Decimal('3.87') - Decimal('18.41')
57edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal('-2.20')
58edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> dig = Decimal(1)
59edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print dig / Decimal(3)
60edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep0.333333333
61edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> getcontext().prec = 18
62edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print dig / Decimal(3)
63edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep0.333333333333333333
64edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print dig.sqrt()
65edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep1
66edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print Decimal(3).sqrt()
67edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep1.73205080756887729
68edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print Decimal(3) ** 123
69edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep4.85192780976896427E+58
70edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> inf = Decimal(1) / Decimal(0)
71edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print inf
72edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepInfinity
73edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> neginf = Decimal(-1) / Decimal(0)
74edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print neginf
75edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep-Infinity
76edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print neginf + inf
77edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepNaN
78edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print neginf * inf
79edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep-Infinity
80edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print dig / 0
81edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepInfinity
82edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> getcontext().traps[DivisionByZero] = 1
83edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print dig / 0
84edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTraceback (most recent call last):
85edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep  ...
86edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep  ...
87edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep  ...
88edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDivisionByZero: x / 0
89edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> c = Context()
90edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> c.traps[InvalidOperation] = 0
91edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print c.flags[InvalidOperation]
92edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep0
93edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> c.divide(Decimal(0), Decimal(0))
94edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDecimal('NaN')
95edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> c.traps[InvalidOperation] = 1
96edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print c.flags[InvalidOperation]
97edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep1
98edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> c.flags[InvalidOperation] = 0
99edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print c.flags[InvalidOperation]
100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep0
101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print c.divide(Decimal(0), Decimal(0))
102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTraceback (most recent call last):
103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep  ...
104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep  ...
105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep  ...
106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepInvalidOperation: 0 / 0
107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print c.flags[InvalidOperation]
108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep1
109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> c.flags[InvalidOperation] = 0
110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> c.traps[InvalidOperation] = 0
111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print c.divide(Decimal(0), Decimal(0))
112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepNaN
113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>> print c.flags[InvalidOperation]
114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep1
115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>>>
116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep"""
117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep__all__ = [
119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Two major classes
120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    'Decimal', 'Context',
121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Contexts
123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    'DefaultContext', 'BasicContext', 'ExtendedContext',
124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Exceptions
126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Constants for use in setting up contexts
130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING',
131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 'ROUND_05UP',
132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Functions for manipulating contexts
134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    'setcontext', 'getcontext', 'localcontext'
135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep]
136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep__version__ = '1.70'    # Highest version of the spec this complies with
138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport copy as _copy
140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport math as _math
141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport numbers as _numbers
142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoeptry:
144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    from collections import namedtuple as _namedtuple
145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent')
146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepexcept ImportError:
147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    DecimalTuple = lambda *args: args
148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Rounding
150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepROUND_DOWN = 'ROUND_DOWN'
151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepROUND_HALF_UP = 'ROUND_HALF_UP'
152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepROUND_CEILING = 'ROUND_CEILING'
154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepROUND_FLOOR = 'ROUND_FLOOR'
155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepROUND_UP = 'ROUND_UP'
156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepROUND_05UP = 'ROUND_05UP'
158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Errors
160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass DecimalException(ArithmeticError):
162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Base exception class.
163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Used exceptions derive from this.
165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    If an exception derives from another exception besides this (such as
166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    called if the others are present.  This isn't actually used for
168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    anything, though.
169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    handle  -- Called when context._raise_error is called and the
171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep               trap_enabler is not set.  First argument is self, second is the
172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep               context.  More arguments can be given, those being after
173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep               the explanation in _raise_error (For example,
174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep               context._raise_error(NewError, '(-x)!', self._sign) would
175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep               call NewError().handle(context, self._sign).)
176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    To define a new exception, it should be sufficient to have it derive
178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    from DecimalException.
179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def handle(self, context, *args):
181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        pass
182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Clamped(DecimalException):
185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Exponent of a 0 changed to fit bounds.
186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    This occurs and signals clamped if the exponent of a result has been
188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    altered in order to fit the constraints of a specific concrete
189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    representation.  This may occur when the exponent of a zero result would
190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    be outside the bounds of a representation, or when a large normal
191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    number would have an encoded exponent that cannot be represented.  In
192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    this latter case, the exponent is reduced to fit and the corresponding
193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    number of zero digits are appended to the coefficient ("fold-down").
194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass InvalidOperation(DecimalException):
197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """An invalid operation was performed.
198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Various bad things cause this:
200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Something creates a signaling NaN
202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    -INF + INF
203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    0 * (+-)INF
204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    (+-)INF / (+-)INF
205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    x % 0
206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    (+-)INF % x
207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    x._rescale( non-integer )
208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    sqrt(-x) , x > 0
209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    0 ** 0
210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    x ** (non-integer)
211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    x ** (+-)INF
212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    An operand is invalid
213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    The result of the operation after these is a quiet positive NaN,
215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    except when the cause is a signaling NaN, in which case the result is
216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    also a quiet NaN, but with the original sign, and an optional
217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    diagnostic information.
218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def handle(self, context, *args):
220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if args:
221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = _dec_from_triple(args[0]._sign, args[0]._int, 'n', True)
222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans._fix_nan(context)
223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _NaN
224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass ConversionSyntax(InvalidOperation):
226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Trying to convert badly formed string.
227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    This occurs and signals invalid-operation if an string is being
229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    converted to a number and it does not conform to the numeric string
230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    syntax.  The result is [0,qNaN].
231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def handle(self, context, *args):
233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _NaN
234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass DivisionByZero(DecimalException, ZeroDivisionError):
236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Division by 0.
237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    This occurs and signals division-by-zero if division of a finite number
239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    by zero was attempted (during a divide-integer or divide operation, or a
240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    power operation with negative right-hand operand), and the dividend was
241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    not zero.
242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    The result of the operation is [sign,inf], where sign is the exclusive
244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    or of the signs of the operands for divide, or is 1 for an odd power of
245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    -0, for power.
246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def handle(self, context, sign, *args):
249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _SignedInfinity[sign]
250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass DivisionImpossible(InvalidOperation):
252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Cannot perform the division adequately.
253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    This occurs and signals invalid-operation if the integer result of a
255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    divide-integer or remainder operation had too many digits (would be
256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    longer than precision).  The result is [0,qNaN].
257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def handle(self, context, *args):
260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _NaN
261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass DivisionUndefined(InvalidOperation, ZeroDivisionError):
263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Undefined result of division.
264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    This occurs and signals invalid-operation if division by zero was
266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    attempted (during a divide-integer, divide, or remainder operation), and
267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    the dividend is also zero.  The result is [0,qNaN].
268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def handle(self, context, *args):
271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _NaN
272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Inexact(DecimalException):
274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Had to round, losing information.
275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    This occurs and signals inexact whenever the result of an operation is
277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    not exact (that is, it needed to be rounded and any discarded digits
278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    were non-zero), or if an overflow or underflow condition occurs.  The
279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    result in all cases is unchanged.
280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    The inexact signal may be tested (or trapped) to determine if a given
282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    operation (or sequence of operations) was inexact.
283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass InvalidContext(InvalidOperation):
286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Invalid context.  Unknown rounding, for example.
287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    This occurs and signals invalid-operation if an invalid context was
289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    detected during an operation.  This can occur if contexts are not checked
290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    on creation and either the precision exceeds the capability of the
291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    underlying concrete representation or an unknown or unsupported rounding
292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    was specified.  These aspects of the context need only be checked when
293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    the values are required to be used.  The result is [0,qNaN].
294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def handle(self, context, *args):
297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _NaN
298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Rounded(DecimalException):
300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Number got rounded (not  necessarily changed during rounding).
301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    This occurs and signals rounded whenever the result of an operation is
303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    rounded (that is, some zero or non-zero digits were discarded from the
304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    coefficient), or if an overflow or underflow condition occurs.  The
305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    result in all cases is unchanged.
306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    The rounded signal may be tested (or trapped) to determine if a given
308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    operation (or sequence of operations) caused a loss of precision.
309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Subnormal(DecimalException):
312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Exponent < Emin before rounding.
313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    This occurs and signals subnormal whenever the result of a conversion or
315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    operation is subnormal (that is, its adjusted exponent is less than
316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Emin, before any rounding).  The result in all cases is unchanged.
317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    The subnormal signal may be tested (or trapped) to determine if a given
319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    or operation (or sequence of operations) yielded a subnormal result.
320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Overflow(Inexact, Rounded):
323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Numerical overflow.
324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    This occurs and signals overflow if the adjusted exponent of a result
326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    (from a conversion or from an operation that is not an attempt to divide
327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    by zero), after rounding, would be greater than the largest value that
328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    can be handled by the implementation (the value Emax).
329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    The result depends on the rounding mode:
331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    For round-half-up and round-half-even (and for round-half-down and
333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    round-up, if implemented), the result of the operation is [sign,inf],
334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    where sign is the sign of the intermediate result.  For round-down, the
335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    result is the largest finite number that can be represented in the
336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    current precision, with the sign of the intermediate result.  For
337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    round-ceiling, the result is the same as for round-down if the sign of
338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    the intermediate result is 1, or is [0,inf] otherwise.  For round-floor,
339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    the result is the same as for round-down if the sign of the intermediate
340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    result is 0, or is [1,inf] otherwise.  In all cases, Inexact and Rounded
341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    will also be raised.
342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def handle(self, context, sign, *args):
345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                ROUND_HALF_DOWN, ROUND_UP):
347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _SignedInfinity[sign]
348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if sign == 0:
349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if context.rounding == ROUND_CEILING:
350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _SignedInfinity[sign]
351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _dec_from_triple(sign, '9'*context.prec,
352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                            context.Emax-context.prec+1)
353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if sign == 1:
354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if context.rounding == ROUND_FLOOR:
355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _SignedInfinity[sign]
356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _dec_from_triple(sign, '9'*context.prec,
357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                             context.Emax-context.prec+1)
358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Underflow(Inexact, Rounded, Subnormal):
361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Numerical underflow with result rounded to 0.
362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    This occurs and signals underflow if a result is inexact and the
364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    adjusted exponent of the result would be smaller (more negative) than
365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    the smallest value that can be handled by the implementation (the value
366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Emin).  That is, the result is both inexact and subnormal.
367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    The result after an underflow will be a subnormal number rounded, if
369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    necessary, so that its exponent is not less than Etiny.  This may result
370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    in 0 with the sign of the intermediate result and an exponent of Etiny.
371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    In all cases, Inexact, Rounded, and Subnormal will also be raised.
373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# List of public traps and flags
376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep           Underflow, InvalidOperation, Subnormal]
378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Map conditions (per the spec) to signals
380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_condition_map = {ConversionSyntax:InvalidOperation,
381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  DivisionImpossible:InvalidOperation,
382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  DivisionUndefined:InvalidOperation,
383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  InvalidContext:InvalidOperation}
384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### Context Functions ##################################################
386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# The getcontext() and setcontext() function manage access to a thread-local
388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# current context.  Py2.4 offers direct support for thread locals.  If that
389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# is not available, use threading.currentThread() which is slower but will
390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# work for older Pythons.  If threads are not part of the build, create a
391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# mock threading object with threading.local() returning the module namespace.
392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoeptry:
394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    import threading
395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepexcept ImportError:
396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Python was compiled without threads; create a mock object instead
397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    import sys
398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    class MockThreading(object):
399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        def local(self, sys=sys):
400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return sys.modules[__name__]
401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    threading = MockThreading()
402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    del sys, MockThreading
403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoeptry:
405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    threading.local
406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepexcept AttributeError:
408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # To fix reloading, force it to create a new context
410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Old contexts have different exceptions in their dicts, making problems.
411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if hasattr(threading.currentThread(), '__decimal_context__'):
412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        del threading.currentThread().__decimal_context__
413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def setcontext(context):
415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Set this thread's context to context."""
416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context in (DefaultContext, BasicContext, ExtendedContext):
417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = context.copy()
418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context.clear_flags()
419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        threading.currentThread().__decimal_context__ = context
420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def getcontext():
422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns this thread's context.
423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        If this thread does not yet have a context, returns
425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a new context and sets this thread's context.
426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        New contexts are copies of DefaultContext.
427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        try:
429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return threading.currentThread().__decimal_context__
430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        except AttributeError:
431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = Context()
432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            threading.currentThread().__decimal_context__ = context
433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context
434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepelse:
436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    local = threading.local()
438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if hasattr(local, '__decimal_context__'):
439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        del local.__decimal_context__
440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def getcontext(_local=local):
442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns this thread's context.
443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        If this thread does not yet have a context, returns
445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a new context and sets this thread's context.
446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        New contexts are copies of DefaultContext.
447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        try:
449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _local.__decimal_context__
450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        except AttributeError:
451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = Context()
452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            _local.__decimal_context__ = context
453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context
454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def setcontext(context, _local=local):
456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Set this thread's context to context."""
457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context in (DefaultContext, BasicContext, ExtendedContext):
458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = context.copy()
459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context.clear_flags()
460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        _local.__decimal_context__ = context
461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    del threading, local        # Don't contaminate the namespace
463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef localcontext(ctx=None):
465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Return a context manager for a copy of the supplied context
466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Uses a copy of the current context if no context is specified
468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    The returned context manager creates a local decimal context
469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    in a with statement:
470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        def sin(x):
471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep             with localcontext() as ctx:
472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                 ctx.prec += 2
473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                 # Rest of sin calculation algorithm
474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                 # uses a precision 2 greater than normal
475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep             return +s  # Convert result to normal precision
476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep         def sin(x):
478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep             with localcontext(ExtendedContext):
479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                 # Rest of sin calculation algorithm
480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                 # uses the Extended Context from the
481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                 # General Decimal Arithmetic Specification
482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep             return +s  # Convert result to normal context
483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    >>> setcontext(DefaultContext)
485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    >>> print getcontext().prec
486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    28
487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    >>> with localcontext():
488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    ...     ctx = getcontext()
489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    ...     ctx.prec += 2
490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    ...     print ctx.prec
491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    ...
492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    30
493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    >>> with localcontext(ExtendedContext):
494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    ...     print getcontext().prec
495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    ...
496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    9
497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    >>> print getcontext().prec
498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    28
499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if ctx is None: ctx = getcontext()
501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return _ContextManager(ctx)
502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### Decimal class #######################################################
505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Decimal(object):
507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Floating point class for decimal arithmetic."""
508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    __slots__ = ('_exp','_int','_sign', '_is_special')
510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Generally, the value of the Decimal instance is given by
511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #  (-1)**_sign * _int * 10**_exp
512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Special values are signified by _is_special == True
513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # We're immutable, so use __new__ not __init__
515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __new__(cls, value="0", context=None):
516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Create a decimal point instance.
517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> Decimal('3.14')              # string input
519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3.14')
520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> Decimal((0, (3, 1, 4), -2))  # tuple (sign, digit_tuple, exponent)
521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3.14')
522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> Decimal(314)                 # int or long
523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('314')
524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> Decimal(Decimal(314))        # another decimal instance
525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('314')
526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> Decimal('  3.14  \\n')        # leading and trailing whitespace okay
527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3.14')
528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Note that the coefficient, self._int, is actually stored as
531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # a string rather than as a tuple of digits.  This speeds up
532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # the "digits to integer" and "integer to digits" conversions
533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # that are used in almost every arithmetic operation on
534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Decimals.  This is an internal detail: the as_tuple function
535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # and the Decimal constructor still deal with tuples of
536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # digits.
537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self = object.__new__(cls)
539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # From a string
541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # REs insist on real strings, so we can too.
542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if isinstance(value, basestring):
543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            m = _parser(value.strip())
544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if m is None:
545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if context is None:
546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    context = getcontext()
547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(ConversionSyntax,
548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                "Invalid literal for Decimal: %r" % value)
549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if m.group('sign') == "-":
551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self._sign = 1
552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self._sign = 0
554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            intpart = m.group('int')
555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if intpart is not None:
556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # finite number
557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                fracpart = m.group('frac') or ''
558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                exp = int(m.group('exp') or '0')
559edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self._int = str(int(intpart+fracpart))
560edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self._exp = exp - len(fracpart)
561edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self._is_special = False
562edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
563edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                diag = m.group('diag')
564edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if diag is not None:
565edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    # NaN
566edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    self._int = str(int(diag or '0')).lstrip('0')
567edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    if m.group('signal'):
568edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        self._exp = 'N'
569edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    else:
570edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        self._exp = 'n'
571edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                else:
572edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    # infinity
573edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    self._int = '0'
574edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    self._exp = 'F'
575edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self._is_special = True
576edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self
577edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
578edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # From an integer
579edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if isinstance(value, (int,long)):
580edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if value >= 0:
581edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self._sign = 0
582edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
583edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self._sign = 1
584edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._exp = 0
585edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._int = str(abs(value))
586edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._is_special = False
587edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self
588edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
589edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # From another decimal
590edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if isinstance(value, Decimal):
591edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._exp  = value._exp
592edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._sign = value._sign
593edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._int  = value._int
594edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._is_special  = value._is_special
595edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self
596edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
597edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # From an internal working value
598edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if isinstance(value, _WorkRep):
599edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._sign = value.sign
600edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._int = str(value.int)
601edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._exp = int(value.exp)
602edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._is_special = False
603edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self
604edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
605edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # tuple/list conversion (possibly from as_tuple())
606edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if isinstance(value, (list,tuple)):
607edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if len(value) != 3:
608edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                raise ValueError('Invalid tuple size in creation of Decimal '
609edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                 'from list or tuple.  The list or tuple '
610edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                 'should have exactly three elements.')
611edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # process sign.  The isinstance test rejects floats
612edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if not (isinstance(value[0], (int, long)) and value[0] in (0,1)):
613edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                raise ValueError("Invalid sign.  The first value in the tuple "
614edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                 "should be an integer; either 0 for a "
615edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                 "positive number or 1 for a negative number.")
616edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._sign = value[0]
617edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if value[2] == 'F':
618edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # infinity: value[1] is ignored
619edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self._int = '0'
620edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self._exp = value[2]
621edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self._is_special = True
622edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
623edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # process and validate the digits in value[1]
624edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                digits = []
625edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                for digit in value[1]:
626edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    if isinstance(digit, (int, long)) and 0 <= digit <= 9:
627edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        # skip leading zeros
628edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        if digits or digit != 0:
629edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                            digits.append(digit)
630edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    else:
631edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        raise ValueError("The second value in the tuple must "
632edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                         "be composed of integers in the range "
633edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                         "0 through 9.")
634edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if value[2] in ('n', 'N'):
635edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    # NaN: digits form the diagnostic
636edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    self._int = ''.join(map(str, digits))
637edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    self._exp = value[2]
638edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    self._is_special = True
639edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                elif isinstance(value[2], (int, long)):
640edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    # finite number: digits give the coefficient
641edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    self._int = ''.join(map(str, digits or [0]))
642edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    self._exp = value[2]
643edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    self._is_special = False
644edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                else:
645edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    raise ValueError("The third value in the tuple must "
646edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                     "be an integer, or one of the "
647edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                     "strings 'F', 'n', 'N'.")
648edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self
649edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
650edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if isinstance(value, float):
651edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            value = Decimal.from_float(value)
652edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._exp  = value._exp
653edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._sign = value._sign
654edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._int  = value._int
655edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._is_special  = value._is_special
656edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self
657edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
658edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        raise TypeError("Cannot convert %r to Decimal" % value)
659edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
660edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # @classmethod, but @decorator is not valid Python 2.3 syntax, so
661edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # don't use it (see notes on Py2.3 compatibility at top of file)
662edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def from_float(cls, f):
663edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Converts a float to a decimal number, exactly.
664edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
665edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Note that Decimal.from_float(0.1) is not the same as Decimal('0.1').
666edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Since 0.1 is not exactly representable in binary floating point, the
667edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        value is stored as the nearest representable value which is
668edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        0x1.999999999999ap-4.  The exact equivalent of the value in decimal
669edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        is 0.1000000000000000055511151231257827021181583404541015625.
670edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
671edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> Decimal.from_float(0.1)
672edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.1000000000000000055511151231257827021181583404541015625')
673edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> Decimal.from_float(float('nan'))
674edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('NaN')
675edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> Decimal.from_float(float('inf'))
676edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('Infinity')
677edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> Decimal.from_float(-float('inf'))
678edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-Infinity')
679edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> Decimal.from_float(-0.0)
680edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-0')
681edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
682edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
683edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if isinstance(f, (int, long)):        # handle integer inputs
684edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return cls(f)
685edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if _math.isinf(f) or _math.isnan(f):  # raises TypeError if not a float
686edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return cls(repr(f))
687edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if _math.copysign(1.0, f) == 1.0:
688edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            sign = 0
689edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
690edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            sign = 1
691edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        n, d = abs(f).as_integer_ratio()
692edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        k = d.bit_length() - 1
693edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = _dec_from_triple(sign, str(n*5**k), -k)
694edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if cls is Decimal:
695edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return result
696edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
697edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return cls(result)
698edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    from_float = classmethod(from_float)
699edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
700edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _isnan(self):
701edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns whether the number is not actually one.
702edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
703edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        0 if a number
704edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        1 if NaN
705edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        2 if sNaN
706edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
707edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special:
708edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            exp = self._exp
709edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if exp == 'n':
710edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return 1
711edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            elif exp == 'N':
712edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return 2
713edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return 0
714edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
715edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _isinfinity(self):
716edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns whether the number is infinite
717edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
718edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        0 if finite or not a number
719edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        1 if +INF
720edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        -1 if -INF
721edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
722edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._exp == 'F':
723edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self._sign:
724edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return -1
725edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return 1
726edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return 0
727edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
728edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _check_nans(self, other=None, context=None):
729edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns whether the number is not actually one.
730edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
731edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self, other are sNaN, signal
732edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self, other are NaN return nan
733edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return 0
734edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
735edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Done before operations.
736edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
737edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
738edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self_is_nan = self._isnan()
739edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is None:
740edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            other_is_nan = False
741edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
742edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            other_is_nan = other._isnan()
743edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
744edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self_is_nan or other_is_nan:
745edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if context is None:
746edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                context = getcontext()
747edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
748edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self_is_nan == 2:
749edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation, 'sNaN',
750edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        self)
751edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if other_is_nan == 2:
752edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation, 'sNaN',
753edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        other)
754edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self_is_nan:
755edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return self._fix_nan(context)
756edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
757edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other._fix_nan(context)
758edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return 0
759edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
760edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _compare_check_nans(self, other, context):
761edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Version of _check_nans used for the signaling comparisons
762edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        compare_signal, __le__, __lt__, __ge__, __gt__.
763edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
764edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Signal InvalidOperation if either self or other is a (quiet
765edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        or signaling) NaN.  Signaling NaNs take precedence over quiet
766edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        NaNs.
767edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
768edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Return 0 if neither operand is a NaN.
769edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
770edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
771edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
772edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
773edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
774edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special or other._is_special:
775edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self.is_snan():
776edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation,
777edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                            'comparison involving sNaN',
778edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                            self)
779edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            elif other.is_snan():
780edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation,
781edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                            'comparison involving sNaN',
782edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                            other)
783edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            elif self.is_qnan():
784edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation,
785edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                            'comparison involving NaN',
786edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                            self)
787edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            elif other.is_qnan():
788edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation,
789edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                            'comparison involving NaN',
790edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                            other)
791edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return 0
792edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
793edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __nonzero__(self):
794edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if self is nonzero; otherwise return False.
795edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
796edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        NaNs and infinities are considered nonzero.
797edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
798edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self._is_special or self._int != '0'
799edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
800edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _cmp(self, other):
801edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Compare the two non-NaN decimal instances self and other.
802edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
803edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Returns -1 if self < other, 0 if self == other and 1
804edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self > other.  This routine is for internal use only."""
805edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
806edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special or other._is_special:
807edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self_inf = self._isinfinity()
808edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            other_inf = other._isinfinity()
809edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self_inf == other_inf:
810edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return 0
811edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            elif self_inf < other_inf:
812edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return -1
813edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
814edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return 1
815edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
816edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # check for zeros;  Decimal('0') == Decimal('-0')
817edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self:
818edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if not other:
819edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return 0
820edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
821edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return -((-1)**other._sign)
822edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not other:
823edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return (-1)**self._sign
824edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
825edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # If different signs, neg one is less
826edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other._sign < self._sign:
827edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return -1
828edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._sign < other._sign:
829edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return 1
830edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
831edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self_adjusted = self.adjusted()
832edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other_adjusted = other.adjusted()
833edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self_adjusted == other_adjusted:
834edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self_padded = self._int + '0'*(self._exp - other._exp)
835edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            other_padded = other._int + '0'*(other._exp - self._exp)
836edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self_padded == other_padded:
837edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return 0
838edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            elif self_padded < other_padded:
839edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return -(-1)**self._sign
840edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
841edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return (-1)**self._sign
842edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif self_adjusted > other_adjusted:
843edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return (-1)**self._sign
844edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else: # self_adjusted < other_adjusted
845edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return -((-1)**self._sign)
846edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
847edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Note: The Decimal standard doesn't cover rich comparisons for
848edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Decimals.  In particular, the specification is silent on the
849edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # subject of what should happen for a comparison involving a NaN.
850edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # We take the following approach:
851edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #
852edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #   == comparisons involving a quiet NaN always return False
853edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #   != comparisons involving a quiet NaN always return True
854edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #   == or != comparisons involving a signaling NaN signal
855edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #      InvalidOperation, and return False or True as above if the
856edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #      InvalidOperation is not trapped.
857edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #   <, >, <= and >= comparisons involving a (quiet or signaling)
858edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #      NaN signal InvalidOperation, and return False if the
859edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #      InvalidOperation is not trapped.
860edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #
861edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # This behavior is designed to conform as closely as possible to
862edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # that specified by IEEE 754.
863edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
864edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __eq__(self, other, context=None):
865edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, allow_float=True)
866edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
867edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
868edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._check_nans(other, context):
869edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return False
870edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self._cmp(other) == 0
871edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
872edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __ne__(self, other, context=None):
873edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, allow_float=True)
874edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
875edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
876edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._check_nans(other, context):
877edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return True
878edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self._cmp(other) != 0
879edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
880edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __lt__(self, other, context=None):
881edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, allow_float=True)
882edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
883edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
884edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._compare_check_nans(other, context)
885edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
886edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return False
887edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self._cmp(other) < 0
888edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
889edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __le__(self, other, context=None):
890edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, allow_float=True)
891edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
892edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
893edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._compare_check_nans(other, context)
894edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
895edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return False
896edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self._cmp(other) <= 0
897edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
898edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __gt__(self, other, context=None):
899edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, allow_float=True)
900edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
901edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
902edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._compare_check_nans(other, context)
903edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
904edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return False
905edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self._cmp(other) > 0
906edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
907edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __ge__(self, other, context=None):
908edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, allow_float=True)
909edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
910edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
911edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._compare_check_nans(other, context)
912edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
913edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return False
914edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self._cmp(other) >= 0
915edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
916edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def compare(self, other, context=None):
917edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Compares one to another.
918edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
919edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        -1 => a < b
920edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        0  => a = b
921edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        1  => a > b
922edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        NaN => one is NaN
923edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Like __cmp__, but returns Decimal instances.
924edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
925edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
926edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
927edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Compare(NaN, NaN) = NaN
928edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if (self._is_special or other and other._is_special):
929edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._check_nans(other, context)
930edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ans:
931edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return ans
932edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
933edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return Decimal(self._cmp(other))
934edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
935edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __hash__(self):
936edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """x.__hash__() <==> hash(x)"""
937edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Decimal integers must hash the same as the ints
938edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        #
939edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # The hash of a nonspecial noninteger Decimal must depend only
940edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # on the value of that Decimal, and not on its representation.
941edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # For example: hash(Decimal('100E-1')) == hash(Decimal('10')).
942edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
943edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Equality comparisons involving signaling nans can raise an
944edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # exception; since equality checks are implicitly and
945edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # unpredictably used when checking set and dict membership, we
946edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # prevent signaling nans from being used as set elements or
947edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # dict keys by making __hash__ raise an exception.
948edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special:
949edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self.is_snan():
950edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                raise TypeError('Cannot hash a signaling NaN value.')
951edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            elif self.is_nan():
952edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # 0 to match hash(float('nan'))
953edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return 0
954edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
955edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # values chosen to match hash(float('inf')) and
956edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # hash(float('-inf')).
957edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if self._sign:
958edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return -271828
959edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                else:
960edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return 314159
961edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
962edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # In Python 2.7, we're allowing comparisons (but not
963edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # arithmetic operations) between floats and Decimals;  so if
964edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # a Decimal instance is exactly representable as a float then
965edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # its hash should match that of the float.
966edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self_as_float = float(self)
967edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if Decimal.from_float(self_as_float) == self:
968edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return hash(self_as_float)
969edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
970edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinteger():
971edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            op = _WorkRep(self.to_integral_value())
972edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # to make computation feasible for Decimals with large
973edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # exponent, we use the fact that hash(n) == hash(m) for
974edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # any two nonzero integers n and m such that (i) n and m
975edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # have the same sign, and (ii) n is congruent to m modulo
976edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # 2**64-1.  So we can replace hash((-1)**s*c*10**e) with
977edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # hash((-1)**s*c*pow(10, e, 2**64-1).
978edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return hash((-1)**op.sign*op.int*pow(10, op.exp, 2**64-1))
979edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # The value of a nonzero nonspecial Decimal instance is
980edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # faithfully represented by the triple consisting of its sign,
981edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # its adjusted exponent, and its coefficient with trailing
982edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # zeros removed.
983edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return hash((self._sign,
984edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                     self._exp+len(self._int),
985edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                     self._int.rstrip('0')))
986edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
987edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def as_tuple(self):
988edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Represents the number as a triple tuple.
989edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
990edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        To show the internals exactly as they are.
991edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
992edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return DecimalTuple(self._sign, tuple(map(int, self._int)), self._exp)
993edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
994edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __repr__(self):
995edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Represents the number as an instance of Decimal."""
996edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Invariant:  eval(repr(d)) == d
997edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return "Decimal('%s')" % str(self)
998edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
999edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __str__(self, eng=False, context=None):
1000edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return string representation of the number in scientific notation.
1001edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1002edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Captures all of the information in the underlying representation.
1003edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1004edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1005edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        sign = ['', '-'][self._sign]
1006edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special:
1007edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self._exp == 'F':
1008edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return sign + 'Infinity'
1009edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            elif self._exp == 'n':
1010edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return sign + 'NaN' + self._int
1011edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else: # self._exp == 'N'
1012edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return sign + 'sNaN' + self._int
1013edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1014edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # number of digits of self._int to left of decimal point
1015edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        leftdigits = self._exp + len(self._int)
1016edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1017edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # dotplace is number of digits of self._int to the left of the
1018edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # decimal point in the mantissa of the output string (that is,
1019edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # after adjusting the exponent)
1020edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._exp <= 0 and leftdigits > -6:
1021edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # no exponent required
1022edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            dotplace = leftdigits
1023edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif not eng:
1024edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # usual scientific notation: 1 digit on left of the point
1025edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            dotplace = 1
1026edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif self._int == '0':
1027edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # engineering notation, zero
1028edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            dotplace = (leftdigits + 1) % 3 - 1
1029edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1030edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # engineering notation, nonzero
1031edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            dotplace = (leftdigits - 1) % 3 + 1
1032edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1033edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if dotplace <= 0:
1034edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            intpart = '0'
1035edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            fracpart = '.' + '0'*(-dotplace) + self._int
1036edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif dotplace >= len(self._int):
1037edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            intpart = self._int+'0'*(dotplace-len(self._int))
1038edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            fracpart = ''
1039edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1040edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            intpart = self._int[:dotplace]
1041edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            fracpart = '.' + self._int[dotplace:]
1042edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if leftdigits == dotplace:
1043edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            exp = ''
1044edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1045edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if context is None:
1046edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                context = getcontext()
1047edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            exp = ['e', 'E'][context.capitals] + "%+d" % (leftdigits-dotplace)
1048edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1049edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return sign + intpart + fracpart + exp
1050edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1051edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def to_eng_string(self, context=None):
1052edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Convert to engineering-type string.
1053edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1054edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Engineering notation has an exponent which is a multiple of 3, so there
1055edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        are up to 3 digits left of the decimal place.
1056edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1057edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Same rules for when in exponential and when as a value as in __str__.
1058edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1059edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self.__str__(eng=True, context=context)
1060edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1061edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __neg__(self, context=None):
1062edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns a copy with the sign switched.
1063edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1064edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Rounds, if it has reason.
1065edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1066edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special:
1067edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._check_nans(context=context)
1068edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ans:
1069edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return ans
1070edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1071edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
1072edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
1073edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1074edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self and context.rounding != ROUND_FLOOR:
1075edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # -Decimal('0') is Decimal('0'), not Decimal('-0'), except
1076edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # in ROUND_FLOOR rounding mode.
1077edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self.copy_abs()
1078edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1079edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self.copy_negate()
1080edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1081edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans._fix(context)
1082edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1083edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __pos__(self, context=None):
1084edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns a copy, unless it is a sNaN.
1085edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1086edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Rounds the number (if more then precision digits)
1087edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1088edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special:
1089edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._check_nans(context=context)
1090edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ans:
1091edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return ans
1092edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1093edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
1094edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
1095edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1096edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self and context.rounding != ROUND_FLOOR:
1097edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # + (-0) = 0, except in ROUND_FLOOR rounding mode.
1098edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self.copy_abs()
1099edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = Decimal(self)
1101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans._fix(context)
1103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __abs__(self, round=True, context=None):
1105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the absolute value of self.
1106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        If the keyword argument 'round' is false, do not round.  The
1108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expression self.__abs__(round=False) is equivalent to
1109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.copy_abs().
1110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not round:
1112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self.copy_abs()
1113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special:
1115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._check_nans(context=context)
1116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ans:
1117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return ans
1118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._sign:
1120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self.__neg__(context=context)
1121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self.__pos__(context=context)
1123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans
1125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __add__(self, other, context=None):
1127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns self + other.
1128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        -INF + INF (or the reverse) cause InvalidOperation errors.
1130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other)
1132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
1133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
1134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
1136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
1137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special or other._is_special:
1139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._check_nans(other, context)
1140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ans:
1141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return ans
1142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self._isinfinity():
1144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # If both INF, same sign => same as both, opposite => error.
1145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if self._sign != other._sign and other._isinfinity():
1146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return context._raise_error(InvalidOperation, '-INF + INF')
1147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return Decimal(self)
1148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if other._isinfinity():
1149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return Decimal(other)  # Can't both be infinity here
1150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        exp = min(self._exp, other._exp)
1152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        negativezero = 0
1153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context.rounding == ROUND_FLOOR and self._sign != other._sign:
1154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # If the answer is 0, the sign should be negative, in this case.
1155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            negativezero = 1
1156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self and not other:
1158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            sign = min(self._sign, other._sign)
1159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if negativezero:
1160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                sign = 1
1161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = _dec_from_triple(sign, '0', exp)
1162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = ans._fix(context)
1163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
1164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self:
1165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            exp = max(exp, other._exp - context.prec-1)
1166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = other._rescale(exp, context.rounding)
1167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = ans._fix(context)
1168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
1169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not other:
1170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            exp = max(exp, self._exp - context.prec-1)
1171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._rescale(exp, context.rounding)
1172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = ans._fix(context)
1173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
1174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        op1 = _WorkRep(self)
1176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        op2 = _WorkRep(other)
1177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        op1, op2 = _normalize(op1, op2, context.prec)
1178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = _WorkRep()
1180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if op1.sign != op2.sign:
1181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # Equal and opposite
1182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if op1.int == op2.int:
1183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                ans = _dec_from_triple(negativezero, '0', exp)
1184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                ans = ans._fix(context)
1185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return ans
1186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if op1.int < op2.int:
1187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                op1, op2 = op2, op1
1188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # OK, now abs(op1) > abs(op2)
1189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if op1.sign == 1:
1190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                result.sign = 1
1191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                op1.sign, op2.sign = op2.sign, op1.sign
1192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
1193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                result.sign = 0
1194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # So we know the sign, and op1 > 0.
1195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif op1.sign == 1:
1196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            result.sign = 1
1197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            op1.sign, op2.sign = (0, 0)
1198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            result.sign = 0
1200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Now, op1 > abs(op2) > 0
1201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if op2.sign == 0:
1203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            result.int = op1.int + op2.int
1204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            result.int = op1.int - op2.int
1206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result.exp = op1.exp
1208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = Decimal(result)
1209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = ans._fix(context)
1210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans
1211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    __radd__ = __add__
1213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __sub__(self, other, context=None):
1215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return self - other"""
1216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other)
1217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
1218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
1219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special or other._is_special:
1221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._check_nans(other, context=context)
1222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ans:
1223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return ans
1224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # self - other is computed as self + other.copy_negate()
1226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self.__add__(other.copy_negate(), context=context)
1227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __rsub__(self, other, context=None):
1229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return other - self"""
1230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other)
1231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
1232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
1233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return other.__sub__(self, context=context)
1235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __mul__(self, other, context=None):
1237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return self * other.
1238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (+-) INF * 0 (or its reverse) raise InvalidOperation.
1240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other)
1242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
1243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
1244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
1246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
1247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        resultsign = self._sign ^ other._sign
1249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special or other._is_special:
1251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._check_nans(other, context)
1252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ans:
1253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return ans
1254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self._isinfinity():
1256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if not other:
1257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return context._raise_error(InvalidOperation, '(+-)INF * 0')
1258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _SignedInfinity[resultsign]
1259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if other._isinfinity():
1261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if not self:
1262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return context._raise_error(InvalidOperation, '0 * (+-)INF')
1263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _SignedInfinity[resultsign]
1264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        resultexp = self._exp + other._exp
1266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Special case for multiplying by zero
1268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self or not other:
1269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = _dec_from_triple(resultsign, '0', resultexp)
1270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # Fixing in case the exponent is out of bounds
1271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = ans._fix(context)
1272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
1273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Special case for multiplying by power of 10
1275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._int == '1':
1276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = _dec_from_triple(resultsign, other._int, resultexp)
1277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = ans._fix(context)
1278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
1279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other._int == '1':
1280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = _dec_from_triple(resultsign, self._int, resultexp)
1281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = ans._fix(context)
1282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
1283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        op1 = _WorkRep(self)
1285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        op2 = _WorkRep(other)
1286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = _dec_from_triple(resultsign, str(op1.int * op2.int), resultexp)
1288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = ans._fix(context)
1289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans
1291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    __rmul__ = __mul__
1292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __truediv__(self, other, context=None):
1294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return self / other."""
1295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other)
1296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
1297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return NotImplemented
1298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
1300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
1301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        sign = self._sign ^ other._sign
1303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special or other._is_special:
1305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._check_nans(other, context)
1306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ans:
1307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return ans
1308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self._isinfinity() and other._isinfinity():
1310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
1311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self._isinfinity():
1313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _SignedInfinity[sign]
1314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if other._isinfinity():
1316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                context._raise_error(Clamped, 'Division by infinity')
1317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _dec_from_triple(sign, '0', context.Etiny())
1318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Special cases for zeroes
1320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not other:
1321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if not self:
1322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(DivisionUndefined, '0 / 0')
1323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(DivisionByZero, 'x / 0', sign)
1324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self:
1326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            exp = self._exp - other._exp
1327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            coeff = 0
1328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # OK, so neither = 0, INF or NaN
1330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            shift = len(other._int) - len(self._int) + context.prec + 1
1331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            exp = self._exp - other._exp - shift
1332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            op1 = _WorkRep(self)
1333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            op2 = _WorkRep(other)
1334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if shift >= 0:
1335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                coeff, remainder = divmod(op1.int * 10**shift, op2.int)
1336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
1337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                coeff, remainder = divmod(op1.int, op2.int * 10**-shift)
1338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if remainder:
1339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # result is not exact; adjust to ensure correct rounding
1340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if coeff % 5 == 0:
1341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    coeff += 1
1342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
1343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # result is exact; get as close to ideal exponent as possible
1344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                ideal_exp = self._exp - other._exp
1345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                while exp < ideal_exp and coeff % 10 == 0:
1346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    coeff //= 10
1347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    exp += 1
1348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = _dec_from_triple(sign, str(coeff), exp)
1350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans._fix(context)
1351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _divide(self, other, context):
1353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return (self // other, self % other), to context.prec precision.
1354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Assumes that neither self nor other is a NaN, that self is not
1356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        infinite and that other is nonzero.
1357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        sign = self._sign ^ other._sign
1359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other._isinfinity():
1360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ideal_exp = self._exp
1361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ideal_exp = min(self._exp, other._exp)
1363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expdiff = self.adjusted() - other.adjusted()
1365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self or other._isinfinity() or expdiff <= -2:
1366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return (_dec_from_triple(sign, '0', 0),
1367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    self._rescale(ideal_exp, context.rounding))
1368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if expdiff <= context.prec:
1369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            op1 = _WorkRep(self)
1370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            op2 = _WorkRep(other)
1371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if op1.exp >= op2.exp:
1372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                op1.int *= 10**(op1.exp - op2.exp)
1373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
1374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                op2.int *= 10**(op2.exp - op1.exp)
1375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            q, r = divmod(op1.int, op2.int)
1376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if q < 10**context.prec:
1377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return (_dec_from_triple(sign, str(q), 0),
1378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        _dec_from_triple(self._sign, str(r), ideal_exp))
1379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Here the quotient is too large to be representable
1381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = context._raise_error(DivisionImpossible,
1382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                   'quotient too large in //, % or divmod')
1383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans, ans
1384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __rtruediv__(self, other, context=None):
1386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Swaps self/other and returns __truediv__."""
1387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other)
1388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
1389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
1390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return other.__truediv__(self, context=context)
1391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    __div__ = __truediv__
1393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    __rdiv__ = __rtruediv__
1394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __divmod__(self, other, context=None):
1396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Return (self // other, self % other)
1398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other)
1400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
1401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
1402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
1404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
1405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._check_nans(other, context)
1407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
1408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return (ans, ans)
1409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        sign = self._sign ^ other._sign
1411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity():
1412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if other._isinfinity():
1413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                ans = context._raise_error(InvalidOperation, 'divmod(INF, INF)')
1414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return ans, ans
1415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
1416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return (_SignedInfinity[sign],
1417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        context._raise_error(InvalidOperation, 'INF % x'))
1418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not other:
1420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if not self:
1421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                ans = context._raise_error(DivisionUndefined, 'divmod(0, 0)')
1422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return ans, ans
1423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
1424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return (context._raise_error(DivisionByZero, 'x // 0', sign),
1425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        context._raise_error(InvalidOperation, 'x % 0'))
1426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        quotient, remainder = self._divide(other, context)
1428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        remainder = remainder._fix(context)
1429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return quotient, remainder
1430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __rdivmod__(self, other, context=None):
1432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Swaps self/other and returns __divmod__."""
1433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other)
1434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
1435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
1436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return other.__divmod__(self, context=context)
1437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __mod__(self, other, context=None):
1439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self % other
1441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other)
1443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
1444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
1445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
1447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
1448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._check_nans(other, context)
1450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
1451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
1452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity():
1454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation, 'INF % x')
1455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif not other:
1456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self:
1457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation, 'x % 0')
1458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
1459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(DivisionUndefined, '0 % 0')
1460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        remainder = self._divide(other, context)[1]
1462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        remainder = remainder._fix(context)
1463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return remainder
1464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __rmod__(self, other, context=None):
1466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Swaps self/other and returns __mod__."""
1467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other)
1468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
1469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
1470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return other.__mod__(self, context=context)
1471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def remainder_near(self, other, context=None):
1473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Remainder nearest to 0-  abs(remainder-near) <= other/2
1475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
1477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
1478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
1480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._check_nans(other, context)
1482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
1483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
1484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # self == +/-infinity -> InvalidOperation
1486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity():
1487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation,
1488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'remainder_near(infinity, x)')
1489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # other == 0 -> either InvalidOperation or DivisionUndefined
1491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not other:
1492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self:
1493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation,
1494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                            'remainder_near(x, 0)')
1495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
1496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(DivisionUndefined,
1497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                            'remainder_near(0, 0)')
1498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # other = +/-infinity -> remainder = self
1500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other._isinfinity():
1501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = Decimal(self)
1502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans._fix(context)
1503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # self = 0 -> remainder = self, with ideal exponent
1505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ideal_exponent = min(self._exp, other._exp)
1506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self:
1507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = _dec_from_triple(self._sign, '0', ideal_exponent)
1508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans._fix(context)
1509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # catch most cases of large or small quotient
1511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expdiff = self.adjusted() - other.adjusted()
1512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if expdiff >= context.prec + 1:
1513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # expdiff >= prec+1 => abs(self/other) > 10**prec
1514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(DivisionImpossible)
1515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if expdiff <= -2:
1516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # expdiff <= -2 => abs(self/other) < 0.1
1517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._rescale(ideal_exponent, context.rounding)
1518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans._fix(context)
1519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # adjust both arguments to have the same exponent, then divide
1521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        op1 = _WorkRep(self)
1522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        op2 = _WorkRep(other)
1523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if op1.exp >= op2.exp:
1524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            op1.int *= 10**(op1.exp - op2.exp)
1525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            op2.int *= 10**(op2.exp - op1.exp)
1527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        q, r = divmod(op1.int, op2.int)
1528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # remainder is r*10**ideal_exponent; other is +/-op2.int *
1529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # 10**ideal_exponent.   Apply correction to ensure that
1530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # abs(remainder) <= abs(other)/2
1531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if 2*r + (q&1) > op2.int:
1532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            r -= op2.int
1533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            q += 1
1534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if q >= 10**context.prec:
1536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(DivisionImpossible)
1537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # result has same sign as self unless r is negative
1539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        sign = self._sign
1540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if r < 0:
1541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            sign = 1-sign
1542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            r = -r
1543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = _dec_from_triple(sign, str(r), ideal_exponent)
1545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans._fix(context)
1546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __floordiv__(self, other, context=None):
1548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """self // other"""
1549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other)
1550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
1551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
1552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
1554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
1555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._check_nans(other, context)
1557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
1558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
1559edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1560edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity():
1561edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if other._isinfinity():
1562edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation, 'INF // INF')
1563edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
1564edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _SignedInfinity[self._sign ^ other._sign]
1565edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1566edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not other:
1567edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self:
1568edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(DivisionByZero, 'x // 0',
1569edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                            self._sign ^ other._sign)
1570edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
1571edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(DivisionUndefined, '0 // 0')
1572edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1573edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self._divide(other, context)[0]
1574edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1575edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __rfloordiv__(self, other, context=None):
1576edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Swaps self/other and returns __floordiv__."""
1577edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other)
1578edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
1579edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
1580edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return other.__floordiv__(self, context=context)
1581edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1582edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __float__(self):
1583edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Float representation."""
1584edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isnan():
1585edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self.is_snan():
1586edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                raise ValueError("Cannot convert signaling NaN to float")
1587edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            s = "-nan" if self._sign else "nan"
1588edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1589edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            s = str(self)
1590edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return float(s)
1591edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1592edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __int__(self):
1593edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Converts self to an int, truncating if necessary."""
1594edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special:
1595edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self._isnan():
1596edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                raise ValueError("Cannot convert NaN to integer")
1597edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            elif self._isinfinity():
1598edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                raise OverflowError("Cannot convert infinity to integer")
1599edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        s = (-1)**self._sign
1600edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._exp >= 0:
1601edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return s*int(self._int)*10**self._exp
1602edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1603edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return s*int(self._int[:self._exp] or '0')
1604edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1605edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    __trunc__ = __int__
1606edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1607edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def real(self):
1608edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self
1609edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    real = property(real)
1610edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1611edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def imag(self):
1612edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return Decimal(0)
1613edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    imag = property(imag)
1614edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1615edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def conjugate(self):
1616edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self
1617edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1618edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __complex__(self):
1619edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return complex(float(self))
1620edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1621edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __long__(self):
1622edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Converts to a long.
1623edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1624edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Equivalent to long(int(self))
1625edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1626edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return long(self.__int__())
1627edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1628edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _fix_nan(self, context):
1629edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Decapitate the payload of a NaN to fit the context"""
1630edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        payload = self._int
1631edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1632edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # maximum length of payload is precision if _clamp=0,
1633edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # precision-1 if _clamp=1.
1634edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        max_payload_len = context.prec - context._clamp
1635edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if len(payload) > max_payload_len:
1636edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            payload = payload[len(payload)-max_payload_len:].lstrip('0')
1637edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _dec_from_triple(self._sign, payload, self._exp, True)
1638edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return Decimal(self)
1639edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1640edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _fix(self, context):
1641edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Round if it is necessary to keep self within prec precision.
1642edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1643edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Rounds and fixes the exponent.  Does not raise on a sNaN.
1644edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1645edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Arguments:
1646edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self - Decimal instance
1647edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context - context used.
1648edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1649edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1650edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special:
1651edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self._isnan():
1652edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # decapitate payload if necessary
1653edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return self._fix_nan(context)
1654edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
1655edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # self is +/-Infinity; return unaltered
1656edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return Decimal(self)
1657edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1658edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # if self is zero then exponent should be between Etiny and
1659edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Emax if _clamp==0, and between Etiny and Etop if _clamp==1.
1660edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Etiny = context.Etiny()
1661edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Etop = context.Etop()
1662edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self:
1663edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            exp_max = [context.Emax, Etop][context._clamp]
1664edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            new_exp = min(max(self._exp, Etiny), exp_max)
1665edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if new_exp != self._exp:
1666edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                context._raise_error(Clamped)
1667edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _dec_from_triple(self._sign, '0', new_exp)
1668edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
1669edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return Decimal(self)
1670edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1671edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # exp_min is the smallest allowable exponent of the result,
1672edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # equal to max(self.adjusted()-context.prec+1, Etiny)
1673edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        exp_min = len(self._int) + self._exp - context.prec
1674edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if exp_min > Etop:
1675edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # overflow: exp_min > Etop iff self.adjusted() > Emax
1676edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = context._raise_error(Overflow, 'above Emax', self._sign)
1677edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context._raise_error(Inexact)
1678edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context._raise_error(Rounded)
1679edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
1680edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1681edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self_is_subnormal = exp_min < Etiny
1682edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self_is_subnormal:
1683edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            exp_min = Etiny
1684edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1685edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # round if self has too many digits
1686edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._exp < exp_min:
1687edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            digits = len(self._int) + self._exp - exp_min
1688edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if digits < 0:
1689edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self = _dec_from_triple(self._sign, '1', exp_min-1)
1690edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                digits = 0
1691edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            rounding_method = self._pick_rounding_function[context.rounding]
1692edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            changed = rounding_method(self, digits)
1693edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            coeff = self._int[:digits] or '0'
1694edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if changed > 0:
1695edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                coeff = str(int(coeff)+1)
1696edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if len(coeff) > context.prec:
1697edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    coeff = coeff[:-1]
1698edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    exp_min += 1
1699edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1700edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # check whether the rounding pushed the exponent out of range
1701edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if exp_min > Etop:
1702edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                ans = context._raise_error(Overflow, 'above Emax', self._sign)
1703edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
1704edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                ans = _dec_from_triple(self._sign, coeff, exp_min)
1705edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1706edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # raise the appropriate signals, taking care to respect
1707edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # the precedence described in the specification
1708edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if changed and self_is_subnormal:
1709edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                context._raise_error(Underflow)
1710edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self_is_subnormal:
1711edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                context._raise_error(Subnormal)
1712edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if changed:
1713edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                context._raise_error(Inexact)
1714edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context._raise_error(Rounded)
1715edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if not ans:
1716edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # raise Clamped on underflow to 0
1717edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                context._raise_error(Clamped)
1718edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
1719edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1720edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self_is_subnormal:
1721edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context._raise_error(Subnormal)
1722edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1723edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # fold down if _clamp == 1 and self has too few digits
1724edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context._clamp == 1 and self._exp > Etop:
1725edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context._raise_error(Clamped)
1726edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self_padded = self._int + '0'*(self._exp - Etop)
1727edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _dec_from_triple(self._sign, self_padded, Etop)
1728edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1729edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # here self was representable to begin with; return unchanged
1730edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return Decimal(self)
1731edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1732edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # for each of the rounding functions below:
1733edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #   self is a finite, nonzero Decimal
1734edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #   prec is an integer satisfying 0 <= prec < len(self._int)
1735edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #
1736edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # each function returns either -1, 0, or 1, as follows:
1737edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #   1 indicates that self should be rounded up (away from zero)
1738edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #   0 indicates that self should be truncated, and that all the
1739edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #     digits to be truncated are zeros (so the value is unchanged)
1740edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #  -1 indicates that there are nonzero digits to be truncated
1741edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1742edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _round_down(self, prec):
1743edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Also known as round-towards-0, truncate."""
1744edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if _all_zeros(self._int, prec):
1745edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return 0
1746edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1747edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return -1
1748edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1749edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _round_up(self, prec):
1750edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Rounds away from 0."""
1751edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return -self._round_down(prec)
1752edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1753edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _round_half_up(self, prec):
1754edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Rounds 5 up (away from 0)"""
1755edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._int[prec] in '56789':
1756edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return 1
1757edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif _all_zeros(self._int, prec):
1758edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return 0
1759edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1760edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return -1
1761edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1762edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _round_half_down(self, prec):
1763edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Round 5 down"""
1764edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if _exact_half(self._int, prec):
1765edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return -1
1766edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1767edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self._round_half_up(prec)
1768edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1769edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _round_half_even(self, prec):
1770edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Round 5 to even, rest to nearest."""
1771edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if _exact_half(self._int, prec) and \
1772edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                (prec == 0 or self._int[prec-1] in '02468'):
1773edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return -1
1774edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1775edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self._round_half_up(prec)
1776edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1777edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _round_ceiling(self, prec):
1778edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Rounds up (not away from 0 if negative.)"""
1779edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._sign:
1780edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self._round_down(prec)
1781edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1782edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return -self._round_down(prec)
1783edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1784edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _round_floor(self, prec):
1785edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Rounds down (not towards 0 if negative)"""
1786edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self._sign:
1787edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self._round_down(prec)
1788edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1789edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return -self._round_down(prec)
1790edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1791edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _round_05up(self, prec):
1792edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Round down unless digit prec-1 is 0 or 5."""
1793edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if prec and self._int[prec-1] not in '05':
1794edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self._round_down(prec)
1795edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1796edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return -self._round_down(prec)
1797edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1798edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    _pick_rounding_function = dict(
1799edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ROUND_DOWN = _round_down,
1800edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ROUND_UP = _round_up,
1801edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ROUND_HALF_UP = _round_half_up,
1802edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ROUND_HALF_DOWN = _round_half_down,
1803edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ROUND_HALF_EVEN = _round_half_even,
1804edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ROUND_CEILING = _round_ceiling,
1805edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ROUND_FLOOR = _round_floor,
1806edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ROUND_05UP = _round_05up,
1807edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    )
1808edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1809edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def fma(self, other, third, context=None):
1810edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Fused multiply-add.
1811edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1812edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Returns self*other+third with no rounding of the intermediate
1813edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        product self*other.
1814edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1815edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self and other are multiplied together, with no rounding of
1816edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        the result.  The third operand is then added to the result,
1817edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        and a single final rounding is performed.
1818edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
1819edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1820edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
1821edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1822edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # compute product; raise InvalidOperation if either operand is
1823edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # a signaling NaN or if the product is zero times infinity.
1824edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special or other._is_special:
1825edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if context is None:
1826edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                context = getcontext()
1827edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self._exp == 'N':
1828edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation, 'sNaN', self)
1829edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if other._exp == 'N':
1830edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation, 'sNaN', other)
1831edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self._exp == 'n':
1832edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                product = self
1833edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            elif other._exp == 'n':
1834edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                product = other
1835edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            elif self._exp == 'F':
1836edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if not other:
1837edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return context._raise_error(InvalidOperation,
1838edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                                'INF * 0 in fma')
1839edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                product = _SignedInfinity[self._sign ^ other._sign]
1840edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            elif other._exp == 'F':
1841edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if not self:
1842edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return context._raise_error(InvalidOperation,
1843edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                                '0 * INF in fma')
1844edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                product = _SignedInfinity[self._sign ^ other._sign]
1845edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1846edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            product = _dec_from_triple(self._sign ^ other._sign,
1847edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                       str(int(self._int) * int(other._int)),
1848edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                       self._exp + other._exp)
1849edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1850edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        third = _convert_other(third, raiseit=True)
1851edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return product.__add__(third, context)
1852edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1853edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _power_modulo(self, other, modulo, context=None):
1854edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Three argument version of __pow__"""
1855edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1856edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # if can't convert other and modulo to Decimal, raise
1857edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # TypeError; there's no point returning NotImplemented (no
1858edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # equivalent of __rpow__ for three argument pow)
1859edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
1860edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        modulo = _convert_other(modulo, raiseit=True)
1861edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1862edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
1863edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
1864edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1865edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # deal with NaNs: if there are any sNaNs then first one wins,
1866edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # (i.e. behaviour for NaNs is identical to that of fma)
1867edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self_is_nan = self._isnan()
1868edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other_is_nan = other._isnan()
1869edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        modulo_is_nan = modulo._isnan()
1870edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self_is_nan or other_is_nan or modulo_is_nan:
1871edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self_is_nan == 2:
1872edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation, 'sNaN',
1873edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        self)
1874edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if other_is_nan == 2:
1875edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation, 'sNaN',
1876edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        other)
1877edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if modulo_is_nan == 2:
1878edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation, 'sNaN',
1879edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        modulo)
1880edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self_is_nan:
1881edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return self._fix_nan(context)
1882edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if other_is_nan:
1883edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return other._fix_nan(context)
1884edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return modulo._fix_nan(context)
1885edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1886edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # check inputs: we apply same restrictions as Python's pow()
1887edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not (self._isinteger() and
1888edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                other._isinteger() and
1889edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                modulo._isinteger()):
1890edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation,
1891edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'pow() 3rd argument not allowed '
1892edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'unless all arguments are integers')
1893edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other < 0:
1894edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation,
1895edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'pow() 2nd argument cannot be '
1896edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'negative when 3rd argument specified')
1897edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not modulo:
1898edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation,
1899edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'pow() 3rd argument cannot be 0')
1900edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1901edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # additional restriction for decimal: the modulus must be less
1902edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # than 10**prec in absolute value
1903edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if modulo.adjusted() >= context.prec:
1904edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation,
1905edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'insufficient precision: pow() 3rd '
1906edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'argument must not have more than '
1907edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'precision digits')
1908edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1909edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # define 0**0 == NaN, for consistency with two-argument pow
1910edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # (even though it hurts!)
1911edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not other and not self:
1912edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation,
1913edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'at least one of pow() 1st argument '
1914edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'and 2nd argument must be nonzero ;'
1915edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        '0**0 is not defined')
1916edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1917edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # compute sign of result
1918edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other._iseven():
1919edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            sign = 0
1920edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
1921edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            sign = self._sign
1922edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1923edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # convert modulo to a Python integer, and self and other to
1924edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Decimal integers (i.e. force their exponents to be >= 0)
1925edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        modulo = abs(int(modulo))
1926edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        base = _WorkRep(self.to_integral_value())
1927edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        exponent = _WorkRep(other.to_integral_value())
1928edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1929edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # compute result using integer pow()
1930edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        base = (base.int % modulo * pow(10, base.exp, modulo)) % modulo
1931edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        for i in xrange(exponent.exp):
1932edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            base = pow(base, 10, modulo)
1933edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        base = pow(base, exponent.int, modulo)
1934edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1935edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _dec_from_triple(sign, str(base), 0)
1936edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1937edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _power_exact(self, other, p):
1938edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Attempt to compute self**other exactly.
1939edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1940edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Given Decimals self and other and an integer p, attempt to
1941edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        compute an exact result for the power self**other, with p
1942edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        digits of precision.  Return None if self**other is not
1943edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        exactly representable in p digits.
1944edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1945edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Assumes that elimination of special cases has already been
1946edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        performed: self and other must both be nonspecial; self must
1947edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        be positive and not numerically equal to 1; other must be
1948edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        nonzero.  For efficiency, other._exp should not be too large,
1949edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        so that 10**abs(other._exp) is a feasible calculation."""
1950edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1951edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # In the comments below, we write x for the value of self and y for the
1952edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # value of other.  Write x = xc*10**xe and abs(y) = yc*10**ye, with xc
1953edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # and yc positive integers not divisible by 10.
1954edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1955edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # The main purpose of this method is to identify the *failure*
1956edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # of x**y to be exactly representable with as little effort as
1957edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # possible.  So we look for cheap and easy tests that
1958edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # eliminate the possibility of x**y being exact.  Only if all
1959edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # these tests are passed do we go on to actually compute x**y.
1960edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1961edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Here's the main idea.  Express y as a rational number m/n, with m and
1962edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # n relatively prime and n>0.  Then for x**y to be exactly
1963edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # representable (at *any* precision), xc must be the nth power of a
1964edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # positive integer and xe must be divisible by n.  If y is negative
1965edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # then additionally xc must be a power of either 2 or 5, hence a power
1966edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # of 2**n or 5**n.
1967edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        #
1968edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # There's a limit to how small |y| can be: if y=m/n as above
1969edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # then:
1970edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        #
1971edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        #  (1) if xc != 1 then for the result to be representable we
1972edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        #      need xc**(1/n) >= 2, and hence also xc**|y| >= 2.  So
1973edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        #      if |y| <= 1/nbits(xc) then xc < 2**nbits(xc) <=
1974edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        #      2**(1/|y|), hence xc**|y| < 2 and the result is not
1975edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        #      representable.
1976edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        #
1977edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        #  (2) if xe != 0, |xe|*(1/n) >= 1, so |xe|*|y| >= 1.  Hence if
1978edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        #      |y| < 1/|xe| then the result is not representable.
1979edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        #
1980edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Note that since x is not equal to 1, at least one of (1) and
1981edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # (2) must apply.  Now |y| < 1/nbits(xc) iff |yc|*nbits(xc) <
1982edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # 10**-ye iff len(str(|yc|*nbits(xc)) <= -ye.
1983edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        #
1984edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # There's also a limit to how large y can be, at least if it's
1985edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # positive: the normalized result will have coefficient xc**y,
1986edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # so if it's representable then xc**y < 10**p, and y <
1987edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # p/log10(xc).  Hence if y*log10(xc) >= p then the result is
1988edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # not exactly representable.
1989edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1990edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # if len(str(abs(yc*xe)) <= -ye then abs(yc*xe) < 10**-ye,
1991edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # so |y| < 1/xe and the result is not representable.
1992edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Similarly, len(str(abs(yc)*xc_bits)) <= -ye implies |y|
1993edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # < 1/nbits(xc).
1994edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
1995edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        x = _WorkRep(self)
1996edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        xc, xe = x.int, x.exp
1997edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        while xc % 10 == 0:
1998edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            xc //= 10
1999edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            xe += 1
2000edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2001edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        y = _WorkRep(other)
2002edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        yc, ye = y.int, y.exp
2003edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        while yc % 10 == 0:
2004edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            yc //= 10
2005edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ye += 1
2006edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2007edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # case where xc == 1: result is 10**(xe*y), with xe*y
2008edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # required to be an integer
2009edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if xc == 1:
2010edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            xe *= yc
2011edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # result is now 10**(xe * 10**ye);  xe * 10**ye must be integral
2012edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            while xe % 10 == 0:
2013edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                xe //= 10
2014edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                ye += 1
2015edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ye < 0:
2016edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return None
2017edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            exponent = xe * 10**ye
2018edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if y.sign == 1:
2019edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                exponent = -exponent
2020edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # if other is a nonnegative integer, use ideal exponent
2021edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if other._isinteger() and other._sign == 0:
2022edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                ideal_exponent = self._exp*int(other)
2023edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                zeros = min(exponent-ideal_exponent, p-1)
2024edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
2025edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                zeros = 0
2026edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _dec_from_triple(0, '1' + '0'*zeros, exponent-zeros)
2027edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2028edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # case where y is negative: xc must be either a power
2029edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # of 2 or a power of 5.
2030edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if y.sign == 1:
2031edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            last_digit = xc % 10
2032edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if last_digit in (2,4,6,8):
2033edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # quick test for power of 2
2034edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if xc & -xc != xc:
2035edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return None
2036edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # now xc is a power of 2; e is its exponent
2037edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                e = _nbits(xc)-1
2038edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2039edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # We now have:
2040edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                #
2041edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                #   x = 2**e * 10**xe, e > 0, and y < 0.
2042edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                #
2043edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # The exact result is:
2044edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                #
2045edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                #   x**y = 5**(-e*y) * 10**(e*y + xe*y)
2046edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                #
2047edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # provided that both e*y and xe*y are integers.  Note that if
2048edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # 5**(-e*y) >= 10**p, then the result can't be expressed
2049edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # exactly with p digits of precision.
2050edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                #
2051edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # Using the above, we can guard against large values of ye.
2052edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # 93/65 is an upper bound for log(10)/log(5), so if
2053edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                #
2054edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                #   ye >= len(str(93*p//65))
2055edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                #
2056edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # then
2057edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                #
2058edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                #   -e*y >= -y >= 10**ye > 93*p/65 > p*log(10)/log(5),
2059edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                #
2060edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # so 5**(-e*y) >= 10**p, and the coefficient of the result
2061edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # can't be expressed in p digits.
2062edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2063edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # emax >= largest e such that 5**e < 10**p.
2064edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                emax = p*93//65
2065edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if ye >= len(str(emax)):
2066edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return None
2067edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2068edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # Find -e*y and -xe*y; both must be integers
2069edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                e = _decimal_lshift_exact(e * yc, ye)
2070edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                xe = _decimal_lshift_exact(xe * yc, ye)
2071edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if e is None or xe is None:
2072edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return None
2073edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2074edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if e > emax:
2075edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return None
2076edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                xc = 5**e
2077edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2078edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            elif last_digit == 5:
2079edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # e >= log_5(xc) if xc is a power of 5; we have
2080edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # equality all the way up to xc=5**2658
2081edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                e = _nbits(xc)*28//65
2082edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                xc, remainder = divmod(5**e, xc)
2083edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if remainder:
2084edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return None
2085edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                while xc % 5 == 0:
2086edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    xc //= 5
2087edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    e -= 1
2088edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2089edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # Guard against large values of ye, using the same logic as in
2090edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # the 'xc is a power of 2' branch.  10/3 is an upper bound for
2091edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # log(10)/log(2).
2092edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                emax = p*10//3
2093edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if ye >= len(str(emax)):
2094edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return None
2095edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2096edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                e = _decimal_lshift_exact(e * yc, ye)
2097edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                xe = _decimal_lshift_exact(xe * yc, ye)
2098edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if e is None or xe is None:
2099edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return None
2100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if e > emax:
2102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return None
2103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                xc = 2**e
2104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
2105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return None
2106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if xc >= 10**p:
2108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return None
2109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            xe = -e-xe
2110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _dec_from_triple(0, str(xc), xe)
2111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # now y is positive; find m and n such that y = m/n
2113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ye >= 0:
2114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            m, n = yc*10**ye, 1
2115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
2116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if xe != 0 and len(str(abs(yc*xe))) <= -ye:
2117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return None
2118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            xc_bits = _nbits(xc)
2119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if xc != 1 and len(str(abs(yc)*xc_bits)) <= -ye:
2120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return None
2121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            m, n = yc, 10**(-ye)
2122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            while m % 2 == n % 2 == 0:
2123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                m //= 2
2124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                n //= 2
2125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            while m % 5 == n % 5 == 0:
2126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                m //= 5
2127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                n //= 5
2128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # compute nth root of xc*10**xe
2130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if n > 1:
2131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # if 1 < xc < 2**n then xc isn't an nth power
2132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if xc != 1 and xc_bits <= n:
2133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return None
2134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            xe, rem = divmod(xe, n)
2136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if rem != 0:
2137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return None
2138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # compute nth root of xc using Newton's method
2140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            a = 1L << -(-_nbits(xc)//n) # initial estimate
2141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            while True:
2142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                q, r = divmod(xc, a**(n-1))
2143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if a <= q:
2144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    break
2145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                else:
2146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    a = (a*(n-1) + q)//n
2147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if not (a == q and r == 0):
2148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return None
2149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            xc = a
2150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # now xc*10**xe is the nth root of the original xc*10**xe
2152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # compute mth power of xc*10**xe
2153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # if m > p*100//_log10_lb(xc) then m > p/log10(xc), hence xc**m >
2155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # 10**p and the result is not representable.
2156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if xc > 1 and m > p*100//_log10_lb(xc):
2157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return None
2158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        xc = xc**m
2159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        xe *= m
2160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if xc > 10**p:
2161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return None
2162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # by this point the result *is* exactly representable
2164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # adjust the exponent to get as close as possible to the ideal
2165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # exponent, if necessary
2166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        str_xc = str(xc)
2167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other._isinteger() and other._sign == 0:
2168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ideal_exponent = self._exp*int(other)
2169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            zeros = min(xe-ideal_exponent, p-len(str_xc))
2170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
2171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            zeros = 0
2172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _dec_from_triple(0, str_xc+'0'*zeros, xe-zeros)
2173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __pow__(self, other, modulo=None, context=None):
2175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return self ** other [ % modulo].
2176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        With two arguments, compute self**other.
2178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        With three arguments, compute (self**other) % modulo.  For the
2180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        three argument form, the following restrictions on the
2181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        arguments hold:
2182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep         - all three arguments must be integral
2184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep         - other must be nonnegative
2185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep         - either self or other (or both) must be nonzero
2186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep         - modulo must be nonzero and must have at most p digits,
2187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep           where p is the context precision.
2188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        If any of these restrictions is violated the InvalidOperation
2190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        flag is raised.
2191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The result of pow(self, other, modulo) is identical to the
2193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result that would be obtained by computing (self**other) %
2194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        modulo with unbounded precision, but is computed more
2195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        efficiently.  It is always exact.
2196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
2197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if modulo is not None:
2199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self._power_modulo(other, modulo, context)
2200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other)
2202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
2203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
2204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
2206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
2207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # either argument is a NaN => result is NaN
2209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._check_nans(other, context)
2210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
2211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
2212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # 0**0 = NaN (!), x**0 = 1 for nonzero x (including +/-Infinity)
2214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not other:
2215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if not self:
2216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation, '0 ** 0')
2217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
2218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _One
2219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # result has sign 1 iff self._sign is 1 and other is an odd integer
2221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result_sign = 0
2222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._sign == 1:
2223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if other._isinteger():
2224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if not other._iseven():
2225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    result_sign = 1
2226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
2227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # -ve**noninteger = NaN
2228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # (-0)**noninteger = 0**noninteger
2229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if self:
2230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return context._raise_error(InvalidOperation,
2231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        'x ** y with x negative and y not an integer')
2232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # negate self, without doing any unwanted rounding
2233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self = self.copy_negate()
2234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # 0**(+ve or Inf)= 0; 0**(-ve or -Inf) = Infinity
2236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self:
2237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if other._sign == 0:
2238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _dec_from_triple(result_sign, '0', 0)
2239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
2240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _SignedInfinity[result_sign]
2241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Inf**(+ve or Inf) = Inf; Inf**(-ve or -Inf) = 0
2243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity():
2244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if other._sign == 0:
2245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _SignedInfinity[result_sign]
2246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
2247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _dec_from_triple(result_sign, '0', 0)
2248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # 1**other = 1, but the choice of exponent and the flags
2250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # depend on the exponent of self, and on whether other is a
2251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # positive integer, a negative integer, or neither
2252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self == _One:
2253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if other._isinteger():
2254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # exp = max(self._exp*max(int(other), 0),
2255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # 1-context.prec) but evaluating int(other) directly
2256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # is dangerous until we know other is small (other
2257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # could be 1e999999999)
2258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if other._sign == 1:
2259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    multiplier = 0
2260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                elif other > context.prec:
2261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    multiplier = context.prec
2262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                else:
2263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    multiplier = int(other)
2264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                exp = self._exp * multiplier
2266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if exp < 1-context.prec:
2267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    exp = 1-context.prec
2268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    context._raise_error(Rounded)
2269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
2270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                context._raise_error(Inexact)
2271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                context._raise_error(Rounded)
2272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                exp = 1-context.prec
2273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _dec_from_triple(result_sign, '1'+'0'*-exp, exp)
2275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # compute adjusted exponent of self
2277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self_adj = self.adjusted()
2278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # self ** infinity is infinity if self > 1, 0 if self < 1
2280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # self ** -infinity is infinity if self < 1, 0 if self > 1
2281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other._isinfinity():
2282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if (other._sign == 0) == (self_adj < 0):
2283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _dec_from_triple(result_sign, '0', 0)
2284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
2285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _SignedInfinity[result_sign]
2286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # from here on, the result always goes through the call
2288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # to _fix at the end of this function.
2289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = None
2290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        exact = False
2291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # crude test to catch cases of extreme overflow/underflow.  If
2293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # log10(self)*other >= 10**bound and bound >= len(str(Emax))
2294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # then 10**bound >= 10**len(str(Emax)) >= Emax+1 and hence
2295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # self**other >= 10**(Emax+1), so overflow occurs.  The test
2296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # for underflow is similar.
2297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        bound = self._log10_exp_bound() + other.adjusted()
2298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if (self_adj >= 0) == (other._sign == 0):
2299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # self > 1 and other +ve, or self < 1 and other -ve
2300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # possibility of overflow
2301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if bound >= len(str(context.Emax)):
2302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                ans = _dec_from_triple(result_sign, '1', context.Emax+1)
2303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
2304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # self > 1 and other -ve, or self < 1 and other +ve
2305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # possibility of underflow to 0
2306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            Etiny = context.Etiny()
2307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if bound >= len(str(-Etiny)):
2308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                ans = _dec_from_triple(result_sign, '1', Etiny-1)
2309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # try for an exact result with precision +1
2311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans is None:
2312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._power_exact(other, context.prec + 1)
2313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ans is not None:
2314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if result_sign == 1:
2315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    ans = _dec_from_triple(1, ans._int, ans._exp)
2316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                exact = True
2317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # usual case: inexact result, x**y computed directly as exp(y*log(x))
2319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans is None:
2320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            p = context.prec
2321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            x = _WorkRep(self)
2322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            xc, xe = x.int, x.exp
2323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            y = _WorkRep(other)
2324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            yc, ye = y.int, y.exp
2325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if y.sign == 1:
2326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                yc = -yc
2327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # compute correctly rounded result:  start with precision +3,
2329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # then increase precision until result is unambiguously roundable
2330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            extra = 3
2331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            while True:
2332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                coeff, exp = _dpower(xc, xe, yc, ye, p+extra)
2333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if coeff % (5*10**(len(str(coeff))-p-1)):
2334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    break
2335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                extra += 3
2336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = _dec_from_triple(result_sign, str(coeff), exp)
2338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # unlike exp, ln and log10, the power function respects the
2340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # rounding mode; no need to switch to ROUND_HALF_EVEN here
2341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # There's a difficulty here when 'other' is not an integer and
2343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # the result is exact.  In this case, the specification
2344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # requires that the Inexact flag be raised (in spite of
2345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # exactness), but since the result is exact _fix won't do this
2346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # for us.  (Correspondingly, the Underflow signal should also
2347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # be raised for subnormal results.)  We can't directly raise
2348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # these signals either before or after calling _fix, since
2349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # that would violate the precedence for signals.  So we wrap
2350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # the ._fix call in a temporary context, and reraise
2351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # afterwards.
2352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if exact and not other._isinteger():
2353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # pad with zeros up to length context.prec+1 if necessary; this
2354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # ensures that the Rounded signal will be raised.
2355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if len(ans._int) <= context.prec:
2356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                expdiff = context.prec + 1 - len(ans._int)
2357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                ans = _dec_from_triple(ans._sign, ans._int+'0'*expdiff,
2358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                       ans._exp-expdiff)
2359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # create a copy of the current context, with cleared flags/traps
2361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            newcontext = context.copy()
2362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            newcontext.clear_flags()
2363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            for exception in _signals:
2364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                newcontext.traps[exception] = 0
2365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # round in the new context
2367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = ans._fix(newcontext)
2368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # raise Inexact, and if necessary, Underflow
2370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            newcontext._raise_error(Inexact)
2371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if newcontext.flags[Subnormal]:
2372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                newcontext._raise_error(Underflow)
2373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # propagate signals to the original context; _fix could
2375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # have raised any of Overflow, Underflow, Subnormal,
2376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # Inexact, Rounded, Clamped.  Overflow needs the correct
2377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # arguments.  Note that the order of the exceptions is
2378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # important here.
2379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if newcontext.flags[Overflow]:
2380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                context._raise_error(Overflow, 'above Emax', ans._sign)
2381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            for exception in Underflow, Subnormal, Inexact, Rounded, Clamped:
2382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if newcontext.flags[exception]:
2383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    context._raise_error(exception)
2384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
2386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = ans._fix(context)
2387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans
2389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __rpow__(self, other, context=None):
2391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Swaps self/other and returns __pow__."""
2392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other)
2393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other is NotImplemented:
2394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return other
2395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return other.__pow__(self, context=context)
2396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def normalize(self, context=None):
2398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
2399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
2401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
2402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special:
2404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._check_nans(context=context)
2405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ans:
2406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return ans
2407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        dup = self._fix(context)
2409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if dup._isinfinity():
2410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return dup
2411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not dup:
2413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _dec_from_triple(dup._sign, '0', 0)
2414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        exp_max = [context.Emax, context.Etop()][context._clamp]
2415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        end = len(dup._int)
2416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        exp = dup._exp
2417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        while dup._int[end-1] == '0' and exp < exp_max:
2418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            exp += 1
2419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            end -= 1
2420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _dec_from_triple(dup._sign, dup._int[:end], exp)
2421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def quantize(self, exp, rounding=None, context=None, watchexp=True):
2423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Quantize self so its exponent is the same as that of exp.
2424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Similar to self._rescale(exp._exp) but with error checking.
2426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
2427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        exp = _convert_other(exp, raiseit=True)
2428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
2430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
2431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if rounding is None:
2432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            rounding = context.rounding
2433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special or exp._is_special:
2435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._check_nans(exp, context)
2436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ans:
2437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return ans
2438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if exp._isinfinity() or self._isinfinity():
2440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if exp._isinfinity() and self._isinfinity():
2441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return Decimal(self)  # if both are inf, it is OK
2442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return context._raise_error(InvalidOperation,
2443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'quantize with one INF')
2444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # if we're not watching exponents, do a simple rescale
2446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not watchexp:
2447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._rescale(exp._exp, rounding)
2448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # raise Inexact and Rounded where appropriate
2449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ans._exp > self._exp:
2450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                context._raise_error(Rounded)
2451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if ans != self:
2452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    context._raise_error(Inexact)
2453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
2454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # exp._exp should be between Etiny and Emax
2456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not (context.Etiny() <= exp._exp <= context.Emax):
2457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation,
2458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                   'target exponent out of bounds in quantize')
2459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self:
2461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = _dec_from_triple(self._sign, '0', exp._exp)
2462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans._fix(context)
2463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self_adjusted = self.adjusted()
2465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self_adjusted > context.Emax:
2466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation,
2467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'exponent of quantize result too large for current context')
2468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self_adjusted - exp._exp + 1 > context.prec:
2469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation,
2470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'quantize result has too many digits for current context')
2471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._rescale(exp._exp, rounding)
2473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans.adjusted() > context.Emax:
2474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation,
2475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'exponent of quantize result too large for current context')
2476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if len(ans._int) > context.prec:
2477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation,
2478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'quantize result has too many digits for current context')
2479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # raise appropriate flags
2481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans and ans.adjusted() < context.Emin:
2482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context._raise_error(Subnormal)
2483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans._exp > self._exp:
2484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ans != self:
2485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                context._raise_error(Inexact)
2486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context._raise_error(Rounded)
2487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # call to fix takes care of any necessary folddown, and
2489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # signals Clamped if necessary
2490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = ans._fix(context)
2491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans
2492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def same_quantum(self, other):
2494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if self and other have the same exponent; otherwise
2495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return False.
2496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        If either operand is a special value, the following rules are used:
2498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep           * return True if both operands are infinities
2499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep           * return True if both operands are NaNs
2500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep           * otherwise, return False.
2501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
2502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
2503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special or other._is_special:
2504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return (self.is_nan() and other.is_nan() or
2505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    self.is_infinite() and other.is_infinite())
2506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self._exp == other._exp
2507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _rescale(self, exp, rounding):
2509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Rescale self so that the exponent is exp, either by padding with zeros
2510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        or by truncating digits, using the given rounding mode.
2511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Specials are returned without change.  This operation is
2513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        quiet: it raises no flags, and uses no information from the
2514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context.
2515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        exp = exp to scale to (an integer)
2517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        rounding = rounding mode
2518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
2519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special:
2520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return Decimal(self)
2521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self:
2522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _dec_from_triple(self._sign, '0', exp)
2523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._exp >= exp:
2525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # pad answer with zeros if necessary
2526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _dec_from_triple(self._sign,
2527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        self._int + '0'*(self._exp - exp), exp)
2528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # too many digits; round and lose data.  If self.adjusted() <
2530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # exp-1, replace self by 10**(exp-1) before rounding
2531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        digits = len(self._int) + self._exp - exp
2532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if digits < 0:
2533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self = _dec_from_triple(self._sign, '1', exp-1)
2534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            digits = 0
2535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        this_function = self._pick_rounding_function[rounding]
2536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        changed = this_function(self, digits)
2537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        coeff = self._int[:digits] or '0'
2538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if changed == 1:
2539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            coeff = str(int(coeff)+1)
2540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _dec_from_triple(self._sign, coeff, exp)
2541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _round(self, places, rounding):
2543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Round a nonzero, nonspecial Decimal to a fixed number of
2544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        significant figures, using the given rounding mode.
2545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Infinities, NaNs and zeros are returned unaltered.
2547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        This operation is quiet: it raises no flags, and uses no
2549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        information from the context.
2550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
2552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if places <= 0:
2553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            raise ValueError("argument should be at least 1 in _round")
2554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special or not self:
2555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return Decimal(self)
2556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._rescale(self.adjusted()+1-places, rounding)
2557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # it can happen that the rescale alters the adjusted exponent;
2558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # for example when rounding 99.97 to 3 significant figures.
2559edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # When this happens we end up with an extra 0 at the end of
2560edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # the number; a second rescale fixes this.
2561edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans.adjusted() != self.adjusted():
2562edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = ans._rescale(ans.adjusted()+1-places, rounding)
2563edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans
2564edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2565edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def to_integral_exact(self, rounding=None, context=None):
2566edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Rounds to a nearby integer.
2567edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2568edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        If no rounding mode is specified, take the rounding mode from
2569edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        the context.  This method raises the Rounded and Inexact flags
2570edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        when appropriate.
2571edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2572edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        See also: to_integral_value, which does exactly the same as
2573edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        this method except that it doesn't raise Inexact or Rounded.
2574edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
2575edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special:
2576edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._check_nans(context=context)
2577edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ans:
2578edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return ans
2579edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return Decimal(self)
2580edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._exp >= 0:
2581edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return Decimal(self)
2582edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self:
2583edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _dec_from_triple(self._sign, '0', 0)
2584edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
2585edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
2586edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if rounding is None:
2587edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            rounding = context.rounding
2588edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._rescale(0, rounding)
2589edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans != self:
2590edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context._raise_error(Inexact)
2591edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context._raise_error(Rounded)
2592edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans
2593edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2594edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def to_integral_value(self, rounding=None, context=None):
2595edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Rounds to the nearest integer, without raising inexact, rounded."""
2596edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
2597edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
2598edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if rounding is None:
2599edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            rounding = context.rounding
2600edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special:
2601edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._check_nans(context=context)
2602edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ans:
2603edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return ans
2604edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return Decimal(self)
2605edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._exp >= 0:
2606edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return Decimal(self)
2607edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
2608edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self._rescale(0, rounding)
2609edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2610edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # the method name changed, but we provide also the old one, for compatibility
2611edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    to_integral = to_integral_value
2612edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2613edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def sqrt(self, context=None):
2614edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return the square root of self."""
2615edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
2616edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
2617edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2618edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special:
2619edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self._check_nans(context=context)
2620edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if ans:
2621edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return ans
2622edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2623edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self._isinfinity() and self._sign == 0:
2624edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return Decimal(self)
2625edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2626edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self:
2627edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # exponent = self._exp // 2.  sqrt(-0) = -0
2628edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = _dec_from_triple(self._sign, '0', self._exp // 2)
2629edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans._fix(context)
2630edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2631edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._sign == 1:
2632edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
2633edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2634edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # At this point self represents a positive number.  Let p be
2635edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # the desired precision and express self in the form c*100**e
2636edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # with c a positive real number and e an integer, c and e
2637edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # being chosen so that 100**(p-1) <= c < 100**p.  Then the
2638edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # (exact) square root of self is sqrt(c)*10**e, and 10**(p-1)
2639edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # <= sqrt(c) < 10**p, so the closest representable Decimal at
2640edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # precision p is n*10**e where n = round_half_even(sqrt(c)),
2641edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # the closest integer to sqrt(c) with the even integer chosen
2642edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # in the case of a tie.
2643edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        #
2644edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # To ensure correct rounding in all cases, we use the
2645edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # following trick: we compute the square root to an extra
2646edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # place (precision p+1 instead of precision p), rounding down.
2647edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Then, if the result is inexact and its last digit is 0 or 5,
2648edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # we increase the last digit to 1 or 6 respectively; if it's
2649edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # exact we leave the last digit alone.  Now the final round to
2650edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # p places (or fewer in the case of underflow) will round
2651edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # correctly and raise the appropriate flags.
2652edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2653edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # use an extra digit of precision
2654edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        prec = context.prec+1
2655edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2656edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # write argument in the form c*100**e where e = self._exp//2
2657edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # is the 'ideal' exponent, to be used if the square root is
2658edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # exactly representable.  l is the number of 'digits' of c in
2659edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # base 100, so that 100**(l-1) <= c < 100**l.
2660edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        op = _WorkRep(self)
2661edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        e = op.exp >> 1
2662edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if op.exp & 1:
2663edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            c = op.int * 10
2664edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            l = (len(self._int) >> 1) + 1
2665edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
2666edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            c = op.int
2667edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            l = len(self._int)+1 >> 1
2668edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2669edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # rescale so that c has exactly prec base 100 'digits'
2670edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        shift = prec-l
2671edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if shift >= 0:
2672edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            c *= 100**shift
2673edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            exact = True
2674edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
2675edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            c, remainder = divmod(c, 100**-shift)
2676edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            exact = not remainder
2677edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        e -= shift
2678edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2679edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # find n = floor(sqrt(c)) using Newton's method
2680edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        n = 10**prec
2681edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        while True:
2682edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            q = c//n
2683edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if n <= q:
2684edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                break
2685edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
2686edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                n = n + q >> 1
2687edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        exact = exact and n*n == c
2688edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2689edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if exact:
2690edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # result is exact; rescale to use ideal exponent e
2691edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if shift >= 0:
2692edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # assert n % 10**shift == 0
2693edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                n //= 10**shift
2694edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
2695edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                n *= 10**-shift
2696edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            e += shift
2697edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
2698edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # result is not exact; fix last digit as described above
2699edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if n % 5 == 0:
2700edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                n += 1
2701edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2702edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = _dec_from_triple(0, str(n), e)
2703edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2704edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # round, and fit to current context
2705edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context = context._shallow_copy()
2706edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        rounding = context._set_rounding(ROUND_HALF_EVEN)
2707edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = ans._fix(context)
2708edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context.rounding = rounding
2709edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2710edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans
2711edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2712edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def max(self, other, context=None):
2713edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the larger value.
2714edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2715edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Like max(self, other) except if one is not a number, returns
2716edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        NaN (and signals if one is sNaN).  Also rounds.
2717edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
2718edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
2719edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2720edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
2721edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
2722edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2723edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special or other._is_special:
2724edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # If one operand is a quiet NaN and the other is number, then the
2725edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # number is always returned
2726edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            sn = self._isnan()
2727edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            on = other._isnan()
2728edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if sn or on:
2729edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if on == 1 and sn == 0:
2730edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return self._fix(context)
2731edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if sn == 1 and on == 0:
2732edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return other._fix(context)
2733edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return self._check_nans(other, context)
2734edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2735edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        c = self._cmp(other)
2736edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if c == 0:
2737edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # If both operands are finite and equal in numerical value
2738edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # then an ordering is applied:
2739edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            #
2740edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # If the signs differ then max returns the operand with the
2741edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # positive sign and min returns the operand with the negative sign
2742edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            #
2743edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # If the signs are the same then the exponent is used to select
2744edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # the result.  This is exactly the ordering used in compare_total.
2745edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            c = self.compare_total(other)
2746edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2747edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if c == -1:
2748edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = other
2749edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
2750edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self
2751edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2752edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans._fix(context)
2753edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2754edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def min(self, other, context=None):
2755edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the smaller value.
2756edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2757edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Like min(self, other) except if one is not a number, returns
2758edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        NaN (and signals if one is sNaN).  Also rounds.
2759edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
2760edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
2761edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2762edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
2763edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
2764edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2765edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special or other._is_special:
2766edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # If one operand is a quiet NaN and the other is number, then the
2767edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # number is always returned
2768edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            sn = self._isnan()
2769edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            on = other._isnan()
2770edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if sn or on:
2771edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if on == 1 and sn == 0:
2772edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return self._fix(context)
2773edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if sn == 1 and on == 0:
2774edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return other._fix(context)
2775edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return self._check_nans(other, context)
2776edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2777edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        c = self._cmp(other)
2778edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if c == 0:
2779edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            c = self.compare_total(other)
2780edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2781edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if c == -1:
2782edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self
2783edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
2784edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = other
2785edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2786edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans._fix(context)
2787edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2788edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _isinteger(self):
2789edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns whether self is an integer"""
2790edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special:
2791edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return False
2792edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._exp >= 0:
2793edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return True
2794edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        rest = self._int[self._exp:]
2795edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return rest == '0'*len(rest)
2796edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2797edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _iseven(self):
2798edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns True if self is even.  Assumes self is an integer."""
2799edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self or self._exp > 0:
2800edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return True
2801edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self._int[-1+self._exp] in '02468'
2802edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2803edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def adjusted(self):
2804edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return the adjusted exponent of self"""
2805edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        try:
2806edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self._exp + len(self._int) - 1
2807edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # If NaN or Infinity, self._exp is string
2808edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        except TypeError:
2809edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return 0
2810edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2811edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def canonical(self, context=None):
2812edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the same Decimal object.
2813edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2814edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        As we do not have different encodings for the same number, the
2815edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        received object already is in its canonical form.
2816edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
2817edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self
2818edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2819edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def compare_signal(self, other, context=None):
2820edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Compares self to the other operand numerically.
2821edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2822edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        It's pretty much like compare(), but all NaNs signal, with signaling
2823edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        NaNs taking precedence over quiet NaNs.
2824edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
2825edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit = True)
2826edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._compare_check_nans(other, context)
2827edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
2828edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
2829edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self.compare(other, context=context)
2830edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2831edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def compare_total(self, other):
2832edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Compares self to other using the abstract representations.
2833edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2834edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        This is not like the standard compare, which use their numerical
2835edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        value. Note that a total ordering is defined for all possible abstract
2836edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        representations.
2837edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
2838edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
2839edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2840edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # if one is negative and the other is positive, it's easy
2841edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._sign and not other._sign:
2842edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _NegativeOne
2843edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self._sign and other._sign:
2844edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _One
2845edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        sign = self._sign
2846edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2847edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # let's handle both NaN types
2848edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self_nan = self._isnan()
2849edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other_nan = other._isnan()
2850edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self_nan or other_nan:
2851edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self_nan == other_nan:
2852edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # compare payloads as though they're integers
2853edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self_key = len(self._int), self._int
2854edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                other_key = len(other._int), other._int
2855edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if self_key < other_key:
2856edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    if sign:
2857edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        return _One
2858edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    else:
2859edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        return _NegativeOne
2860edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if self_key > other_key:
2861edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    if sign:
2862edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        return _NegativeOne
2863edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    else:
2864edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        return _One
2865edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _Zero
2866edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2867edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if sign:
2868edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if self_nan == 1:
2869edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return _NegativeOne
2870edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if other_nan == 1:
2871edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return _One
2872edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if self_nan == 2:
2873edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return _NegativeOne
2874edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if other_nan == 2:
2875edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return _One
2876edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
2877edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if self_nan == 1:
2878edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return _One
2879edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if other_nan == 1:
2880edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return _NegativeOne
2881edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if self_nan == 2:
2882edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return _One
2883edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if other_nan == 2:
2884edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return _NegativeOne
2885edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2886edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self < other:
2887edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _NegativeOne
2888edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self > other:
2889edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _One
2890edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2891edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._exp < other._exp:
2892edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if sign:
2893edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _One
2894edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
2895edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _NegativeOne
2896edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._exp > other._exp:
2897edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if sign:
2898edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _NegativeOne
2899edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
2900edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return _One
2901edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _Zero
2902edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2903edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2904edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def compare_total_mag(self, other):
2905edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Compares self to other using abstract repr., ignoring sign.
2906edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2907edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Like compare_total, but with operand's sign ignored and assumed to be 0.
2908edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
2909edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
2910edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2911edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        s = self.copy_abs()
2912edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        o = other.copy_abs()
2913edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return s.compare_total(o)
2914edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2915edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def copy_abs(self):
2916edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns a copy with the sign set to 0. """
2917edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _dec_from_triple(0, self._int, self._exp, self._is_special)
2918edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2919edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def copy_negate(self):
2920edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns a copy with the sign inverted."""
2921edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._sign:
2922edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _dec_from_triple(0, self._int, self._exp, self._is_special)
2923edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
2924edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _dec_from_triple(1, self._int, self._exp, self._is_special)
2925edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2926edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def copy_sign(self, other):
2927edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns self with the sign of other."""
2928edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
2929edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _dec_from_triple(other._sign, self._int,
2930edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                self._exp, self._is_special)
2931edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2932edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def exp(self, context=None):
2933edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns e ** self."""
2934edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2935edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
2936edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
2937edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2938edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # exp(NaN) = NaN
2939edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._check_nans(context=context)
2940edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
2941edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
2942edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2943edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # exp(-Infinity) = 0
2944edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity() == -1:
2945edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _Zero
2946edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2947edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # exp(0) = 1
2948edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self:
2949edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _One
2950edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2951edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # exp(Infinity) = Infinity
2952edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity() == 1:
2953edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return Decimal(self)
2954edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2955edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # the result is now guaranteed to be inexact (the true
2956edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # mathematical result is transcendental). There's no need to
2957edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # raise Rounded and Inexact here---they'll always be raised as
2958edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # a result of the call to _fix.
2959edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        p = context.prec
2960edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        adj = self.adjusted()
2961edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2962edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # we only need to do any computation for quite a small range
2963edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # of adjusted exponents---for example, -29 <= adj <= 10 for
2964edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # the default context.  For smaller exponent the result is
2965edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # indistinguishable from 1 at the given precision, while for
2966edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # larger exponent the result either overflows or underflows.
2967edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._sign == 0 and adj > len(str((context.Emax+1)*3)):
2968edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # overflow
2969edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = _dec_from_triple(0, '1', context.Emax+1)
2970edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif self._sign == 1 and adj > len(str((-context.Etiny()+1)*3)):
2971edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # underflow to 0
2972edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = _dec_from_triple(0, '1', context.Etiny()-1)
2973edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif self._sign == 0 and adj < -p:
2974edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # p+1 digits; final round will raise correct flags
2975edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = _dec_from_triple(0, '1' + '0'*(p-1) + '1', -p)
2976edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif self._sign == 1 and adj < -p-1:
2977edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # p+1 digits; final round will raise correct flags
2978edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = _dec_from_triple(0, '9'*(p+1), -p-1)
2979edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # general case
2980edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
2981edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            op = _WorkRep(self)
2982edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            c, e = op.int, op.exp
2983edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if op.sign == 1:
2984edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                c = -c
2985edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2986edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # compute correctly rounded result: increase precision by
2987edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # 3 digits at a time until we get an unambiguously
2988edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # roundable result
2989edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            extra = 3
2990edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            while True:
2991edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                coeff, exp = _dexp(c, e, p+extra)
2992edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if coeff % (5*10**(len(str(coeff))-p-1)):
2993edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    break
2994edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                extra += 3
2995edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2996edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = _dec_from_triple(0, str(coeff), exp)
2997edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
2998edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # at this stage, ans should round correctly with *any*
2999edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # rounding mode, not just with ROUND_HALF_EVEN
3000edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context = context._shallow_copy()
3001edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        rounding = context._set_rounding(ROUND_HALF_EVEN)
3002edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = ans._fix(context)
3003edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context.rounding = rounding
3004edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3005edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans
3006edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3007edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_canonical(self):
3008edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if self is canonical; otherwise return False.
3009edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3010edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Currently, the encoding of a Decimal instance is always
3011edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        canonical, so this method returns True for any Decimal.
3012edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
3013edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return True
3014edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3015edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_finite(self):
3016edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if self is finite; otherwise return False.
3017edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3018edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        A Decimal instance is considered finite if it is neither
3019edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        infinite nor a NaN.
3020edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
3021edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return not self._is_special
3022edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3023edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_infinite(self):
3024edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if self is infinite; otherwise return False."""
3025edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self._exp == 'F'
3026edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3027edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_nan(self):
3028edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if self is a qNaN or sNaN; otherwise return False."""
3029edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self._exp in ('n', 'N')
3030edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3031edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_normal(self, context=None):
3032edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if self is a normal number; otherwise return False."""
3033edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special or not self:
3034edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return False
3035edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3036edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3037edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return context.Emin <= self.adjusted()
3038edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3039edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_qnan(self):
3040edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if self is a quiet NaN; otherwise return False."""
3041edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self._exp == 'n'
3042edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3043edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_signed(self):
3044edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if self is negative; otherwise return False."""
3045edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self._sign == 1
3046edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3047edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_snan(self):
3048edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if self is a signaling NaN; otherwise return False."""
3049edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self._exp == 'N'
3050edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3051edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_subnormal(self, context=None):
3052edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if self is subnormal; otherwise return False."""
3053edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special or not self:
3054edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return False
3055edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3056edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3057edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self.adjusted() < context.Emin
3058edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3059edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_zero(self):
3060edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if self is a zero; otherwise return False."""
3061edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return not self._is_special and self._int == '0'
3062edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3063edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _ln_exp_bound(self):
3064edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Compute a lower bound for the adjusted exponent of self.ln().
3065edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        In other words, compute r such that self.ln() >= 10**r.  Assumes
3066edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        that self is finite and positive and that self != 1.
3067edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
3068edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3069edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # for 0.1 <= x <= 10 we use the inequalities 1-1/x <= ln(x) <= x-1
3070edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        adj = self._exp + len(self._int) - 1
3071edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if adj >= 1:
3072edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # argument >= 10; we use 23/10 = 2.3 as a lower bound for ln(10)
3073edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return len(str(adj*23//10)) - 1
3074edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if adj <= -2:
3075edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # argument <= 0.1
3076edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return len(str((-1-adj)*23//10)) - 1
3077edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        op = _WorkRep(self)
3078edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        c, e = op.int, op.exp
3079edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if adj == 0:
3080edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # 1 < self < 10
3081edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            num = str(c-10**-e)
3082edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            den = str(c)
3083edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return len(num) - len(den) - (num < den)
3084edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # adj == -1, 0.1 <= self < 1
3085edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return e + len(str(10**-e - c)) - 1
3086edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3087edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3088edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def ln(self, context=None):
3089edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the natural (base e) logarithm of self."""
3090edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3091edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3092edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3093edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3094edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # ln(NaN) = NaN
3095edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._check_nans(context=context)
3096edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
3097edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
3098edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3099edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # ln(0.0) == -Infinity
3100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self:
3101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _NegativeInfinity
3102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # ln(Infinity) = Infinity
3104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity() == 1:
3105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _Infinity
3106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # ln(1.0) == 0.0
3108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self == _One:
3109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _Zero
3110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # ln(negative) raises InvalidOperation
3112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._sign == 1:
3113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation,
3114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'ln of a negative value')
3115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # result is irrational, so necessarily inexact
3117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        op = _WorkRep(self)
3118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        c, e = op.int, op.exp
3119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        p = context.prec
3120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # correctly rounded result: repeatedly increase precision by 3
3122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # until we get an unambiguously roundable result
3123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        places = p - self._ln_exp_bound() + 2 # at least p+3 places
3124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        while True:
3125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            coeff = _dlog(c, e, places)
3126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # assert len(str(abs(coeff)))-p >= 1
3127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if coeff % (5*10**(len(str(abs(coeff)))-p-1)):
3128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                break
3129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            places += 3
3130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places)
3131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context = context._shallow_copy()
3133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        rounding = context._set_rounding(ROUND_HALF_EVEN)
3134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = ans._fix(context)
3135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context.rounding = rounding
3136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans
3137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _log10_exp_bound(self):
3139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Compute a lower bound for the adjusted exponent of self.log10().
3140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        In other words, find r such that self.log10() >= 10**r.
3141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Assumes that self is finite and positive and that self != 1.
3142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
3143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # For x >= 10 or x < 0.1 we only need a bound on the integer
3145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # part of log10(self), and this comes directly from the
3146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # exponent of x.  For 0.1 <= x <= 10 we use the inequalities
3147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # 1-1/x <= log(x) <= x-1. If x > 1 we have |log10(x)| >
3148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # (1-1/x)/2.31 > 0.  If x < 1 then |log10(x)| > (1-x)/2.31 > 0
3149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        adj = self._exp + len(self._int) - 1
3151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if adj >= 1:
3152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # self >= 10
3153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return len(str(adj))-1
3154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if adj <= -2:
3155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # self < 0.1
3156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return len(str(-1-adj))-1
3157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        op = _WorkRep(self)
3158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        c, e = op.int, op.exp
3159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if adj == 0:
3160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # 1 < self < 10
3161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            num = str(c-10**-e)
3162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            den = str(231*c)
3163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return len(num) - len(den) - (num < den) + 2
3164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # adj == -1, 0.1 <= self < 1
3165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        num = str(10**-e-c)
3166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return len(num) + e - (num < "231") - 1
3167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def log10(self, context=None):
3169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the base 10 logarithm of self."""
3170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # log10(NaN) = NaN
3175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._check_nans(context=context)
3176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
3177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
3178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # log10(0.0) == -Infinity
3180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self:
3181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _NegativeInfinity
3182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # log10(Infinity) = Infinity
3184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity() == 1:
3185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _Infinity
3186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # log10(negative or -Infinity) raises InvalidOperation
3188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._sign == 1:
3189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation,
3190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                        'log10 of a negative value')
3191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # log10(10**n) = n
3193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._int[0] == '1' and self._int[1:] == '0'*(len(self._int) - 1):
3194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # answer may need rounding
3195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = Decimal(self._exp + len(self._int) - 1)
3196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
3197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # result is irrational, so necessarily inexact
3198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            op = _WorkRep(self)
3199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            c, e = op.int, op.exp
3200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            p = context.prec
3201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # correctly rounded result: repeatedly increase precision
3203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # until result is unambiguously roundable
3204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            places = p-self._log10_exp_bound()+2
3205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            while True:
3206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                coeff = _dlog10(c, e, places)
3207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # assert len(str(abs(coeff)))-p >= 1
3208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if coeff % (5*10**(len(str(abs(coeff)))-p-1)):
3209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    break
3210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                places += 3
3211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places)
3212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context = context._shallow_copy()
3214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        rounding = context._set_rounding(ROUND_HALF_EVEN)
3215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = ans._fix(context)
3216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context.rounding = rounding
3217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans
3218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def logb(self, context=None):
3220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """ Returns the exponent of the magnitude of self's MSD.
3221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The result is the integer which is the exponent of the magnitude
3223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        of the most significant digit of self (as though it were truncated
3224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        to a single digit while maintaining the value of that digit and
3225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        without limiting the resulting exponent).
3226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
3227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # logb(NaN) = NaN
3228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._check_nans(context=context)
3229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
3230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
3231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # logb(+/-Inf) = +Inf
3236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity():
3237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _Infinity
3238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # logb(0) = -Inf, DivisionByZero
3240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self:
3241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(DivisionByZero, 'logb(0)', 1)
3242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # otherwise, simply return the adjusted exponent of self, as a
3244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Decimal.  Note that no attempt is made to fit the result
3245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # into the current context.
3246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = Decimal(self.adjusted())
3247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans._fix(context)
3248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _islogical(self):
3250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if self is a logical operand.
3251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        For being logical, it must be a finite number with a sign of 0,
3253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        an exponent of 0, and a coefficient whose digits must all be
3254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        either 0 or 1.
3255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
3256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._sign != 0 or self._exp != 0:
3257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return False
3258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        for dig in self._int:
3259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if dig not in '01':
3260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return False
3261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return True
3262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _fill_logical(self, context, opa, opb):
3264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        dif = context.prec - len(opa)
3265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if dif > 0:
3266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            opa = '0'*dif + opa
3267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif dif < 0:
3268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            opa = opa[-context.prec:]
3269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        dif = context.prec - len(opb)
3270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if dif > 0:
3271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            opb = '0'*dif + opb
3272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif dif < 0:
3273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            opb = opb[-context.prec:]
3274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return opa, opb
3275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def logical_and(self, other, context=None):
3277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Applies an 'and' operation between self and other's digits."""
3278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
3282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self._islogical() or not other._islogical():
3284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation)
3285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # fill to context.prec
3287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (opa, opb) = self._fill_logical(context, self._int, other._int)
3288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # make the operation, and clean starting zeroes
3290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = "".join([str(int(a)&int(b)) for a,b in zip(opa,opb)])
3291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _dec_from_triple(0, result.lstrip('0') or '0', 0)
3292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def logical_invert(self, context=None):
3294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Invert all its digits."""
3295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self.logical_xor(_dec_from_triple(0,'1'*context.prec,0),
3298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                context)
3299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def logical_or(self, other, context=None):
3301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Applies an 'or' operation between self and other's digits."""
3302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
3306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self._islogical() or not other._islogical():
3308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation)
3309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # fill to context.prec
3311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (opa, opb) = self._fill_logical(context, self._int, other._int)
3312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # make the operation, and clean starting zeroes
3314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = "".join([str(int(a)|int(b)) for a,b in zip(opa,opb)])
3315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _dec_from_triple(0, result.lstrip('0') or '0', 0)
3316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def logical_xor(self, other, context=None):
3318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Applies an 'xor' operation between self and other's digits."""
3319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
3323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self._islogical() or not other._islogical():
3325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation)
3326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # fill to context.prec
3328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (opa, opb) = self._fill_logical(context, self._int, other._int)
3329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # make the operation, and clean starting zeroes
3331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = "".join([str(int(a)^int(b)) for a,b in zip(opa,opb)])
3332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _dec_from_triple(0, result.lstrip('0') or '0', 0)
3333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def max_mag(self, other, context=None):
3335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Compares the values numerically with their sign ignored."""
3336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
3337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special or other._is_special:
3342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # If one operand is a quiet NaN and the other is number, then the
3343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # number is always returned
3344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            sn = self._isnan()
3345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            on = other._isnan()
3346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if sn or on:
3347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if on == 1 and sn == 0:
3348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return self._fix(context)
3349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if sn == 1 and on == 0:
3350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return other._fix(context)
3351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return self._check_nans(other, context)
3352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        c = self.copy_abs()._cmp(other.copy_abs())
3354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if c == 0:
3355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            c = self.compare_total(other)
3356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if c == -1:
3358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = other
3359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
3360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self
3361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans._fix(context)
3363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def min_mag(self, other, context=None):
3365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Compares the values numerically with their sign ignored."""
3366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
3367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special or other._is_special:
3372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # If one operand is a quiet NaN and the other is number, then the
3373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # number is always returned
3374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            sn = self._isnan()
3375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            on = other._isnan()
3376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if sn or on:
3377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if on == 1 and sn == 0:
3378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return self._fix(context)
3379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if sn == 1 and on == 0:
3380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    return other._fix(context)
3381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return self._check_nans(other, context)
3382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        c = self.copy_abs()._cmp(other.copy_abs())
3384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if c == 0:
3385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            c = self.compare_total(other)
3386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if c == -1:
3388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self
3389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
3390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = other
3391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans._fix(context)
3393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def next_minus(self, context=None):
3395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the largest representable number smaller than itself."""
3396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._check_nans(context=context)
3400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
3401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
3402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity() == -1:
3404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _NegativeInfinity
3405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity() == 1:
3406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _dec_from_triple(0, '9'*context.prec, context.Etop())
3407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context = context.copy()
3409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context._set_rounding(ROUND_FLOOR)
3410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context._ignore_all_flags()
3411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        new_self = self._fix(context)
3412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if new_self != self:
3413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return new_self
3414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self.__sub__(_dec_from_triple(0, '1', context.Etiny()-1),
3415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                            context)
3416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def next_plus(self, context=None):
3418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the smallest representable number larger than itself."""
3419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._check_nans(context=context)
3423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
3424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
3425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity() == 1:
3427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _Infinity
3428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity() == -1:
3429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _dec_from_triple(1, '9'*context.prec, context.Etop())
3430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context = context.copy()
3432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context._set_rounding(ROUND_CEILING)
3433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context._ignore_all_flags()
3434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        new_self = self._fix(context)
3435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if new_self != self:
3436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return new_self
3437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self.__add__(_dec_from_triple(0, '1', context.Etiny()-1),
3438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                            context)
3439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def next_toward(self, other, context=None):
3441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the number closest to self, in the direction towards other.
3442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The result is the closest representable number to self
3444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (excluding self) that is in the direction towards other,
3445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        unless both have the same value.  If the two operands are
3446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        numerically equal, then the result is a copy of self with the
3447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        sign set to be the same as the sign of other.
3448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
3449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
3450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._check_nans(other, context)
3455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
3456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
3457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        comparison = self._cmp(other)
3459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if comparison == 0:
3460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self.copy_sign(other)
3461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if comparison == -1:
3463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self.next_plus(context)
3464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else: # comparison == 1
3465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ans = self.next_minus(context)
3466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # decide which flags to raise using value of ans
3468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans._isinfinity():
3469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context._raise_error(Overflow,
3470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                 'Infinite result from next_toward',
3471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                 ans._sign)
3472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context._raise_error(Inexact)
3473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context._raise_error(Rounded)
3474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif ans.adjusted() < context.Emin:
3475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context._raise_error(Underflow)
3476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context._raise_error(Subnormal)
3477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context._raise_error(Inexact)
3478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context._raise_error(Rounded)
3479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # if precision == 1 then we don't raise Clamped for a
3480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # result 0E-Etiny.
3481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if not ans:
3482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                context._raise_error(Clamped)
3483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ans
3485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def number_class(self, context=None):
3487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns an indication of the class of self.
3488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The class is one of the following strings:
3490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          sNaN
3491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          NaN
3492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          -Infinity
3493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          -Normal
3494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          -Subnormal
3495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          -Zero
3496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          +Zero
3497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          +Subnormal
3498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          +Normal
3499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          +Infinity
3500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
3501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self.is_snan():
3502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return "sNaN"
3503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self.is_qnan():
3504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return "NaN"
3505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        inf = self._isinfinity()
3506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if inf == 1:
3507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return "+Infinity"
3508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if inf == -1:
3509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return "-Infinity"
3510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self.is_zero():
3511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self._sign:
3512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return "-Zero"
3513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
3514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return "+Zero"
3515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self.is_subnormal(context=context):
3518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self._sign:
3519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return "-Subnormal"
3520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
3521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return "+Subnormal"
3522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # just a normal, regular, boring number, :)
3523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._sign:
3524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return "-Normal"
3525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
3526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return "+Normal"
3527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def radix(self):
3529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Just returns 10, as this is Decimal, :)"""
3530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return Decimal(10)
3531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def rotate(self, other, context=None):
3533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns a rotated copy of self, value-of-other times."""
3534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
3538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._check_nans(other, context)
3540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
3541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
3542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other._exp != 0:
3544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation)
3545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not (-context.prec <= int(other) <= context.prec):
3546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation)
3547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity():
3549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return Decimal(self)
3550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # get values, pad if necessary
3552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        torot = int(other)
3553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        rotdig = self._int
3554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        topad = context.prec - len(rotdig)
3555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if topad > 0:
3556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            rotdig = '0'*topad + rotdig
3557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif topad < 0:
3558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            rotdig = rotdig[-topad:]
3559edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3560edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # let's rotate!
3561edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        rotated = rotdig[torot:] + rotdig[:torot]
3562edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _dec_from_triple(self._sign,
3563edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                rotated.lstrip('0') or '0', self._exp)
3564edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3565edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def scaleb(self, other, context=None):
3566edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns self operand after adding the second value to its exp."""
3567edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3568edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3569edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3570edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
3571edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3572edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._check_nans(other, context)
3573edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
3574edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
3575edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3576edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other._exp != 0:
3577edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation)
3578edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        liminf = -2 * (context.Emax + context.prec)
3579edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        limsup =  2 * (context.Emax + context.prec)
3580edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not (liminf <= int(other) <= limsup):
3581edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation)
3582edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3583edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity():
3584edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return Decimal(self)
3585edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3586edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        d = _dec_from_triple(self._sign, self._int, self._exp + int(other))
3587edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        d = d._fix(context)
3588edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return d
3589edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3590edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def shift(self, other, context=None):
3591edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns a shifted copy of self, value-of-other times."""
3592edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3593edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3594edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3595edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = _convert_other(other, raiseit=True)
3596edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3597edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ans = self._check_nans(other, context)
3598edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ans:
3599edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return ans
3600edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3601edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if other._exp != 0:
3602edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation)
3603edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not (-context.prec <= int(other) <= context.prec):
3604edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return context._raise_error(InvalidOperation)
3605edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3606edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._isinfinity():
3607edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return Decimal(self)
3608edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3609edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # get values, pad if necessary
3610edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        torot = int(other)
3611edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        rotdig = self._int
3612edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        topad = context.prec - len(rotdig)
3613edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if topad > 0:
3614edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            rotdig = '0'*topad + rotdig
3615edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif topad < 0:
3616edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            rotdig = rotdig[-topad:]
3617edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3618edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # let's shift!
3619edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if torot < 0:
3620edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            shifted = rotdig[:torot]
3621edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
3622edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            shifted = rotdig + '0'*torot
3623edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            shifted = shifted[-context.prec:]
3624edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3625edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _dec_from_triple(self._sign,
3626edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                    shifted.lstrip('0') or '0', self._exp)
3627edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3628edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Support for pickling, copy, and deepcopy
3629edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __reduce__(self):
3630edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return (self.__class__, (str(self),))
3631edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3632edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __copy__(self):
3633edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if type(self) is Decimal:
3634edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self     # I'm immutable; therefore I am my own clone
3635edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self.__class__(str(self))
3636edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3637edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __deepcopy__(self, memo):
3638edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if type(self) is Decimal:
3639edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self     # My components are also immutable
3640edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self.__class__(str(self))
3641edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3642edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # PEP 3101 support.  the _localeconv keyword argument should be
3643edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # considered private: it's provided for ease of testing only.
3644edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __format__(self, specifier, context=None, _localeconv=None):
3645edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Format a Decimal instance according to the given specifier.
3646edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3647edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The specifier should be a standard format specifier, with the
3648edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        form described in PEP 3101.  Formatting types 'e', 'E', 'f',
3649edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        'F', 'g', 'G', 'n' and '%' are supported.  If the formatting
3650edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        type is omitted it defaults to 'g' or 'G', depending on the
3651edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        value of context.capitals.
3652edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
3653edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3654edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Note: PEP 3101 says that if the type is not present then
3655edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # there should be at least one digit after the decimal point.
3656edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # We take the liberty of ignoring this requirement for
3657edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Decimal---it's presumably there to make sure that
3658edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # format(float, '') behaves similarly to str(float).
3659edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if context is None:
3660edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            context = getcontext()
3661edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3662edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        spec = _parse_format_specifier(specifier, _localeconv=_localeconv)
3663edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3664edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # special values don't care about the type or precision
3665edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if self._is_special:
3666edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            sign = _format_sign(self._sign, spec)
3667edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            body = str(self.copy_abs())
3668edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return _format_align(sign, body, spec)
3669edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3670edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # a type of None defaults to 'g' or 'G', depending on context
3671edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if spec['type'] is None:
3672edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            spec['type'] = ['g', 'G'][context.capitals]
3673edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3674edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # if type is '%', adjust exponent of self accordingly
3675edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if spec['type'] == '%':
3676edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self = _dec_from_triple(self._sign, self._int, self._exp+2)
3677edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3678edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # round if necessary, taking rounding mode from the context
3679edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        rounding = context.rounding
3680edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        precision = spec['precision']
3681edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if precision is not None:
3682edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if spec['type'] in 'eE':
3683edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self = self._round(precision+1, rounding)
3684edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            elif spec['type'] in 'fF%':
3685edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self = self._rescale(-precision, rounding)
3686edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            elif spec['type'] in 'gG' and len(self._int) > precision:
3687edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self = self._round(precision, rounding)
3688edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # special case: zeros with a positive exponent can't be
3689edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # represented in fixed point; rescale them to 0e0.
3690edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self and self._exp > 0 and spec['type'] in 'fF%':
3691edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self = self._rescale(0, rounding)
3692edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3693edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # figure out placement of the decimal point
3694edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        leftdigits = self._exp + len(self._int)
3695edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if spec['type'] in 'eE':
3696edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if not self and precision is not None:
3697edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                dotplace = 1 - precision
3698edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
3699edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                dotplace = 1
3700edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif spec['type'] in 'fF%':
3701edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            dotplace = leftdigits
3702edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif spec['type'] in 'gG':
3703edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            if self._exp <= 0 and leftdigits > -6:
3704edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                dotplace = leftdigits
3705edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            else:
3706edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                dotplace = 1
3707edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3708edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # find digits before and after decimal point, and get exponent
3709edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if dotplace < 0:
3710edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            intpart = '0'
3711edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            fracpart = '0'*(-dotplace) + self._int
3712edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif dotplace > len(self._int):
3713edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            intpart = self._int + '0'*(dotplace-len(self._int))
3714edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            fracpart = ''
3715edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
3716edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            intpart = self._int[:dotplace] or '0'
3717edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            fracpart = self._int[dotplace:]
3718edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        exp = leftdigits-dotplace
3719edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3720edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # done with the decimal-specific stuff;  hand over the rest
3721edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # of the formatting to the _format_number function
3722edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return _format_number(self._sign, intpart, fracpart, exp, spec)
3723edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3724edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _dec_from_triple(sign, coefficient, exponent, special=False):
3725edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Create a decimal instance directly, without any validation,
3726edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    normalization (e.g. removal of leading zeros) or argument
3727edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    conversion.
3728edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3729edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    This function is for *internal use only*.
3730edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
3731edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3732edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    self = object.__new__(Decimal)
3733edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    self._sign = sign
3734edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    self._int = coefficient
3735edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    self._exp = exponent
3736edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    self._is_special = special
3737edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3738edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return self
3739edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3740edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Register Decimal as a kind of Number (an abstract base class).
3741edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# However, do not register it as Real (because Decimals are not
3742edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# interoperable with floats).
3743edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_numbers.Number.register(Decimal)
3744edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3745edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3746edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### Context class #######################################################
3747edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3748edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass _ContextManager(object):
3749edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Context manager class to support localcontext().
3750edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3751edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      Sets a copy of the supplied context in __enter__() and restores
3752edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      the previous decimal context in __exit__()
3753edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
3754edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __init__(self, new_context):
3755edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.new_context = new_context.copy()
3756edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __enter__(self):
3757edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.saved_context = getcontext()
3758edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        setcontext(self.new_context)
3759edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self.new_context
3760edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __exit__(self, t, v, tb):
3761edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        setcontext(self.saved_context)
3762edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3763edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Context(object):
3764edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Contains the context for a Decimal instance.
3765edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3766edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Contains:
3767edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    prec - precision (for use in rounding, division, square roots..)
3768edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    rounding - rounding type (how you round)
3769edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    traps - If traps[exception] = 1, then the exception is
3770edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    raised when it is caused.  Otherwise, a value is
3771edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    substituted in.
3772edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    flags  - When an exception is caused, flags[exception] is set.
3773edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep             (Whether or not the trap_enabler is set)
3774edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep             Should be reset by user of Decimal instance.
3775edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Emin -   Minimum exponent
3776edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Emax -   Maximum exponent
3777edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    capitals -      If 1, 1*10^1 is printed as 1E+1.
3778edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    If 0, printed as 1e1
3779edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    _clamp - If 1, change exponents if too high (Default 0)
3780edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
3781edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3782edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __init__(self, prec=None, rounding=None,
3783edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                 traps=None, flags=None,
3784edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                 Emin=None, Emax=None,
3785edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                 capitals=None, _clamp=0,
3786edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                 _ignored_flags=None):
3787edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Set defaults; for everything except flags and _ignored_flags,
3788edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # inherit from DefaultContext.
3789edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        try:
3790edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            dc = DefaultContext
3791edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        except NameError:
3792edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            pass
3793edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3794edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.prec = prec if prec is not None else dc.prec
3795edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.rounding = rounding if rounding is not None else dc.rounding
3796edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.Emin = Emin if Emin is not None else dc.Emin
3797edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.Emax = Emax if Emax is not None else dc.Emax
3798edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.capitals = capitals if capitals is not None else dc.capitals
3799edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self._clamp = _clamp if _clamp is not None else dc._clamp
3800edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3801edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if _ignored_flags is None:
3802edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._ignored_flags = []
3803edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
3804edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._ignored_flags = _ignored_flags
3805edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3806edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if traps is None:
3807edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.traps = dc.traps.copy()
3808edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif not isinstance(traps, dict):
3809edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.traps = dict((s, int(s in traps)) for s in _signals)
3810edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
3811edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.traps = traps
3812edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3813edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if flags is None:
3814edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.flags = dict.fromkeys(_signals, 0)
3815edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif not isinstance(flags, dict):
3816edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.flags = dict((s, int(s in flags)) for s in _signals)
3817edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
3818edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.flags = flags
3819edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3820edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __repr__(self):
3821edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Show the current context."""
3822edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        s = []
3823edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        s.append('Context(prec=%(prec)d, rounding=%(rounding)s, '
3824edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                 'Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d'
3825edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                 % vars(self))
3826edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        names = [f.__name__ for f, v in self.flags.items() if v]
3827edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        s.append('flags=[' + ', '.join(names) + ']')
3828edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        names = [t.__name__ for t, v in self.traps.items() if v]
3829edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        s.append('traps=[' + ', '.join(names) + ']')
3830edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ', '.join(s) + ')'
3831edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3832edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def clear_flags(self):
3833edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Reset all flags to zero"""
3834edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        for flag in self.flags:
3835edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.flags[flag] = 0
3836edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3837edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _shallow_copy(self):
3838edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns a shallow copy from self."""
3839edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        nc = Context(self.prec, self.rounding, self.traps,
3840edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                     self.flags, self.Emin, self.Emax,
3841edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                     self.capitals, self._clamp, self._ignored_flags)
3842edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return nc
3843edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3844edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def copy(self):
3845edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns a deep copy from self."""
3846edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        nc = Context(self.prec, self.rounding, self.traps.copy(),
3847edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                     self.flags.copy(), self.Emin, self.Emax,
3848edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                     self.capitals, self._clamp, self._ignored_flags)
3849edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return nc
3850edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    __copy__ = copy
3851edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3852edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _raise_error(self, condition, explanation = None, *args):
3853edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Handles an error
3854edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3855edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        If the flag is in _ignored_flags, returns the default response.
3856edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Otherwise, it sets the flag, then, if the corresponding
3857edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        trap_enabler is set, it reraises the exception.  Otherwise, it returns
3858edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        the default value after setting the flag.
3859edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
3860edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        error = _condition_map.get(condition, condition)
3861edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if error in self._ignored_flags:
3862edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # Don't touch the flag
3863edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return error().handle(self, *args)
3864edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3865edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.flags[error] = 1
3866edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not self.traps[error]:
3867edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # The errors define how to handle themselves.
3868edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return condition().handle(self, *args)
3869edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3870edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Errors should only be risked on copies of the context
3871edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # self._ignored_flags = []
3872edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        raise error(explanation)
3873edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3874edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _ignore_all_flags(self):
3875edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Ignore all flags, if they are raised"""
3876edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return self._ignore_flags(*_signals)
3877edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3878edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _ignore_flags(self, *flags):
3879edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Ignore the flags, if they are raised"""
3880edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Do not mutate-- This way, copies of a context leave the original
3881edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # alone.
3882edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self._ignored_flags = (self._ignored_flags + list(flags))
3883edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return list(flags)
3884edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3885edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _regard_flags(self, *flags):
3886edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Stop ignoring the flags, if they are raised"""
3887edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if flags and isinstance(flags[0], (tuple,list)):
3888edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            flags = flags[0]
3889edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        for flag in flags:
3890edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self._ignored_flags.remove(flag)
3891edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3892edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # We inherit object.__hash__, so we must deny this explicitly
3893edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    __hash__ = None
3894edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3895edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def Etiny(self):
3896edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns Etiny (= Emin - prec + 1)"""
3897edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return int(self.Emin - self.prec + 1)
3898edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3899edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def Etop(self):
3900edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns maximum exponent (= Emax - prec + 1)"""
3901edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return int(self.Emax - self.prec + 1)
3902edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3903edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _set_rounding(self, type):
3904edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Sets the rounding type.
3905edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3906edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Sets the rounding type, and returns the current (previous)
3907edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        rounding type.  Often used like:
3908edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3909edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context = context.copy()
3910edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # so you don't change the calling context
3911edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # if an error occurs in the middle.
3912edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        rounding = context._set_rounding(ROUND_UP)
3913edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        val = self.__sub__(other, context=context)
3914edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context._set_rounding(rounding)
3915edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3916edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        This will make it round up for that operation.
3917edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
3918edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        rounding = self.rounding
3919edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.rounding= type
3920edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return rounding
3921edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3922edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def create_decimal(self, num='0'):
3923edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Creates a new Decimal instance but using self as context.
3924edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3925edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        This method implements the to-number operation of the
3926edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        IBM Decimal specification."""
3927edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3928edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if isinstance(num, basestring) and num != num.strip():
3929edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self._raise_error(ConversionSyntax,
3930edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                     "no trailing or leading whitespace is "
3931edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                     "permitted.")
3932edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3933edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        d = Decimal(num, context=self)
3934edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if d._isnan() and len(d._int) > self.prec - self._clamp:
3935edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return self._raise_error(ConversionSyntax,
3936edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                     "diagnostic info too long in NaN")
3937edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return d._fix(self)
3938edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3939edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def create_decimal_from_float(self, f):
3940edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Creates a new Decimal instance from a float but rounding using self
3941edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        as the context.
3942edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3943edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> context = Context(prec=5, rounding=ROUND_DOWN)
3944edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> context.create_decimal_from_float(3.1415926535897932)
3945edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3.1415')
3946edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> context = Context(prec=5, traps=[Inexact])
3947edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> context.create_decimal_from_float(3.1415926535897932)
3948edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Traceback (most recent call last):
3949edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            ...
3950edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Inexact: None
3951edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3952edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
3953edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        d = Decimal.from_float(f)       # An exact conversion
3954edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return d._fix(self)             # Apply the context rounding
3955edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3956edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Methods
3957edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def abs(self, a):
3958edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the absolute value of the operand.
3959edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3960edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        If the operand is negative, the result is the same as using the minus
3961edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        operation on the operand.  Otherwise, the result is the same as using
3962edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        the plus operation on the operand.
3963edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3964edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.abs(Decimal('2.1'))
3965edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2.1')
3966edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.abs(Decimal('-100'))
3967edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('100')
3968edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.abs(Decimal('101.5'))
3969edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('101.5')
3970edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.abs(Decimal('-101.5'))
3971edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('101.5')
3972edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.abs(-1)
3973edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
3974edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
3975edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
3976edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.__abs__(context=self)
3977edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3978edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def add(self, a, b):
3979edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return the sum of the two operands.
3980edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3981edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
3982edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('19.00')
3983edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
3984edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.02E+4')
3985edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.add(1, Decimal(2))
3986edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3')
3987edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.add(Decimal(8), 5)
3988edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('13')
3989edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.add(5, 5)
3990edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('10')
3991edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
3992edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
3993edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        r = a.__add__(b, context=self)
3994edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if r is NotImplemented:
3995edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            raise TypeError("Unable to convert %s to Decimal" % b)
3996edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
3997edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return r
3998edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
3999edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def _apply(self, a):
4000edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return str(a._fix(self))
4001edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4002edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def canonical(self, a):
4003edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the same Decimal object.
4004edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4005edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        As we do not have different encodings for the same number, the
4006edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        received object already is in its canonical form.
4007edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4008edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.canonical(Decimal('2.50'))
4009edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2.50')
4010edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4011edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.canonical(context=self)
4012edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4013edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def compare(self, a, b):
4014edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Compares values numerically.
4015edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4016edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        If the signs of the operands differ, a value representing each operand
4017edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ('-1' if the operand is less than zero, '0' if the operand is zero or
4018edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        negative zero, or '1' if the operand is greater than zero) is used in
4019edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        place of that operand for the comparison instead of the actual
4020edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        operand.
4021edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4022edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The comparison is then effected by subtracting the second operand from
4023edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        the first and then returning a value according to the result of the
4024edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        subtraction: '-1' if the result is less than zero, '0' if the result is
4025edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        zero or negative zero, or '1' if the result is greater than zero.
4026edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4027edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
4028edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4029edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
4030edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4031edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
4032edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4033edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
4034edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4035edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
4036edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4037edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
4038edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4039edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare(1, 2)
4040edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4041edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare(Decimal(1), 2)
4042edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4043edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare(1, Decimal(2))
4044edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4045edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4046edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4047edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.compare(b, context=self)
4048edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4049edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def compare_signal(self, a, b):
4050edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Compares the values of the two operands numerically.
4051edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4052edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        It's pretty much like compare(), but all NaNs signal, with signaling
4053edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        NaNs taking precedence over quiet NaNs.
4054edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4055edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c = ExtendedContext
4056edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.compare_signal(Decimal('2.1'), Decimal('3'))
4057edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4058edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.compare_signal(Decimal('2.1'), Decimal('2.1'))
4059edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4060edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.flags[InvalidOperation] = 0
4061edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> print c.flags[InvalidOperation]
4062edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        0
4063edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.compare_signal(Decimal('NaN'), Decimal('2.1'))
4064edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('NaN')
4065edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> print c.flags[InvalidOperation]
4066edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        1
4067edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.flags[InvalidOperation] = 0
4068edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> print c.flags[InvalidOperation]
4069edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        0
4070edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.compare_signal(Decimal('sNaN'), Decimal('2.1'))
4071edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('NaN')
4072edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> print c.flags[InvalidOperation]
4073edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        1
4074edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.compare_signal(-1, 2)
4075edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4076edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.compare_signal(Decimal(-1), 2)
4077edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4078edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.compare_signal(-1, Decimal(2))
4079edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4080edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4081edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4082edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.compare_signal(b, context=self)
4083edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4084edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def compare_total(self, a, b):
4085edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Compares two operands using their abstract representation.
4086edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4087edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        This is not like the standard compare, which use their numerical
4088edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        value. Note that a total ordering is defined for all possible abstract
4089edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        representations.
4090edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4091edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare_total(Decimal('12.73'), Decimal('127.9'))
4092edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4093edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare_total(Decimal('-127'),  Decimal('12'))
4094edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4095edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare_total(Decimal('12.30'), Decimal('12.3'))
4096edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4097edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare_total(Decimal('12.30'), Decimal('12.30'))
4098edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4099edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare_total(Decimal('12.3'),  Decimal('12.300'))
4100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare_total(Decimal('12.3'),  Decimal('NaN'))
4102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare_total(1, 2)
4104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare_total(Decimal(1), 2)
4106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.compare_total(1, Decimal(2))
4108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.compare_total(b)
4112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def compare_total_mag(self, a, b):
4114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Compares two operands using their abstract representation ignoring sign.
4115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Like compare_total, but with operand's sign ignored and assumed to be 0.
4117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.compare_total_mag(b)
4120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def copy_abs(self, a):
4122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns a copy of the operand with the sign set to 0.
4123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.copy_abs(Decimal('2.1'))
4125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2.1')
4126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.copy_abs(Decimal('-100'))
4127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('100')
4128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.copy_abs(-1)
4129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.copy_abs()
4133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def copy_decimal(self, a):
4135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns a copy of the decimal object.
4136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.copy_decimal(Decimal('2.1'))
4138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2.1')
4139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.copy_decimal(Decimal('-1.00'))
4140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1.00')
4141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.copy_decimal(1)
4142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return Decimal(a)
4146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def copy_negate(self, a):
4148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns a copy of the operand with the sign inverted.
4149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.copy_negate(Decimal('101.5'))
4151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-101.5')
4152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.copy_negate(Decimal('-101.5'))
4153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('101.5')
4154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.copy_negate(1)
4155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.copy_negate()
4159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def copy_sign(self, a, b):
4161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Copies the second operand's sign to the first one.
4162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        In detail, it returns a copy of the first operand with the sign
4164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        equal to the sign of the second operand.
4165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('7.33'))
4167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.50')
4168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('7.33'))
4169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.50')
4170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('-7.33'))
4171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1.50')
4172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('-7.33'))
4173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1.50')
4174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.copy_sign(1, -2)
4175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.copy_sign(Decimal(1), -2)
4177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.copy_sign(1, Decimal(-2))
4179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.copy_sign(b)
4183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def divide(self, a, b):
4185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Decimal division in a specified context.
4186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
4188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.333333333')
4189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
4190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.666666667')
4191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
4192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2.5')
4193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
4194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.1')
4195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
4196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
4198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('4.00')
4199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
4200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.20')
4201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
4202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('10')
4203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
4204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1000')
4205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
4206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.20E+6')
4207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide(5, 5)
4208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide(Decimal(5), 5)
4210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide(5, Decimal(5))
4212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        r = a.__div__(b, context=self)
4216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if r is NotImplemented:
4217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            raise TypeError("Unable to convert %s to Decimal" % b)
4218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
4219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return r
4220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def divide_int(self, a, b):
4222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Divides two numbers and returns the integer part of the result.
4223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
4225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
4227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3')
4228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
4229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3')
4230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide_int(10, 3)
4231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3')
4232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide_int(Decimal(10), 3)
4233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3')
4234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divide_int(10, Decimal(3))
4235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3')
4236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        r = a.__floordiv__(b, context=self)
4239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if r is NotImplemented:
4240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            raise TypeError("Unable to convert %s to Decimal" % b)
4241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
4242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return r
4243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def divmod(self, a, b):
4245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return (a // b, a % b).
4246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divmod(Decimal(8), Decimal(3))
4248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (Decimal('2'), Decimal('2'))
4249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divmod(Decimal(8), Decimal(4))
4250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (Decimal('2'), Decimal('0'))
4251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divmod(8, 4)
4252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (Decimal('2'), Decimal('0'))
4253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divmod(Decimal(8), 4)
4254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (Decimal('2'), Decimal('0'))
4255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.divmod(8, Decimal(4))
4256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (Decimal('2'), Decimal('0'))
4257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        r = a.__divmod__(b, context=self)
4260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if r is NotImplemented:
4261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            raise TypeError("Unable to convert %s to Decimal" % b)
4262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
4263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return r
4264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def exp(self, a):
4266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns e ** a.
4267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c = ExtendedContext.copy()
4269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emin = -999
4270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emax = 999
4271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.exp(Decimal('-Infinity'))
4272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.exp(Decimal('-1'))
4274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.367879441')
4275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.exp(Decimal('0'))
4276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.exp(Decimal('1'))
4278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2.71828183')
4279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.exp(Decimal('0.693147181'))
4280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2.00000000')
4281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.exp(Decimal('+Infinity'))
4282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('Infinity')
4283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.exp(10)
4284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('22026.4658')
4285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a =_convert_other(a, raiseit=True)
4287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.exp(context=self)
4288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def fma(self, a, b, c):
4290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns a multiplied by b, plus c.
4291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The first two operands are multiplied together, using multiply,
4293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        the third operand is then added to the result of that
4294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        multiplication, using add, all with only one final rounding.
4295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.fma(Decimal('3'), Decimal('5'), Decimal('7'))
4297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('22')
4298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.fma(Decimal('3'), Decimal('-5'), Decimal('7'))
4299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-8')
4300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.fma(Decimal('888565290'), Decimal('1557.96930'), Decimal('-86087.7578'))
4301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.38435736E+12')
4302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.fma(1, 3, 4)
4303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('7')
4304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.fma(1, Decimal(3), 4)
4305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('7')
4306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.fma(1, 3, Decimal(4))
4307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('7')
4308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.fma(b, c, context=self)
4311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_canonical(self, a):
4313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if the operand is canonical; otherwise return False.
4314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Currently, the encoding of a Decimal instance is always
4316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        canonical, so this method returns True for any Decimal.
4317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_canonical(Decimal('2.50'))
4319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.is_canonical()
4322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_finite(self, a):
4324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if the operand is finite; otherwise return False.
4325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        A Decimal instance is considered finite if it is neither
4327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        infinite nor a NaN.
4328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_finite(Decimal('2.50'))
4330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_finite(Decimal('-0.3'))
4332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_finite(Decimal('0'))
4334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_finite(Decimal('Inf'))
4336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_finite(Decimal('NaN'))
4338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_finite(1)
4340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.is_finite()
4344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_infinite(self, a):
4346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if the operand is infinite; otherwise return False.
4347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_infinite(Decimal('2.50'))
4349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_infinite(Decimal('-Inf'))
4351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_infinite(Decimal('NaN'))
4353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_infinite(1)
4355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.is_infinite()
4359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_nan(self, a):
4361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if the operand is a qNaN or sNaN;
4362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        otherwise return False.
4363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_nan(Decimal('2.50'))
4365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_nan(Decimal('NaN'))
4367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_nan(Decimal('-sNaN'))
4369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_nan(1)
4371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.is_nan()
4375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_normal(self, a):
4377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if the operand is a normal number;
4378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        otherwise return False.
4379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c = ExtendedContext.copy()
4381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emin = -999
4382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emax = 999
4383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.is_normal(Decimal('2.50'))
4384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.is_normal(Decimal('0.1E-999'))
4386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.is_normal(Decimal('0.00'))
4388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.is_normal(Decimal('-Inf'))
4390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.is_normal(Decimal('NaN'))
4392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.is_normal(1)
4394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.is_normal(context=self)
4398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_qnan(self, a):
4400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if the operand is a quiet NaN; otherwise return False.
4401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_qnan(Decimal('2.50'))
4403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_qnan(Decimal('NaN'))
4405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_qnan(Decimal('sNaN'))
4407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_qnan(1)
4409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.is_qnan()
4413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_signed(self, a):
4415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if the operand is negative; otherwise return False.
4416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_signed(Decimal('2.50'))
4418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_signed(Decimal('-12'))
4420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_signed(Decimal('-0'))
4422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_signed(8)
4424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_signed(-8)
4426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.is_signed()
4430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_snan(self, a):
4432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if the operand is a signaling NaN;
4433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        otherwise return False.
4434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_snan(Decimal('2.50'))
4436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_snan(Decimal('NaN'))
4438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_snan(Decimal('sNaN'))
4440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_snan(1)
4442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.is_snan()
4446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_subnormal(self, a):
4448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if the operand is subnormal; otherwise return False.
4449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c = ExtendedContext.copy()
4451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emin = -999
4452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emax = 999
4453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.is_subnormal(Decimal('2.50'))
4454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.is_subnormal(Decimal('0.1E-999'))
4456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.is_subnormal(Decimal('0.00'))
4458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.is_subnormal(Decimal('-Inf'))
4460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.is_subnormal(Decimal('NaN'))
4462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.is_subnormal(1)
4464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.is_subnormal(context=self)
4468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def is_zero(self, a):
4470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return True if the operand is a zero; otherwise return False.
4471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_zero(Decimal('0'))
4473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_zero(Decimal('2.50'))
4475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_zero(Decimal('-0E+2'))
4477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_zero(1)
4479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
4480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.is_zero(0)
4481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
4482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.is_zero()
4485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def ln(self, a):
4487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the natural (base e) logarithm of the operand.
4488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c = ExtendedContext.copy()
4490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emin = -999
4491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emax = 999
4492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.ln(Decimal('0'))
4493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-Infinity')
4494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.ln(Decimal('1.000'))
4495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.ln(Decimal('2.71828183'))
4497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.00000000')
4498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.ln(Decimal('10'))
4499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2.30258509')
4500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.ln(Decimal('+Infinity'))
4501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('Infinity')
4502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.ln(1)
4503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.ln(context=self)
4507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def log10(self, a):
4509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the base 10 logarithm of the operand.
4510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c = ExtendedContext.copy()
4512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emin = -999
4513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emax = 999
4514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.log10(Decimal('0'))
4515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-Infinity')
4516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.log10(Decimal('0.001'))
4517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-3')
4518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.log10(Decimal('1.000'))
4519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.log10(Decimal('2'))
4521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.301029996')
4522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.log10(Decimal('10'))
4523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.log10(Decimal('70'))
4525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.84509804')
4526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.log10(Decimal('+Infinity'))
4527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('Infinity')
4528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.log10(0)
4529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-Infinity')
4530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.log10(1)
4531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.log10(context=self)
4535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def logb(self, a):
4537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """ Returns the exponent of the magnitude of the operand's MSD.
4538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The result is the integer which is the exponent of the magnitude
4540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        of the most significant digit of the operand (as though the
4541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        operand were truncated to a single digit while maintaining the
4542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        value of that digit and without limiting the resulting exponent).
4543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logb(Decimal('250'))
4545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2')
4546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logb(Decimal('2.50'))
4547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logb(Decimal('0.03'))
4549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-2')
4550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logb(Decimal('0'))
4551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-Infinity')
4552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logb(1)
4553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logb(10)
4555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logb(100)
4557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2')
4558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4559edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4560edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.logb(context=self)
4561edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4562edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def logical_and(self, a, b):
4563edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Applies the logical operation 'and' between each operand's digits.
4564edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4565edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The operands must be both logical numbers.
4566edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4567edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_and(Decimal('0'), Decimal('0'))
4568edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4569edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_and(Decimal('0'), Decimal('1'))
4570edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4571edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_and(Decimal('1'), Decimal('0'))
4572edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4573edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_and(Decimal('1'), Decimal('1'))
4574edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4575edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_and(Decimal('1100'), Decimal('1010'))
4576edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1000')
4577edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_and(Decimal('1111'), Decimal('10'))
4578edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('10')
4579edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_and(110, 1101)
4580edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('100')
4581edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_and(Decimal(110), 1101)
4582edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('100')
4583edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_and(110, Decimal(1101))
4584edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('100')
4585edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4586edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4587edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.logical_and(b, context=self)
4588edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4589edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def logical_invert(self, a):
4590edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Invert all the digits in the operand.
4591edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4592edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The operand must be a logical number.
4593edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4594edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_invert(Decimal('0'))
4595edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('111111111')
4596edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_invert(Decimal('1'))
4597edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('111111110')
4598edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_invert(Decimal('111111111'))
4599edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4600edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_invert(Decimal('101010101'))
4601edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('10101010')
4602edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_invert(1101)
4603edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('111110010')
4604edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4605edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4606edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.logical_invert(context=self)
4607edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4608edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def logical_or(self, a, b):
4609edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Applies the logical operation 'or' between each operand's digits.
4610edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4611edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The operands must be both logical numbers.
4612edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4613edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_or(Decimal('0'), Decimal('0'))
4614edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4615edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_or(Decimal('0'), Decimal('1'))
4616edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4617edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_or(Decimal('1'), Decimal('0'))
4618edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4619edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_or(Decimal('1'), Decimal('1'))
4620edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4621edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_or(Decimal('1100'), Decimal('1010'))
4622edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1110')
4623edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_or(Decimal('1110'), Decimal('10'))
4624edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1110')
4625edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_or(110, 1101)
4626edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1111')
4627edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_or(Decimal(110), 1101)
4628edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1111')
4629edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_or(110, Decimal(1101))
4630edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1111')
4631edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4632edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4633edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.logical_or(b, context=self)
4634edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4635edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def logical_xor(self, a, b):
4636edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Applies the logical operation 'xor' between each operand's digits.
4637edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4638edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The operands must be both logical numbers.
4639edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4640edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('0'))
4641edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4642edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('1'))
4643edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4644edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('0'))
4645edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4646edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('1'))
4647edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4648edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_xor(Decimal('1100'), Decimal('1010'))
4649edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('110')
4650edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_xor(Decimal('1111'), Decimal('10'))
4651edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1101')
4652edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_xor(110, 1101)
4653edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1011')
4654edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_xor(Decimal(110), 1101)
4655edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1011')
4656edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.logical_xor(110, Decimal(1101))
4657edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1011')
4658edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4659edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4660edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.logical_xor(b, context=self)
4661edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4662edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def max(self, a, b):
4663edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """max compares two values numerically and returns the maximum.
4664edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4665edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        If either operand is a NaN then the general rules apply.
4666edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Otherwise, the operands are compared as though by the compare
4667edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        operation.  If they are numerically equal then the left-hand operand
4668edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        is chosen as the result.  Otherwise the maximum (closer to positive
4669edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        infinity) of the two operands is chosen as the result.
4670edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4671edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
4672edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3')
4673edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
4674edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3')
4675edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
4676edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4677edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
4678edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('7')
4679edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.max(1, 2)
4680edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2')
4681edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.max(Decimal(1), 2)
4682edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2')
4683edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.max(1, Decimal(2))
4684edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2')
4685edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4686edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4687edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.max(b, context=self)
4688edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4689edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def max_mag(self, a, b):
4690edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Compares the values numerically with their sign ignored.
4691edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4692edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.max_mag(Decimal('7'), Decimal('NaN'))
4693edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('7')
4694edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.max_mag(Decimal('7'), Decimal('-10'))
4695edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-10')
4696edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.max_mag(1, -2)
4697edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-2')
4698edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.max_mag(Decimal(1), -2)
4699edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-2')
4700edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.max_mag(1, Decimal(-2))
4701edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-2')
4702edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4703edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4704edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.max_mag(b, context=self)
4705edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4706edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def min(self, a, b):
4707edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """min compares two values numerically and returns the minimum.
4708edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4709edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        If either operand is a NaN then the general rules apply.
4710edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Otherwise, the operands are compared as though by the compare
4711edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        operation.  If they are numerically equal then the left-hand operand
4712edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        is chosen as the result.  Otherwise the minimum (closer to negative
4713edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        infinity) of the two operands is chosen as the result.
4714edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4715edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
4716edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2')
4717edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
4718edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-10')
4719edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
4720edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.0')
4721edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
4722edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('7')
4723edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.min(1, 2)
4724edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4725edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.min(Decimal(1), 2)
4726edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4727edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.min(1, Decimal(29))
4728edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4729edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4730edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4731edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.min(b, context=self)
4732edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4733edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def min_mag(self, a, b):
4734edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Compares the values numerically with their sign ignored.
4735edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4736edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.min_mag(Decimal('3'), Decimal('-2'))
4737edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-2')
4738edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.min_mag(Decimal('-3'), Decimal('NaN'))
4739edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-3')
4740edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.min_mag(1, -2)
4741edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4742edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.min_mag(Decimal(1), -2)
4743edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4744edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.min_mag(1, Decimal(-2))
4745edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
4746edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4747edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4748edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.min_mag(b, context=self)
4749edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4750edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def minus(self, a):
4751edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Minus corresponds to unary prefix minus in Python.
4752edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4753edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The operation is evaluated using the same rules as subtract; the
4754edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        operation minus(a) is calculated as subtract('0', a) where the '0'
4755edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        has the same exponent as the operand.
4756edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4757edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.minus(Decimal('1.3'))
4758edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1.3')
4759edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.minus(Decimal('-1.3'))
4760edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.3')
4761edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.minus(1)
4762edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4763edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4764edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4765edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.__neg__(context=self)
4766edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4767edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def multiply(self, a, b):
4768edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """multiply multiplies two operands.
4769edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4770edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        If either operand is a special value then the general rules apply.
4771edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Otherwise, the operands are multiplied together
4772edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        ('long multiplication'), resulting in a number which may be as long as
4773edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        the sum of the lengths of the two operands.
4774edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4775edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
4776edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3.60')
4777edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
4778edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('21')
4779edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
4780edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.72')
4781edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
4782edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-0.0')
4783edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
4784edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('4.28135971E+11')
4785edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.multiply(7, 7)
4786edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('49')
4787edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.multiply(Decimal(7), 7)
4788edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('49')
4789edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.multiply(7, Decimal(7))
4790edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('49')
4791edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4792edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4793edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        r = a.__mul__(b, context=self)
4794edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if r is NotImplemented:
4795edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            raise TypeError("Unable to convert %s to Decimal" % b)
4796edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
4797edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return r
4798edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4799edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def next_minus(self, a):
4800edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the largest representable number smaller than a.
4801edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4802edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c = ExtendedContext.copy()
4803edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emin = -999
4804edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emax = 999
4805edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.next_minus(Decimal('1'))
4806edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.999999999')
4807edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.next_minus(Decimal('1E-1007'))
4808edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0E-1007')
4809edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.next_minus(Decimal('-1.00000003'))
4810edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1.00000004')
4811edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.next_minus(Decimal('Infinity'))
4812edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('9.99999999E+999')
4813edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.next_minus(1)
4814edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.999999999')
4815edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4816edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4817edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.next_minus(context=self)
4818edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4819edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def next_plus(self, a):
4820edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the smallest representable number larger than a.
4821edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4822edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c = ExtendedContext.copy()
4823edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emin = -999
4824edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emax = 999
4825edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.next_plus(Decimal('1'))
4826edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.00000001')
4827edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.next_plus(Decimal('-1E-1007'))
4828edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-0E-1007')
4829edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.next_plus(Decimal('-1.00000003'))
4830edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1.00000002')
4831edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.next_plus(Decimal('-Infinity'))
4832edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-9.99999999E+999')
4833edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.next_plus(1)
4834edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.00000001')
4835edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4836edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4837edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.next_plus(context=self)
4838edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4839edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def next_toward(self, a, b):
4840edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the number closest to a, in direction towards b.
4841edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4842edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The result is the closest representable number from the first
4843edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        operand (but not the first operand) that is in the direction
4844edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        towards the second operand, unless the operands have the same
4845edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        value.
4846edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4847edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c = ExtendedContext.copy()
4848edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emin = -999
4849edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emax = 999
4850edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.next_toward(Decimal('1'), Decimal('2'))
4851edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.00000001')
4852edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.next_toward(Decimal('-1E-1007'), Decimal('1'))
4853edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-0E-1007')
4854edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.next_toward(Decimal('-1.00000003'), Decimal('0'))
4855edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1.00000002')
4856edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.next_toward(Decimal('1'), Decimal('0'))
4857edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.999999999')
4858edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.next_toward(Decimal('1E-1007'), Decimal('-100'))
4859edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0E-1007')
4860edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.next_toward(Decimal('-1.00000003'), Decimal('-10'))
4861edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1.00000004')
4862edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.next_toward(Decimal('0.00'), Decimal('-0.0000'))
4863edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-0.00')
4864edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.next_toward(0, 1)
4865edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1E-1007')
4866edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.next_toward(Decimal(0), 1)
4867edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1E-1007')
4868edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.next_toward(0, Decimal(1))
4869edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1E-1007')
4870edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4871edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4872edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.next_toward(b, context=self)
4873edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4874edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def normalize(self, a):
4875edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """normalize reduces an operand to its simplest form.
4876edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4877edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Essentially a plus operation with all trailing zeros removed from the
4878edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result.
4879edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4880edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.normalize(Decimal('2.1'))
4881edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2.1')
4882edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.normalize(Decimal('-2.0'))
4883edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-2')
4884edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.normalize(Decimal('1.200'))
4885edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.2')
4886edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.normalize(Decimal('-120'))
4887edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1.2E+2')
4888edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.normalize(Decimal('120.00'))
4889edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.2E+2')
4890edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.normalize(Decimal('0.00'))
4891edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
4892edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.normalize(6)
4893edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('6')
4894edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4895edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4896edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.normalize(context=self)
4897edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4898edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def number_class(self, a):
4899edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns an indication of the class of the operand.
4900edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4901edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The class is one of the following strings:
4902edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          -sNaN
4903edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          -NaN
4904edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          -Infinity
4905edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          -Normal
4906edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          -Subnormal
4907edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          -Zero
4908edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          +Zero
4909edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          +Subnormal
4910edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          +Normal
4911edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep          +Infinity
4912edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4913edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c = Context(ExtendedContext)
4914edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emin = -999
4915edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emax = 999
4916edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.number_class(Decimal('Infinity'))
4917edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '+Infinity'
4918edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.number_class(Decimal('1E-10'))
4919edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '+Normal'
4920edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.number_class(Decimal('2.50'))
4921edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '+Normal'
4922edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.number_class(Decimal('0.1E-999'))
4923edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '+Subnormal'
4924edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.number_class(Decimal('0'))
4925edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '+Zero'
4926edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.number_class(Decimal('-0'))
4927edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '-Zero'
4928edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.number_class(Decimal('-0.1E-999'))
4929edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '-Subnormal'
4930edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.number_class(Decimal('-1E-10'))
4931edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '-Normal'
4932edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.number_class(Decimal('-2.50'))
4933edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '-Normal'
4934edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.number_class(Decimal('-Infinity'))
4935edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '-Infinity'
4936edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.number_class(Decimal('NaN'))
4937edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        'NaN'
4938edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.number_class(Decimal('-NaN'))
4939edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        'NaN'
4940edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.number_class(Decimal('sNaN'))
4941edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        'sNaN'
4942edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.number_class(123)
4943edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '+Normal'
4944edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4945edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4946edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.number_class(context=self)
4947edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4948edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def plus(self, a):
4949edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Plus corresponds to unary prefix plus in Python.
4950edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4951edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The operation is evaluated using the same rules as add; the
4952edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        operation plus(a) is calculated as add('0', a) where the '0'
4953edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        has the same exponent as the operand.
4954edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4955edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.plus(Decimal('1.3'))
4956edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.3')
4957edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.plus(Decimal('-1.3'))
4958edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1.3')
4959edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.plus(-1)
4960edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
4961edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
4962edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
4963edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.__pos__(context=self)
4964edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4965edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def power(self, a, b, modulo=None):
4966edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Raises a to the power of b, to modulo if given.
4967edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4968edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        With two arguments, compute a**b.  If a is negative then b
4969edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        must be integral.  The result will be inexact unless b is
4970edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        integral and the result is finite and can be expressed exactly
4971edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        in 'precision' digits.
4972edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4973edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        With three arguments, compute (a**b) % modulo.  For the
4974edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        three argument form, the following restrictions on the
4975edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        arguments hold:
4976edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4977edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep         - all three arguments must be integral
4978edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep         - b must be nonnegative
4979edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep         - at least one of a or b must be nonzero
4980edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep         - modulo must be nonzero and have at most 'precision' digits
4981edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4982edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The result of pow(a, b, modulo) is identical to the result
4983edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        that would be obtained by computing (a**b) % modulo with
4984edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        unbounded precision, but is computed more efficiently.  It is
4985edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        always exact.
4986edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4987edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c = ExtendedContext.copy()
4988edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emin = -999
4989edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.Emax = 999
4990edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('2'), Decimal('3'))
4991edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('8')
4992edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('-2'), Decimal('3'))
4993edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-8')
4994edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('2'), Decimal('-3'))
4995edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.125')
4996edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('1.7'), Decimal('8'))
4997edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('69.7575744')
4998edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('10'), Decimal('0.301029996'))
4999edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2.00000000')
5000edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('Infinity'), Decimal('-1'))
5001edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
5002edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('Infinity'), Decimal('0'))
5003edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
5004edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('Infinity'), Decimal('1'))
5005edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('Infinity')
5006edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('-Infinity'), Decimal('-1'))
5007edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-0')
5008edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('-Infinity'), Decimal('0'))
5009edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
5010edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('-Infinity'), Decimal('1'))
5011edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-Infinity')
5012edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('-Infinity'), Decimal('2'))
5013edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('Infinity')
5014edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('0'), Decimal('0'))
5015edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('NaN')
5016edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5017edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('3'), Decimal('7'), Decimal('16'))
5018edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('11')
5019edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('-3'), Decimal('7'), Decimal('16'))
5020edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-11')
5021edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('-3'), Decimal('8'), Decimal('16'))
5022edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
5023edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('3'), Decimal('7'), Decimal('-16'))
5024edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('11')
5025edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('23E12345'), Decimal('67E189'), Decimal('123456789'))
5026edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('11729830')
5027edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('-0'), Decimal('17'), Decimal('1729'))
5028edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-0')
5029edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> c.power(Decimal('-23'), Decimal('0'), Decimal('65537'))
5030edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
5031edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.power(7, 7)
5032edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('823543')
5033edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.power(Decimal(7), 7)
5034edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('823543')
5035edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.power(7, Decimal(7), 2)
5036edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
5037edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
5038edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
5039edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        r = a.__pow__(b, modulo, context=self)
5040edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if r is NotImplemented:
5041edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            raise TypeError("Unable to convert %s to Decimal" % b)
5042edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
5043edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return r
5044edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5045edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def quantize(self, a, b):
5046edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns a value equal to 'a' (rounded), having the exponent of 'b'.
5047edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5048edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The coefficient of the result is derived from that of the left-hand
5049edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        operand.  It may be rounded using the current rounding setting (if the
5050edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        exponent is being increased), multiplied by a positive power of ten (if
5051edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        the exponent is being decreased), or is unchanged (if the exponent is
5052edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        already equal to that of the right-hand operand).
5053edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5054edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Unlike other operations, if the length of the coefficient after the
5055edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        quantize operation would be greater than precision then an Invalid
5056edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        operation condition is raised.  This guarantees that, unless there is
5057edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        an error condition, the exponent of the result of a quantize is always
5058edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        equal to that of the right-hand operand.
5059edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5060edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Also unlike other operations, quantize will never raise Underflow, even
5061edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if the result is subnormal and inexact.
5062edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5063edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
5064edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2.170')
5065edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
5066edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2.17')
5067edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
5068edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2.2')
5069edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
5070edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2')
5071edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
5072edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0E+1')
5073edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
5074edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-Infinity')
5075edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
5076edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('NaN')
5077edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
5078edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-0')
5079edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
5080edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-0E+5')
5081edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
5082edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('NaN')
5083edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
5084edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('NaN')
5085edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
5086edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('217.0')
5087edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
5088edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('217')
5089edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
5090edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2.2E+2')
5091edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
5092edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2E+2')
5093edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(1, 2)
5094edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
5095edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(Decimal(1), 2)
5096edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
5097edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.quantize(1, Decimal(2))
5098edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
5099edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
5100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
5101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.quantize(b, context=self)
5102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def radix(self):
5104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Just returns 10, as this is Decimal, :)
5105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.radix()
5107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('10')
5108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
5109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return Decimal(10)
5110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def remainder(self, a, b):
5112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the remainder from integer division.
5113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The result is the residue of the dividend after the operation of
5115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        calculating integer division as described for divide-integer, rounded
5116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        to precision digits if necessary.  The sign of the result, if
5117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        non-zero, is the same as that of the original dividend.
5118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        This operation will fail under the same conditions as integer division
5120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (that is, if integer division on the same two operands would fail, the
5121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        remainder cannot be calculated).
5122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
5124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2.1')
5125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
5126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
5127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
5128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
5129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
5130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.2')
5131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
5132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.1')
5133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
5134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.0')
5135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder(22, 6)
5136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('4')
5137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder(Decimal(22), 6)
5138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('4')
5139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder(22, Decimal(6))
5140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('4')
5141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
5142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
5143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        r = a.__mod__(b, context=self)
5144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if r is NotImplemented:
5145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            raise TypeError("Unable to convert %s to Decimal" % b)
5146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
5147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return r
5148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def remainder_near(self, a, b):
5150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns to be "a - b * n", where n is the integer nearest the exact
5151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        value of "x / b" (if two integers are equally near then the even one
5152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        is chosen).  If the result is equal to 0 then its sign will be the
5153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        sign of a.
5154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        This operation will fail under the same conditions as integer division
5156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (that is, if integer division on the same two operands would fail, the
5157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        remainder cannot be calculated).
5158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
5160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-0.9')
5161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
5162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-2')
5163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
5164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
5165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
5166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-1')
5167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
5168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.2')
5169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
5170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.1')
5171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
5172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-0.3')
5173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder_near(3, 11)
5174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3')
5175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder_near(Decimal(3), 11)
5176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3')
5177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.remainder_near(3, Decimal(11))
5178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3')
5179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
5180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
5181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.remainder_near(b, context=self)
5182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def rotate(self, a, b):
5184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns a rotated copy of a, b times.
5185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The coefficient of the result is a rotated copy of the digits in
5187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        the coefficient of the first operand.  The number of places of
5188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        rotation is taken from the absolute value of the second operand,
5189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        with the rotation being to the left if the second operand is
5190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        positive or to the right otherwise.
5191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.rotate(Decimal('34'), Decimal('8'))
5193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('400000003')
5194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.rotate(Decimal('12'), Decimal('9'))
5195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('12')
5196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('-2'))
5197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('891234567')
5198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('0'))
5199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('123456789')
5200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('+2'))
5201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('345678912')
5202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.rotate(1333333, 1)
5203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('13333330')
5204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.rotate(Decimal(1333333), 1)
5205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('13333330')
5206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.rotate(1333333, Decimal(1))
5207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('13333330')
5208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
5209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
5210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.rotate(b, context=self)
5211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def same_quantum(self, a, b):
5213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns True if the two operands have the same exponent.
5214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The result is never affected by either the sign or the coefficient of
5216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        either operand.
5217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
5219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
5220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
5221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
5222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
5223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        False
5224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
5225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
5226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.same_quantum(10000, -1)
5227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
5228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.same_quantum(Decimal(10000), -1)
5229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
5230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.same_quantum(10000, Decimal(-1))
5231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        True
5232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
5233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
5234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.same_quantum(b)
5235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def scaleb (self, a, b):
5237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns the first operand after adding the second value its exp.
5238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('-2'))
5240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.0750')
5241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('0'))
5242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('7.50')
5243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('3'))
5244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('7.50E+3')
5245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.scaleb(1, 4)
5246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1E+4')
5247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.scaleb(Decimal(1), 4)
5248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1E+4')
5249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.scaleb(1, Decimal(4))
5250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1E+4')
5251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
5252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
5253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.scaleb(b, context=self)
5254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def shift(self, a, b):
5256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Returns a shifted copy of a, b times.
5257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The coefficient of the result is a shifted copy of the digits
5259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        in the coefficient of the first operand.  The number of places
5260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        to shift is taken from the absolute value of the second operand,
5261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        with the shift being to the left if the second operand is
5262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        positive or to the right otherwise.  Digits shifted into the
5263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        coefficient are zeros.
5264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.shift(Decimal('34'), Decimal('8'))
5266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('400000000')
5267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.shift(Decimal('12'), Decimal('9'))
5268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
5269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.shift(Decimal('123456789'), Decimal('-2'))
5270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1234567')
5271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.shift(Decimal('123456789'), Decimal('0'))
5272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('123456789')
5273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.shift(Decimal('123456789'), Decimal('+2'))
5274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('345678900')
5275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.shift(88888888, 2)
5276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('888888800')
5277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.shift(Decimal(88888888), 2)
5278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('888888800')
5279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.shift(88888888, Decimal(2))
5280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('888888800')
5281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
5282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
5283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.shift(b, context=self)
5284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def sqrt(self, a):
5286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Square root of a non-negative number to context precision.
5287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        If the result must be inexact, it is rounded using the round-half-even
5289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        algorithm.
5290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.sqrt(Decimal('0'))
5292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0')
5293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.sqrt(Decimal('-0'))
5294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-0')
5295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.sqrt(Decimal('0.39'))
5296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.624499800')
5297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.sqrt(Decimal('100'))
5298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('10')
5299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.sqrt(Decimal('1'))
5300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1')
5301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.sqrt(Decimal('1.0'))
5302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.0')
5303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.sqrt(Decimal('1.00'))
5304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.0')
5305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.sqrt(Decimal('7'))
5306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2.64575131')
5307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.sqrt(Decimal('10'))
5308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3.16227766')
5309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.sqrt(2)
5310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.41421356')
5311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.prec
5312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        9
5313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
5314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
5315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.sqrt(context=self)
5316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def subtract(self, a, b):
5318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Return the difference between the two operands.
5319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
5321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.23')
5322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
5323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('0.00')
5324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
5325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-0.77')
5326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.subtract(8, 5)
5327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3')
5328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.subtract(Decimal(8), 5)
5329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3')
5330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.subtract(8, Decimal(5))
5331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('3')
5332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
5333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
5334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        r = a.__sub__(b, context=self)
5335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if r is NotImplemented:
5336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            raise TypeError("Unable to convert %s to Decimal" % b)
5337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
5338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            return r
5339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def to_eng_string(self, a):
5341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Converts a number to a string, using scientific notation.
5342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The operation is not affected by the context.
5344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
5345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
5346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.to_eng_string(context=self)
5347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def to_sci_string(self, a):
5349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Converts a number to a string, using scientific notation.
5350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        The operation is not affected by the context.
5352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
5353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
5354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.__str__(context=self)
5355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def to_integral_exact(self, a):
5357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Rounds to an integer.
5358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        When the operand has a negative exponent, the result is the same
5360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        as using the quantize() operation using the given operand as the
5361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        left-hand-operand, 1E+0 as the right-hand-operand, and the precision
5362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        of the operand as the precision setting; Inexact and Rounded flags
5363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        are allowed in this operation.  The rounding mode is taken from the
5364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        context.
5365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.to_integral_exact(Decimal('2.1'))
5367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2')
5368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.to_integral_exact(Decimal('100'))
5369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('100')
5370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.to_integral_exact(Decimal('100.0'))
5371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('100')
5372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.to_integral_exact(Decimal('101.5'))
5373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('102')
5374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.to_integral_exact(Decimal('-101.5'))
5375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-102')
5376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.to_integral_exact(Decimal('10E+5'))
5377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.0E+6')
5378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.to_integral_exact(Decimal('7.89E+77'))
5379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('7.89E+77')
5380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.to_integral_exact(Decimal('-Inf'))
5381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-Infinity')
5382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
5383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
5384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.to_integral_exact(context=self)
5385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def to_integral_value(self, a):
5387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Rounds to an integer.
5388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        When the operand has a negative exponent, the result is the same
5390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        as using the quantize() operation using the given operand as the
5391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        left-hand-operand, 1E+0 as the right-hand-operand, and the precision
5392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        of the operand as the precision setting, except that no flags will
5393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        be set.  The rounding mode is taken from the context.
5394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.to_integral_value(Decimal('2.1'))
5396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('2')
5397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.to_integral_value(Decimal('100'))
5398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('100')
5399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.to_integral_value(Decimal('100.0'))
5400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('100')
5401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.to_integral_value(Decimal('101.5'))
5402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('102')
5403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.to_integral_value(Decimal('-101.5'))
5404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-102')
5405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.to_integral_value(Decimal('10E+5'))
5406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('1.0E+6')
5407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.to_integral_value(Decimal('7.89E+77'))
5408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('7.89E+77')
5409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        >>> ExtendedContext.to_integral_value(Decimal('-Inf'))
5410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Decimal('-Infinity')
5411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
5412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        a = _convert_other(a, raiseit=True)
5413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return a.to_integral_value(context=self)
5414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # the method name changed, but we provide also the old one, for compatibility
5416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    to_integral = to_integral_value
5417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass _WorkRep(object):
5419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    __slots__ = ('sign','int','exp')
5420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # sign: 0 or 1
5421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # int:  int or long
5422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # exp:  None, int, or string
5423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __init__(self, value=None):
5425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if value is None:
5426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.sign = None
5427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.int = 0
5428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.exp = None
5429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif isinstance(value, Decimal):
5430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.sign = value._sign
5431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.int = int(value._int)
5432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.exp = value._exp
5433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
5434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # assert isinstance(value, tuple)
5435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.sign = value[0]
5436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.int = value[1]
5437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.exp = value[2]
5438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __repr__(self):
5440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
5441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    __str__ = __repr__
5443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _normalize(op1, op2, prec = 0):
5447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Normalizes op1, op2 to have the same exp and length of coefficient.
5448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Done during addition.
5450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
5451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if op1.exp < op2.exp:
5452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        tmp = op2
5453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = op1
5454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    else:
5455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        tmp = op1
5456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other = op2
5457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Let exp = min(tmp.exp - 1, tmp.adjusted() - precision - 1).
5459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Then adding 10**exp to tmp has the same effect (after rounding)
5460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # as adding any positive quantity smaller than 10**exp; similarly
5461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # for subtraction.  So if other is smaller than 10**exp we replace
5462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # it with 10**exp.  This avoids tmp.exp - other.exp getting too large.
5463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    tmp_len = len(str(tmp.int))
5464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    other_len = len(str(other.int))
5465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    exp = tmp.exp + min(-1, tmp_len - prec - 2)
5466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if other_len + other.exp - 1 < exp:
5467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other.int = 1
5468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        other.exp = exp
5469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    tmp.int *= 10 ** (tmp.exp - other.exp)
5471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    tmp.exp = other.exp
5472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return op1, op2
5473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### Integer arithmetic functions used by ln, log10, exp and __pow__ #####
5475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# This function from Tim Peters was taken from here:
5477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# http://mail.python.org/pipermail/python-list/1999-July/007758.html
5478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# The correction being in the function definition is for speed, and
5479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# the whole function is not resolved with math.log because of avoiding
5480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# the use of floats.
5481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _nbits(n, correction = {
5482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '0': 4, '1': 3, '2': 2, '3': 2,
5483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '4': 1, '5': 1, '6': 1, '7': 1,
5484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '8': 0, '9': 0, 'a': 0, 'b': 0,
5485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        'c': 0, 'd': 0, 'e': 0, 'f': 0}):
5486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Number of bits in binary representation of the positive integer n,
5487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    or 0 if n == 0.
5488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
5489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if n < 0:
5490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        raise ValueError("The argument to _nbits should be nonnegative.")
5491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    hex_n = "%x" % n
5492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return 4*len(hex_n) - correction[hex_n[0]]
5493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _decimal_lshift_exact(n, e):
5495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """ Given integers n and e, return n * 10**e if it's an integer, else None.
5496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    The computation is designed to avoid computing large powers of 10
5498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    unnecessarily.
5499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    >>> _decimal_lshift_exact(3, 4)
5501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    30000
5502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    >>> _decimal_lshift_exact(300, -999999999)  # returns None
5503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
5505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if n == 0:
5506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return 0
5507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    elif e >= 0:
5508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return n * 10**e
5509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    else:
5510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # val_n = largest power of 10 dividing n.
5511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        str_n = str(abs(n))
5512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        val_n = len(str_n) - len(str_n.rstrip('0'))
5513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return None if val_n < -e else n // 10**-e
5514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _sqrt_nearest(n, a):
5516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Closest integer to the square root of the positive integer n.  a is
5517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    an initial approximation to the square root.  Any positive integer
5518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    will do for a, but the closer a is to the square root of n the
5519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    faster convergence will be.
5520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
5522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if n <= 0 or a <= 0:
5523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        raise ValueError("Both arguments to _sqrt_nearest should be positive.")
5524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    b=0
5526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    while a != b:
5527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        b, a = a, a--n//a>>1
5528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return a
5529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _rshift_nearest(x, shift):
5531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Given an integer x and a nonnegative integer shift, return closest
5532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    integer to x / 2**shift; use round-to-even in case of a tie.
5533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
5535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    b, q = 1L << shift, x >> shift
5536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return q + (2*(x & (b-1)) + (q&1) > b)
5537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _div_nearest(a, b):
5539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Closest integer to a/b, a and b positive integers; rounds to even
5540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    in the case of a tie.
5541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
5543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    q, r = divmod(a, b)
5544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return q + (2*r + (q&1) > b)
5545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _ilog(x, M, L = 8):
5547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Integer approximation to M*log(x/M), with absolute error boundable
5548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    in terms only of x/M.
5549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Given positive integers x and M, return an integer approximation to
5551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    M * log(x/M).  For L = 8 and 0.1 <= x/M <= 10 the difference
5552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    between the approximation and the exact result is at most 22.  For
5553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    L = 8 and 1.0 <= x/M <= 10.0 the difference is at most 15.  In
5554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    both cases these are upper bounds on the error; it will usually be
5555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    much smaller."""
5556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # The basic algorithm is the following: let log1p be the function
5558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # log1p(x) = log(1+x).  Then log(x/M) = log1p((x-M)/M).  We use
5559edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # the reduction
5560edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #
5561edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #    log1p(y) = 2*log1p(y/(1+sqrt(1+y)))
5562edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #
5563edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # repeatedly until the argument to log1p is small (< 2**-L in
5564edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # absolute value).  For small y we can use the Taylor series
5565edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # expansion
5566edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #
5567edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #    log1p(y) ~ y - y**2/2 + y**3/3 - ... - (-y)**T/T
5568edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #
5569edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # truncating at T such that y**T is small enough.  The whole
5570edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # computation is carried out in a form of fixed-point arithmetic,
5571edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # with a real number z being represented by an integer
5572edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # approximation to z*M.  To avoid loss of precision, the y below
5573edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # is actually an integer approximation to 2**R*y*M, where R is the
5574edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # number of reductions performed so far.
5575edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5576edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    y = x-M
5577edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # argument reduction; R = number of reductions performed
5578edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    R = 0
5579edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    while (R <= L and long(abs(y)) << L-R >= M or
5580edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep           R > L and abs(y) >> R-L >= M):
5581edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        y = _div_nearest(long(M*y) << 1,
5582edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         M + _sqrt_nearest(M*(M+_rshift_nearest(y, R)), M))
5583edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        R += 1
5584edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5585edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Taylor series with T terms
5586edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    T = -int(-10*len(str(M))//(3*L))
5587edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    yshift = _rshift_nearest(y, R)
5588edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    w = _div_nearest(M, T)
5589edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    for k in xrange(T-1, 0, -1):
5590edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        w = _div_nearest(M, k) - _div_nearest(yshift*w, M)
5591edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5592edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return _div_nearest(w*y, M)
5593edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5594edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _dlog10(c, e, p):
5595edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Given integers c, e and p with c > 0, p >= 0, compute an integer
5596edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    approximation to 10**p * log10(c*10**e), with an absolute error of
5597edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    at most 1.  Assumes that c*10**e is not exactly 1."""
5598edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5599edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # increase precision by 2; compensate for this by dividing
5600edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # final result by 100
5601edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    p += 2
5602edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5603edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # write c*10**e as d*10**f with either:
5604edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #   f >= 0 and 1 <= d <= 10, or
5605edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #   f <= 0 and 0.1 <= d <= 1.
5606edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Thus for c*10**e close to 1, f = 0
5607edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    l = len(str(c))
5608edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    f = e+l - (e+l >= 1)
5609edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5610edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if p > 0:
5611edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        M = 10**p
5612edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        k = e+p-f
5613edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if k >= 0:
5614edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            c *= 10**k
5615edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
5616edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            c = _div_nearest(c, 10**-k)
5617edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5618edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        log_d = _ilog(c, M) # error < 5 + 22 = 27
5619edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        log_10 = _log10_digits(p) # error < 1
5620edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        log_d = _div_nearest(log_d*M, log_10)
5621edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        log_tenpower = f*M # exact
5622edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    else:
5623edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        log_d = 0  # error < 2.31
5624edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        log_tenpower = _div_nearest(f, 10**-p) # error < 0.5
5625edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5626edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return _div_nearest(log_tenpower+log_d, 100)
5627edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5628edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _dlog(c, e, p):
5629edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Given integers c, e and p with c > 0, compute an integer
5630edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    approximation to 10**p * log(c*10**e), with an absolute error of
5631edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    at most 1.  Assumes that c*10**e is not exactly 1."""
5632edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5633edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Increase precision by 2. The precision increase is compensated
5634edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # for at the end with a division by 100.
5635edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    p += 2
5636edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5637edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # rewrite c*10**e as d*10**f with either f >= 0 and 1 <= d <= 10,
5638edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # or f <= 0 and 0.1 <= d <= 1.  Then we can compute 10**p * log(c*10**e)
5639edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # as 10**p * log(d) + 10**p*f * log(10).
5640edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    l = len(str(c))
5641edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    f = e+l - (e+l >= 1)
5642edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5643edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # compute approximation to 10**p*log(d), with error < 27
5644edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if p > 0:
5645edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        k = e+p-f
5646edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if k >= 0:
5647edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            c *= 10**k
5648edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
5649edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            c = _div_nearest(c, 10**-k)  # error of <= 0.5 in c
5650edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5651edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # _ilog magnifies existing error in c by a factor of at most 10
5652edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        log_d = _ilog(c, 10**p) # error < 5 + 22 = 27
5653edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    else:
5654edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # p <= 0: just approximate the whole thing by 0; error < 2.31
5655edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        log_d = 0
5656edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5657edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # compute approximation to f*10**p*log(10), with error < 11.
5658edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if f:
5659edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        extra = len(str(abs(f)))-1
5660edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if p + extra >= 0:
5661edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # error in f * _log10_digits(p+extra) < |f| * 1 = |f|
5662edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # after division, error < |f|/10**extra + 0.5 < 10 + 0.5 < 11
5663edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            f_log_ten = _div_nearest(f*_log10_digits(p+extra), 10**extra)
5664edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
5665edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            f_log_ten = 0
5666edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    else:
5667edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        f_log_ten = 0
5668edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5669edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # error in sum < 11+27 = 38; error after division < 0.38 + 0.5 < 1
5670edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return _div_nearest(f_log_ten + log_d, 100)
5671edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5672edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass _Log10Memoize(object):
5673edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Class to compute, store, and allow retrieval of, digits of the
5674edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    constant log(10) = 2.302585....  This constant is needed by
5675edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Decimal.ln, Decimal.log10, Decimal.exp and Decimal.__pow__."""
5676edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def __init__(self):
5677edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.digits = "23025850929940456840179914546843642076011014886"
5678edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5679edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def getdigits(self, p):
5680edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """Given an integer p >= 0, return floor(10**p)*log(10).
5681edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5682edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        For example, self.getdigits(3) returns 2302.
5683edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """
5684edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # digits are stored as a string, for quick conversion to
5685edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # integer in the case that we've already computed enough
5686edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # digits; the stored digits should always be correct
5687edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # (truncated, not rounded to nearest).
5688edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if p < 0:
5689edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            raise ValueError("p should be nonnegative")
5690edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5691edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if p >= len(self.digits):
5692edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # compute p+3, p+6, p+9, ... digits; continue until at
5693edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # least one of the extra digits is nonzero
5694edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            extra = 3
5695edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            while True:
5696edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                # compute p+extra digits, correct to within 1ulp
5697edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                M = 10**(p+extra+2)
5698edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                digits = str(_div_nearest(_ilog(10*M, M), 100))
5699edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                if digits[-extra:] != '0'*extra:
5700edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                    break
5701edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                extra += 3
5702edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # keep all reliable digits so far; remove trailing zeros
5703edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # and next nonzero digit
5704edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.digits = digits.rstrip('0')[:-1]
5705edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return int(self.digits[:p+1])
5706edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5707edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_log10_digits = _Log10Memoize().getdigits
5708edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5709edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _iexp(x, M, L=8):
5710edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Given integers x and M, M > 0, such that x/M is small in absolute
5711edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    value, compute an integer approximation to M*exp(x/M).  For 0 <=
5712edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    x/M <= 2.4, the absolute error in the result is bounded by 60 (and
5713edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    is usually much smaller)."""
5714edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5715edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Algorithm: to compute exp(z) for a real number z, first divide z
5716edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # by a suitable power R of 2 so that |z/2**R| < 2**-L.  Then
5717edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # compute expm1(z/2**R) = exp(z/2**R) - 1 using the usual Taylor
5718edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # series
5719edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #
5720edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #     expm1(x) = x + x**2/2! + x**3/3! + ...
5721edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #
5722edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Now use the identity
5723edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #
5724edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #     expm1(2x) = expm1(x)*(expm1(x)+2)
5725edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #
5726edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # R times to compute the sequence expm1(z/2**R),
5727edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # expm1(z/2**(R-1)), ... , exp(z/2), exp(z).
5728edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5729edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Find R such that x/2**R/M <= 2**-L
5730edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    R = _nbits((long(x)<<L)//M)
5731edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5732edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Taylor series.  (2**L)**T > M
5733edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    T = -int(-10*len(str(M))//(3*L))
5734edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    y = _div_nearest(x, T)
5735edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Mshift = long(M)<<R
5736edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    for i in xrange(T-1, 0, -1):
5737edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        y = _div_nearest(x*(Mshift + y), Mshift * i)
5738edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5739edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Expansion
5740edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    for k in xrange(R-1, -1, -1):
5741edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Mshift = long(M)<<(k+2)
5742edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        y = _div_nearest(y*(y+Mshift), Mshift)
5743edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5744edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return M+y
5745edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5746edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _dexp(c, e, p):
5747edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Compute an approximation to exp(c*10**e), with p decimal places of
5748edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    precision.
5749edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5750edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Returns integers d, f such that:
5751edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5752edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      10**(p-1) <= d <= 10**p, and
5753edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      (d-1)*10**f < exp(c*10**e) < (d+1)*10**f
5754edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5755edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    In other words, d*10**f is an approximation to exp(c*10**e) with p
5756edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    digits of precision, and with an error in d of at most 1.  This is
5757edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    almost, but not quite, the same as the error being < 1ulp: when d
5758edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    = 10**(p-1) the error could be up to 10 ulp."""
5759edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5760edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # we'll call iexp with M = 10**(p+2), giving p+3 digits of precision
5761edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    p += 2
5762edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5763edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # compute log(10) with extra precision = adjusted exponent of c*10**e
5764edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    extra = max(0, e + len(str(c)) - 1)
5765edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    q = p + extra
5766edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5767edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # compute quotient c*10**e/(log(10)) = c*10**(e+q)/(log(10)*10**q),
5768edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # rounding down
5769edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    shift = e+q
5770edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if shift >= 0:
5771edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        cshift = c*10**shift
5772edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    else:
5773edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        cshift = c//10**-shift
5774edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    quot, rem = divmod(cshift, _log10_digits(q))
5775edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5776edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # reduce remainder back to original precision
5777edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    rem = _div_nearest(rem, 10**extra)
5778edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5779edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # error in result of _iexp < 120;  error after division < 0.62
5780edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return _div_nearest(_iexp(rem, 10**p), 1000), quot - p + 3
5781edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5782edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _dpower(xc, xe, yc, ye, p):
5783edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Given integers xc, xe, yc and ye representing Decimals x = xc*10**xe and
5784edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    y = yc*10**ye, compute x**y.  Returns a pair of integers (c, e) such that:
5785edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5786edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      10**(p-1) <= c <= 10**p, and
5787edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      (c-1)*10**e < x**y < (c+1)*10**e
5788edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5789edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    in other words, c*10**e is an approximation to x**y with p digits
5790edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    of precision, and with an error in c of at most 1.  (This is
5791edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    almost, but not quite, the same as the error being < 1ulp: when c
5792edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    == 10**(p-1) we can only guarantee error < 10ulp.)
5793edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5794edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    We assume that: x is positive and not equal to 1, and y is nonzero.
5795edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
5796edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5797edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # Find b such that 10**(b-1) <= |y| <= 10**b
5798edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    b = len(str(abs(yc))) + ye
5799edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5800edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # log(x) = lxc*10**(-p-b-1), to p+b+1 places after the decimal point
5801edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    lxc = _dlog(xc, xe, p+b+1)
5802edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5803edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # compute product y*log(x) = yc*lxc*10**(-p-b-1+ye) = pc*10**(-p-1)
5804edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    shift = ye-b
5805edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if shift >= 0:
5806edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        pc = lxc*yc*10**shift
5807edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    else:
5808edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        pc = _div_nearest(lxc*yc, 10**-shift)
5809edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5810edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if pc == 0:
5811edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # we prefer a result that isn't exactly 1; this makes it
5812edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # easier to compute a correctly rounded result in __pow__
5813edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if ((len(str(xc)) + xe >= 1) == (yc > 0)): # if x**y > 1:
5814edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            coeff, exp = 10**(p-1)+1, 1-p
5815edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        else:
5816edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            coeff, exp = 10**p-1, -p
5817edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    else:
5818edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        coeff, exp = _dexp(pc, -(p+1), p+1)
5819edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        coeff = _div_nearest(coeff, 10)
5820edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        exp += 1
5821edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5822edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return coeff, exp
5823edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5824edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _log10_lb(c, correction = {
5825edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '1': 100, '2': 70, '3': 53, '4': 40, '5': 31,
5826edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '6': 23, '7': 16, '8': 10, '9': 5}):
5827edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Compute a lower bound for 100*log10(c) for a positive integer c."""
5828edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if c <= 0:
5829edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        raise ValueError("The argument to _log10_lb should be nonnegative.")
5830edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    str_c = str(c)
5831edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return 100*len(str_c) - correction[str_c[0]]
5832edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5833edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### Helper Functions ####################################################
5834edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5835edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _convert_other(other, raiseit=False, allow_float=False):
5836edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Convert other to Decimal.
5837edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5838edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Verifies that it's ok to use in an implicit construction.
5839edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    If allow_float is true, allow conversion from float;  this
5840edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    is used in the comparison methods (__eq__ and friends).
5841edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5842edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
5843edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if isinstance(other, Decimal):
5844edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return other
5845edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if isinstance(other, (int, long)):
5846edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return Decimal(other)
5847edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if allow_float and isinstance(other, float):
5848edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return Decimal.from_float(other)
5849edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5850edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if raiseit:
5851edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        raise TypeError("Unable to convert %s to Decimal" % other)
5852edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return NotImplemented
5853edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5854edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### Setup Specific Contexts ############################################
5855edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5856edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# The default context prototype used by Context()
5857edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Is mutable, so that new contexts can have different default values
5858edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5859edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDefaultContext = Context(
5860edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        prec=28, rounding=ROUND_HALF_EVEN,
5861edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        traps=[DivisionByZero, Overflow, InvalidOperation],
5862edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        flags=[],
5863edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Emax=999999999,
5864edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Emin=-999999999,
5865edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        capitals=1
5866edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep)
5867edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5868edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Pre-made alternate contexts offered by the specification
5869edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Don't change these; the user should be able to select these
5870edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# contexts and be able to reproduce results from other implementations
5871edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# of the spec.
5872edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5873edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepBasicContext = Context(
5874edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        prec=9, rounding=ROUND_HALF_UP,
5875edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
5876edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        flags=[],
5877edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep)
5878edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5879edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepExtendedContext = Context(
5880edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        prec=9, rounding=ROUND_HALF_EVEN,
5881edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        traps=[],
5882edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        flags=[],
5883edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep)
5884edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5885edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5886edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### crud for parsing strings #############################################
5887edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#
5888edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Regular expression used for parsing numeric strings.  Additional
5889edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# comments:
5890edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#
5891edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 1. Uncomment the two '\s*' lines to allow leading and/or trailing
5892edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# whitespace.  But note that the specification disallows whitespace in
5893edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# a numeric string.
5894edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#
5895edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 2. For finite numbers (not infinities and NaNs) the body of the
5896edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# number between the optional sign and the optional exponent must have
5897edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# at least one decimal digit, possibly after the decimal point.  The
5898edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# lookahead expression '(?=\d|\.\d)' checks this.
5899edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5900edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport re
5901edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_parser = re.compile(r"""        # A numeric string consists of:
5902edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#    \s*
5903edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    (?P<sign>[-+])?              # an optional sign, followed by either...
5904edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    (
5905edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (?=\d|\.\d)              # ...a number (with at least one digit)
5906edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (?P<int>\d*)             # having a (possibly empty) integer part
5907edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (\.(?P<frac>\d*))?       # followed by an optional fractional part
5908edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (E(?P<exp>[-+]?\d+))?    # followed by an optional exponent, or...
5909edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    |
5910edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        Inf(inity)?              # ...an infinity, or...
5911edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    |
5912edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (?P<signal>s)?           # ...an (optionally signaling)
5913edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        NaN                      # NaN
5914edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        (?P<diag>\d*)            # with (possibly empty) diagnostic info.
5915edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    )
5916edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#    \s*
5917edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    \Z
5918edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""", re.VERBOSE | re.IGNORECASE | re.UNICODE).match
5919edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5920edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_all_zeros = re.compile('0*$').match
5921edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_exact_half = re.compile('50*$').match
5922edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5923edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### PEP3101 support functions ##############################################
5924edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# The functions in this section have little to do with the Decimal
5925edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# class, and could potentially be reused or adapted for other pure
5926edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Python numeric classes that want to implement __format__
5927edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#
5928edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# A format specifier for Decimal looks like:
5929edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#
5930edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#   [[fill]align][sign][0][minimumwidth][,][.precision][type]
5931edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5932edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_parse_format_specifier_regex = re.compile(r"""\A
5933edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep(?:
5934edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep   (?P<fill>.)?
5935edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep   (?P<align>[<>=^])
5936edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep)?
5937edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep(?P<sign>[-+ ])?
5938edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep(?P<zeropad>0)?
5939edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep(?P<minimumwidth>(?!0)\d+)?
5940edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep(?P<thousands_sep>,)?
5941edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep(?:\.(?P<precision>0|(?!0)\d+))?
5942edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep(?P<type>[eEfFgGn%])?
5943edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\Z
5944edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""", re.VERBOSE)
5945edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5946edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdel re
5947edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5948edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# The locale module is only needed for the 'n' format specifier.  The
5949edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# rest of the PEP 3101 code functions quite happily without it, so we
5950edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# don't care too much if locale isn't present.
5951edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoeptry:
5952edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    import locale as _locale
5953edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepexcept ImportError:
5954edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    pass
5955edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5956edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _parse_format_specifier(format_spec, _localeconv=None):
5957edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Parse and validate a format specifier.
5958edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5959edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Turns a standard numeric format specifier into a dict, with the
5960edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    following entries:
5961edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5962edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      fill: fill character to pad field to minimum width
5963edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      align: alignment type, either '<', '>', '=' or '^'
5964edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      sign: either '+', '-' or ' '
5965edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      minimumwidth: nonnegative integer giving minimum width
5966edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      zeropad: boolean, indicating whether to pad with zeros
5967edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      thousands_sep: string to use as thousands separator, or ''
5968edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      grouping: grouping for thousands separators, in format
5969edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        used by localeconv
5970edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      decimal_point: string to use for decimal point
5971edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      precision: nonnegative integer giving precision, or None
5972edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      type: one of the characters 'eEfFgG%', or None
5973edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      unicode: boolean (always True for Python 3.x)
5974edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5975edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
5976edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    m = _parse_format_specifier_regex.match(format_spec)
5977edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if m is None:
5978edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        raise ValueError("Invalid format specifier: " + format_spec)
5979edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5980edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # get the dictionary
5981edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    format_dict = m.groupdict()
5982edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
5983edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # zeropad; defaults for fill and alignment.  If zero padding
5984edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # is requested, the fill and align fields should be absent.
5985edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    fill = format_dict['fill']
5986edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    align = format_dict['align']
5987edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    format_dict['zeropad'] = (format_dict['zeropad'] is not None)
5988edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if format_dict['zeropad']:
5989edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if fill is not None:
5990edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            raise ValueError("Fill character conflicts with '0'"
5991edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                             " in format specifier: " + format_spec)
5992edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if align is not None:
5993edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            raise ValueError("Alignment conflicts with '0' in "
5994edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                             "format specifier: " + format_spec)
5995edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    format_dict['fill'] = fill or ' '
5996edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # PEP 3101 originally specified that the default alignment should
5997edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # be left;  it was later agreed that right-aligned makes more sense
5998edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # for numeric types.  See http://bugs.python.org/issue6857.
5999edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    format_dict['align'] = align or '>'
6000edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6001edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # default sign handling: '-' for negative, '' for positive
6002edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if format_dict['sign'] is None:
6003edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        format_dict['sign'] = '-'
6004edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6005edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # minimumwidth defaults to 0; precision remains None if not given
6006edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    format_dict['minimumwidth'] = int(format_dict['minimumwidth'] or '0')
6007edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if format_dict['precision'] is not None:
6008edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        format_dict['precision'] = int(format_dict['precision'])
6009edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6010edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # if format type is 'g' or 'G' then a precision of 0 makes little
6011edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # sense; convert it to 1.  Same if format type is unspecified.
6012edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if format_dict['precision'] == 0:
6013edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if format_dict['type'] is None or format_dict['type'] in 'gG':
6014edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            format_dict['precision'] = 1
6015edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6016edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # determine thousands separator, grouping, and decimal separator, and
6017edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # add appropriate entries to format_dict
6018edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if format_dict['type'] == 'n':
6019edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # apart from separators, 'n' behaves just like 'g'
6020edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        format_dict['type'] = 'g'
6021edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if _localeconv is None:
6022edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            _localeconv = _locale.localeconv()
6023edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if format_dict['thousands_sep'] is not None:
6024edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            raise ValueError("Explicit thousands separator conflicts with "
6025edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                             "'n' type in format specifier: " + format_spec)
6026edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        format_dict['thousands_sep'] = _localeconv['thousands_sep']
6027edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        format_dict['grouping'] = _localeconv['grouping']
6028edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        format_dict['decimal_point'] = _localeconv['decimal_point']
6029edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    else:
6030edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if format_dict['thousands_sep'] is None:
6031edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            format_dict['thousands_sep'] = ''
6032edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        format_dict['grouping'] = [3, 0]
6033edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        format_dict['decimal_point'] = '.'
6034edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6035edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # record whether return type should be str or unicode
6036edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    format_dict['unicode'] = isinstance(format_spec, unicode)
6037edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6038edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return format_dict
6039edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6040edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _format_align(sign, body, spec):
6041edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Given an unpadded, non-aligned numeric string 'body' and sign
6042edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    string 'sign', add padding and alignment conforming to the given
6043edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    format specifier dictionary 'spec' (as produced by
6044edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    parse_format_specifier).
6045edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6046edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    Also converts result to unicode if necessary.
6047edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6048edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
6049edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # how much extra space do we have to play with?
6050edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    minimumwidth = spec['minimumwidth']
6051edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    fill = spec['fill']
6052edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    padding = fill*(minimumwidth - len(sign) - len(body))
6053edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6054edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    align = spec['align']
6055edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if align == '<':
6056edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = sign + body + padding
6057edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    elif align == '>':
6058edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = padding + sign + body
6059edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    elif align == '=':
6060edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = sign + padding + body
6061edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    elif align == '^':
6062edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        half = len(padding)//2
6063edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = padding[:half] + sign + body + padding[half:]
6064edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    else:
6065edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        raise ValueError('Unrecognised alignment field')
6066edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6067edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # make sure that result is unicode if necessary
6068edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if spec['unicode']:
6069edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = unicode(result)
6070edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6071edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return result
6072edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6073edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _group_lengths(grouping):
6074edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Convert a localeconv-style grouping into a (possibly infinite)
6075edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    iterable of integers representing group lengths.
6076edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6077edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
6078edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # The result from localeconv()['grouping'], and the input to this
6079edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # function, should be a list of integers in one of the
6080edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # following three forms:
6081edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #
6082edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #   (1) an empty list, or
6083edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #   (2) nonempty list of positive integers + [0]
6084edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    #   (3) list of positive integers + [locale.CHAR_MAX], or
6085edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6086edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    from itertools import chain, repeat
6087edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if not grouping:
6088edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return []
6089edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    elif grouping[-1] == 0 and len(grouping) >= 2:
6090edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return chain(grouping[:-1], repeat(grouping[-2]))
6091edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    elif grouping[-1] == _locale.CHAR_MAX:
6092edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return grouping[:-1]
6093edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    else:
6094edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        raise ValueError('unrecognised format for grouping')
6095edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6096edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _insert_thousands_sep(digits, spec, min_width=1):
6097edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Insert thousands separators into a digit string.
6098edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6099edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    spec is a dictionary whose keys should include 'thousands_sep' and
6100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    'grouping'; typically it's the result of parsing the format
6101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    specifier using _parse_format_specifier.
6102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    The min_width keyword argument gives the minimum length of the
6104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    result, which will be padded on the left with zeros if necessary.
6105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    If necessary, the zero padding adds an extra '0' on the left to
6107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    avoid a leading thousands separator.  For example, inserting
6108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    commas every three digits in '123456', with min_width=8, gives
6109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    '0,123,456', even though that has length 9.
6110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
6112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    sep = spec['thousands_sep']
6114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    grouping = spec['grouping']
6115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    groups = []
6117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    for l in _group_lengths(grouping):
6118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if l <= 0:
6119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            raise ValueError("group length should be positive")
6120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # max(..., 1) forces at least 1 digit to the left of a separator
6121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        l = min(max(len(digits), min_width, 1), l)
6122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        groups.append('0'*(l - len(digits)) + digits[-l:])
6123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        digits = digits[:-l]
6124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        min_width -= l
6125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if not digits and min_width <= 0:
6126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            break
6127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        min_width -= len(sep)
6128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    else:
6129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        l = max(len(digits), min_width, 1)
6130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        groups.append('0'*(l - len(digits)) + digits[-l:])
6131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return sep.join(reversed(groups))
6132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _format_sign(is_negative, spec):
6134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Determine sign character."""
6135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if is_negative:
6137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return '-'
6138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    elif spec['sign'] in ' +':
6139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return spec['sign']
6140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    else:
6141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return ''
6142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _format_number(is_negative, intpart, fracpart, exp, spec):
6144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """Format a number, given the following data:
6145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    is_negative: true if the number is negative, else false
6147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    intpart: string of digits that must appear before the decimal point
6148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    fracpart: string of digits that must come after the point
6149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    exp: exponent, as an integer
6150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    spec: dictionary resulting from parsing the format specifier
6151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    This function uses the information in spec to:
6153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      insert separators (decimal separator and thousands separators)
6154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      format the sign
6155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      format the exponent
6156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      add trailing '%' for the '%' type
6157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      zero-pad if necessary
6158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep      fill and align if necessary
6159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    """
6160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    sign = _format_sign(is_negative, spec)
6162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if fracpart:
6164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        fracpart = spec['decimal_point'] + fracpart
6165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if exp != 0 or spec['type'] in 'eE':
6167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        echar = {'E': 'E', 'e': 'e', 'G': 'E', 'g': 'e'}[spec['type']]
6168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        fracpart += "{0}{1:+}".format(echar, exp)
6169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if spec['type'] == '%':
6170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        fracpart += '%'
6171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if spec['zeropad']:
6173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        min_width = spec['minimumwidth'] - len(fracpart) - len(sign)
6174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    else:
6175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        min_width = 0
6176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    intpart = _insert_thousands_sep(intpart, spec, min_width)
6177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    return _format_align(sign, intpart+fracpart, spec)
6179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep##### Useful Constants (internal use only) ################################
6182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Reusable defaults
6184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_Infinity = Decimal('Inf')
6185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_NegativeInfinity = Decimal('-Inf')
6186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_NaN = Decimal('NaN')
6187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_Zero = Decimal(0)
6188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_One = Decimal(1)
6189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_NegativeOne = Decimal(-1)
6190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# _SignedInfinity[sign] is infinity w/ that sign
6192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep_SignedInfinity = (_Infinity, _NegativeInfinity)
6193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepif __name__ == '__main__':
6197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    import doctest, sys
6198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    doctest.testmod(sys.modules[__name__])
6199