_control87, _controlfp, __control87_2
获取和设置浮点控制字。 _controlfp 的一种较为安全的版本可用; _controlfp_s参见。
unsigned int _control87(
unsigned int new,
unsigned int mask
);
unsigned int _controlfp(
unsigned int new,
unsigned int mask
);
int __control87_2(
unsigned int new,
unsigned int mask,
unsigned int* x86_cw,
unsigned int* sse2_cw
);
参数
new
新的 Word 控件位值。mask
掩码对新的 Word 控件位可以设置。x86_cw
使用 x87 浮点单元测试的控制字填充。 通过在 0 (NULL) 设置仅将控制字。sse2_cw
SSE 浮点单元测试的控制字。 通过在 0 (NULL) 设置仅 x87 控制字。
返回值
为 _control87 和 _controlfp,按位返回的值指示浮点状态。 对位的完整定义由 _control87返回,请参见 FLOAT.H。
对于 __control87_2,则返回值是 1,指示成功。
备注
_control87函数获取和设置浮点控制字。 浮点控制字允许过程更改精度,舍入和 INFINITY 模式在浮点数学包。 使用 _control87,还可以掩码或撕下浮点异常情况面具。 如果 mask 的值为等于 0, _control87获取浮点控制字。 如果 mask 不为零,控制字的新值设置:对于打开 (了所有位等于 1)。 mask,在 new 中对应的位用于更新控制字。 换言之, fpcntrl = (fpcntrl & ~mask)|(new & mask)其中 fpcntrl 是浮点控制字。
备注
默认情况下运行库掩码所有浮点异常。
_controlfp是 _control87的一个独立于平台的,可移植版本。 它几乎完成相当于在 Intel (x86) 平台的 _control87功能和乘以 MIPS 和 ALPHA 平台支持。 若要确保浮点代码移植到 MIPS 或 ALPHA,请使用 _controlfp。 如果面向 x86 平台,请使用 _control87或 _controlfp。
在 _control87和 _controlfp的不同之处在于该方法这些功能将 DENORMAL 值。 为 Intel (x86) 平台, _control87可以设置和清除 DENORMAL 操作数异常掩码。 APPHA 的平台不支持此异常,并且, _controlfp不修改 DENORMAL 操作数异常掩码。 下面的示例演示差异:
_control87( _EM_INVALID, _MCW_EM );
// DENORMAL is unmasked by this call
_controlfp( _EM_INVALID, _MCW_EM );
// DENORMAL exception mask remains unchanged
常数的掩码的可能值 (mask) 和新值的控件 (new) 位于以下十六进制值表所示。 用作参数下面列出的 (_MCW_EM, _EM_INVALID,等等) 可移植的常数这些功能,而不是显式提供十六进制值。
APPHA 的平台支持在软件的 DENORMAL 输入和输出值。 windows NT 默认行为。这些平台的是刷新 DENORMAL 输入和输出值为零。 _controlfp 提供新掩码保持和刷新输入和输出 DENORMAL 值。
Intel (x86) 平台支持在硬件的 DENORMAL 输入和输出值。 此行为是保持 DENORMAL 值。 _control87 不提供掩码更改此行为。 下面的示例演示差异:
_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 and x86
// processors with SSE2 support. Ignored on other x86 platforms.
如果有 _control87 和 _controlfp 影响该 x87 和 SSE2 的控制字,。 函数 __control87_2 允许将同时也可以分别进行控制的 x87 和 SSE2 浮点单元。 如果希望影响两个单位,请将两个整数地址对 x86_cw 和 sse2_cw。 如果希望仅影响一个单元,请通过在该参数的地址,但是通过在 0 (空) 其他的。 如果 0 为这些参数之一传递,函数没有对该浮点单元的效果。 此功能可能很有用的一部分的代码使用 x87 浮点单元的情况,代码的其他部分使用 SSE2 浮点单元。 如果在程序中的一部分使用 __control87_2 并将浮点控制字不同的值,然后使用 _control87 或 _controlfp 进一步操作控制字,则 _control87 和 _controlfp 可能无法返回一个控件来表示两个浮点单元状态。 在这种情况下,这些功能集 EM_AMBIGUOUS 标志按 backspace 的整数值指示有两个控制字之间的不一致。 这是警告返回的控制字可能无法准确地表示两个浮点控制字状态。
在 x64 体系结构,更改浮点精度不受支持。 如果精度控件掩码。该平台使用,断言以及无效参数调用处理程序,如 参数验证所述。
备注
__control87_2 在 x64 体系结构不受支持。如果使用 __control87_2 和生成 x64 体系结构的过程,会生成错误。
这些函数已弃用,在使用编译 /clr(公共语言运行时编译) 或 /clr:pure 时,这是因为公共语言运行时仅支持默认浮点精度。
十六进制值
为 _MCW_EM 蒙板,清除掩码设置异常,允许硬件异常;设置 mask 隐藏异常。 请注意,如果 _EM_UNDERFLOW 或 _EM_OVERFLOW 发生,硬件不会引发异常,直到下浮点命令执行。 若要生成在 _EM_UNDERFLOW 或 _EM_OVERFLOW后的一个硬件异常,请调用 FWAIT MASM 指令。
掩码 |
十六进制值 |
常量 |
十六进制值 |
---|---|---|---|
_MCW_DN (不正常的控件) |
0x03000000 |
_DN_SAVE _DN_FLUSH |
0x00000000 为 0x01000000 |
_MCW_EM (中断异常屏蔽) |
0x0008001F |
_EM_INVALID _EM_DENORMAL _EM_ZERODIVIDE _EM_OVERFLOW _EM_UNDERFLOW _EM_INEXACT |
0x00000010 0x00080000 0x00000008 0x00000004 0x00000002 0x00000001 |
_MCW_IC (无限制控件) |
0x00040000 |
_IC_AFFINE _IC_PROJECTIVE |
0x00040000 0x00000000 |
_MCW_RC (舍入控件) |
0x00000300 |
_RC_CHOP _RC_UP _RC_DOWN _RC_NEAR |
0x00000300 0x00000200 0x00000100 0x00000000 |
_MCW_PC (精度控件) |
0x00030000 |
_PC_24 (24 位) _PC_53 (53 位) _PC_64 (64 位) |
0x00020000 0x00010000 0x00000000 |
要求
实例 |
必需的头 |
---|---|
_control87, _controlfp, _control87_2 |
float.h |
有关更多兼容性信息,请参见中介绍的 兼容性 。
示例
// crt_cntrl87.c
// processor: x86
// This program uses __control87_2 to output the x87 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_x87;
// Show original x87 control word and do calculation.
control_word_x87 = __control87_2(0, 0,
&control_word_x87, 0);
printf( "Original: 0x%.4x\n", control_word_x87 );
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
// Set precision to 24 bits and recalculate.
control_word_x87 = __control87_2(_PC_24, MCW_PC,
&control_word_x87, 0);
printf( "24-bit: 0x%.4x\n", control_word_x87 );
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
// Restore default precision-control bits and recalculate.
control_word_x87 = __control87_2( _CW_DEFAULT, MCW_PC,
&control_word_x87, 0 );
printf( "Default: 0x%.4x\n", control_word_x87 );
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
}
Output
Original: 0x0001
0.1 * 0.1 = 1.000000000000000e-002
24-bit: 0x0001
0.1 * 0.1 = 9.999999776482582e-003
Default: 0x0001
0.1 * 0.1 = 1.000000000000000e-002
.NET Framework 等效项
不适用。若要调用标准 C 函数,请使用 PInvoke。有关更多信息,请参见 平台调用示例。