Skip to main content

29.14. fpectl —浮点异常控制

注解

fpectl 模块不是默认构建的,它的使用是不鼓励的,可能是危险的,除非在专家的手中。有关更多详细信息,另见 限制和其他注意事项 有关限制。


大多数计算机执行符合所谓的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_PROTECTPyFPE_END_PROTECT 以适当的方式插入到代码中。 Python本身已经被修改为支持 fpectl 模块,但是许多其他的数值分析师感兴趣的代码没有。

fpectl 模块不是线程安全的。

参见

源分发中的一些文件可能有兴趣更多地了解此模块如何操作。包含文件 Include/pyfpe.h 以一定的长度讨论了此模块的实现。 Modules/fpetestmodule.c 给出了几个使用的例子。许多其他的例子可以在 Objects/floatobject.c 中找到。