如何使用 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 无法捕获错误