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_PROTECTPyFPE_END_PROTECT插入到代码中。Python本身已经被修改以支持fpectl模块,但是数值分析师感兴趣的许多其他代码没有。

fpectl模块不是线程安全的。

也可以看看

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