:mod:`decimal` --- Decimal fixed point and floating point arithmetic
====================================================================

.. module:: decimal
   :synopsis: Implementation of the General Decimal Arithmetic  Specification.

.. moduleauthor:: Eric Price <eprice at tjhsst.edu>
.. moduleauthor:: Facundo Batista <facundo at taniquetil.com.ar>
.. moduleauthor:: Raymond Hettinger <python at rcn.com>
.. moduleauthor:: Aahz <aahz at pobox.com>
.. moduleauthor:: Tim Peters <tim.one at comcast.net>
.. moduleauthor:: Stefan Krah <skrah at bytereef.org>
.. sectionauthor:: Raymond D. Hettinger <python at rcn.com>

.. import modules for testing inline doctests with the Sphinx doctest builder
.. testsetup:: *

   import decimal
   import math
   from decimal import *
   # make sure each group gets a fresh context
   setcontext(Context())

The :mod:`decimal` module provides support for fast correctly-rounded
decimal floating point arithmetic. It offers several advantages over the
:class:`float` datatype:

* Decimal "is based on a floating-point model which was designed with people
  in mind, and necessarily has a paramount guiding principle -- computers must
  provide an arithmetic that works in the same way as the arithmetic that
  people learn at school." -- excerpt from the decimal arithmetic specification.

* Decimal numbers can be represented exactly.  In contrast, numbers like
  :const:`1.1` and :const:`2.2` do not have exact representations in binary
  floating point. End users typically would not expect ``1.1 + 2.2`` to display
  as :const:`3.3000000000000003` as it does with binary floating point.

* The exactness carries over into arithmetic.  In decimal floating point, ``0.1
  + 0.1 + 0.1 - 0.3`` is exactly equal to zero.  In binary floating point, the result
  is :const:`5.5511151231257827e-017`.  While near to zero, the differences
  prevent reliable equality testing and differences can accumulate. For this
  reason, decimal is preferred in accounting applications which have strict
  equality invariants.

* The decimal module incorporates a notion of significant places so that ``1.30
  + 1.20`` is :const:`2.50`.  The trailing zero is kept to indicate significance.
  This is the customary presentation for monetary applications. For
  multiplication, the "schoolbook" approach uses all the figures in the
  multiplicands.  For instance, ``1.3 * 1.2`` gives :const:`1.56` while ``1.30 *
  1.20`` gives :const:`1.5600`.

* Unlike hardware based binary floating point, the decimal module has a user
  alterable precision (defaulting to 28 places) which can be as large as needed for
  a given problem:

     >>> from decimal import *
     >>> getcontext().prec = 6
     >>> Decimal(1) / Decimal(7)
     Decimal('0.142857')
     >>> getcontext().prec = 28
     >>> Decimal(1) / Decimal(7)
     Decimal('0.1428571428571428571428571429')

* Both binary and decimal floating point are implemented in terms of published
  standards.  While the built-in float type exposes only a modest portion of its
  capabilities, the decimal module exposes all required parts of the standard.
  When needed, the programmer has full control over rounding and signal handling.
  This includes an option to enforce exact arithmetic by using exceptions
  to block any inexact operations.

* The decimal module was designed to support "without prejudice, both exact
  unrounded decimal arithmetic (sometimes called fixed-point arithmetic)
  and rounded floating-point arithmetic."  -- excerpt from the decimal
  arithmetic specification.

The module design is centered around three concepts:  the decimal number, the
context for arithmetic, and signals.

A decimal number is immutable.  It has a sign, coefficient digits, and an
exponent.  To preserve significance, the coefficient digits do not truncate
trailing zeros.  Decimals also include special values such as
:const:`Infinity`, :const:`-Infinity`, and :const:`NaN`.  The standard also
differentiates :const:`-0` from :const:`+0`.

The context for arithmetic is an environment specifying precision, rounding
rules, limits on exponents, flags indicating the results of operations, and trap
enablers which determine whether signals are treated as exceptions.  Rounding
options include :const:`ROUND_CEILING`, :const:`ROUND_DOWN`,
:const:`ROUND_FLOOR`, :const:`ROUND_HALF_DOWN`, :const:`ROUND_HALF_EVEN`,
:const:`ROUND_HALF_UP`, :const:`ROUND_UP`, and :const:`ROUND_05UP`.

Signals are groups of exceptional conditions arising during the course of
computation.  Depending on the needs of the application, signals may be ignored,
considered as informational, or treated as exceptions. The signals in the
decimal module are: :const:`Clamped`, :const:`InvalidOperation`,
:const:`DivisionByZero`, :const:`Inexact`, :const:`Rounded`, :const:`Subnormal`,
:const:`Overflow`, :const:`Underflow` and :const:`FloatOperation`.

For each signal there is a flag and a trap enabler.  When a signal is
encountered, its flag is set to one, then, if the trap enabler is
set to one, an exception is raised.  Flags are sticky, so the user needs to
reset them before monitoring a calculation.


.. seealso::

   * IBM's General Decimal Arithmetic Specification, `The General Decimal Arithmetic
     Specification <http://speleotrove.com/decimal/decarith.html>`_.

   * IEEE standard 854-1987, `Unofficial IEEE 854 Text
     <http://754r.ucbtest.org/standards/854.pdf>`_.

.. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


.. _decimal-tutorial:

Quick-start Tutorial
--------------------

The usual start to using decimals is importing the module, viewing the current
context with :func:`getcontext` and, if necessary, setting new values for
precision, rounding, or enabled traps::

   >>> from decimal import *
   >>> getcontext()
   Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
           capitals=1, clamp=0, flags=[], traps=[Overflow, DivisionByZero,
           InvalidOperation])

   >>> getcontext().prec = 7       # Set a new precision

Decimal instances can be constructed from integers, strings, floats, or tuples.
Construction from an integer or a float performs an exact conversion of the
value of that integer or float.  Decimal numbers include special values such as
:const:`NaN` which stands for "Not a number", positive and negative
:const:`Infinity`, and :const:`-0`::

   >>> getcontext().prec = 28
   >>> Decimal(10)
   Decimal('10')
   >>> Decimal('3.14')
   Decimal('3.14')
   >>> Decimal(3.14)
   Decimal('3.140000000000000124344978758017532527446746826171875')
   >>> Decimal((0, (3, 1, 4), -2))
   Decimal('3.14')
   >>> Decimal(str(2.0 ** 0.5))
   Decimal('1.4142135623730951')
   >>> Decimal(2) ** Decimal('0.5')
   Decimal('1.414213562373095048801688724')
   >>> Decimal('NaN')
   Decimal('NaN')
   >>> Decimal('-Infinity')
   Decimal('-Infinity')

If the :exc:`FloatOperation` signal is trapped, accidental mixing of
decimals and floats in constructors or ordering comparisons raises
an exception::

   >>> c = getcontext()
   >>> c.traps[FloatOperation] = True
   >>> Decimal(3.14)
   Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
   >>> Decimal('3.5') < 3.7
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
   >>> Decimal('3.5') == 3.5
   True

.. versionadded:: 3.3

The significance of a new Decimal is determined solely by the number of digits
input.  Context precision and rounding only come into play during arithmetic
operations.

.. doctest:: newcontext

   >>> getcontext().prec = 6
   >>> Decimal('3.0')
   Decimal('3.0')
   >>> Decimal('3.1415926535')
   Decimal('3.1415926535')
   >>> Decimal('3.1415926535') + Decimal('2.7182818285')
   Decimal('5.85987')
   >>> getcontext().rounding = ROUND_UP
   >>> Decimal('3.1415926535') + Decimal('2.7182818285')
   Decimal('5.85988')

If the internal limits of the C version are exceeded, constructing
a decimal raises :class:`InvalidOperation`::

   >>> Decimal("1e9999999999999999999")
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]

.. versionchanged:: 3.3

Decimals interact well with much of the rest of Python.  Here is a small decimal
floating point flying circus:

