如何使用 try-catch 捕获浮点错误?

Posted

技术标签:

【中文标题】如何使用 try-catch 捕获浮点错误?【英文标题】:How to use try-catch to catch floating point errors? 【发布时间】:2020-11-12 15:59:31 【问题描述】:
#include <iostream>
#include <float.h>
#pragma fenv_access (on)
int main(int, char**argv)

    unsigned int fp_control_word;
    _controlfp_s(&fp_control_word, 0, 0);
    const unsigned int new_fp_control_word = fp_control_word | _EM_INVALID | _EM_DENORMAL
        | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW | _EM_INEXACT;
    _controlfp_s(&fp_control_word, new_fp_control_word, _MCW_EM);
   try
       std::cout << std::atof(argv[1]) / std::atof(argv[2]) << std::endl;
    catch (...)
       std::cout << "caught exception" << std::endl;
   

我记得可以使用 try-catch 块捕获 Windows 上的内存访问错误。

已经有一个关于这个主题的问题。但它已有 10 年历史,提供的代码不会导致异常,而是会打印 NAN。

我一直对使用此功能以一种很好的方式中止某些数字代码感到好奇。动机是立即中止一些非常复杂的代码,如果此代码中的任何地方发生浮点异常,而不是继续使用 NAN 结果评估其余代码 - 这相当慢而且无论如何没有意义。

请:我不在乎这是否不受 C++ 标准的支持!

问题是,如何让这段代码运行到 catch-block 中——例如通过使用命令行参数 0.0 0.0!

对我来说,它总是打印出 NAN。

需要使用哪些编译器选项?

还是需要改代码?

如果在 try 块中引发 nullptr 取消引用,则将在 catch 块中结束。但不适用于除以零。 需要使用编译器选项 /EHa 来启用结构化异常处理。

【问题讨论】:

您的问题是什么?是你帖子的标题吗?假设您要查找的浮点错误实际上是抛出的异常,您可以使用 try/catch 捕获浮点错误,就像使用 try/catch 捕获任何类型的异常一样。 用调试器很容易看到,新的控制字和旧的一样。您想取消屏蔽这些异常,因此请使用 fp_control_word & ~(_EM_INVALID | _EM_DENORMAL ...)。 /EHa 需要,工作正常。 【参考方案1】:

感谢https://***.com/users/17034/hans-passant 的解决方案。

下面是工作代码:

#include <iostream>
#include <float.h>
#pragma fenv_access (on)
int main(int, char**argv)

    unsigned int fp_control_word;
    _controlfp_s(&fp_control_word, 0, _MCW_EM);
    const unsigned int new_fp_control_word = fp_control_word & ~(_EM_INVALID
        | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW | _EM_INEXACT);
    _controlfp_s(&fp_control_word, new_fp_control_word, _MCW_EM);
    try
       std::cout << std::atof(argv[1]) / std::atof(argv[2]) << std::endl;
     catch (...)
       std::cout << "caught exception" << std::endl;
    

【讨论】:

以上是关于如何使用 try-catch 捕获浮点错误?的主要内容,如果未能解决你的问题,请参考以下文章

当服务器在 try-catch 块中发送 422 时,axios 无法捕获错误

在获取期间无法在 try-catch 中捕获 403

猿类如何捕获少女心--难以琢磨的try-catch

捕获错误并处理try-catch

Close-SMBOpenFile引发错误,没有被try-catch捕获

2个简单实例让你快速理解try-catch的用法