# [Python-checkins] python/nondist/sandbox/decimal libdecimal.tex, 1.4, 1.5

rhettinger at users.sourceforge.net rhettinger at users.sourceforge.net
Sun Jul 4 06:52:19 EDT 2004

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

Modified Files:
libdecimal.tex
Log Message:
Add the tutorial section

Index: libdecimal.tex
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/decimal/libdecimal.tex,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** libdecimal.tex	4 Jul 2004 08:55:42 -0000	1.4
--- libdecimal.tex	4 Jul 2004 10:52:14 -0000	1.5
***************
*** 34,38 ****

\item 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.
--- 34,38 ----

\item The exactness carries over to arithmetic.  In decimal floating point,
! \samp{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.
***************
*** 41,49 ****

\item The decimal module incorporates notion of significant 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, the 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}.

\item Unlike hardware based binary floating point, the decimal module has a user
--- 41,49 ----

\item The decimal module incorporates notion of significant places so that
! \samp{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, the schoolbook'' approach uses all the figures in the
! multiplicands.  For instance, \samp{1.3 * 1.2} gives \constant{1.56} while
! \samp{1.30 * 1.20} gives \constant{1.5600}.

\item Unlike hardware based binary floating point, the decimal module has a user
***************
*** 73,79 ****
exponent.  To preserve significance, the coefficient digits do not truncate
trailing zeroes.  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 standard also differentiates \constant{-0} from
\constant{+0}.

--- 73,79 ----
exponent.  To preserve significance, the coefficient digits do not truncate
trailing zeroes.  Decimals also include special values such as
! \constant{Infinity} (the result of \samp{1 / 0}), \constant{-Infinity},
! (the result of \samp{-1 / 0}), and \constant{NaN} (the result of
! \samp{0 / 0}).  The standard also differentiates \constant{-0} from
\constant{+0}.

***************
*** 114,147 ****
\subsection{Quick-start Tutorial \label{decimal-tutorial}}

\begin{verbatim}
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
setflags=[], settraps=[])
! >>> Decimal(5) / Decimal(0)
Decimal("Infinity")
! >>> getcontext()
! Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
!         setflags=['DivisionByZero'], settraps=[])
\end{verbatim}

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

\begin{verbatim}
>>> 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
\end{verbatim}

! 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.

--- 114,293 ----
\subsection{Quick-start Tutorial \label{decimal-tutorial}}

+ The normal start to using decimals is to import the module, and then use
+ \function{getcontext()} to view the context and, if necessary, set the context
+ precision, rounding, or trap enablers:
+
\begin{verbatim}
+ >>> from decimal import *
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
setflags=[], settraps=[])
!
! >>> getcontext().prec = 7
! \end{verbatim}
!
! Decimal instances can be constructed from integers or strings.  To create a
! Decimal from a \class{float}, first convert it to a string.  This serves as an
! explicit reminder of the details of the conversion (including representation
! error).  Malformed strings signal \constant{ConversionSyntax} and return a
! special kind of Decimal called a \constant{NaN} which stands for Not a
! number''. Positive and negative \constant{Infinity} is yet another special
! kind of Decimal.
!
! \begin{verbatim}
! >>> Decimal(10)
! Decimal("10")
! >>> Decimal('3.14')
! Decimal("3.14")
! >>> Decimal(str(2.0 ** 0.5))
! Decimal("1.41421356237")
! >>> Decimal('Mickey Mouse')
! Decimal("NaN")
! >>> Decimal('-Infinity')
! Decimal("-Infinity")
! \end{verbatim}
!
! Creating decimals is unaffected by context precision.  Their level of
! significance is completely determined by the number of digits input.  It is
! the arithmetic operations that are governed by the context.
!
! \begin{verbatim}
! >>> getcontext().prec = 6
! >>> Decimal('3.0000')
! Decimal("3.0000")
! >>> 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")
! \end{verbatim}
!
! Decimals interact well with much of the rest of python.  Here is a small
! flying circus of work with decimal floating point:
!
! \begin{verbatim}
! >>> data = 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.3400000000000001
! >>> round(a, 1)
! 1.3
! >>> int(a)
! 1
! >>> a * 5
! Decimal("6.70")
! >>> a * b
! Decimal("2.5058")
! >>> c % a
! Decimal("0.77")
! \end{verbatim}
!
! The \function{getcontext()} function accesses the current context.  This one
! context is sufficient for many applications; however, for more advanced work,
! multiple contexts can be created using the Context() constructor.  To make a
! new context active, use the \function{setcontext()} function.
!
! In accordance with the standard, the \module{Decimal} module provides two
! ready to use standard contexts, \constant{BasicContext} and
! \constant{ExtendedContext}. The former is especially useful for debugging
! because many of the traps are enabled:
!
! \begin{verbatim}
! >>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN)
! >>> myothercontext
! Context(prec=60, rounding=ROUND_HALF_DOWN, Emin=-999999999, Emax=999999999,
!         setflags=[], settraps=[])
! >>> ExtendedContext
! Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
!         setflags=[], settraps=[])
! >>> setcontext(myothercontext)
! >>> Decimal(1) / Decimal(7)
! Decimal("0.142857142857142857142857142857142857142857142857142857142857")
! >>> 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
\end{verbatim}

! Besides using contexts to control precision, rounding, and trapping signals,
! they can be used to monitor flags which give information collected during
! computation.  The flags remain set until explicitly cleared, so it is best to
! clear the flags before each set of monitored computations by using the
! \method{clear_flags()} method.

\begin{verbatim}
+ >>> setcontext(ExtendedContext)
>>> getcontext().clear_flags()
+ >>> Decimal(355) / Decimal(113)
+ Decimal("3.14159292")
>>> getcontext()
+ Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
+         setflags=['Inexact', 'Rounded'], settraps=[])
+ \end{verbatim}
+
+ The \var{setflags} entry shows that the rational approximation to
+ \constant{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 \member{trap_enablers}
+ field of a context:
+
+ \begin{verbatim}
+ >>> Decimal(1) / Decimal(0)
+ Decimal("Infinity")
>>> getcontext().trap_enablers[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
\end{verbatim}

! To turn all the traps on or off all at once, use a loop.  Also, the
! \method{dict.update()} method is useful for changing a few particular values.
!
! \begin{verbatim}
! >>> getcontext.clear_flags()
! >>> for sig in getcontext().trap_enablers:
! ...     getcontext().trap_enablers[sig] = 1
!
! >>> getcontext().trap_enablers.update({Rounded:0, Inexact:0, Subnormal:0})
! >>> getcontext()
! Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
!         setflags=[], settraps=['Underflow', 'DecimalException', 'Clamped',
!         'InvalidContext', 'InvalidOperation', 'ConversionSyntax',
!         'DivisionByZero', 'DivisionImpossible', 'DivisionUndefined',
!         'Overflow'])
! \end{verbatim}
!
! Applications typically set the context once at the beginning of a program
! and no further changes are needed.  For many applications, the data resides
! in a resource external to the program and is converted to \class{Decimal} with
! a single cast inside a loop.  Afterwards, decimals are as easily manipulated
! as other Python numeric types.



More information about the Python-checkins mailing list