.. doctest::
   :options: +NORMALIZE_WHITESPACE

   >>> data = list(map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split()))
   >>> max(data)
   Decimal('9.25')
   >>> min(data)
   Decimal('0.03')
   >>> sorted(data)
   [Decimal('0.03'), Decimal('1.00'), Decimal('1.34'), Decimal('1.87'),
    Decimal('2.35'), Decimal('3.45'), Decimal('9.25')]
   >>> sum(data)
   Decimal('19.29')
   >>> a,b,c = data[:3]
   >>> str(a)
   '1.34'
   >>> float(a)
   1.34
   >>> round(a, 1)
   Decimal('1.3')
   >>> int(a)
   1
   >>> a * 5
   Decimal('6.70')
   >>> a * b
   Decimal('2.5058')
   >>> c % a
   Decimal('0.77')

And some mathematical functions are also available to Decimal:

   >>> getcontext().prec = 28
   >>> Decimal(2).sqrt()
   Decimal('1.414213562373095048801688724')
   >>> Decimal(1).exp()
   Decimal('2.718281828459045235360287471')
   >>> Decimal('10').ln()
   Decimal('2.302585092994045684017991455')
   >>> Decimal('10').log10()
   Decimal('1')

The :meth:`quantize` method rounds a number to a fixed exponent.  This method is
useful for monetary applications that often round results to a fixed number of
places:

   >>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)
   Decimal('7.32')
   >>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)
   Decimal('8')

As shown above, the :func:`getcontext` function accesses the current context and
allows the settings to be changed.  This approach meets the needs of most
applications.

For more advanced work, it may be useful to create alternate contexts using the
Context() constructor.  To make an alternate active, use the :func:`setcontext`
function.

In accordance with the standard, the :mod:`Decimal` module provides two ready to
use standard contexts, :const:`BasicContext` and :const:`ExtendedContext`. The
former is especially useful for debugging because many of the traps are
enabled:

.. doctest:: newcontext
   :options: +NORMALIZE_WHITESPACE

   >>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN)
   >>> setcontext(myothercontext)
   >>> Decimal(1) / Decimal(7)
   Decimal('0.142857142857142857142857142857142857142857142857142857142857')

   >>> ExtendedContext
   Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
           capitals=1, clamp=0, flags=[], traps=[])
   >>> setcontext(ExtendedContext)
   >>> Decimal(1) / Decimal(7)
   Decimal('0.142857143')
   >>> Decimal(42) / Decimal(0)
   Decimal('Infinity')

   >>> setcontext(BasicContext)
   >>> Decimal(42) / Decimal(0)
   Traceback (most recent call last):
     File "<pyshell#143>", line 1, in -toplevel-
       Decimal(42) / Decimal(0)
   DivisionByZero: x / 0

Contexts also have signal flags for monitoring exceptional conditions
encountered during computations.  The flags remain set until explicitly cleared,
so it is best to clear the flags before each set of monitored computations by
using the :meth:`clear_flags` method. ::

   >>> setcontext(ExtendedContext)
   >>> getcontext().clear_flags()
   >>> Decimal(355) / Decimal(113)
   Decimal('3.14159292')
   >>> getcontext()
   Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
           capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[])

The *flags* entry shows that the rational approximation to :const:`Pi` was
rounded (digits beyond the context precision were thrown away) and that the
result is inexact (some of the discarded digits were non-zero).

Individual traps are set using the dictionary in the :attr:`traps` field of a
context:

.. doctest:: newcontext

   >>> setcontext(ExtendedContext)
   >>> Decimal(1) / Decimal(0)
   Decimal('Infinity')
   >>> getcontext().traps[DivisionByZero] = 1
   >>> Decimal(1) / Decimal(0)
   Traceback (most recent call last):
     File "<pyshell#112>", line 1, in -toplevel-
       Decimal(1) / Decimal(0)
   DivisionByZero: x / 0

Most programs adjust the current context only once, at the beginning of the
program.  And, in many applications, data is converted to :class:`Decimal` with
a single cast inside a loop.  With context set and decimals created, the bulk of
the program manipulates the data no differently than with other Python numeric
types.

.. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


.. _decimal-decimal:

Decimal objects
---------------


