应除以零引发异常 [英] should divide by zero raise an exception

查看:36
本文介绍了应除以零引发异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在 VS2015 中调试一个 C++ 应用程序,发现我的许多双变量在除以零之后以 NaN 结束.虽然这是合理的,但我启用了浮点异常 (/fp:except),因此我预计这会引发异常.查看

Edit2:进一步阅读此处关于 IEE 754向我建议启用浮点异常后我应该得到一个异常.然而,对先前链接问题的评论指出'名称浮点异常"是一个历史误称.浮点除以零是明确定义的(根据附件 F/IEEE754)并且不会产生任何信号.'

解决方案

浮点异常与 C++ 异常不同.它们要么必须使用 std::fetestexcept()(下面)或被困(SIGFPE).使用陷阱需要调用 _controlfp() 在 MSVC 和 feenableexcept() 在 GCC 中.

#include #include <cfenv>#include //MSVC 特定,见//https://docs.microsoft.com/en-us/cpp/preprocessor/fenv-access?view=msvc-160#pragma fenv_access(上)int main() {std::feclearexcept(FE_ALL_EXCEPT);双 y = 0.0;双重结果{};结果 = 1/y;std::cout <<结果<

在 SEI CERT C 编码标准中有更多这样的例子:https://wiki.sei.cmu.edu/confluence/display/c/FLP03-C.+Detect+and+handle+floating-point+errors.

请注意,除以零是未定义的;不需要发出信号,但定义 __STDC_IEC_559__ 的 C 和 C++ 实现应"信号.

I've been debugging a C++ application in VS2015 and found that a number of my double variables were ending up a NaN following a divide by zero. While this is reasonable, I have floating point exceptions enabled (/fp:except) so I would have expected this to raise an exception. Looking at the MS help page, it doesn't list what causes a floating point exception. According to this answer to a related question, divide by zero is a floating point exception. This is not the case, i.e. the following test program with /fp:except enabled

int main()
{
    try
    {
        double x = 1;
        double y = 0;
        double z = x / y;
        printf("%f\n", z);
        return 0;
    }
    catch (...)
    {
        printf("Exception!\n");
        return 0;
    }
}

displays "inf". Should this raise a floating point exception?

Edit: Checked the exceptions were enabled in the debugger and get the same result regardless

Edit2: Further reading here on IEE 754 suggests to me that with floating point exceptions enabled I should be getting an exception. A comment to the previously linked question however states 'The name "floating point exception" is a historical misnomer. Floating point division by zero is well-defined (per Annex F/IEEE754) and does not produce any signal.'

解决方案

Floating point exceptions are not the same as C++ exceptions. They either have to be checked using std::fetestexcept() (below) or trapped (SIGFPE). Using traps requires calling _controlfp() in MSVC and feenableexcept() in GCC.

#include <iostream>
#include <cfenv>
#include <stdexcept>

// MSVC specific, see
// https://docs.microsoft.com/en-us/cpp/preprocessor/fenv-access?view=msvc-160
#pragma fenv_access (on)

int main() {
    std::feclearexcept(FE_ALL_EXCEPT);
    double y = 0.0;
    double result{};
    result = 1 / y;
    std::cout << result << std::endl;
    if (std::fetestexcept(FE_ALL_EXCEPT) & FE_DIVBYZERO) {
        throw std::runtime_error("Division by zero");
    }
    return 0;
}

There are more examples of this in the SEI CERT C Coding Standard: https://wiki.sei.cmu.edu/confluence/display/c/FLP03-C.+Detect+and+handle+floating-point+errors.

Note that division by zero is undefined; it's not required to signal, but C and C++ implementations that define __STDC_IEC_559__ "shall" signal.

这篇关于应除以零引发异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