【问题标题】:Disable exception with Infinity and NaN使用 Infinity 和 NaN 禁用异常
【发布时间】:2023-04-01 00:58:01
【问题描述】:

我有一个巨大的项目(不是我建造的),它允许有 InfinityNaN 值。尽管这是允许的,但这是不可取的。我read 这些值是由这些操作生成的:

1/0 = ∞
log (0) = -∞
sqrt (-1) = NaN

除此之外,当他们到达时,应该抛出一个FP Exception

如果我的项目允许对NaNInfinity进行操作,我认为SIGFPE会在某个地方处理,但我在整个项目中搜索并没有找到。

还有其他方法可以禁用此异常吗?我的目标是能够检测到这些值的第一次出现。

编辑: 我使用的是 Windows,我打算启用信号,但在启用之前,我想了解它是否被禁用。

【问题讨论】:

  • 那么除以零的结果应该是什么?
  • “还有其他方法可以禁用此异常吗?我的目标是能够检测到这些值的第一次出现。” 这不是说您实际上想要启用这个异常吗?
  • 我不确定我是否理解正确:您是否希望抛出 SIGFPE?我正在使用 GCC,在我的安装中,它没有被抛出,而且我(还)找不到启用它的方法。
  • 你在什么操作系统上运行?
  • 来自您提到的 GCC 文档:当异常发生时(在引发异常时,以标准的语言),可能会发生以下两种情况之一。默认情况下,异常只是简单地在浮点状态字中注明,程序继续进行,就好像什么都没发生一样。该操作会产生一个默认值,这取决于异常 [...])。您的程序可以检查状态字以找出发生了哪些异常。

标签: c nan infinity math.h


【解决方案1】:

我认为您不会遇到您所说的问题。默认情况下,不会引发 FP 异常。来自Windowsdocumentation

默认情况下,系统已关闭所有 FP 异常。所以, 计算会导致 NAN 或 INFINITY,而不是异常。 在使用结构化捕获浮点 (FP) 异常之前 异常处理,必须调用_controlfp_sC运行库 函数打开所有可能的 FP 异常。仅诱捕 特殊例外,仅使用与 要捕获的异常。请注意,任何处理 FP 错误的处理程序都应该 调用 _clearfp 作为它的第一条 FP 指令。该功能清除 浮点异常。

GCC 也是如此,documentation 表示:

发生异常时(引发异常时,以 标准),可能会发生以下两种情况之一。默认情况下异常 只是在浮点状态字中注明,而程序 继续,好像什么事都没发生过。该操作产生一个默认值 值,这取决于异常 [...])。你的程序可以检查 状态字以找出发生了哪些异常。

要在您的 Windows 环境中启用异常(这将停止您的程序的执行),您可以尝试类似

#include <float.h>

int main() {
    _clearfp();
    unsigned int current_word = 0;
    _controlfp_s(&current_word, ~_EM_ZERODIVIDE, _MCW_EM);
    double div = 0.;
    double f = 1. / div;
}

对于非阻塞解决方案,请尝试使用 fenv.h,如 cppreference.com 上的 here 所述。

【讨论】:

  • 也许我应该使用feraiseexcept 来启用?
  • 我不明白您是要启用还是禁用例外。
  • 现在我理解了上下文。我要启用。
  • 请注意,纯 C 的 VC 支持带有 __try {...} __except(){...} 的 SEH 您的程序将不会中止(但是,它不会告诉您异常发生的位置。为此,请删除 SEH 并运行程序在调试器中)。
猜你喜欢
  • 2017-07-23
  • 2013-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-08
  • 2021-12-08
  • 2010-10-27
  • 2015-12-24
相关资源
最近更新 更多