.. class:: Decimal(value="0", context=None)

   Construct a new :class:`Decimal` object based from *value*.

   *value* can be an integer, string, tuple, :class:`float`, or another :class:`Decimal`
   object. If no *value* is given, returns ``Decimal('0')``.  If *value* is a
   string, it should conform to the decimal numeric string syntax after leading
   and trailing whitespace characters are removed::

      sign           ::=  '+' | '-'
      digit          ::=  '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
      indicator      ::=  'e' | 'E'
      digits         ::=  digit [digit]...
      decimal-part   ::=  digits '.' [digits] | ['.'] digits
      exponent-part  ::=  indicator [sign] digits
      infinity       ::=  'Infinity' | 'Inf'
      nan            ::=  'NaN' [digits] | 'sNaN' [digits]
      numeric-value  ::=  decimal-part [exponent-part] | infinity
      numeric-string ::=  [sign] numeric-value | [sign] nan

   Other Unicode decimal digits are also permitted where ``digit``
   appears above.  These include decimal digits from various other
   alphabets (for example, Arabic-Indic and Devanāgarī digits) along
   with the fullwidth digits ``'\uff10'`` through ``'\uff19'``.

   If *value* is a :class:`tuple`, it should have three components, a sign
   (:const:`0` for positive or :const:`1` for negative), a :class:`tuple` of
   digits, and an integer exponent. For example, ``Decimal((0, (1, 4, 1, 4), -3))``
   returns ``Decimal('1.414')``.

   If *value* is a :class:`float`, the binary floating point value is losslessly
   converted to its exact decimal equivalent.  This conversion can often require
   53 or more digits of precision.  For example, ``Decimal(float('1.1'))``
   converts to
   ``Decimal('1.100000000000000088817841970012523233890533447265625')``.

   The *context* precision does not affect how many digits are stored. That is
   determined exclusively by the number of digits in *value*. For example,
   ``Decimal('3.00000')`` records all five zeros even if the context precision is
   only three.

   The purpose of the *context* argument is determining what to do if *value* is a
   malformed string.  If the context traps :const:`InvalidOperation`, an exception
   is raised; otherwise, the constructor returns a new Decimal with the value of
   :const:`NaN`.

   Once constructed, :class:`Decimal` objects are immutable.

   .. versionchanged:: 3.2
      The argument to the constructor is now permitted to be a :class:`float`
      instance.

   .. versionchanged:: 3.3
      :class:`float` arguments raise an exception if the :exc:`FloatOperation`
      trap is set. By default the trap is off.

   Decimal floating point objects share many properties with the other built-in
   numeric types such as :class:`float` and :class:`int`.  All of the usual math
   operations and special methods apply.  Likewise, decimal objects can be
   copied, pickled, printed, used as dictionary keys, used as set elements,
   compared, sorted, and coerced to another type (such as :class:`float` or
   :class:`int`).

   Decimal objects cannot generally be combined with floats or
   instances of :class:`fractions.Fraction` in arithmetic operations:
   an attempt to add a :class:`Decimal` to a :class:`float`, for
   example, will raise a :exc:`TypeError`.  However, it is possible to
   use Python's comparison operators to compare a :class:`Decimal`
   instance ``x`` with another number ``y``.  This avoids confusing results
   when doing equality comparisons between numbers of different types.

   .. versionchanged:: 3.2
      Mixed-type comparisons between :class:`Decimal` instances and other
      numeric types are now fully supported.

   In addition to the standard numeric properties, decimal floating point
   objects also have a number of specialized methods:


   .. method:: adjusted()

      Return the adjusted exponent after shifting out the coefficient's
      rightmost digits until only the lead digit remains:
      ``Decimal('321e+5').adjusted()`` returns seven.  Used for determining the
      position of the most significant digit with respect to the decimal point.


   .. method:: as_tuple()

      Return a :term:`named tuple` representation of the number:
      ``DecimalTuple(sign, digits, exponent)``.


   .. method:: canonical()

      Return the canonical encoding of the argument.  Currently, the encoding of
      a :class:`Decimal` instance is always canonical, so this operation returns
      its argument unchanged.

   .. method:: compare(other[, context])

      Compare the values of two Decimal instances.  :meth:`compare` returns a
      Decimal instance, and if either operand is a NaN then the result is a
      NaN::

         a or b is a NaN  ==> Decimal('NaN')
         a < b            ==> Decimal('-1')
         a == b           ==> Decimal('0')
         a > b            ==> Decimal('1')

   .. method:: compare_signal(other[, context])

      This operation is identical to the :meth:`compare` method, except that all
      NaNs signal.  That is, if neither operand is a signaling NaN then any
      quiet NaN operand is treated as though it were a signaling NaN.

   .. method:: compare_total(other)

      Compare two operands using their abstract representation rather than their
      numerical value.  Similar to the :meth:`compare` method, but the result
      gives a total ordering on :class:`Decimal` instances.  Two
      :class:`Decimal` instances with the same numeric value but different
      representations compare unequal in this ordering:

         >>> Decimal('12.0').compare_total(Decimal('12'))
         Decimal('-1')

      Quiet and signaling NaNs are also included in the total ordering.  The
      result of this function is ``Decimal('0')`` if both operands have the same
      representation, ``Decimal('-1')`` if the first operand is lower in the
      total order than the second, and ``Decimal('1')`` if the first operand is
      higher in the total order than the second operand.  See the specification
      for details of the total order.

   .. method:: compare_total_mag(other)

      Compare two operands using their abstract representation rather than their
      value as in :meth:`compare_total`, but ignoring the sign of each operand.
      ``x.compare_total_mag(y)`` is equivalent to
      ``x.copy_abs().compare_total(y.copy_abs())``.

   .. method:: conjugate()

      Just returns self, this method is only to comply with the Decimal
      Specification.

   .. method:: copy_abs()

      Return the absolute value of the argument.  This operation is unaffected
      by the context and is quiet: no flags are changed and no rounding is
      performed.

   .. method:: copy_negate()

      Return the negation of the argument.  This operation is unaffected by the
      context and is quiet: no flags are changed and no rounding is performed.

   .. method:: copy_sign(other)

      Return a copy of the first operand with the sign set to be the same as the
      sign of the second operand.  For example:

         >>> Decimal('2.3').copy_sign(Decimal('-1.5'))
         Decimal('-2.3')

      This operation is unaffected by the context and is quiet: no flags are
      changed and no rounding is performed.

   .. method:: exp([context])

      Return the value of the (natural) exponential function ``e**x`` at the
      given number.  The result is correctly rounded using the
      :const:`ROUND_HALF_EVEN` rounding mode.

      >>> Decimal(1).exp()
      Decimal('2.718281828459045235360287471')
      >>> Decimal(321).exp()
      Decimal('2.561702493119680037517373933E+139')

   .. method:: from_float(f)

      Classmethod that converts a float to a decimal number, exactly.

      Note `Decimal.from_float(0.1)` is not the same as `Decimal('0.1')`.
      Since 0.1 is not exactly representable in binary floating point, the
      value is stored as the nearest representable value which is
      `0x1.999999999999ap-4`.  That equivalent value in decimal is
      `0.1000000000000000055511151231257827021181583404541015625`.

      .. note:: From Python 3.2 onwards, a :class:`Decimal` instance
         can also be constructed directly from a :class:`float`.

      .. doctest::

          >>> Decimal.from_float(0.1)
          Decimal('0.1000000000000000055511151231257827021181583404541015625')
          >>> Decimal.from_float(float('nan'))
          Decimal('NaN')
          >>> Decimal.from_float(float('inf'))
          Decimal('Infinity')
          >>> Decimal.from_float(float('-inf'))
          Decimal('-Infinity')

      .. versionadded:: 3.1

   .. method:: fma(other, third[, context])

      Fused multiply-add.  Return self*other+third with no rounding of the
      intermediate product self*other.

      >>> Decimal(2).fma(3, 5)
      Decimal('11')

   .. method:: is_canonical()

      Return :const:`True` if the argument is canonical and :const:`False`
      otherwise.  Currently, a :class:`Decimal` instance is always canonical, so
      this operation always returns :const:`True`.

   .. method:: is_finite()

      Return :const:`True` if the argument is a finite number, and
      :const:`False` if the argument is an infinity or a NaN.

   .. method:: is_infinite()

      Return :const:`True` if the argument is either positive or negative
      infinity and :const:`False` otherwise.

   .. method:: is_nan()

      Return :const:`True` if the argument is a (quiet or signaling) NaN and
      :const:`False` otherwise.

   .. method:: is_normal()

      Return :const:`True` if the argument is a *normal* finite number.  Return
      :const:`False` if the argument is zero, subnormal, infinite or a NaN.

   .. method:: is_qnan()

      Return :const:`True` if the argument is a quiet NaN, and
      :const:`False` otherwise.

   .. method:: is_signed()

      Return :const:`True` if the argument has a negative sign and
      :const:`False` otherwise.  Note that zeros and NaNs can both carry signs.

   .. method:: is_snan()

      Return :const:`True` if the argument is a signaling NaN and :const:`False`
      otherwise.

   .. method:: is_subnormal()

      Return :const:`True` if the argument is subnormal, and :const:`False`
      otherwise.

   .. method:: is_zero()

      Return :const:`True` if the argument is a (positive or negative) zero and
      :const:`False` otherwise.

   .. method:: ln([context])

      Return the natural (base e) logarithm of the operand.  The result is
      correctly rounded using the :const:`ROUND_HALF_EVEN` rounding mode.

   .. method:: log10([context])

      Return the base ten logarithm of the operand.  The result is correctly
      rounded using the :const:`ROUND_HALF_EVEN` rounding mode.

   .. method:: logb([context])

      For a nonzero number, return the adjusted exponent of its operand as a
      :class:`Decimal` instance.  If the operand is a zero then
      ``Decimal('-Infinity')`` is returned and the :const:`DivisionByZero` flag
      is raised.  If the operand is an infinity then ``Decimal('Infinity')`` is
      returned.

   .. method:: logical_and(other[, context])

      :meth:`logical_and` is a logical operation which takes two *logical
      operands* (see :ref:`logical_operands_label`).  The result is the
      digit-wise ``and`` of the two operands.

   .. method:: logical_invert([context])

      :meth:`logical_invert` is a logical operation.  The
      result is the digit-wise inversion of the operand.

   .. method:: logical_or(other[, context])

      :meth:`logical_or` is a logical operation which takes two *logical
      operands* (see :ref:`logical_operands_label`).  The result is the
      digit-wise ``or`` of the two operands.

   .. method:: logical_xor(other[, context])

      :meth:`logical_xor` is a logical operation which takes two *logical
      operands* (see :ref:`logical_operands_label`).  The result is the
      digit-wise exclusive or of the two operands.

   .. method:: max(other[, context])

      Like ``max(self, other)`` except that the context rounding rule is applied
      before returning and that :const:`NaN` values are either signaled or
      ignored (depending on the context and whether they are signaling or
      quiet).

   .. method:: max_mag(other[, context])

      Similar to the :meth:`.max` method, but the comparison is done using the
      absolute values of the operands.

   .. method:: min(other[, context])

      Like ``min(self, other)`` except that the context rounding rule is applied
      before returning and that :const:`NaN` values are either signaled or
      ignored (depending on the context and whether they are signaling or
      quiet).

   .. method:: min_mag(other[, context])

      Similar to the :meth:`.min` method, but the comparison is done using the
      absolute values of the operands.

   .. method:: next_minus([context])

      Return the largest number representable in the given context (or in the
      current thread's context if no context is given) that is smaller than the
      given operand.

   .. method:: next_plus([context])

      Return the smallest number representable in the given context (or in the
      current thread's context if no context is given) that is larger than the
      given operand.

   .. method:: next_toward(other[, context])

      If the two operands are unequal, return the number closest to the first
      operand in the direction of the second operand.  If both operands are
      numerically equal, return a copy of the first operand with the sign set to
      be the same as the sign of the second operand.

   .. method:: normalize([context])

      Normalize the number by stripping the rightmost trailing zeros and
      converting any result equal to :const:`Decimal('0')` to
      :const:`Decimal('0e0')`. Used for producing canonical values for attributes
      of an equivalence class. For example, ``Decimal('32.100')`` and
      ``Decimal('0.321000e+2')`` both normalize to the equivalent value
      ``Decimal('32.1')``.

   .. method:: number_class([context])

      Return a string describing the *class* of the operand.  The returned value
      is one of the following ten strings.

      * ``"-Infinity"``, indicating that the operand is negative infinity.
      * ``"-Normal"``, indicating that the operand is a negative normal number.
      * ``"-Subnormal"``, indicating that the operand is negative and subnormal.
      * ``"-Zero"``, indicating that the operand is a negative zero.
      * ``"+Zero"``, indicating that the operand is a positive zero.
      * ``"+Subnormal"``, indicating that the operand is positive and subnormal.
      * ``"+Normal"``, indicating that the operand is a positive normal number.
      * ``"+Infinity"``, indicating that the operand is positive infinity.
      * ``"NaN"``, indicating that the operand is a quiet NaN (Not a Number).
      * ``"sNaN"``, indicating that the operand is a signaling NaN.

   .. method:: quantize(exp[, rounding[, context[, watchexp]]])

      Return a value equal to the first operand after rounding and having the
      exponent of the second operand.

      >>> Decimal('1.41421356').quantize(Decimal('1.000'))
      Decimal('1.414')

      Unlike other operations, if the length of the coefficient after the
      quantize operation would be greater than precision, then an
      :const:`InvalidOperation` is signaled. This guarantees that, unless there
      is an error condition, the quantized exponent is always equal to that of
      the right-hand operand.

      Also unlike other operations, quantize never signals Underflow, even if
      the result is subnormal and inexact.

      If the exponent of the second operand is larger than that of the first
      then rounding may be necessary.  In this case, the rounding mode is
      determined by the ``rounding`` argument if given, else by the given
      ``context`` argument; if neither argument is given the rounding mode of
      the current thread's context is used.

      If *watchexp* is set (default), then an error is returned whenever the
      resulting exponent is greater than :attr:`Emax` or less than
      :attr:`Etiny`.

   .. method:: radix()

      Return ``Decimal(10)``, the radix (base) in which the :class:`Decimal`
      class does all its arithmetic.  Included for compatibility with the
      specification.

   .. method:: remainder_near(other[, context])

      Compute the modulo as either a positive or negative value depending on
      which is closest to zero.  For instance, ``Decimal(10).remainder_near(6)``
      returns ``Decimal('-2')`` which is closer to zero than ``Decimal('4')``.

      If both are equally close, the one chosen will have the same sign as
      *self*.

   .. method:: rotate(other[, context])

      Return the result of rotating the digits of the first operand by an amount
      specified by the second operand.  The second operand must be an integer in
      the range -precision through precision.  The absolute value of the second
      operand gives the number of places to rotate.  If the second operand is
      positive then rotation is to the left; otherwise rotation is to the right.
      The coefficient of the first operand is padded on the left with zeros to
      length precision if necessary.  The sign and exponent of the first operand
      are unchanged.

   .. method:: same_quantum(other[, context])

      Test whether self and other have the same exponent or whether both are
      :const:`NaN`.

   .. method:: scaleb(other[, context])

      Return the first operand with exponent adjusted by the second.
      Equivalently, return the first operand multiplied by ``10**other``.  The
      second operand must be an integer.

   .. method:: shift(other[, context])

      Return the result of shifting the digits of the first operand by an amount
      specified by the second operand.  The second operand must be an integer in
      the range -precision through precision.  The absolute value of the second
      operand gives the number of places to shift.  If the second operand is
      positive then the shift is to the left; otherwise the shift is to the
      right.  Digits shifted into the coefficient are zeros.  The sign and
      exponent of the first operand are unchanged.

   .. method:: sqrt([context])

      Return the square root of the argument to full precision.


   .. method:: to_eng_string([context])

      Convert to an engineering-type string.

      Engineering notation has an exponent which is a multiple of 3, so there
      are up to 3 digits left of the decimal place.  For example, converts
      ``Decimal('123E+1')`` to ``Decimal('1.23E+3')``

   .. method:: to_integral([rounding[, context]])

      Identical to the :meth:`to_integral_value` method.  The ``to_integral``
      name has been kept for compatibility with older versions.

   .. method:: to_integral_exact([rounding[, context]])

      Round to the nearest integer, signaling :const:`Inexact` or
      :const:`Rounded` as appropriate if rounding occurs.  The rounding mode is
      determined by the ``rounding`` parameter if given, else by the given
      ``context``.  If neither parameter is given then the rounding mode of the
      current context is used.

   .. method:: to_integral_value([rounding[, context]])

      Round to the nearest integer without signaling :const:`Inexact` or
      :const:`Rounded`.  If given, applies *rounding*; otherwise, uses the
      rounding method in either the supplied *context* or the current context.


.. _logical_operands_label:

Logical operands
^^^^^^^^^^^^^^^^

The :meth:`logical_and`, :meth:`logical_invert`, :meth:`logical_or`,
and :meth:`logical_xor` methods expect their arguments to be *logical
operands*.  A *logical operand* is a :class:`Decimal` instance whose
exponent and sign are both zero, and whose digits are all either
:const:`0` or :const:`1`.

.. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


.. _decimal-context:

Context objects
---------------

Contexts are environments for arithmetic operations.  They govern precision, set
rules for rounding, determine which signals are treated as exceptions, and limit
the range for exponents.

Each thread has its own current context which is accessed or changed using the
:func:`getcontext` and :func:`setcontext` functions:


.. function:: getcontext()

   Return the current context for the active thread.


.. function:: setcontext(c)

   Set the current context for the active thread to *c*.

You can also use the :keyword:`with` statement and the :func:`localcontext`
function to temporarily change the active context.

.. function:: localcontext([c])

   Return a context manager that will set the current context for the active thread
   to a copy of *c* on entry to the with-statement and restore the previous context
   when exiting the with-statement. If no context is specified, a copy of the
   current context is used.

   For example, the following code sets the current decimal precision to 42 places,
   performs a calculation, and then automatically restores the previous context::

      from decimal import localcontext

      with localcontext() as ctx:
          ctx.prec = 42   # Perform a high precision calculation
          s = calculate_something()
      s = +s  # Round the final result back to the default precision

New contexts can also be created using the :class:`Context` constructor
described below. In addition, the module provides three pre-made contexts:


.. class:: BasicContext

   This is a standard context defined by the General Decimal Arithmetic
   Specification.  Precision is set to nine.  Rounding is set to
   :const:`ROUND_HALF_UP`.  All flags are cleared.  All traps are enabled (treated
   as exceptions) except :const:`Inexact`, :const:`Rounded`, and
   :const:`Subnormal`.

   Because many of the traps are enabled, this context is useful for debugging.


.. class:: ExtendedContext

   This is a standard context defined by the General Decimal Arithmetic
   Specification.  Precision is set to nine.  Rounding is set to
   :const:`ROUND_HALF_EVEN`.  All flags are cleared.  No traps are enabled (so that
   exceptions are not raised during computations).

   Because the traps are disabled, this context is useful for applications that
   prefer to have result value of :const:`NaN` or :const:`Infinity` instead of
   raising exceptions.  This allows an application to complete a run in the
   presence of conditions that would otherwise halt the program.


.. class:: DefaultContext

   This context is used by the :class:`Context` constructor as a prototype for new
   contexts.  Changing a field (such a precision) has the effect of changing the
   default for new contexts created by the :class:`Context` constructor.

   This context is most useful in multi-threaded environments.  Changing one of the
   fields before threads are started has the effect of setting system-wide
   defaults.  Changing the fields after threads have started is not recommended as
   it would require thread synchronization to prevent race conditions.

   In single threaded environments, it is preferable to not use this context at
   all.  Instead, simply create contexts explicitly as described below.

   The default values are :attr:`prec`\ =\ :const:`28`,
   :attr:`rounding`\ =\ :const:`ROUND_HALF_EVEN`,
   and enabled traps for :class:`Overflow`, :class:`InvalidOperation`, and
   :class:`DivisionByZero`.

In addition to the three supplied contexts, new contexts can be created with the
:class:`Context` constructor.


.. class:: Context(prec=None, rounding=None, Emin=None, Emax=None, capitals=None, clamp=None, flags=None, traps=None)

   Creates a new context.  If a field is not specified or is :const:`None`, the
   default values are copied from the :const:`DefaultContext`.  If the *flags*
   field is not specified or is :const:`None`, all flags are cleared.

   *prec* is an integer in the range [:const:`1`, :const:`MAX_PREC`] that sets
   the precision for arithmetic operations in the context.

   The *rounding* option is one of the constants listed in the section
   `Rounding Modes`_.

   The *traps* and *flags* fields list any signals to be set. Generally, new
   contexts should only set traps and leave the flags clear.

   The *Emin* and *Emax* fields are integers specifying the outer limits allowable
   for exponents. *Emin* must be in the range [:const:`MIN_EMIN`, :const:`0`],
   *Emax* in the range [:const:`0`, :const:`MAX_EMAX`].

   The *capitals* field is either :const:`0` or :const:`1` (the default). If set to
   :const:`1`, exponents are printed with a capital :const:`E`; otherwise, a
   lowercase :const:`e` is used: :const:`Decimal('6.02e+23')`.

   The *clamp* field is either :const:`0` (the default) or :const:`1`.
   If set to :const:`1`, the exponent ``e`` of a :class:`Decimal`
   instance representable in this context is strictly limited to the
   range ``Emin - prec + 1 <= e <= Emax - prec + 1``.  If *clamp* is
   :const:`0` then a weaker condition holds: the adjusted exponent of
   the :class:`Decimal` instance is at most ``Emax``.  When *clamp* is
   :const:`1`, a large normal number will, where possible, have its
   exponent reduced and a corresponding number of zeros added to its
   coefficient, in order to fit the exponent constraints; this
   preserves the value of the number but loses information about
   significant trailing zeros.  For example::

      >>> Context(prec=6, Emax=999, clamp=1).create_decimal('1.23e999')
      Decimal('1.23000E+999')

   A *clamp* value of :const:`1` allows compatibility with the
   fixed-width decimal interchange formats specified in IEEE 754.

   The :class:`Context` class defines several general purpose methods as well as
   a large number of methods for doing arithmetic directly in a given context.
   In addition, for each of the :class:`Decimal` methods described above (with
   the exception of the :meth:`adjusted` and :meth:`as_tuple` methods) there is
   a corresponding :class:`Context` method.  For example, for a :class:`Context`
   instance ``C`` and :class:`Decimal` instance ``x``, ``C.exp(x)`` is
   equivalent to ``x.exp(context=C)``.  Each :class:`Context` method accepts a
   Python integer (an instance of :class:`int`) anywhere that a
   Decimal instance is accepted.


   .. method:: clear_flags()

      Resets all of the flags to :const:`0`.

   .. method:: clear_traps()

      Resets all of the traps to :const:`0`.

      .. versionadded:: 3.3

   .. method:: copy()

      Return a duplicate of the context.

   .. method:: copy_decimal(num)

      Return a copy of the Decimal instance num.

   .. method:: create_decimal(num)

      Creates a new Decimal instance from *num* but using *self* as
      context. Unlike the :class:`Decimal` constructor, the context precision,
      rounding method, flags, and traps are applied to the conversion.

      This is useful because constants are often given to a greater precision
      than is needed by the application.  Another benefit is that rounding
      immediately eliminates unintended effects from digits beyond the current
      precision. In the following example, using unrounded inputs means that
      adding zero to a sum can change the result:

      .. doctest:: newcontext

         >>> getcontext().prec = 3
         >>> Decimal('3.4445') + Decimal('1.0023')
         Decimal('4.45')
         >>> Decimal('3.4445') + Decimal(0) + Decimal('1.0023')
         Decimal('4.44')

      This method implements the to-number operation of the IBM specification.
      If the argument is a string, no leading or trailing whitespace is
      permitted.

   .. method:: create_decimal_from_float(f)

      Creates a new Decimal instance from a float *f* but rounding using *self*
      as the context.  Unlike the :meth:`Decimal.from_float` class method,
      the context precision, rounding method, flags, and traps are applied to
      the conversion.

      .. doctest::

         >>> context = Context(prec=5, rounding=ROUND_DOWN)
         >>> context.create_decimal_from_float(math.pi)
         Decimal('3.1415')
         >>> context = Context(prec=5, traps=[Inexact])
         >>> context.create_decimal_from_float(math.pi)
         Traceback (most recent call last):
             ...
         decimal.Inexact: None

      .. versionadded:: 3.1

   .. method:: Etiny()

      Returns a value equal to ``Emin - prec + 1`` which is the minimum exponent
      value for subnormal results.  When underflow occurs, the exponent is set
      to :const:`Etiny`.

   .. method:: Etop()

      Returns a value equal to ``Emax - prec + 1``.

   The usual approach to working with decimals is to create :class:`Decimal`
   instances and then apply arithmetic operations which take place within the
   current context for the active thread.  An alternative approach is to use
   context methods for calculating within a specific context.  The methods are
   similar to those for the :class:`Decimal` class and are only briefly
   recounted here.


   .. method:: abs(x)

      Returns the absolute value of *x*.


   .. method:: add(x, y)

      Return the sum of *x* and *y*.


   .. method:: canonical(x)

      Returns the same Decimal object *x*.


   .. method:: compare(x, y)

      Compares *x* and *y* numerically.


   .. method:: compare_signal(x, y)

      Compares the values of the two operands numerically.


   .. method:: compare_total(x, y)

      Compares two operands using their abstract representation.


   .. method:: compare_total_mag(x, y)

      Compares two operands using their abstract representation, ignoring sign.


   .. method:: copy_abs(x)

      Returns a copy of *x* with the sign set to 0.


   .. method:: copy_negate(x)

      Returns a copy of *x* with the sign inverted.


   .. method:: copy_sign(x, y)

      Copies the sign from *y* to *x*.


   .. method:: divide(x, y)

      Return *x* divided by *y*.


   .. method:: divide_int(x, y)

      Return *x* divided by *y*, truncated to an integer.


   .. method:: divmod(x, y)

      Divides two numbers and returns the integer part of the result.


   .. method:: exp(x)

      Returns `e ** x`.


   .. method:: fma(x, y, z)

      Returns *x* multiplied by *y*, plus *z*.


   .. method:: is_canonical(x)

      Returns True if *x* is canonical; otherwise returns False.


   .. method:: is_finite(x)

      Returns True if *x* is finite; otherwise returns False.


   .. method:: is_infinite(x)

      Returns True if *x* is infinite; otherwise returns False.


   .. method:: is_nan(x)

      Returns True if *x* is a qNaN or sNaN; otherwise returns False.


   .. method:: is_normal(x)

      Returns True if *x* is a normal number; otherwise returns False.


   .. method:: is_qnan(x)

      Returns True if *x* is a quiet NaN; otherwise returns False.


   .. method:: is_signed(x)

      Returns True if *x* is negative; otherwise returns False.


   .. method:: is_snan(x)

      Returns True if *x* is a signaling NaN; otherwise returns False.


   .. method:: is_subnormal(x)

      Returns True if *x* is subnormal; otherwise returns False.


   .. method:: is_zero(x)

      Returns True if *x* is a zero; otherwise returns False.


   .. method:: ln(x)

      Returns the natural (base e) logarithm of *x*.


   .. method:: log10(x)

      Returns the base 10 logarithm of *x*.


   .. method:: logb(x)

       Returns the exponent of the magnitude of the operand's MSD.


   .. method:: logical_and(x, y)

      Applies the logical operation *and* between each operand's digits.


   .. method:: logical_invert(x)

      Invert all the digits in *x*.


   .. method:: logical_or(x, y)

      Applies the logical operation *or* between each operand's digits.


   .. method:: logical_xor(x, y)

      Applies the logical operation *xor* between each operand's digits.


   .. method:: max(x, y)

      Compares two values numerically and returns the maximum.


   .. method:: max_mag(x, y)

      Compares the values numerically with their sign ignored.


   .. method:: min(x, y)

      Compares two values numerically and returns the minimum.


   .. method:: min_mag(x, y)

      Compares the values numerically with their sign ignored.


   .. method:: minus(x)

      Minus corresponds to the unary prefix minus operator in Python.


   .. method:: multiply(x, y)

      Return the product of *x* and *y*.


   .. method:: next_minus(x)

      Returns the largest representable number smaller than *x*.


   .. method:: next_plus(x)

      Returns the smallest representable number larger than *x*.


   .. method:: next_toward(x, y)

      Returns the number closest to *x*, in direction towards *y*.


   .. method:: normalize(x)

      Reduces *x* to its simplest form.


   .. method:: number_class(x)

      Returns an indication of the class of *x*.


   .. method:: plus(x)

      Plus corresponds to the unary prefix plus operator in Python.  This
      operation applies the context precision and rounding, so it is *not* an
      identity operation.


   .. method:: power(x, y[, modulo])

      Return ``x`` to the power of ``y``, reduced modulo ``modulo`` if given.

      With two arguments, compute ``x**y``.  If ``x`` is negative then ``y``
      must be integral.  The result will be inexact unless ``y`` is integral and
      the result is finite and can be expressed exactly in 'precision' digits.
      The rounding mode of the context is used. Results are always correctly-rounded
      in the Python version.

      .. versionchanged:: 3.3
         The C module computes :meth:`power` in terms of the correctly-rounded
         :meth:`exp` and :meth:`ln` functions. The result is well-defined but
         only "almost always correctly-rounded".

      With three arguments, compute ``(x**y) % modulo``.  For the three argument
      form, the following restrictions on the arguments hold:

         - all three arguments must be integral
         - ``y`` must be nonnegative
         - at least one of ``x`` or ``y`` must be nonzero
         - ``modulo`` must be nonzero and have at most 'precision' digits

      The value resulting from ``Context.power(x, y, modulo)`` is
      equal to the value that would be obtained by computing ``(x**y)
      % modulo`` with unbounded precision, but is computed more
      efficiently.  The exponent of the result is zero, regardless of
      the exponents of ``x``, ``y`` and ``modulo``.  The result is
      always exact.


   .. method:: quantize(x, y)

      Returns a value equal to *x* (rounded), having the exponent of *y*.


   .. method:: radix()

      Just returns 10, as this is Decimal, :)


   .. method:: remainder(x, y)

      Returns the remainder from integer division.

      The sign of the result, if non-zero, is the same as that of the original
      dividend.


   .. method:: remainder_near(x, y)

      Returns ``x - y * n``, where *n* is the integer nearest the exact value
      of ``x / y`` (if the result is 0 then its sign will be the sign of *x*).


   .. method:: rotate(x, y)

      Returns a rotated copy of *x*, *y* times.


   .. method:: same_quantum(x, y)

      Returns True if the two operands have the same exponent.


   .. method:: scaleb (x, y)

      Returns the first operand after adding the second value its exp.


   .. method:: shift(x, y)

      Returns a shifted copy of *x*, *y* times.


   .. method:: sqrt(x)

      Square root of a non-negative number to context precision.


   .. method:: subtract(x, y)

      Return the difference between *x* and *y*.


   .. method:: to_eng_string(x)

      Converts a number to a string, using scientific notation.


   .. method:: to_integral_exact(x)

      Rounds to an integer.


   .. method:: to_sci_string(x)

      Converts a number to a string using scientific notation.

.. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

.. _decimal-rounding-modes:

Constants
---------

The constants in this section are only relevant for the C module. They
are also included in the pure Python version for compatibility.

+---------------------+---------------------+-------------------------------+
|                     |       32-bit        |            64-bit             |
+=====================+=====================+===============================+
| .. data:: MAX_PREC  | :const:`425000000`  | :const:`999999999999999999`   |
+---------------------+---------------------+-------------------------------+
| .. data:: MAX_EMAX  | :const:`425000000`  | :const:`999999999999999999`   |
+---------------------+---------------------+-------------------------------+
| .. data:: MIN_EMIN  | :const:`-425000000` | :const:`-999999999999999999`  |
+---------------------+---------------------+-------------------------------+
| .. data:: MIN_ETINY | :const:`-849999999` | :const:`-1999999999999999997` |
+---------------------+---------------------+-------------------------------+


.. data:: HAVE_THREADS

   The default value is True. If Python is compiled without threads, the
   C version automatically disables the expensive thread local context
   machinery. In this case, the value is False.

Rounding modes
--------------

.. data:: ROUND_CEILING

   Round towards :const:`Infinity`.

.. data:: ROUND_DOWN

   Round towards zero.

.. data:: ROUND_FLOOR

   Round towards :const:`-Infinity`.

.. data:: ROUND_HALF_DOWN

   Round to nearest with ties going towards zero.

.. data:: ROUND_HALF_EVEN

   Round to nearest with ties going to nearest even integer.

.. data:: ROUND_HALF_UP

   Round to nearest with ties going away from zero.

.. data:: ROUND_UP

   Round away from zero.

.. data:: ROUND_05UP

   Round away from zero if last digit after rounding towards zero would have
   been 0 or 5; otherwise round towards zero.


.. _decimal-signals:

Signals
-------

Signals represent conditions that arise during computation. Each corresponds to
one context flag and one context trap enabler.

The context flag is set whenever the condition is encountered. After the
computation, flags may be checked for informational purposes (for instance, to
determine whether a computation was exact). After checking the flags, be sure to
clear all flags before starting the next computation.

If the context's trap enabler is set for the signal, then the condition causes a
Python exception to be raised.  For example, if the :class:`DivisionByZero` trap
is set, then a :exc:`DivisionByZero` exception is raised upon encountering the
condition.


.. class:: Clamped

   Altered an exponent to fit representation constraints.

   Typically, clamping occurs when an exponent falls outside the context's
   :attr:`Emin` and :attr:`Emax` limits.  If possible, the exponent is reduced to
   fit by adding zeros to the coefficient.


.. class:: DecimalException

   Base class for other signals and a subclass of :exc:`ArithmeticError`.


.. class:: DivisionByZero

   Signals the division of a non-infinite number by zero.

   Can occur with division, modulo division, or when raising a number to a negative
   power.  If this signal is not trapped, returns :const:`Infinity` or
   :const:`-Infinity` with the sign determined by the inputs to the calculation.


.. class:: Inexact

   Indicates that rounding occurred and the result is not exact.

   Signals when non-zero digits were discarded during rounding. The rounded result
   is returned.  The signal flag or trap is used to detect when results are
   inexact.


.. class:: InvalidOperation

   An invalid operation was performed.

   Indicates that an operation was requested that does not make sense. If not
   trapped, returns :const:`NaN`.  Possible causes include::

      Infinity - Infinity
      0 * Infinity
      Infinity / Infinity
      x % 0
      Infinity % x
      sqrt(-x) and x > 0
      0 ** 0
      x ** (non-integer)
      x ** Infinity


.. class:: Overflow

   Numerical overflow.

   Indicates the exponent is larger than :attr:`Emax` after rounding has
   occurred.  If not trapped, the result depends on the rounding mode, either
   pulling inward to the largest representable finite number or rounding outward
   to :const:`Infinity`.  In either case, :class:`Inexact` and :class:`Rounded`
   are also signaled.


.. class:: Rounded

   Rounding occurred though possibly no information was lost.

   Signaled whenever rounding discards digits; even if those digits are zero
   (such as rounding :const:`5.00` to :const:`5.0`).  If not trapped, returns
   the result unchanged.  This signal is used to detect loss of significant
   digits.


.. class:: Subnormal

   Exponent was lower than :attr:`Emin` prior to rounding.

   Occurs when an operation result is subnormal (the exponent is too small). If
   not trapped, returns the result unchanged.


.. class:: Underflow

   Numerical underflow with result rounded to zero.

   Occurs when a subnormal result is pushed to zero by rounding. :class:`Inexact`
   and :class:`Subnormal` are also signaled.


.. class:: FloatOperation

    Enable stricter semantics for mixing floats and Decimals.

    If the signal is not trapped (default), mixing floats and Decimals is
    permitted in the :class:`~decimal.Decimal` constructor,
    :meth:`~decimal.Context.create_decimal` and all comparison operators.
    Both conversion and comparisons are exact. Any occurrence of a mixed
    operation is silently recorded by setting :exc:`FloatOperation` in the
    context flags. Explicit conversions with :meth:`~decimal.Decimal.from_float`
    or :meth:`~decimal.Context.create_decimal_from_float` do not set the flag.

    Otherwise (the signal is trapped), only equality comparisons and explicit
    conversions are silent. All other mixed operations raise :exc:`FloatOperation`.


The following table summarizes the hierarchy of signals::

   exceptions.ArithmeticError(exceptions.Exception)
       DecimalException
           Clamped
           DivisionByZero(DecimalException, exceptions.ZeroDivisionError)
           Inexact
               Overflow(Inexact, Rounded)
               Underflow(Inexact, Rounded, Subnormal)
           InvalidOperation
           Rounded
           Subnormal
           FloatOperation(DecimalException, exceptions.TypeError)

.. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



.. _decimal-notes:

Floating Point Notes
--------------------


Mitigating round-off error with increased precision
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The use of decimal floating point eliminates decimal representation error
(making it possible to represent :const:`0.1` exactly); however, some operations
can still incur round-off error when non-zero digits exceed the fixed precision.

The effects of round-off error can be amplified by the addition or subtraction
of nearly offsetting quantities resulting in loss of significance.  Knuth
provides two instructive examples where rounded floating point arithmetic with
insufficient precision causes the breakdown of the associative and distributive
properties of addition:

.. doctest:: newcontext

   # Examples from Seminumerical Algorithms, Section 4.2.2.
   >>> from decimal import Decimal, getcontext
   >>> getcontext().prec = 8

   >>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')
   >>> (u + v) + w
   Decimal('9.5111111')
   >>> u + (v + w)
   Decimal('10')

   >>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')
   >>> (u*v) + (u*w)
   Decimal('0.01')
   >>> u * (v+w)
   Decimal('0.0060000')

The :mod:`decimal` module makes it possible to restore the identities by
expanding the precision sufficiently to avoid loss of significance:

.. doctest:: newcontext

   >>> getcontext().prec = 20
   >>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')
   >>> (u + v) + w
   Decimal('9.51111111')
   >>> u + (v + w)
   Decimal('9.51111111')
   >>>
   >>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')
   >>> (u*v) + (u*w)
   Decimal('0.0060000')
   >>> u * (v+w)
   Decimal('0.0060000')


Special values
^^^^^^^^^^^^^^

The number system for the :mod:`decimal` module provides special values
including :const:`NaN`, :const:`sNaN`, :const:`-Infinity`, :const:`Infinity`,
and two zeros, :const:`+0` and :const:`-0`.

Infinities can be constructed directly with:  ``Decimal('Infinity')``. Also,
they can arise from dividing by zero when the :exc:`DivisionByZero` signal is
not trapped.  Likewise, when the :exc:`Overflow` signal is not trapped, infinity
can result from rounding beyond the limits of the largest representable number.

The infinities are signed (affine) and can be used in arithmetic operations
where they get treated as very large, indeterminate numbers.  For instance,
adding a constant to infinity gives another infinite result.

Some operations are indeterminate and return :const:`NaN`, or if the
:exc:`InvalidOperation` signal is trapped, raise an exception.  For example,
``0/0`` returns :const:`NaN` which means "not a number".  This variety of
:const:`NaN` is quiet and, once created, will flow through other computations
always resulting in another :const:`NaN`.  This behavior can be useful for a
series of computations that occasionally have missing inputs --- it allows the
calculation to proceed while flagging specific results as invalid.

A variant is :const:`sNaN` which signals rather than remaining quiet after every
operation.  This is a useful return value when an invalid result needs to
interrupt a calculation for special handling.

The behavior of Python's comparison operators can be a little surprising where a
:const:`NaN` is involved.  A test for equality where one of the operands is a
quiet or signaling :const:`NaN` always returns :const:`False` (even when doing
``Decimal('NaN')==Decimal('NaN')``), while a test for inequality always returns
:const:`True`.  An attempt to compare two Decimals using any of the ``<``,
``<=``, ``>`` or ``>=`` operators will raise the :exc:`InvalidOperation` signal
if either operand is a :const:`NaN`, and return :const:`False` if this signal is
not trapped.  Note that the General Decimal Arithmetic specification does not
specify the behavior of direct comparisons; these rules for comparisons
involving a :const:`NaN` were taken from the IEEE 854 standard (see Table 3 in
section 5.7).  To ensure strict standards-compliance, use the :meth:`compare`
and :meth:`compare-signal` methods instead.

The signed zeros can result from calculations that underflow. They keep the sign
that would have resulted if the calculation had been carried out to greater
precision.  Since their magnitude is zero, both positive and negative zeros are
treated as equal and their sign is informational.

In addition to the two signed zeros which are distinct yet equal, there are
various representations of zero with differing precisions yet equivalent in
value.  This takes a bit of getting used to.  For an eye accustomed to
normalized floating point representations, it is not immediately obvious that
the following calculation returns a value equal to zero:

   >>> 1 / Decimal('Infinity')
   Decimal('0E-1000026')

.. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


.. _decimal-threads:

Working with threads
--------------------

The :func:`getcontext` function accesses a different :class:`Context` object for
each thread.  Having separate thread contexts means that threads may make
changes (such as ``getcontext().prec=10``) without interfering with other threads.

Likewise, the :func:`setcontext` function automatically assigns its target to
the current thread.

If :func:`setcontext` has not been called before :func:`getcontext`, then
:func:`getcontext` will automatically create a new context for use in the
current thread.

The new context is copied from a prototype context called *DefaultContext*. To
control the defaults so that each thread will use the same values throughout the
application, directly modify the *DefaultContext* object. This should be done
*before* any threads are started so that there won't be a race condition between
threads calling :func:`getcontext`. For example::

   # Set applicationwide defaults for all threads about to be launched
   DefaultContext.prec = 12
   DefaultContext.rounding = ROUND_DOWN
   DefaultContext.traps = ExtendedContext.traps.copy()
   DefaultContext.traps[InvalidOperation] = 1
   setcontext(DefaultContext)

   # Afterwards, the threads can be started
   t1.start()
   t2.start()
   t3.start()
    . . .

.. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


.. _decimal-recipes:

Recipes
-------

Here are a few recipes that serve as utility functions and that demonstrate ways
to work with the :class:`Decimal` class::

   def moneyfmt(value, places=2, curr='', sep=',', dp='.',
                pos='', neg='-', trailneg=''):
       """Convert Decimal to a money formatted string.

       places:  required number of places after the decimal point
       curr:    optional currency symbol before the sign (may be blank)
       sep:     optional grouping separator (comma, period, space, or blank)
       dp:      decimal point indicator (comma or period)
                only specify as blank when places is zero
       pos:     optional sign for positive numbers: '+', space or blank
       neg:     optional sign for negative numbers: '-', '(', space or blank
       trailneg:optional trailing minus indicator:  '-', ')', space or blank

       >>> d = Decimal('-1234567.8901')
       >>> moneyfmt(d, curr='$')
       '-$1,234,567.89'
       >>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-')
       '1.234.568-'
       >>> moneyfmt(d, curr='$', neg='(', trailneg=')')
       '($1,234,567.89)'
       >>> moneyfmt(Decimal(123456789), sep=' ')
       '123 456 789.00'
       >>> moneyfmt(Decimal('-0.02'), neg='<', trailneg='>')
       '<0.02>'

       """
       q = Decimal(10) ** -places      # 2 places --> '0.01'
       sign, digits, exp = value.quantize(q).as_tuple()
       result = []
       digits = list(map(str, digits))
       build, next = result.append, digits.pop
       if sign:
           build(trailneg)
       for i in range(places):
           build(next() if digits else '0')
       if places:
           build(dp)
       if not digits:
           build('0')
       i = 0
       while digits:
           build(next())
           i += 1
           if i == 3 and digits:
               i = 0
               build(sep)
       build(curr)
       build(neg if sign else pos)
       return ''.join(reversed(result))

   def pi():
       """Compute Pi to the current precision.

       >>> print(pi())
       3.141592653589793238462643383

       """
       getcontext().prec += 2  # extra digits for intermediate steps
       three = Decimal(3)      # substitute "three=3.0" for regular floats
       lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
       while s != lasts:
           lasts = s
           n, na = n+na, na+8
           d, da = d+da, da+32
           t = (t * n) / d
           s += t
       getcontext().prec -= 2
       return +s               # unary plus applies the new precision

   def exp(x):
       """Return e raised to the power of x.  Result type matches input type.

       >>> print(exp(Decimal(1)))
       2.718281828459045235360287471
       >>> print(exp(Decimal(2)))
       7.389056098930650227230427461
       >>> print(exp(2.0))
       7.38905609893
       >>> print(exp(2+0j))
       (7.38905609893+0j)

       """
       getcontext().prec += 2
       i, lasts, s, fact, num = 0, 0, 1, 1, 1
       while s != lasts:
           lasts = s
           i += 1
           fact *= i
           num *= x
           s += num / fact
       getcontext().prec -= 2
       return +s

   def cos(x):
       """Return the cosine of x as measured in radians.

       The Taylor series approximation works best for a small value of x.
       For larger values, first compute x = x % (2 * pi).

       >>> print(cos(Decimal('0.5')))
       0.8775825618903727161162815826
       >>> print(cos(0.5))
       0.87758256189
       >>> print(cos(0.5+0j))
       (0.87758256189+0j)

       """
       getcontext().prec += 2
       i, lasts, s, fact, num, sign = 0, 0, 1, 1, 1, 1
       while s != lasts:
           lasts = s
           i += 2
           fact *= i * (i-1)
           num *= x * x
           sign *= -1
           s += num / fact * sign
       getcontext().prec -= 2
       return +s

   def sin(x):
       """Return the sine of x as measured in radians.

       The Taylor series approximation works best for a small value of x.
       For larger values, first compute x = x % (2 * pi).

       >>> print(sin(Decimal('0.5')))
       0.4794255386042030002732879352
       >>> print(sin(0.5))
       0.479425538604
       >>> print(sin(0.5+0j))
       (0.479425538604+0j)

       """
       getcontext().prec += 2
       i, lasts, s, fact, num, sign = 1, 0, x, 1, x, 1
       while s != lasts:
           lasts = s
           i += 2
           fact *= i * (i-1)
           num *= x * x
           sign *= -1
           s += num / fact * sign
       getcontext().prec -= 2
       return +s


.. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


.. _decimal-faq:

Decimal FAQ
-----------

Q. It is cumbersome to type ``decimal.Decimal('1234.5')``.  Is there a way to
minimize typing when using the interactive interpreter?

A. Some users abbreviate the constructor to just a single letter:

   >>> D = decimal.Decimal
   >>> D('1.23') + D('3.45')
   Decimal('4.68')

Q. In a fixed-point application with two decimal places, some inputs have many
places and need to be rounded.  Others are not supposed to have excess digits
and need to be validated.  What methods should be used?

A. The :meth:`quantize` method rounds to a fixed number of decimal places. If
the :const:`Inexact` trap is set, it is also useful for validation:

   >>> TWOPLACES = Decimal(10) ** -2       # same as Decimal('0.01')

   >>> # Round to two places
   >>> Decimal('3.214').quantize(TWOPLACES)
   Decimal('3.21')

   >>> # Validate that a number does not exceed two places
   >>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))
   Decimal('3.21')

   >>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))
   Traceback (most recent call last):
      ...
   Inexact: None

