[Python-checkins] python/nondist/sandbox/decimal libdecimal.tex, NONE, 1.1

rhettinger at users.sourceforge.net rhettinger at users.sourceforge.net
Sun Jul 4 02:27:07 EDT 2004

Update of /cvsroot/python/python/nondist/sandbox/decimal
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27178

Added Files:
Log Message:
Module documentation. Part I

--- NEW FILE: libdecimal.tex ---
\section{\module{decimal} ---
         Decimal floating point arithmetic}

\modulesynopsis{Implementation of the General Decimal Arithmetic 

\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}{guido at python.org}

\sectionauthor{Raymond D. Hettinger}{python at rcn.com}

Eric Price <eprice at tjhsst.edu>
#    and Facundo Batista <facundo at taniquetil.com.ar>
#    and Raymond Hettinger <python at rcn.com>
#    and Aahz <aahz at pobox.com>
#    and Tim Peters


The decimal \module{module} provides support for decimal floating point
arithmetic.  It offers several advantages over the \class{float()} data type.

Decimal numbers can be represented exactly.  In contrast, numbers like
\constant{1.1} do not have an exact reprentations in binary floating point.
End users typically wound not expect \constant{1.1} to display as
\constant{1.1000000000000001} as it does with binary floating point.

The exactness carries over to arithmetic.  In decimal floating point,
\code{0.1 + 0.1 + 0.1 - 0.3} is exactly equal to zero.  In binary floating
point, result is \constant{5.5511151231257827e-017}.  While near to zero, the
differences prevent reliable equality testing and differences can accumulate.
For this reason, decimal would be preferred in accounting applications which
have strict equality invariants.

The decimal module incorporates notion signficant places so that
\code{1.30 + 1.20} is \constant{2.50}.  The trailing zero is kept to indicate
significance.  This is a customary presentation for monetary applications. For
multiplication, a ``schoolbook'' approach uses all the figures in the
multiplicands.  For instance, \code{1.3 * 1.2} gives \constant{1.56} while
\code{1.30 * 1.20} gives \constant{1.5600}.

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

>>> Decimal(1) / Decimal(7)
>>> getcontext().prec = 28
>>> Decimal(1) / Decimal(7)

* Both binary and decimal floating point are implemented in terms of published
standards.  The builtin float type exposes only a modest portion of its
capabilities.  In contrast, the decimal module exposes all required parts of
the standard.  When needed, the programmer has full control over rounding and
handling signals from the underlying implementation.

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
trailings zeros.  Decimals also include special values such as
\constant{Infinity} (the result of \code{1 / 0}), \constant{-Infinity},
(the result of \code{-1 / 0}), and \constant{NaN} (the result of
\code{0 / 0}).                                            
The context for arithmetic is an environment specifying precision, rounding
rules, limits on exponents, flags the indicate the results of operations,
and trap enablers which determine whether signals are to be treated as
exceptions.  Rounding options include \constant{ROUND_CEILING},
\constant{ROUND_DOWN}, \constant{ROUND_FLOOR}, \constant{ROUND_HALF_DOWN},
\constant{ROUND_HALF_EVEN}, \constant{ROUND_HALF_UP}, and \constant{ROUND_UP}.

Signals are types of information that arise during the course of a
computation.  Depending on the needs of the application, some signals may be
ignored, considered as informational, or treated as exceptions. The signals in
the decimal module are: \constant{Clamped}, \constant{InvalidOperation},
\constant{ConversionSyntax}, \constant{DivisionByZero},
\constant{DivisionImpossible}, \constant{DivisionUndefined},
\constant{Inexact}, \constant{InvalidContext}, \constant{Rounded},
\constant{Subnormal}, \constant{Overflow}, \constant{Underflow}.

For each there is a flag and a trap enabler.  When a signal is encountered,
its flag incremented from zero and, then, if the trap enabler is set to
one, then the signal will raise an exception.

  \seetext{IBM's General Decimal Arithmetic Specification,
           {The General Decimal Arithmetic Specification}.}

  \seetext{IEEE standard 854-1987,
           {Unofficial IEEE 854 Text}.} 

\subsection{Quick-start Tutorial \label{decimal-tutorial}}

>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
        setflags=[], settraps=[])
>>> Decimal(5) / Decimal(0)
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
        setflags=['DivisionByZero'], settraps=[])

The division by zero, set a flag indicating that the signal occurred.  Since
no trap was set, the computation continued without raising an exception.

>>> getcontext().clear_flags()
>>> getcontext()
>>> getcontext().trap_enablers[DivisionByZero] = 1
>>> Decimal(5) / Decimal(0)

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

This time, with the DivisionByZero trap enabled, the computation raises an
exception.  The trap enablers and flags provide the programmer with fine
control over what is considered to be an exception, what is information,
and what can be ignored.

\subsection{Decimal objects \label{decimal-decimal}}

\subsection{Context objects \label{decimal-decimal}}

\subsection{Signals \label{decimal-signals}}

\subsection{Working with threads \label{decimal-threads}}

More information about the Python-checkins mailing list