Floating-Point Exceptions
The exception codes include seven distinct codes for floating-point exceptions. These exceptions are disabled initially and will not occur without first setting the processor-independent floating-point mask with the _controlfp function. There are specific exceptions for underflow, overflow, division by zero, inexact results, and so on, as shown in a later code fragment. Turn the mask bit off to enable the particular exception.
DWORD _controlfp (DWORD new, DWORD mask)
The actual value of the floating-point mask is determined by its current value (current_mask) and the two arguments as follows:
(current_mask & ~mask) | (new & mask)
The function sets the bits specified by new that are enabled by mask. All bits not in mask are unaltered. The floating-point mask also controls precision, rounding, and infinity values, so it is important not to alter these settings when you're enabling floating-point exceptions.The return value will be the actual setting. Thus, if both argument values are 0, the return value is the current mask setting, which can be used later to restore the mask. On the other hand, if mask is 0xFFFFFFFF, then the register is set to new, so that, for example, an old value can be restored.Normally, to enable the floating-point exceptions, use the floating-point exception mask value, MCW_EM, as shown in the following example. Notice also that, when a floating-point exception is processed, the exception must be cleared using the _clearfp function.
#include <float.h>
DWORD FPOld, FPNew; /* Old and new mask values. */
...
FPOld = _controlfp (0, 0); /* Saved old mask. */
/* Specify six exceptions to be enabled. */
FPNew = FPOld & ~(EM_OVERFLOW | EM_UNDERFLOW
| EM_INEXACT | EM_ZERODIVIDE | EM_DENORMAL | EM_INVALID);
/* Set new control mask. MCW_EM combines the six
exceptions in the previous statement. */
_controlfp (FPNew, MCW_EM);
while (...) __try { /* Perform FP calculations. */
... /* An FP exception could occur here. */
}
__except (EXCEPTION_EXECUTE_HANDLER) {
... /* Process the FP exception. */
_clearfp (); /* Clear the exception. */
_controlfp (FPOld, 0xFFFFFFFF); /* Restore mask. */
}
This example enables all possible floating-point exceptions except for the floating-point stack overflow, EXCEPTION_FLT_STACK_CHECK. Alternatively, enable specific exceptions by using only selected exception masks, such as EM_OVERFLOW. Program 4-3 uses similar code in the context of a larger example.