Q. Once I have valid two place inputs, how do I maintain that invariant
throughout an application?

A. Some operations like addition, subtraction, and multiplication by an integer
will automatically preserve fixed point.  Others operations, like division and
non-integer multiplication, will change the number of decimal places and need to
be followed-up with a :meth:`quantize` step:

    >>> a = Decimal('102.72')           # Initial fixed-point values
    >>> b = Decimal('3.17')
    >>> a + b                           # Addition preserves fixed-point
    Decimal('105.89')
    >>> a - b
    Decimal('99.55')
    >>> a * 42                          # So does integer multiplication
    Decimal('4314.24')
    >>> (a * b).quantize(TWOPLACES)     # Must quantize non-integer multiplication
    Decimal('325.62')
    >>> (b / a).quantize(TWOPLACES)     # And quantize division
    Decimal('0.03')

In developing fixed-point applications, it is convenient to define functions
to handle the :meth:`quantize` step:

    >>> def mul(x, y, fp=TWOPLACES):
    ...     return (x * y).quantize(fp)
    >>> def div(x, y, fp=TWOPLACES):
    ...     return (x / y).quantize(fp)

    >>> mul(a, b)                       # Automatically preserve fixed-point
    Decimal('325.62')
    >>> div(b, a)
    Decimal('0.03')

