使用 Infinity 和 NaN 禁用异常

Disable exception with Infinity and NaN

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

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

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

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

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

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

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

By default, the system has all FP exceptions turned off. Therefore, computations result in NAN or INFINITY, rather than an exception. Before you can trap floating-point (FP) exceptions using structured exception handling, you must call the _controlfp_s C run-time library function to turn on all possible FP exceptions. To trap only particular exceptions, use only the flags that correspond to the exceptions to be trapped. Note that any handler for FP errors should call _clearfp as its first FP instruction. This function clears floating-point exceptions.

GCC 也是如此,其中 documentation 表示:

When exceptions occur (when exceptions are raised, in the language of the standard), one of two things can happen. By default the exception is simply noted in the floating-point status word, and the program continues as if nothing had happened. The operation produces a default value, which depends on the exception [...]). Your program can check the status word to find out which exceptions happened.

要在您的 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;
}

对于非阻塞解决方案,请按照 cppreference.com 上的 here 说明尝试使用 fenv.h