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