_controlfp() - get and set floating point control word
#include <float.h>
unsigned int _controlfp(unsigned int new, unsinged int mask)
The _controlfp(3) call is a platform-independent way to set the floating point control word. You can change the precision, rounding, and infinity modes in the floating-point math package, and mask or unmask floating-point exceptions.
The new argument is the set of new control-word bit
values, and the mask argument is the mask for the new
control-word bits to set. For any bit that is set to 1 in
mask, the corresponding bit in new is used to update
the control word. That is, for a floating-point control word
fpcntrl
:
fpcntrl = ((fpcntrl & ~mask) | (new & mask))
If the value for mask is 0, the _controlfp(3) call gets the current floating point control word. If mask is non-zero, it sets the floating point control word.
By default, all floating-point exceptions are masked.
This call is very similar to the Intel platform-specific call _control87(3). The _controlfp(3) is more portable. The _control87(3) call modifies the DENORMAL OPERAND exception mask, while the _controlfp(3) call does not. For example:
_control87(_EM_INVALID, _MCW_EM); /* DENORMAL unmasked */
_controlfp(_EM_INVALID, _MCW_EM); /* DENORMAL not changed */
Denormal control: (This value is ignored; it is used with the Intel-specific _control87(3) call, which is nearly identical to _controlfp(3).)
Mask | Value | Constant | Value |
---|---|---|---|
_MCW_DN | 0x03000000 | ||
_DN_SAVE | 0x00000000 | ||
_DN_FLUSH | 0x01000000 |
Interrupt exception control:
Mask | Value | Constant | Value |
---|---|---|---|
_MCW_EM | 0x0008001F | ||
_EM_INVALID | 0x00000010 | ||
_EM_DENORMAL | 0x00080000 | ||
_EM_ZERODIVIDE | 0x00000008 | ||
_EM_OVERFLOW | 0x00000004 | ||
_EM_UNDERFLOW | 0x000000002 | ||
_EM_INEXACT | 0x000000001 |
Infinity control:
Mask | Value | Constant | Value |
---|---|---|---|
_MCW_IC | 0x00040000 | ||
_IC_AFFINE | 0x00040000 | ||
_IC_PROJECTIVE | 0x00000000 |
Rounding control:
Mask | Value | Constant | Value |
---|---|---|---|
_MCW_RC | 0x00000300 | ||
_RC_CHOP | 0x00000300 | ||
_RC_UP | 0x00000200 | ||
_RC_DOWN | 0x00000100 | ||
_RC_NEAR | 0x00000000 |
Precision control: (The number after the underscore is the number of bits of precision.)
Mask | Value | Constant | Value |
---|---|---|---|
_MCW_PC | 0x00030000 | ||
_PC_24 | 0x00020000 | ||
_PC_53 | 0x00010000 | ||
_PC_64 | 0x00000000 |
The _controlfp(3) call returns an int that describes the current state of floating-point control.
The following program turns on floating-point exceptions:
#include <stdio.h>
#include <float.h>
main()
{
double x, y;
unsigned int mask;
x = 1.0;
y = 0.0;
mask = _controlfp(0,0);
printf("old floating-point control mask = %#x\n", mask);
printf("%g=\n", x / y);
/* turn on floating point exceptions */
mask = _controlfp(0, _MCW_EM);
printf("new floating-point control mask = %#x\n", mask);
printf("%g\n", x / y );
}