Q. There are many ways to express the same value.  The numbers :const:`200`,
:const:`200.000`, :const:`2E2`, and :const:`.02E+4` all have the same value at
various precisions. Is there a way to transform them to a single recognizable
canonical value?

A. The :meth:`normalize` method maps all equivalent values to a single
representative:

   >>> values = map(Decimal, '200 200.000 2E2 .02E+4'.split())
   >>> [v.normalize() for v in values]
   [Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2')]

Q. Some decimal values always print with exponential notation.  Is there a way
to get a non-exponential representation?

A. For some values, exponential notation is the only way to express the number
of significant places in the coefficient.  For example, expressing
:const:`5.0E+3` as :const:`5000` keeps the value constant but cannot show the
original's two-place significance.

If an application does not care about tracking significance, it is easy to
remove the exponent and trailing zeroes, losing significance, but keeping the
value unchanged:

    >>> def remove_exponent(d):
    ...     return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()

    >>> remove_exponent(Decimal('5E+3'))
    Decimal('5000')

Q. Is there a way to convert a regular float to a :class:`Decimal`?

A. Yes, any binary floating point number can be exactly expressed as a
Decimal though an exact conversion may take more precision than intuition would
suggest:

.. doctest::

    >>> Decimal(math.pi)
    Decimal('3.141592653589793115997963468544185161590576171875')

Q. Within a complex calculation, how can I make sure that I haven't gotten a
spurious result because of insufficient precision or rounding anomalies.

A. The decimal module makes it easy to test results.  A best practice is to
re-run calculations using greater precision and with various rounding modes.
Widely differing results indicate insufficient precision, rounding mode issues,
ill-conditioned inputs, or a numerically unstable algorithm.

Q. I noticed that context precision is applied to the results of operations but
not to the inputs.  Is there anything to watch out for when mixing values of
different precisions?

A. Yes.  The principle is that all values are considered to be exact and so is
the arithmetic on those values.  Only the results are rounded.  The advantage
for inputs is that "what you type is what you get".  A disadvantage is that the
results can look odd if you forget that the inputs haven't been rounded:

.. doctest:: newcontext

   >>> getcontext().prec = 3
   >>> Decimal('3.104') + Decimal('2.104')
   Decimal('5.21')
   >>> Decimal('3.104') + Decimal('0.000') + Decimal('2.104')
   Decimal('5.20')

The solution is either to increase precision or to force rounding of inputs
using the unary plus operation:

.. doctest:: newcontext

   >>> getcontext().prec = 3
   >>> +Decimal('1.23456789')      # unary plus triggers rounding
   Decimal('1.23')

Alternatively, inputs can be rounded upon creation using the
:meth:`Context.create_decimal` method:

   >>> Context(prec=5, rounding=ROUND_DOWN).create_decimal('1.2345678')
   Decimal('1.2345')

