Fred Drake | a5e7ad9 | 2001-01-09 20:38:54 +0000 | [diff] [blame] | 1 | \section{\module{fpectl} --- |
| 2 | Floating point exception control} |
| 3 | |
| 4 | \declaremodule{extension}{fpectl} |
Fred Drake | bcd1df7 | 2001-07-05 21:17:08 +0000 | [diff] [blame] | 5 | \platform{Unix} |
Fred Drake | a5e7ad9 | 2001-01-09 20:38:54 +0000 | [diff] [blame] | 6 | \moduleauthor{Lee Busby}{busby1@llnl.gov} |
| 7 | \sectionauthor{Lee Busby}{busby1@llnl.gov} |
| 8 | \modulesynopsis{Provide control for floating point exception handling.} |
| 9 | |
Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 10 | \note{The \module{fpectl} module is not built by default, and its usage |
| 11 | is discouraged and may be dangerous except in the hands of |
| 12 | experts. See also the section \ref{fpectl-limitations} on |
| 13 | limitations for more details.} |
| 14 | |
Fred Drake | a5e7ad9 | 2001-01-09 20:38:54 +0000 | [diff] [blame] | 15 | Most computers carry out floating point operations\index{IEEE-754} |
| 16 | in conformance with the so-called IEEE-754 standard. |
| 17 | On any real computer, |
| 18 | some floating point operations produce results that cannot |
| 19 | be expressed as a normal floating point value. |
| 20 | For example, try |
| 21 | |
| 22 | \begin{verbatim} |
| 23 | >>> import math |
| 24 | >>> math.exp(1000) |
| 25 | inf |
Fred Drake | bcd1df7 | 2001-07-05 21:17:08 +0000 | [diff] [blame] | 26 | >>> math.exp(1000) / math.exp(1000) |
Fred Drake | a5e7ad9 | 2001-01-09 20:38:54 +0000 | [diff] [blame] | 27 | nan |
| 28 | \end{verbatim} |
| 29 | |
| 30 | (The example above will work on many platforms. |
| 31 | DEC Alpha may be one exception.) |
| 32 | "Inf" is a special, non-numeric value in IEEE-754 that |
| 33 | stands for "infinity", and "nan" means "not a number." |
| 34 | Note that, |
| 35 | other than the non-numeric results, |
| 36 | nothing special happened when you asked Python |
| 37 | to carry out those calculations. |
| 38 | That is in fact the default behaviour prescribed in the IEEE-754 standard, |
| 39 | and if it works for you, |
| 40 | stop reading now. |
| 41 | |
| 42 | In some circumstances, |
| 43 | it would be better to raise an exception and stop processing |
| 44 | at the point where the faulty operation was attempted. |
| 45 | The \module{fpectl} module |
| 46 | is for use in that situation. |
| 47 | It provides control over floating point |
| 48 | units from several hardware manufacturers, |
| 49 | allowing the user to turn on the generation |
| 50 | of \constant{SIGFPE} whenever any of the |
| 51 | IEEE-754 exceptions Division by Zero, Overflow, or |
| 52 | Invalid Operation occurs. |
| 53 | In tandem with a pair of wrapper macros that are inserted |
| 54 | into the C code comprising your python system, |
| 55 | \constant{SIGFPE} is trapped and converted into the Python |
| 56 | \exception{FloatingPointError} exception. |
| 57 | |
| 58 | The \module{fpectl} module defines the following functions and |
| 59 | may raise the given exception: |
| 60 | |
| 61 | \begin{funcdesc}{turnon_sigfpe}{} |
| 62 | Turn on the generation of \constant{SIGFPE}, |
| 63 | and set up an appropriate signal handler. |
| 64 | \end{funcdesc} |
| 65 | |
| 66 | \begin{funcdesc}{turnoff_sigfpe}{} |
| 67 | Reset default handling of floating point exceptions. |
| 68 | \end{funcdesc} |
| 69 | |
| 70 | \begin{excdesc}{FloatingPointError} |
| 71 | After \function{turnon_sigfpe()} has been executed, |
| 72 | a floating point operation that raises one of the |
| 73 | IEEE-754 exceptions |
| 74 | Division by Zero, Overflow, or Invalid operation |
| 75 | will in turn raise this standard Python exception. |
| 76 | \end{excdesc} |
| 77 | |
| 78 | |
| 79 | \subsection{Example \label{fpectl-example}} |
| 80 | |
| 81 | The following example demonstrates how to start up and test operation of |
| 82 | the \module{fpectl} module. |
| 83 | |
| 84 | \begin{verbatim} |
| 85 | >>> import fpectl |
| 86 | >>> import fpetest |
| 87 | >>> fpectl.turnon_sigfpe() |
| 88 | >>> fpetest.test() |
| 89 | overflow PASS |
| 90 | FloatingPointError: Overflow |
| 91 | |
| 92 | div by 0 PASS |
| 93 | FloatingPointError: Division by zero |
| 94 | [ more output from test elided ] |
| 95 | >>> import math |
| 96 | >>> math.exp(1000) |
| 97 | Traceback (most recent call last): |
| 98 | File "<stdin>", line 1, in ? |
| 99 | FloatingPointError: in math_1 |
| 100 | \end{verbatim} |
| 101 | |
| 102 | |
Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 103 | \subsection{Limitations and other considerations \label{fpectl-limitations}} |
Fred Drake | a5e7ad9 | 2001-01-09 20:38:54 +0000 | [diff] [blame] | 104 | |
| 105 | Setting up a given processor to trap IEEE-754 floating point |
| 106 | errors currently requires custom code on a per-architecture basis. |
| 107 | You may have to modify \module{fpectl} to control your particular hardware. |
| 108 | |
| 109 | Conversion of an IEEE-754 exception to a Python exception requires |
| 110 | that the wrapper macros \code{PyFPE_START_PROTECT} and |
| 111 | \code{PyFPE_END_PROTECT} be inserted into your code in an appropriate |
| 112 | fashion. Python itself has been modified to support the |
| 113 | \module{fpectl} module, but many other codes of interest to numerical |
| 114 | analysts have not. |
| 115 | |
| 116 | The \module{fpectl} module is not thread-safe. |
| 117 | |
| 118 | \begin{seealso} |
| 119 | \seetext{Some files in the source distribution may be interesting in |
| 120 | learning more about how this module operates. |
| 121 | The include file \file{Include/pyfpe.h} discusses the |
| 122 | implementation of this module at some length. |
| 123 | \file{Modules/fpetestmodule.c} gives several examples of |
| 124 | use. |
| 125 | Many additional examples can be found in |
| 126 | \file{Objects/floatobject.c}.} |
| 127 | \end{seealso} |