除以零不会抛出SIGFPE

Yur*_*sov 17 c++ floating-point gcc sigfpe

我有一个小程序执行零浮点除法,所以我期待SIGFPE.

#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

void signal_handler (int signo) {
    if(signo == SIGFPE) {
      std::cout << "Caught FPE\n";
    }
}

int main (void) {
  signal(SIGFPE,(*signal_handler));

  double b = 1.0;
  double c = 0.0;
  double d = b/c;
  std::cout << "d = "<< d << std::endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

实际上,我得到了以下输出:

d = inf
Run Code Online (Sandbox Code Playgroud)

gcc版本4.5.2(Ubuntu/Linaro 4.5.2-8ubuntu4)

在这种情况下,我应该怎么做才能抛出SIGFPE?FP操作行为依赖于哪些因素(编译器标志/ CPU类型等)?

谢谢

Mot*_*tti 10

如果执行整数除以零,则只会得到一个信号.对于浮点数,除以零是明确定义的.

这实际上在维基百科的文章中得到了很好的解释.

  • 阅读源码watspedia:http://754r.ucbtest.org/standards/754.pdf:7.2:"如果除数为零且被除数是有限的非零数,则除以零除外的信号应发出信号.结果,当没有陷阱发生时,应该是一个正确签名的INFINITY(6.3)." 第8章告诉我们,用户应该能够指定一个陷阱处理程序,当ch.7中的任何异常发生时都会引发该陷阱处理程序. (5认同)
  • 我并不是对你的答案吹毛求疵,只是对 IEEE 标准中的愚蠢行为吹毛求疵。想想这有多大意义:如果执行*整数*除以零,您会得到一个*浮点异常*。默认情况下,如果执行浮点除以零,则不会出现浮点异常。以数值计算为生的人往往讨厌这是默认行为。更糟糕的是,没有标准可以让我们获得所需的行为。除以零等几乎总是出现问题的迹象。 (3认同)

Ole*_*leg 6

对于浮点数,您可以通过设置FPU控制字来更改此行为.看看这里

  • @Yuri:看看你的标准包含文件 `&lt;fenv.h&gt;` 是否定义了 `fesettrapenable`。这是非标准的,但广泛可用。在 linux 上,使用 `feenableexcept` -- 但你需要在 `#include &lt;fenv.h&gt;` 之前使用 `#define _GNU_SOURCE`。 (2认同)

Dav*_*men 5

您没有收到信号,因为大多数计算机上的默认行为是使用NaN(非数字)和无穷大来污染您的数据.您必须启用浮点异常,以及如何执行此操作是特定于机器的.fenv.h如果您有系统标题,请查看系统标题.该函数fesettrapenable可以在许多机器上捕获浮点异常.

不幸的是,没有标准函数可以打开浮点异常处理.