如何在C中引发不同的浮点异常?

时间:2019-06-27 03:33:39

标签: c floating-point gnu fenv

我对提出Division by zeroOverflowUnderflow等浮点异常很感兴趣。

我认为,如果我们可以在发生浮点异常时更改陷阱的默认行为,那我想做的事情就是可能的。

我正在使用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

0 个答案:

没有答案