我对提出Division by zero
,Overflow
,Underflow
等浮点异常很感兴趣。
我认为,如果我们可以在发生浮点异常时更改陷阱的默认行为,那我想做的事情就是可能的。
我正在使用fenv.h
中的函数。首先,我使用
feenableexcept
,然后使用feraiseexcept
引发异常。
#define _GNU_SOURCE
#include <fenv.h>
#include <stdio.h>
int main(void) {
feenableexcept(FE_UNDERFLOW);
feraiseexcept(FE_OVERFLOW);
return 0;
}
终端显示的消息是
Floating point exception (core dumped)
相反,我想要这种形式的消息
Overflow
我也尝试处理SIGFPE。由于对于每个浮点异常,都会引发相同的信号SIGPE,因此无助于区分信号的不同原因。堆栈溢出有类似的question,但没有令人满意的答案。
我们可以使用fetestexcept(FE_OVERFLOW),但是必须在每次浮点操作之后明确写出它,以检查是否溢出。
注意:我使用
编译程序 gcc test_float -lm
修改:
我试图捕捉SIGFPE并编写了该程序
#define _GNU_SOURCE
#include <fenv.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
void catch_fpe (int sig) {
//#pragma STDC FENV_ACCESS ON
printf("i am in catch_fpe\n");
if(fetestexcept(FE_OVERFLOW))
printf("OVERFLOW\n");
else if(fetestexcept(FE_UNDERFLOW))
printf("UNDERFLOW\n");
else if(fetestexcept(FE_DIVBYZERO))
printf("DIVBYZERO\n");
else if(fetestexcept(FE_INVALID))
printf("INVALID OPERATION\n");
else if(fetestexcept(FE_INEXACT))
printf("INEXACT RESULT\n");
exit(0);
}
int main()
{
feclearexcept(FE_ALL_EXCEPT);
feenableexcept(FE_INVALID |
FE_DIVBYZERO |
FE_OVERFLOW |
FE_UNDERFLOW);
signal(SIGFPE, catch_fpe);
feraiseexcept(FE_DIVBYZERO);
}
它没有按我预期的那样工作。输出是
i am in catch_fpe
它也应该显示DIVBYZERO
。