共用方式為


_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)

請參閱

參考

浮點支援

_clear87 _clearfp

_status87,_statusfp _statusfp2