diff options
author | Raymond Hettinger <python@rcn.com> | 2004-08-15 23:47:48 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2004-08-15 23:47:48 (GMT) |
commit | 2864b808c7e1fde231c8a307c8993d336930ec4d (patch) | |
tree | 604000ff2ab2bf229a917cfc6a7fbd193ecca4aa | |
parent | 5c8d29cb134be7d67d24c172da870c9e062e6ab7 (diff) | |
download | cpython-2864b808c7e1fde231c8a307c8993d336930ec4d.zip cpython-2864b808c7e1fde231c8a307c8993d336930ec4d.tar.gz cpython-2864b808c7e1fde231c8a307c8993d336930ec4d.tar.bz2 |
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.
-rw-r--r-- | Doc/lib/libdecimal.tex | 98 |
1 files changed, 97 insertions, 1 deletions
diff --git a/Doc/lib/libdecimal.tex b/Doc/lib/libdecimal.tex index cf21b8d..c009f5b 100644 --- a/Doc/lib/libdecimal.tex +++ b/Doc/lib/libdecimal.tex @@ -829,6 +829,102 @@ The following table summarizes the hierarchy of signals: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\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}} The \function{getcontext()} function accesses a different \class{Context} @@ -864,7 +960,7 @@ t2.start() t3.start() . . . \end{verbatim} - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |