Share via


_control87, _controlfp

Get and set the floating-point control word.

unsignedint_control87(unsignedintnew**,unsignedintmask);**

unsignedint_controlfp(unsignedintnew**,unsignedintmask);**

Routine Required Header Compatibility
_control87 <float.h> Win 95, Win NT
_controlfp <float.h> Win 95, Win NT

For additional compatibility information, see Compatibility in the Introduction.

Libraries

LIBC.LIB Single thread static library, retail version
LIBCMT.LIB Multithread static library, retail version
MSVCRT.LIB Import library for MSVCRT.DLL, retail version

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.

Parameters

new

New control-word bit values

mask

Mask for new control-word bits to set

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 Table R.1. 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

Table R.1   Hexadecimal Values

Mask Hex Value Constant Hex Value
_MCW_DN (Denormal control) 0x03000000

_DN_SAVE

_DN_FLUSH



0x00000000

0x01000000

_MCW_EM (Interrupt exception) 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

Example

/* 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>

void 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:  0x001f
0.1 * 0.1 = 1.000000000000000e-002

Floating-Point Support Routines

See Also   _clear87, _status87