c – NAN – >区分除零和指数具有非常大的负值

我在我的测试套件中包含了一个check for nan’s.

现在SIGFPE抛出以下行

const double retVal =exp(exponent); 

指数的值约为-4000.这当然非常接近于零,如果没有纳米检查,计算将继续为零.

信号SIGFPE现在被抛出.我假设这是一个denormal number(表示为NAN).

如何区分除零和带负值非常大的指数?

在第二种情况下,在我的情况下进行进一步的零计算,因为我不需要区分0和-0.

编辑:
我尝试了@ user2079303的建议.我的代码看起来像这样

#include <signal.h>
void fpe_handler(int signo, siginfo_t *info, void *context) {
    switch(info->si_code) {
        case FPE_INTDIV: // division by zero
            break;
        case FPE_FLTUND: // underflow
            break;
        // other cases ...
    }
}

int main() {
    struct sigaction action = {};
    action.sa_flags     = SA_SIGINFO;
    action.sa_sigaction = fpe_handler;
    sigaction(SIGFPE, &action, NULL);
    const double a = 0.0/0.0;
    if (a>0) 
        return 0;
    else
        return 1;
}

这会编译,但不会抛出信号或错误消息.

最佳答案
从技术上讲,从C的角度来看,除零具有未定义的行为,因此没有标准的方法来处理它.

在无处不在的IEEE 754标准中,除零被明确定义,并且不会产生信号.可以使用< cfenv>来测试先前执行的计算是否除以零.标题:

std::feclearexcept(FE_ALL_EXCEPT);
// do calculation here
if(std::fetestexcept(FE_DIVBYZERO)) {
    // I was just divided by zero. The sky is falling.
    std::abort();
} else if(std::fetestexcept(FE_UNDERFLOW)) {
    // I just underflowed. This is my life now.
}

现在,将正常浮点数除以零不会引发信号,除非您要求它使用feenableexcept(这是GNU扩展;非标准).

在标准C中无法区分SIGFPE的不同原因.但是有a way in POSIX标准:

void fpe_handler(int signo, siginfo_t *info, void *context)
{
    switch(info->si_code) {
        case FPE_FLTDIV: // division by zero
            break;
        case FPE_FLTUND: // underflow
            break;
        // other cases ...
    }
}

// registering
struct sigaction action = {};
action.sa_flags     = SA_SIGINFO;
action.sa_sigaction = fpe_handler;
sigaction(SIGFPE, &action, NULL);

转载注明原文:c – NAN – >区分除零和指数具有非常大的负值 - 代码日志