首页 > 解决方案 > 信号和除零

问题描述

我在代码中得到了除以零的不需要的结果(代码是用 C++ 编写的):

#include <iostream>
#include <signal.h>
#include <fenv.h>

void div0(int signo, siginfo_t *info, void *ucontext)
{
    if(signo == SIGFPE && info->si_code == FPE_FLTDIV)
    {
        std::cout << "You can't divide numbers by 0, idiot!\n";
        exit(EXIT_FAILURE);
    }
}

int main()
{
    feenableexcept(FE_ALL_EXCEPT);

    struct sigaction act;
    act.sa_flags = SA_SIGINFO | SA_NODEFER;
    act.sa_sigaction = div0;

    int retn = sigaction(SIGFPE, &act, NULL);
    if(retn == -1)
    {
        perror("sigaction");
        return -1;
    }

    int n1, n2;

    std::cout << "Enter a number: ";
    std::cin >> n1;

    std::cout << "Enter another number to divide by: ";
    std::cin >> n2;

    double div = n1 / 1.0 / n2;
    std::cout << n1 << " / " << n2 << " = " << div << "\n";

    return 0;
}

当我0在变量中赋值n2时,结果是,例如:5 / 0 = inf. 但我想得到:You can't divide numbers by zero, idiot!。我将SIGFPE信号与FPE_FLTDIV信号代码一起使用,并尝试将其更改doublefloat,但仍然无法正常工作。我在互联网上搜索并没有找到任何解决方案。我错过了什么?谢谢您的帮助。

标签: c++linuxsignalsposixdivide-by-zero

解决方案


为什么不尝试简单if (n2 == 0) std::cout << "You can't divide numbers by zero, i***t!"

另一种方法是if isnan(div) std::cout << "You already divided by zero, i***t!"

0/0 部分在double和中是无声的float。您将收到一个NaN而不是任何异常。这将使您能够更好地处理错误。

添加以解决评论

如果要生成信号,则需要使用所有变量 asinteger并避免编译器进行优化。在“The linux programming interface”一书中有很好的例子,你可以在这里找到


推荐阅读