_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 的值非零,新的控制字會被設置: 對於開啟的位元 (等於 1) 於 mask , new 裏對應的位元會被用來更新控制字。 換句話說, fpcntrl= ((fpcntrl& ~mask)|(new & mask)) 其中 fpcntrl 是浮點控制字。
注意事項 |
---|
預設執行階段程式庫遮罩所有浮點例外狀況。 |
_controlfp 是與平台無關的,可移植版本的 _control87 。 它與 _control87 函式在 Intel (x86) 平台非常相似並為 MIPS 和 ALPHA 平台所支援。 為了確保您的浮點程式碼可移植於 MIPS 或 ALPHA ,請使用 _controlfp 。 如果您以 x86 平台為目標,請使用 _control87 或 _controlfp 。
_control87 和 _controlfp 之間的不同在於它們處理 DENORMAL 值的方式。 若是 Intel (x86) 平台, _control87 會設置並清除 DENORMAL OPERAND 例外狀況遮罩。 ALPHA 平台並不支援此例外狀況,且 _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 等等) 為參數予這些函式,而不要直接提供十六進位值。
ALPHA 平台於軟體支援 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 旗標來表示兩個控制字之間存在不協調的情況。 這是一個警告,用來表示控制字可能無法精確地表示兩個浮點控制字的狀態。
在 x64 結構,不支援改變浮點精準度。 如果在該平台使用精準度控制遮罩,會調用一個斷言與無效參數處理常式,如 參數驗證 中所述。
注意事項 |
---|
__control87_2 不為 x64 結構所支援。如果您使用 __control87_2 且將您的應用程式以 x64 結構來編譯,編譯器會產生錯誤。 |
這些函式現在已不建議在 /clr (Common Language Runtime 編譯) 或 /clr:pure 下編譯時使用,因為共同語言執行階段只支援預設浮點精準度。
十六進位值
對於 _MCW_EM 遮罩,清除遮罩會設置例外狀況,它允許硬體例外狀況。設定遮罩會隱藏例外狀況。 請注意,如果 _EM_UNDERFLOW 或 _EM_OVERFLOW 發生,硬體例外狀況不會被擲回,直到下一個浮點指示執行。 若要在 _EM_UNDERFLOW 或 _EM_OVERFLOW 後的立即產生硬體例外狀況,請呼叫 FWAIT MASM 指令。
遮罩 |
十六進位值 |
常數 |
十六進位值 |
---|---|---|---|
_MCW_DN (Denormal 控制項) |
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> |
如需更多關於相容性的資訊,請參閱入門介紹中的 相容性 (Compatibility) 。
範例
// 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。 如需更多的資訊,請參閱 平台調用範例 (Platform Invoke Examples) 。