Gets and sets the floating-point control word. This is a version of _control87, _controlfp, __control87_2 with security enhancements as described in Security Features in the CRT.

errno_t _controlfp_s(
    unsigned int *currentControl,
    unsigned int newControl,
    unsigned int mask


  • currentControl
    The current control-word bit value.

  • newControl
    New control-word bit values.

  • mask
    Mask for new control-word bits to set.

Return Value

Zero if successful or an errno value error code.


The _controlfp_s is a platform-independent and more secure version of _control87, which gets and sets the floating-point control word into the address of currentControl and newControl, respectively. The bits in the values indicate the floating-point control state. The floating-point control state allows the program to change the precision, rounding, and infinity modes in the floating-point math package. One can also mask or unmask floating-point exceptions using _controlfp_s.

If the value for mask is equal to 0, _controlfp_s gets the floating-point control word and stores the retrieved value in currentControl.

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. In this scenario, currentControl is set to the value after the change completes; it is not the old control-word bit value.


The run-time libraries mask all floating-point exceptions by default.

_controlfp_s is nearly identical to the _control87 function on Intel (x86) platforms and is supported by the MIPS and ALPHA platforms. To ensure that the floating-point code is portable to MIPS or ALPHA, use _controlfp_s. If you are targeting x86 platforms, use _control87 or _controlfp_s.

The difference between _control87 and _controlfp_s 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_s 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 (newControl) are shown in the following Hexadecimal Values table. Use the portable constants listed below (_MCW_EM, _EM_INVALID, and so on) 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_s 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

_controlfp_s affects the control words for both the x87 and the SSE2, if present. It is possible for the two control words to be inconsistent with each other (because of a previous call to __control87_2, for example); if there is an inconsistency between the two control words, _controlfp_s sets the EM_AMBIGUOUS flag in currentControl. This is a warning that the returned control word might not represent the state of both floating-point control words accurately.

On the x64 architecture, changing the floating-point precision is not supported. If the precision control mask is used on that platform, the invalid parameter handler is invoked, as described in Parameter Validation.

If the mask is not set correctly, this function generates an invalid parameter exception, as described in Parameter Validation. If execution is allowed to continue, this function returns EINVAL and sets errno to EINVAL.

This function is deprecated when compiling with /clr (Common Language Runtime Compilation) or /clr:pure because the common language runtime only supports the default floating-point precision.

Hexadecimal Values

For 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 is 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.


Hex value


Hex value

_MCW_DN (Denormal control)






_MCW_EM (Interrupt exception mask)














_MCW_IC (Infinity control)






_MCW_RC (Rounding control)










_MCW_PC (Precision control)


_PC_24 (24 bits)

_PC_53 (53 bits)

_PC_64 (64 bits)






Required header



For more compatibility information, see Compatibility in the Introduction.


// crt_contrlfp_s.c
// processor: x86
// This program uses _controlfp_s to output the FP control 
// word, set the precision to 24 bits, and reset the status to 
// the default.

#include <stdio.h>
#include <float.h>
#pragma fenv_access (on)

int main( void )
    double a = 0.1;
    unsigned int control_word;
    int err;

    // Show original FP control word and do calculation.
    err = _controlfp_s(&control_word, 0, 0);
    if ( err ) /* handle error here */;

    printf( "Original: 0x%.4x\n", control_word );
    printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );

    // Set precision to 24 bits and recalculate.
    err = _controlfp_s(&control_word, _PC_24, MCW_PC);
    if ( err ) /* handle error here */;

    printf( "24-bit:   0x%.4x\n", control_word );
    printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );

    // Restore default precision-control bits and recalculate.
    err = _controlfp_s(&control_word, _CW_DEFAULT, MCW_PC);
    if ( err ) /* handle error here */;

    printf( "Default:  0x%.4x\n", control_word );
    printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );


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

NET Framework Equivalent

Not applicable. To call the standard C function, use PInvoke. For more information, see Platform Invoke Examples.

See Also


Floating-Point Support

_clear87, _clearfp

_status87, _statusfp, _statusfp2