# 29.14. `fpectl` - 浮点异常控制

注意

`fpectl`模块不是默认构建的，它的使用是不鼓励的，可能是危险的，除非在专家的手中。有关更多详细信息，另见有关限制的Limitations and other considerations部分。

大多数计算机执行符合所谓的IEEE-754标准的浮点运算。在任何实际计算机上，一些浮点运算产生的结果不能表示为正常浮点值。例如，尝试

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

（上面的例子将在许多平台上工作。DEC Alpha可能是一个例外。）“Inf”是IEEE-754中表示“无穷大”的特殊非数字值，“nan”表示“不是数字”。请注意，除非非数字结果， Python来执行这些计算。这实际上是IEEE-754标准中规定的默认行为，如果它适用于你，现在就停止读。

在某些情况下，最好引入异常并在尝试有故障的操作时停止处理。`fpectl`模块适用于这种情况。它提供对来自几个硬件制造商的浮点单元的控制，允许用户在发生任何IEEE-754异常除零，溢出或无效操作时打开`SIGFPE`的生成。与插入到包含您的python系统的C代码中的一对包装宏一起，`SIGFPE`被捕获并转换为Python `FloatingPointError`异常。

`fpectl`模块定义以下函数，并可能引发给定异常：

`fpectl.``turnon_sigfpe`()

  打开`SIGFPE`的生成，并设置适当的信号处理程序。

`fpectl.``turnoff_sigfpe`()

  重置缺省处理浮点异常。

exception `fpectl.``FloatingPointError`

  在执行`turnon_sigfpe()`之后，引发IEEE-754异常除以零，溢出或无效操作的浮点操作将反过来引发此标准Python异常。

## 29.14.1. 示例

以下示例演示如何启动和测试`fpectl`模块的操作。

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

## 29.14.2. 限制和其他考虑

设置给定处理器以捕获IEEE-754浮点错误当前需要基于每架构的自定义代码。您可能需要修改`fpectl`才能控制您的特定硬件。

将IEEE-754异常转换为Python异常需要以适当的方式将包装器宏`PyFPE_START_PROTECT`和`PyFPE_END_PROTECT`插入到代码中。Python本身已经被修改以支持`fpectl`模块，但是数值分析师感兴趣的许多其他代码没有。

`fpectl`模块不是线程安全的。

也可以看看

源分发中的一些文件可能有兴趣更多地了解此模块如何操作。include文件`Include/pyfpe.h`讨论了此模块的实现过程。`Modules/fpetestmodule.c`提供了几个使用示例。许多其他示例可以在`Objects/floatobject.c`中找到。