_controlfp_s_controlfp_s

获取并设置浮点控制字。Gets and sets the floating-point control word. 此版本的 _control87、_controlfp、__control87_2 具有安全增强功能,如 CRT 中的安全功能中所述。This version of _control87, _controlfp, __control87_2 has security enhancements, as described in Security Features in the CRT.

语法Syntax

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

参数Parameters

currentControlcurrentControl
当前控制字位值。The current control-word bit value.

newControlnewControl
新的控制字位值。New control-word bit values.

掩码mask
要设置的新控制字位掩码。Mask for new control-word bits to set.

返回值Return Value

如果成功,或者将为零errno值错误代码。Zero if successful, or an errno value error code.

备注Remarks

_Controlfp_s函数是独立于平台的更安全版本, _control87,后者将获取存储在地址到浮点控制字currentControl并将其设置通过使用newControlThe _controlfp_s function is a platform-independent and more secure version of _control87, which gets the floating-point control word into the address that's stored in currentControl and sets it by using newControl. 值中的位表示浮点控制状态。The bits in the values indicate the floating-point control state. 浮点控制状态允许程序在浮点数学包中更改精度、舍入和无穷模式,具体取决于平台。The floating-point control state enables the program to change the precision, rounding, and infinity modes in the floating-point math package, depending on the platform. 你还可以使用 _controlfp_s屏蔽或取消屏蔽浮点异常。You can also use _controlfp_s to mask or unmask floating-point exceptions.

如果值掩码等于 0, _controlfp_s获取浮点控制字并将存储中检索到的值currentControlIf the value for mask is equal to 0, _controlfp_s gets the floating-point control word and stores the retrieved value in currentControl.

如果掩码是新的控制字值设置为零,: 设置任何位 (即,等于 1) 在掩码中的对应位用于更新控件word。If mask is nonzero, a new value for the control word is set: For any bit that is set (that is, equal to 1) in mask, the corresponding bit in new is used to update the control word. 换而言之, fpcntrl = ((fpcntrl & ~掩码) | (newControl & 掩码)) 其中fpcntrl是浮点控制字。In other words, fpcntrl = ((fpcntrl & ~mask) | (newControl & mask)) where fpcntrl is the floating-point control word. 在此方案中, currentControl设置为值后更改完成; 它不是旧的控制字位值。In this scenario, currentControl is set to the value after the change completes; it is not the old control-word bit value.

备注

默认情况下,运行时库屏蔽所有浮点异常。By default, the run-time libraries mask all floating-point exceptions.

_controlfp_s几乎等同于 _control87 (x86)、 x64 和 ARM 平台上 Intel 函数。_controlfp_s is nearly identical to the _control87 function on Intel (x86), x64, and ARM platforms. 如果你正面向 x86、 x64 或 ARM 平台上,则可以使用 _control87_controlfp_sIf you are targeting x86, x64, or ARM platforms, you can use _control87 or _controlfp_s.

之间的差异 _control87_controlfp_s是在它们如何处理非常规值。The difference between _control87 and _controlfp_s is in how they treat denormal values. X64 和 ARM 平台上,intel (x86), _control87可以设置和清除非常规操作数异常掩码。For Intel (x86), x64, and ARM platforms, _control87 can set and clear the DENORMAL OPERAND exception mask. _controlfp_s不会修改非常规操作数异常掩码。_controlfp_s does not modify the DENORMAL OPERAND exception mask. 此示例演示了差别:This example demonstrates the difference:

_control87( _EM_INVALID, _MCW_EM );
// DENORMAL is unmasked by this call.
unsigned int current_word = 0;
_controlfp_s( &current_word, _EM_INVALID, _MCW_EM );
// DENORMAL exception mask remains unchanged.

掩码常量的可能值 (掩码) 和控件的新值 (newControl) 下的十六进制值表中显示。The possible values for the mask constant (mask) and new control values (newControl) are shown in the following Hexadecimal Values table. 使用下面列出的可移植常量 (_MCW_EM_EM_INVALID,依次类推) 作为对这些函数的自变量,而不是提供十六进制值显式。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.

Intel (x86) 派生的平台支持硬盘中的 DENORMAL 输入和输出值。Intel (x86)-derived platforms support the DENORMAL input and output values in hardware. x86 行为是为了保留 DENORMAL 值。The x86 behavior is to preserve DENORMAL values. ARM 平台和 x64 平台具有 SSE2 支持启用 DENORMAL 操作数和结果,以刷新,或强制为零。The ARM platform and the x64 platforms that have SSE2 support enable DENORMAL operands and results to be flushed, or forced to zero. _Controlfp_s_controlfp,和 _control87函数提供的掩码要更改此行为。The _controlfp_s, _controlfp, and _control87 functions provide a mask to change this behavior. 下面的示例演示此掩码的使用:The following example demonstrates the use of this mask:

