在C中捕获浮点溢出 [英] Trapping floating-point overflow in C

查看:125
本文介绍了在C中捕获浮点溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试捕获C中的浮点溢出。这是我尝试过的内容

I am trying to trap floating-point overflow in C. Here is what I have tried

#define _GNU_SOURCE

#include <fenv.h>
#include <signal.h>
#include <stdio.h>

void catch_overflow (int sig) {   
  printf ("caught division by zero\n");   
  signal (sig, catch_overflow); 
}


int main(void) {   
  feenableexcept(FE_DIVBYZERO);   
  signal (FE_DIVBYZERO, catch_overflow);


  float a = 1., b = 0.;   float c = a/b;   return 0; }

我希望看到被零除的消息,但我只收到核心转储消息,浮点异常(核心已转储)。我如何修改程序以获取被零除的消息?

I expected to see "caught division by zero" message, but I only get a core dump message, "Floating point exception (core dumped)". How could I modify the program to get the "caught division by zero" message?

谢谢。

推荐答案

浮点异常以与机器和操作系统相关的方式转换为某些信令方法。但是这种方法不允许混合使用不同的常量空间,例如FE_xxx和SIGxxx。使用 FE_DIVBYZERO 作为signal(),您确实捕获到了 SIGILL ,它不是为浮点错误生成的(因为您做了没有指定操作系统,我可以自由选择任何操作系统-就我的情况而言,是Linux。)

A floating point exception is translated in machine- and OS-dependent way to some signaling approach. But no such way allows mixing of different constant spaces, as FE_xxx and SIGxxx. Using FE_DIVBYZERO for signal(), you really caught SIGILL which is not generated for floating-point errors (because you did not specify OS, I was free to choose any - Linux in my case).

对于您的程序,我在使用Linux的情况下进行了以下两项更改来捕获此异常:

For your program, I have made this exception catching working under Linux with two changes:


  1. 设置信号编号以处理 SIGFPE

a,b,c 声明为易失性(防止编译器计算 c 作为 INF 在编译时)。

Declaring a, b, c as volatile (prevents compiler from calculating c as INF at compile time).

此后,该程序陷入永恒循环,打印被零除,因为此类错误的信号处理程序将执行恢复为同一命令。您应仔细考虑如何纠正此类错误,而不会使错误的说明永远存在。例如,您可以使用 longjmp 从信号处理程序转到已安装的异常处理程序。

After this, the program fell into eternal cycle printing "caught division by zero" because signal handler for such error restores execution to the same command. You shall carefully consider how to fix such errors without making an erroneous instruction eternal. For example, you can use longjmp to go out of signal handler to an installed exception handler.

然后,仍然应该咨询目标OS手册以了解如何捕获FP错误。

And, you still should consult your target OS manuals for how to catch FP errors.

(主要部分的注释中已经对此进行了描述-但我认为是一个明确的答案。 )

(This has been already described in comments in main parts - but I considered to form an explicit answer.)

这篇关于在C中捕获浮点溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