28.16. fpectl — 浮点异常控制 — Python 文档
28.16. 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 异常。
28.16.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 <module>
FloatingPointError: in math_1
28.16.2. 限制和其他注意事项
设置给定的处理器以捕获 IEEE-754 浮点错误当前需要基于每个架构的自定义代码。 您可能需要修改 fpectl 来控制您的特定硬件。
将 IEEE-754 异常转换为 Python 异常需要以适当的方式将包装宏 PyFPE_START_PROTECT
和 PyFPE_END_PROTECT
插入到您的代码中。 Python 本身已被修改为支持 fpectl 模块,但数值分析人员感兴趣的许多其他代码还没有。
fpectl 模块不是线程安全的。
也可以看看
源代码分发中的某些文件可能对了解有关此模块如何运行的更多信息很感兴趣。 包含文件 :source:`Include/pyfpe.h` 详细讨论了这个模块的实现。 :source:`Modules/fpetestmodule.c` 给出了几个使用示例。 许多其他示例可以在 :source:`Objects/floatobject.c` 中找到。