使用 Infinity 和 NaN 禁用异常
Posted
技术标签:
【中文标题】使用 Infinity 和 NaN 禁用异常【英文标题】:Disable exception with Infinity and NaN 【发布时间】:2019-04-13 00:14:48 【问题描述】:我有一个巨大的项目(不是我建造的),它允许有 Infinity
和 NaN
值。尽管这是允许的,但这是不可取的。我read 这些值是由这些操作生成的:
1/0 = ∞
log (0) = -∞
sqrt (-1) = NaN
除此之外,当他们到达时,应该抛出一个FP Exception
。
如果我的项目允许对NaN
和Infinity
进行操作,我认为SIGFPE
会在某个地方处理,但我在整个项目中搜索并没有找到。
还有其他方法可以禁用此异常吗?我的目标是能够检测到这些值的第一次出现。
编辑: 我使用的是 Windows,我打算启用信号,但在启用之前,我想了解它是否被禁用。
【问题讨论】:
那么除以零的结果应该是什么? “还有其他方法可以禁用此异常吗?我的目标是能够检测到这些值的第一次出现。” 这不是说您实际上想要启用这个异常吗? 我不确定我是否理解正确:您是否希望抛出 SIGFPE?我正在使用 GCC,在我的安装中,它没有被抛出,而且我(还)找不到启用它的方法。 你在什么操作系统上运行? 来自您提到的 GCC 文档:当异常发生时(在引发异常时,以标准的语言),可能会发生以下两种情况之一。默认情况下,异常只是简单地在浮点状态字中注明,程序继续进行,就好像什么都没发生一样。该操作会产生一个默认值,这取决于异常 [...])。您的程序可以检查状态字以找出发生了哪些异常。 【参考方案1】:我认为您不会遇到您所说的问题。默认情况下,不会引发 FP 异常。来自Windowsdocumentation:
默认情况下,系统已关闭所有 FP 异常。所以, 计算会导致 NAN 或 INFINITY,而不是异常。 在使用结构化捕获浮点 (FP) 异常之前 异常处理,必须调用
_controlfp_s
C运行库 函数打开所有可能的 FP 异常。仅诱捕 特殊例外,仅使用与 要捕获的异常。请注意,任何处理 FP 错误的处理程序都应该 调用_clearfp
作为它的第一条 FP 指令。该功能清除 浮点异常。
GCC 也是如此,documentation 表示:
发生异常时(引发异常时,以 标准),可能会发生以下两种情况之一。默认情况下异常 只是在浮点状态字中注明,而程序 继续,好像什么事都没发生过。该操作产生一个默认值 值,这取决于异常 [...])。你的程序可以检查 状态字以找出发生了哪些异常。
要在您的 Windows 环境中启用异常(这将停止您的程序的执行),您可以尝试类似
#include <float.h>
int main()
_clearfp();
unsigned int current_word = 0;
_controlfp_s(¤t_word, ~_EM_ZERODIVIDE, _MCW_EM);
double div = 0.;
double f = 1. / div;
对于非阻塞解决方案,请尝试使用 fenv.h
,如 cppreference.com 上的 here 所述。
【讨论】:
也许我应该使用feraiseexcept
来启用?
我不明白您是要启用还是禁用例外。
现在我理解了上下文。我要启用。
请注意,纯 C 的 VC 支持带有 __try ... __except()...
的 SEH 您的程序将不会中止(但是,它不会告诉您异常发生的位置。为此,请删除 SEH 并运行程序在调试器中)。以上是关于使用 Infinity 和 NaN 禁用异常的主要内容,如果未能解决你的问题,请参考以下文章