
``fpectl`` --- Floating point exception control
***********************************************

*Platforms: *Unix

Note: The ``fpectl`` module is not built by default, and its usage is
  discouraged and may be dangerous except in the hands of experts.
  See also the section *Limitations and other considerations* on
  limitations for more details.

Most computers carry out floating point operations in conformance with
the so-called IEEE-754 standard. On any real computer, some floating
point operations produce results that cannot be expressed as a normal
floating point value. For example, try

   >>> import math
   >>> math.exp(1000)
   inf
   >>> math.exp(1000) / math.exp(1000)
   nan

(The example above will work on many platforms. DEC Alpha may be one
exception.) "Inf" is a special, non-numeric value in IEEE-754 that
stands for "infinity", and "nan" means "not a number." Note that,
other than the non-numeric results, nothing special happened when you
asked Python to carry out those calculations. That is in fact the
default behaviour prescribed in the IEEE-754 standard, and if it works
for you, stop reading now.

In some circumstances, it would be better to raise an exception and
stop processing at the point where the faulty operation was attempted.
The ``fpectl`` module is for use in that situation. It provides
control over floating point units from several hardware manufacturers,
allowing the user to turn on the generation of ``SIGFPE`` whenever any
of the IEEE-754 exceptions Division by Zero, Overflow, or Invalid
Operation occurs. In tandem with a pair of wrapper macros that are
inserted into the C code comprising your python system, ``SIGFPE`` is
trapped and converted into the Python ``FloatingPointError``
exception.

The ``fpectl`` module defines the following functions and may raise
the given exception:

fpectl.turnon_sigfpe()

   Turn on the generation of ``SIGFPE``, and set up an appropriate
   signal handler.

fpectl.turnoff_sigfpe()

   Reset default handling of floating point exceptions.

exception exception fpectl.FloatingPointError

   After ``turnon_sigfpe()`` has been executed, a floating point
   operation that raises one of the IEEE-754 exceptions Division by
   Zero, Overflow, or Invalid operation will in turn raise this
   standard Python exception.


Example
=======

The following example demonstrates how to start up and test operation
of the ``fpectl`` module.

   >>> import fpectl
   >>> import fpetest
   >>> fpectl.turnon_sigfpe()
   >>> fpetest.test()
   overflow        PASS
   FloatingPointError: Overflow

   div by 0        PASS
   FloatingPointError: Division by zero
     [ more output from test elided ]
   >>> import math
   >>> math.exp(1000)
   Traceback (most recent call last):
     File "<stdin>", line 1, in ?
   FloatingPointError: in math_1


Limitations and other considerations
====================================

Setting up a given processor to trap IEEE-754 floating point errors
currently requires custom code on a per-architecture basis. You may
have to modify ``fpectl`` to control your particular hardware.

Conversion of an IEEE-754 exception to a Python exception requires
that the wrapper macros ``PyFPE_START_PROTECT`` and
``PyFPE_END_PROTECT`` be inserted into your code in an appropriate
fashion.  Python itself has been modified to support the ``fpectl``
module, but many other codes of interest to numerical analysts have
not.

The ``fpectl`` module is not thread-safe.

See also:

   Some files in the source distribution may be interesting in
   learning more about how this module operates. The include file
   ``Include/pyfpe.h`` discusses the implementation of this module at
   some length. ``Modules/fpetestmodule.c`` gives several examples of
   use. Many additional examples can be found in
   ``Objects/floatobject.c``.
