plus an infinite number of additional terms. IEEE 754 has to chop off
that infinitely repeated decimal after 52 digits, so the
representation is slightly inaccurate.
Sometimes you can see this inaccuracy when the number is printed:
\begin{verbatim}
>>> from decimal import *
>>> Decimal('0.70') * Decimal('1.05')
Decimal("0.7350")
>>> .70 * 1.05
0.73499999999999999
>>> 1.1
1.1000000000000001
\end{verbatim}
Note that the \class{Decimal} result keeps a trailing zero, automatically
inferring four place significance from two digit mulitiplicands. A key
goal is to reproduce the mathematics we do by hand and avoid the tricky
issues that arise when decimal numbers cannot be represented exactly in
binary floating point.
The inaccuracy isn't always visible when you print the number because
the FP-to-decimal-string conversion is provided by the C library, and
most C libraries try to produce sensible output, but the inaccuracy is
still there and subsequent operations can magnify the error.
For many applications this doesn't matter. If I'm plotting points and
displaying them on my monitor, the difference between 1.1 and
1.1000000000000001 is too small to be visible. Reports often limit
output to a certain number of decimal places, and if you round the
number to two or three or even eight decimal places, the error is
never apparent. However, for applications where it does matter,
it's a lot of work to implement your own custom arithmetic routines.
\subsection{The \class{Decimal} type}
Exact representation enables the \class{Decimal} class to perform
modulo calculations and equality tests that would fail in binary
floating point:
A new module, \module{decimal}, was added to Python's standard library.
It contains two classes, \class{Decimal} and \class{Context}.
\class{Decimal} instances represent numbers, and
\class{Context} instances are used to wrap up various settings such as the precision and default rounding mode.
\class{Decimal} instances, like regular Python integers and FP numbers, are immutable; once they've been created, you can't change the value it represents.
\class{Decimal} instances can be created from integers or strings:
\begin{verbatim}
>>> Decimal('1.00') % Decimal('.10')
Decimal("0.00")
>>> 1.00 % 0.10
0.09999999999999995
>>> sum([Decimal('0.1')]*10) == Decimal('1.0')
True
>>> sum([0.1]*10) == 1.0
False
>>> import decimal
>>> decimal.Decimal(1972)
Decimal("1972")
>>> decimal.Decimal("1.1")
Decimal("1.1")
\end{verbatim}
You can also provide tuples containing the sign, mantissa represented
as a tuple of decimal digits, and exponent:
\begin{verbatim}
>>> decimal.Decimal((1, (1, 4, 7, 5), -2))
Decimal("-14.75")
\end{verbatim}
Cautionary note: the sign bit is a Boolean value, so 0 is positive and 1 is negative.
Floating-point numbers posed a bit of a problem: should the FP number
representing 1.1 turn into the decimal number for exactly 1.1, or for
1.1 plus whatever inaccuracies are introduced? The decision was to
leave such a conversion out of the API. Instead, you should convert
the floating-point number into a string using the desired precision and
pass the string to the \class{Decimal} constructor:
\begin{verbatim}
>>> f = 1.1
>>> decimal.Decimal(str(f))
Decimal("1.1")
>>> decimal.Decimal(repr(f))
Decimal("1.1000000000000001")
\end{verbatim}
The \module{decimal} module also allows arbitrarily large precisions to be
set for calculation:
Once you have \class{Decimal} instances, you can perform the usual
mathematical operations on them. One limitation: exponentiation
requires an integer exponent:
\begin{verbatim}
>>> getcontext().prec = 24
>>> Decimal(1) / Decimal(7)
Decimal("0.142857142857142857142857")
>>> a = decimal.Decimal('35.72')
>>> b = decimal.Decimal('1.73')
>>> a+b
Decimal("37.45")
>>> a-b
Decimal("33.99")
>>> a*b
Decimal("61.7956")
>>> a/b
Decimal("20.6473988")
>>> a ** 2
Decimal("1275.9184")
>>> a ** b
Decimal("NaN")
\end{verbatim}
You can combine \class{Decimal} instances with integers, but not with
floating-point numbers:
\begin{verbatim}
>>> a + 4
Decimal("39.72")
>>> a + 4.5
Traceback (most recent call last):
...
TypeError: You can interact Decimal only with int, long or Decimal data types.
>>>
\end{verbatim}
\class{Decimal} numbers can be used with the \module{math} and
\module{cmath} modules, though you'll get back a regular
floating-point number and not a \class{Decimal}. Instances also have a \method{sqrt()} method:
\begin{verbatim}
>>> import math, cmath
>>> d = decimal.Decimal('123456789012.345')
>>> math.sqrt(d)
351364.18288201344
>>> cmath.sqrt(-d)
351364.18288201344j
>>> d.sqrt()
Decimal(``351364.1828820134592177245001'')
\end{verbatim}
\subsection{The \class{Context} type}
Instances of the \class{Context} class encapsulate several settings for
decimal operations:
\begin{itemize}
\item\member{prec} is the precision, the number of decimal places.
\item\member{rounding} specifies the rounding mode. The \module{decimal}
module has constants for the various possibilities:
\constant{ROUND_DOWN}, \constant{ROUND_CEILING}, \constant{ROUND_HALF_EVEN}, and various others.
\item\member{trap_enablers} is a dictionary specifying what happens on
encountering certain error conditions: either an exception is raised or
a value is returned. Some examples of error conditions are
division by zero, loss of precision, and overflow.
\end{itemize}
There's a thread-local default context available by calling
\function{getcontext()}; you can change the properties of this context
to alter the default precision, rounding, or trap handling.
\begin{verbatim}
>>> decimal.getcontext().prec
28
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal(``0.1428571428571428571428571429'')
>>> decimal.getcontext().prec = 9
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal(``0.142857143'')
\end{verbatim}
The default action for error conditions is to return a special value
such as infinity or not-a-number, but you can request that exceptions