_control87, _controlfp
Get and set the floating-point control word.
unsigned int _control87( unsigned int new, unsigned int mask ); unsigned int _controlfp( unsigned int new, unsigned int mask );
Parameters
- new
- New control-word bit values.
- mask
- Mask for new control-word bits to set.
Return Value
The bits in the value returned indicate the floating-point control state. See FLOAT.H for a complete definition of the bits returned by _control87.
Remarks
The _control87 function gets and sets the floating-point control word. The floating-point control word allows the program to change the precision, rounding, and infinity modes in the floating-point math package. You can also mask or unmask floating-point exceptions using _control87. If the value for mask is equal to 0, _control87 gets the floating-point control word. If mask is nonzero, a new value for the control word is set: For any bit that is on (equal to 1) in mask, the corresponding bit in new is used to update the control word. In other words, fpcntrl = ((fpcntrl & ~mask) | (new & mask)) where fpcntrl is the floating-point control word.
Note The run-time libraries mask all floating-point exceptions by default.
_controlfp is a platform-independent, portable version of _control87. It is nearly identical to the _control87 function on Intel (x86) platforms and is also supported by the MIPS and ALPHA platforms. To ensure that your floating-point code is portable to MIPS or ALPHA, use _controlfp. If you are targeting x86 platforms, use either _control87 or _controlfp.
The difference between _control87 and _controlfp is the way these two functions treat DENORMAL values. For Intel (x86) platforms, _control87 can set and clear the DENORMAL OPERAND exception mask. ALPHA platforms do not support this exception, and _controlfp does not modify the DENORMAL OPERAND exception mask. The following example demonstrates the difference:
_control87( _EM_INVALID, _MCW_EM ); // DENORMAL is unmasked by this call _controlfp( _EM_INVALID, _MCW_EM ); // DENORMAL exception mask remains unchanged
The possible values for the mask constant (mask) and new control values (new) are shown in the following Hexadecimal Values table. Use the portable constants listed below (_MCW_EM, _EM_INVALID, and so forth) as arguments to these functions, rather than supplying the hexadecimal values explicitly.
ALPHA platforms support the DENORMAL input and output values in software. The default behavior of Windows NT on these platforms is to flush the DENORMAL input and output values to zero. _controlfp provides a new mask to preserve and flush the input and output DENORMAL values.
Intel (x86) platforms support the DENORMAL input and output values in hardware. The behavior is to preserve DENORMAL values. _control87 does not provide a mask to change this behavior. The following example demonstrates this difference:
controlfp( _DN_SAVE, _MCW_DN); // Denormal values preserved by software on ALPHA. NOP on x86 controlfp( _DN_FLUSH, _MCW_DN); // Denormal values flushed to zero by hardware on Alpha. Ignored on x86
Hexadecimal Values
Regarding the _MCW_EM mask, clearing the mask sets the exception, which allows the hardware exception; setting the mask hides the exception. Note that if a _EM_UNDERFLOW or_EM_OVERFLOW occurs, no hardware exception will be thrown until the next floating point instruction is executed. To generate a hardware exception immediately after _EM_UNDERFLOW or_EM_OVERFLOW, call the FWAIT MASM instruction.
| Mask | Hex value | Constant | Hex value |
|---|---|---|---|
| _MCW_DN (Denormal control) | 0x03000000 | _DN_SAVE _DN_FLUSH | 0x00000000
0x01000000 |
| _MCW_EM (Interrupt exception mask) | 0x0008001F | _EM_INVALID _EM_DENORMAL _EM_ZERODIVIDE _EM_OVERFLOW _EM_UNDERFLOW _EM_INEXACT | 0x00000010
0x00080000 0x00000008 0x00000004 0x00000002 0x00000001 |
| _MCW_IC (Infinity control) | 0x00040000 | _IC_AFFINE _IC_PROJECTIVE | 0x00040000
0x00000000 |
| _MCW_RC (Rounding control) | 0x00000300 | _RC_CHOP _RC_UP _RC_DOWN _RC_NEAR | 0x00000300
0x00000200 0x00000100 0x00000000 |
| _MCW_PC (Precision control) | 0x00030000 | _PC_24 (24 bits)
_PC_53 (53 bits) _PC_64 (64 bits) | 0x00020000
0x00010000 0x00000000 |
Requirements
| Routine | Required header | Compatibility |
|---|---|---|
| _control87 | <float.h> | Win 98, Win Me, Win NT, Win 2000, Win XP |
| _controlfp | <float.h> | Win 98, Win Me, Win NT, Win 2000, Win XP |
For additional compatibility information, see Compatibility in the Introduction.
Libraries
All versions of the C run-time libraries.
Example
// crt_cntrl87.c
/* This program uses _control87 to output the control
* word, set the precision to 24 bits, and reset the status to
* the default.
*/
#include <stdio.h>
#include <float.h>
int main( void )
{
double a = 0.1;
/* Show original control word and do calculation. */
printf( "Original: 0x%.4x\n", _control87( 0, 0 ) );
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
/* Set precision to 24 bits and recalculate. */
printf( "24-bit: 0x%.4x\n", _control87( _PC_24, MCW_PC ) );
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
/* Restore to default and recalculate. */
printf( "Default: 0x%.4x\n",
_control87( _CW_DEFAULT, 0xfffff ) );
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
}
Output
Original: 0x9001f 0.1 * 0.1 = 1.000000000000000e-002 24-bit: 0xa001f 0.1 * 0.1 = 9.999999776482582e-003 Default: 0x9001f 0.1 * 0.1 = 1.000000000000000e-002
See Also
Floating-Point Support Routines | _clear87 | _status87 | Run-Time Routines and .NET Framework Equivalents