首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为SIGFPE设置标志并忽略FPE继续执行

为SIGFPE设置标志并忽略FPE继续执行
EN

Stack Overflow用户
提问于 2013-07-11 05:10:38
回答 1查看 1.2K关注 0票数 3

在数值应用程序中,我想知道在计算完成后是否发生了浮点异常。默认情况下,浮点除法和无效操作将以静默方式忽略。

我的尝试是启用我关心的FPE,通过设置标志并再次禁用它们来处理SIGFPE,以允许继续执行:

代码语言:javascript
复制
#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)。它们都不能像预期的那样工作。

输出:

代码语言:javascript
复制
Dividing by zero..
Caught in handler, disabling
Floating point exception (core dumped)

预期输出:

代码语言:javascript
复制
Dividing by zero..
Caught in handler, disabling
Continuing
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-11 06:13:50

如果您只想知道在计算完成后是否发生了浮点异常,那么就不应该使用信号,因为它们具有很高的开销。取而代之的是使用浮点异常标志,这些标志由处理器在正常执行期间快速设置。

请参阅<fenv.h>上的C标准。简要地说:

  • 在源文件中插入#include <fenv.h>
  • 在可能访问浮点标志或在非默认浮点模式下运行的任何源代码之前插入#pragma STDC FENV_ACCESS on
  • 如果需要,请在上述源代码之后插入#pragma STDC FENV_ACCESS off,当以下源代码不访问标志或在非默认浮点计算下运行时,执行< code >D12清除标志。< code >H213
  • 计算后,执行fetestexcept(exceptions)以测试标志。exceptions应该是FE_DIVBYZEROFE_INEXACTFE_INVALIDFE_OVERFLOW和/或FE_UNDERFLOW以及可能的附加实现定义标志的逐位OR。

请注意,一些C实现对访问浮点环境的支持很差。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17580950

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档