_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
新的控制字組位元值。
mask
要設定之新控制字組位元的遮罩。
x86_cw
填入 x87 浮點單位的控制字組。 傳入 0 (NULL
),僅設定 SSE2 控制字組。
sse2_cw
SSE 浮點單位的控制字組。 傳入 0 (NULL
),僅設定 x87 控制字組。
傳回值
針對 _control87
和 _controlfp
,傳回值中的位元表示浮點控制狀態。 如需 所 _control87
傳回之位的完整定義,請參閱 FLOAT.H
。
針對 __control87_2
,傳回值是 1,表示成功。
備註
_control87
函式會取得和設定浮點控制字組。 浮點控制字可讓程序根據平台變更精確度、四捨五入和無限模式。 您也可以使用 _control87
來遮罩或取消遮罩浮點例外狀況。 如果 mask
的值等於 0,_control87
會取得浮點控制字組。 如果 mask
為非零,則會設定控制字組的新值:針對 mask
中為開啟的任何位元 (即等於 1),會使用 new
中的對應位元來更新控制字組。 換句話說, fpcntrl = ((fpcntrl & ~mask) | (new & mask))
其中 fpcntrl
是浮點控制字。
注意
根據預設,執行階段程式庫會遮罩所有浮點例外狀況。
_controlfp
是與平台無關的可攜式版本 _control87
,幾乎與函 _control87
式完全相同。 如果您的程式代碼以多個平台為目標,請使用 _controlfp
或 _controlfp_s
。 _control87
與 _controlfp
之間的差異在於它們如何處理 DENORMAL
值。 針對 x86、x64、ARM 和 ARM64 平臺, _control87
可以設定及清除 DENORMAL OPERAND
例外狀況遮罩。 _controlfp
不會修改例外狀況 DENORMAL OPERAND
遮罩。 這個範例示範差異:
_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
等) 作為這些函式的引數,而不是明確地提供十六進位值。
Intel x86 衍生的平臺支持 DENORMAL
硬體中的輸入和輸出值。 x86 行為是保留 DENORMAL
值。 具有 SSE2 支援的 ARM 和 ARM64 平臺和 x64 平臺可讓 DENORMAL
操作數和結果排清,或強制為零。 _controlfp
和 _control87
函式提供遮罩來變更此行為。 下列範例示範如何使用此遮罩。
_controlfp(_DN_SAVE, _MCW_DN);
// Denormal values preserved on ARM platforms and on x64 processors with
// SSE2 support. NOP on x86 platforms.
_controlfp(_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 和 ARM64 平臺上, _control87
和 _controlfp
函式會套用至 FPSCR 快取器。 只有儲存在 MXCSR 快取器中的 SSE2 控制字會在 x64 平臺上受到影響。 在 x86 平臺上, _control87
如果存在,則 _controlfp
會影響 x87 和 SSE2 的控制字組。
__control87_2
函式會一併或分開控制 x87 和 SSE2 浮點單位。 若要影響這兩個單位,請將兩個整數的 x86_cw
位址傳入 和 sse2_cw
。 如果您只想要影響一個單位,請傳入該參數的位址,但針對另一個單位傳入 0 (NULL
) 。 如果針對其中一個參數傳遞 0,則此函式不會影響該浮點單位。 當程式代碼的一部分使用 x87 浮點單位,而另一個部分使用 SSE2 浮點單位時,會很有用。
如果您使用 __control87_2
來設定浮點控制字的不同值,則 _control87
或 _controlfp
可能無法傳回單一控制字來表示這兩個浮點單位的狀態。 在這種情況下,這些函式會在 EM_AMBIGUOUS
傳回的整數值中設定旗標,以表示這兩個控制字組之間的不一致。 旗 EM_AMBIGUOUS
標是傳回的控制字組可能無法正確表示這兩個浮點控件字的狀態的警告。
在ARM、ARM64和 x64平臺上,不支援變更無限模式或浮點精確度。 如果在 x64 平臺上使用有效位數控制遮罩,函式會引發判斷提示,並叫用無效的參數處理程式,如參數驗證中所述。
注意
__control87_2
ARM、ARM64 或 x64 平台不支援。 如果您使用 __control87_2
和編譯 ARM、ARM64 或 x64 平臺的程式,編譯程式會產生錯誤。
當您使用 /clr
[Common Language Runtime 編譯] 進行編譯時,會忽略這些函式。 Common Language Runtime (CLR) 僅支援預設浮點精確度。
控制文字遮罩和值
針對 _MCW_EM
遮罩,清除遮罩會設定例外狀況,以允許硬體例外狀況;設定遮罩則會隱藏例外狀況。 如果發生 _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 (無限大控制項)(ARM 或 x64 平臺上不支援。 |
0x00040000 | _IC_AFFINE _IC_PROJECTIVE |
0x00040000 0x00000000 |
_MCW_RC (四捨五入控制項) |
0x00000300 | _RC_CHOP _RC_UP _RC_DOWN _RC_NEAR |
0x00000300 0x00000200 0x00000100 0x00000000 |
_MCW_PC (精確度控制項)(ARM 或 x64 平臺上不支援。 |
0x00030000 | _PC_24 (24 位元)_PC_53 (53 位元)_PC_64 (64 位元) |
0x00020000 0x00010000 0x00000000 |
需求
常式 | 必要的標頭 |
---|---|
_control87 、 、 _controlfp _control87_2 |
<float.h> |
如需相容性詳細資訊,請參閱相容性。
範例
// crt_cntrl87.c
// processor: x86
// compile by using: cl /W4 /arch:IA32 crt_cntrl87.c
// 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 = 0;
int result;
// Show original x87 control word and do calculation.
result = __control87_2(0, 0, &control_word_x87, 0 );
printf( "Original: 0x%.8x\n", control_word_x87 );
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
// Set precision to 24 bits and recalculate.
result = __control87_2(_PC_24, MCW_PC, &control_word_x87, 0 );
printf( "24-bit: 0x%.8x\n", control_word_x87 );
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
// Restore default precision-control bits and recalculate.
result = __control87_2( _CW_DEFAULT, MCW_PC, &control_word_x87, 0 );
printf( "Default: 0x%.8x\n", control_word_x87 );
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
}
Original: 0x0009001f
0.1 * 0.1 = 1.000000000000000e-02
24-bit: 0x000a001f
0.1 * 0.1 = 9.999999776482582e-03
Default: 0x0009001f
0.1 * 0.1 = 1.000000000000000e-02
另請參閱
數學與浮點支援
_clear87
, _clearfp
_status87
、 、 _statusfp
_statusfp2
_controlfp_s