[英]Set flag for SIGFPE and continue execution ignoring FPEs
在數值應用程序中,我想知道計算完成后是否發生浮點異常。 默認情況下,將以靜默方式忽略浮點除法和無效操作。
我的嘗試是啟用我關心的FPE,通過設置標志來處理SIGFPE並再次禁用它們以允許繼續執行:
#include <fenv.h>
#include <signal.h>
#include <stdio.h>
int caught = 0;
struct sigaction old_sa;
/* (2) */ fenv_t fenv_hold;
void sighandler()
{
caught = 1;
printf("Caught in handler, disabling\n");
/* (1) */ fedisableexcept(FE_ALL_EXCEPT);
/* (2) */ feholdexcept(&fenv_hold);
sigaction(SIGFPE, &old_sa, NULL);
}
int main(void)
{
struct sigaction sa;
volatile double a=1, b=0;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = sighandler;
sigaction(SIGFPE, &sa, &old_sa);
feenableexcept(FE_DIVBYZERO);
printf("Dividing by zero..\n");
a/=b;
printf("Continuing\n");
}
我采用了兩種方法,第一種用(1)
標記,第二種用(2)
標記。 它們都沒有按預期工作。
輸出:
Dividing by zero..
Caught in handler, disabling
Floating point exception (core dumped)
預期產出:
Dividing by zero..
Caught in handler, disabling
Continuing
如果您只是想知道,在計算完成后,是否發生了浮點異常,那么您不應該使用信號,因為它們的開銷很高。 而是使用浮點異常標志,這些標志在正常執行期間由處理器快速設置。
請參閱<fenv.h>
上的C標准。 簡述:
#include <fenv.h>
。 #pragma STDC FENV_ACCESS on
。 #pragma STDC FENV_ACCESS off
,此時以下源代碼不訪問標志或在非默認模式下運行。 feclearexcept(FE_ALL_EXCEPT)
以清除標志。 fetestexcept(exceptions)
來測試標志。 exceptions
應該是一個按位或的FE_DIVBYZERO
, FE_INEXACT
, FE_INVALID
, FE_OVERFLOW
,和/或FE_UNDERFLOW
,以及可能的附加實現定義的標志。 請注意,某些C實現對訪問浮點環境的支持較差。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.