Commit 2864b808 authored by Raymond Hettinger's avatar Raymond Hettinger

Add a notes section to the docs:

* Discuss representation error versus loss of significance.
* Document special values including qNaN, sNaN, +0, -0.
* Show the suprising display of non-normalized zero values.
parent 5c8d29cb
......@@ -828,6 +828,102 @@ The following table summarizes the hierarchy of signals:
\end{verbatim}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Floating Point Notes \label{decimal-notes}}
The use of decimal floating point eliminates decimal representation error
(making it possible to represent \constant{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 break down of the associative and
distributive properties of addition:
\begin{verbatim}
# Examples from Seminumerical Algorithms, Section 4.2.2.
>>> from decimal import *
>>> 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")
\end{verbatim}
The \module{decimal} module makes it possible to restore the identities
by expanding the precision sufficiently to avoid loss of significance:
\begin{verbatim}
>>> 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")
\end{verbatim}
The number system for the \module{decimal} module provides special
values including \constant{NaN}, \constant{sNaN}, \constant{-Infinity},
\constant{Infinity}, and two zeroes, \constant{+0} and \constant{-0}.
Infinities can constructed directly with: \code{Decimal('Infinity')}. Also,
they can arise from dividing by zero when the \exception{DivisionByZero}
signal is not trapped. Likewise, when the \exception{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 \constant{NaN} or when the
\exception{InvalidOperation} signal is trapped, raise an exception. For
example, \code{0/0} returns \constant{NaN} which means ``not a number''. This
variety of \constant{NaN} is quiet and, once created, will flow through other
computations always resulting in another \constant{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 \constant{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 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, the positive and negative zero 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:
\begin{verbatim}
>>> 1 / Decimal('Infinity')
Decimal("0E-1000000026")
\end{verbatim}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Working with threads \label{decimal-threads}}
......@@ -864,7 +960,7 @@ t2.start()
t3.start()
. . .
\end{verbatim}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment