在C++中处理浮点异常

Joo*_*s99 11 c++ floating-point exception visual-c++

我发现浮点模型/错误问题相当令人困惑.这是一个我不熟悉的领域,我不是一个低级别的C/asm程序员,所以我很感激一点建议.

我有一个使用VS2012(VC11)构建的大型C++应用程序,我已经将其配置为抛出浮点异常(或者更确切地说,允许C++运行时和/或硬件抛出fp异常) - 并且它投入了很多它们在发布(优化)版本中,但不在调试版本中.我假设这是由于优化和浮点模型(尽管为发布和调试版本设置了编译器/ fp:精确切换).

我的第一个问题涉及管理应用程序的调试.我想控制抛出fp异常的位置以及它们被"屏蔽"的位置.这是必需的,因为我正在调试(优化的)发布版本(这是fp异常发生的地方) - 我想在我检测到问题的某些函数中禁用fp-exceptions,这样我就可以找到新的FP问题了.但我对使用_controlfp_s执行此操作(工作正常)和编译器(和#pragma float_control)切换"/ fp:except"(这似乎没有任何效果)之间的区别感到困惑.这两种机制有什么区别?它们是否应该对fp异常产生相同的影响?

其次,我得到了一些"浮点堆栈检查"异常 - 包括一个似乎在调用GDI + dll时抛出的异常.在网上搜索,这个异常的少数提及似乎表明它是由编译器错误引起的.通常情况如此吗?如果是这样,我该如何解决这个问题呢?是否最好禁用问题函数的编译器优化,或者如果似乎没有返回任何错误的浮点值,则仅针对有问题的代码区域禁用fp-exceptions?例如,在抛出此异常的GDI +调用(到GraphicsPath :: GetPointCount)中,实际返回的整数值似乎是正确的.目前我正在使用_controlfp_s在GDI +调用之前立即禁用fp-exceptions - 然后再次使用它在调用后直接重新启用异常.

最后,我的应用程序确实进行了大量的浮点计算,并且需要稳健可靠,但不一定非常准确.应用程序的本质是浮点值通常表示概率,因此本质上有些不精确.但是,我想捕获任何纯逻辑错误,例如除以零.什么是最好的fp模型?目前我是:

  • 使用_controlfp_s和SIGFPE信号处理程序捕获所有fp异常(即EM_OVERFLOW | EM_UNDERFLOW | EM_ZERODIVIDE | EM_DENORMAL | EM_INVALID),
  • 已启用非正规零(DAZ)和齐射到零(FTZ)(即_MM_SET_FLUSH_ZERO_MODE(_MM_DENORMALS_ZERO_ON)),以及
  • 我使用默认的VC11编译器设置/ fp:精确的/ fp:除了没有指定.

这是最好的型号吗?

感谢致敬!

Emi*_*rea 0

我一直在努力获取有关在 Linux 上处理浮点异常的一些信息,我可以告诉你我学到了什么:有几种启用异常机制的方法:

  1. fesetenv (FE_NOMASK_ENV); 启用所有异常
  2. 费纳布尔例外(FE_ALL_EXCEPT);
 fpu_control_t fw;
 _FPU_GETCW(fw);
 fw |=FE_ALL_EXCEPT;
 _FPU_SETCW(fw);
Run Code Online (Sandbox Code Playgroud)

4.

> fenv_t envp; include bits/fenv.h   
> fegetenv(&envp);    
 envp.__control_word |= ~_FPU_MASK_OM;   
> fesetenv(&envp);
Run Code Online (Sandbox Code Playgroud)

5.

> fpu_control_t cw;
> __asm__ ("fnstcw %0" : "=m" (*&cw));get config word
>cw |= ~FE_UNDERFLOW;
> __asm__ ("fldcw %0" : : "m" (*&cw));write config word
Run Code Online (Sandbox Code Playgroud)

6.C++模式:std::feclearexcept(FE_ALL_EXCEPT);

有一些有用的链接: http://frs.web.cern.ch/frs/Source/MAC_headers/fpu_control.h http://en.cppreference.com/w/cpp/numeric/fenv/fetest except http:// technopark02.blogspot.ro/2005/10/handling-sigfpe.html