unsigned int current_word = 0;
_controlfp_s(&current_word, _DN_SAVE, _MCW_DN);
// Denormal values preserved on ARM platforms and on x64 processors with
// SSE2 support. NOP on x86 platforms.
_controlfp_s(&current_word, _DN_FLUSH, _MCW_DN);
// Denormal values flushed to zero by hardware on ARM platforms
// and x64 processors with SSE2 support. Ignored on other x86 platforms.

在 ARM 平台上, _controlfp_s函数将应用于 FPSCR 寄存器。On ARM platforms, the _controlfp_s function applies to the FPSCR register. 在 x64 体系结构中,仅存储 SSE2 控制字 MXCSR 注册受到影响。On x64 architectures, only the SSE2 control word that's stored in the MXCSR register is affected. 在 Intel (x86) 平台 _controlfp_s影响 x87 和 SSE2 的控制字,如果存在。On Intel (x86) platforms, _controlfp_s affects the control words for both the x87 and the SSE2, if present. 可能的两个控件单词不相互一致 (因以前调用而__control87_2,例如); 如果存在两个控件单词,之间不一致 _controlfp_s设置EM_AMBIGUOUS中标记出来currentControlIt 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.

在 ARM 和 x64 体系结构,更改无穷大模式或的浮点精度不支持。On the ARM and x64 architectures, changing the infinity mode or the floating-point precision is not supported. 如果在 x64 上使用的精度控制掩码平台,该函数引发了断言并调用无效参数处理程序,如中所述参数验证If the precision control mask is used on the x64 platform, the function raises an assertion and 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. 如果允许执行继续,则此函数将返回EINVAL和设置errnoEINVALIf execution is allowed to continue, this function returns EINVAL and sets errno to EINVAL.

当你使用此函数将忽略/clr (公共语言运行时编译)来编译,因为公共语言运行时 (CLR) 仅支持默认的浮点精度。This function is ignored when you use /clr (Common Language Runtime Compilation) to compile because the common language runtime (CLR) only supports the default floating-point precision.

掩码常量和值Mask constants and values

有关 _MCW_EM掩码,清除此复选框设置允许的硬件异常的异常; 将其设置隐藏异常。For the _MCW_EM mask, clearing it sets the exception, which allows the hardware exception; setting it hides the exception. 如果 _EM_UNDERFLOW_EM_OVERFLOW发生,直到执行下一步的浮点指令不引发任何硬件异常。If a _EM_UNDERFLOW or _EM_OVERFLOW occurs, no hardware exception is thrown until the next floating-point instruction is executed. 生成硬件异常后立即 _EM_UNDERFLOW_EM_OVERFLOW,调用 FWAIT MASM 指令。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 (不正常控制)_MCW_DN (Denormal control) 0x030000000x03000000 _DN_SAVE_DN_SAVE

_DN_FLUSH_DN_FLUSH
0x000000000x00000000

0x010000000x01000000
_MCW_EM (中断异常掩码)_MCW_EM (Interrupt exception mask) 0x0008001F0x0008001F _EM_INVALID_EM_INVALID

_EM_DENORMAL_EM_DENORMAL

_EM_ZERODIVIDE_EM_ZERODIVIDE

_EM_OVERFLOW_EM_OVERFLOW

_EM_UNDERFLOW_EM_UNDERFLOW

_EM_INEXACT_EM_INEXACT
0x000000100x00000010

0x000800000x00080000

0x000000080x00000008

0x000000040x00000004

0x000000020x00000002

0x000000010x00000001
_MCW_IC (无穷大控件)_MCW_IC (Infinity control)

(不支持在 ARM 或 x64 平台。)(Not supported on ARM or x64 platforms.)
0x000400000x00040000 _IC_AFFINE_IC_AFFINE

_IC_PROJECTIVE_IC_PROJECTIVE
0x000400000x00040000

0x000000000x00000000
_MCW_RC (舍入控件)_MCW_RC (Rounding control) 0x000003000x00000300 _RC_CHOP_RC_CHOP

_RC_UP_RC_UP

_RC_DOWN_RC_DOWN

_RC_NEAR_RC_NEAR
0x000003000x00000300

0x000002000x00000200

0x000001000x00000100

0x000000000x00000000
_MCW_PC (精度控制)_MCW_PC (Precision control)

(不支持在 ARM 或 x64 平台。)(Not supported on ARM or x64 platforms.)
0x000300000x00030000 _PC_24 (24 位)_PC_24 (24 bits)

_PC_53 (53 位)_PC_53 (53 bits)

_PC_64 (64 位)_PC_64 (64 bits)
0x000200000x00020000

0x000100000x00010000

0x000000000x00000000

要求Requirements

例程Routine 必需的标头Required header
_controlfp_s_controlfp_s <float.h><float.h>

有关更多兼容性信息,请参阅 兼容性For more compatibility information, see Compatibility.

示例Example

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

请参阅See also

浮点支持Floating-Point Support
_clear87、_clearfp_clear87, _clearfp
_status87、_statusfp、_statusfp2_status87, _statusfp, _statusfp2
_control87、_controlfp、__control87_2_control87, _controlfp, __control87_2