且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在C ++中处理浮点异常

更新时间:1970-01-01 07:59:54

来自Bruce Dawson的博文(链接) 。

Most of the the following information comes from Bruce Dawson's blog post on the subject (link).

由于使用C ++,您可以创建一个RAII类,以范围方式启用或禁用浮点异常。这让你有更大的控制,所以你只暴露异常状态到你的代码,而不是手动管理调用_controlfp_s()自己。此外,以这种方式设置的浮点异常状态是系统范围的,因此记住控制字的先前状态并在需要时恢复它是真正可取的。

Since you're working with C++, you can create a RAII class that enables or disables floating point exceptions in a scoped manner. This lets you have greater control so that you're only exposing the exception state to your code, rather than manually managing calling _controlfp_s() yourself. In addition, floating point exception state that is set this way is system wide, so it's really advisable to remember the previous state of the control word and restore it when needed. RAII can take care of this for you and is a good solution for the issues with GDI+ that you're describing.

异常标志_EM_OVERFLOW,_EM_ZERODIVIDE和_EM_INVALID分别是用来描述GDI +的问题的解决方案。最重要的是要考虑。 _EM_OVERFLOW在正或负无穷大是计算结果时上升,而_EM_INVALID在结果是信号NaN时上升。 _EM_UNDERFLOW可以安全忽略;它会在您的计算结果非零并且在-FLT_MIN和FLT_MIN(换句话说,当您生成反规范时)发出信号。 _EM_INEXACT由于浮点运算的性质而被频繁地引用以至于无法实际使用,但是如果在某些情况下尝试跟踪不精确的结果,则可能会提供信息。

The exception flags _EM_OVERFLOW, _EM_ZERODIVIDE, and _EM_INVALID are the most important to account for. _EM_OVERFLOW is raised when positive or negative infinity is the result of a calculation, whereas _EM_INVALID is raised when a result is a signaling NaN. _EM_UNDERFLOW is safe to ignore; it signals when your computation result is non-zero and between -FLT_MIN and FLT_MIN (in other words, when you generate a denormal). _EM_INEXACT is raised too frequently to be of any practical use due to the nature of floating point arithmetic, although it can be informative if trying to track down imprecise results in some situations.

SIMD代码增加了更多的皱纹;因为你没有明确指出使用SIMD我将省略一个讨论,除了注意指定除了/ fp:fast之外的任何东西可以禁用您的代码在VS 2012的自动矢量化;有关详情,请参阅此答案

SIMD code adds more wrinkles to the mix; since you don't indicate using SIMD explicitly I'll leave out a discussion of that except to note that specifying anything other than /fp:fast can disable automatic vectorization of your code in VS 2012; see this answer for details on this.