_controlfp_s
取得和設定浮點控制字組。 此版本的_control87
、 _controlfp
__control87_2
具有安全性增強功能,如 CRT 中的安全性功能中所述。
語法
errno_t _controlfp_s(
unsigned int *currentControl,
unsigned int newControl,
unsigned int mask
);
參數
currentControl
目前的控制字組位元值。
newControl
新的控制字組位元值。
mask
要設定之新控制字組位元的遮罩。
傳回值
如果成功,則為零,或 errno
值錯誤碼。
備註
_controlfp_s
函式是與平台無關且更安全的 _control87
版本,可將浮點控制字組放入 currentControl
中所儲存的位址,並使用 newControl
進行設定。 值中的位元表示浮點控制狀態。 浮點控制狀態可讓程式變更浮點數學套件中的精確度、四捨五入和無限大模式 (視平台而定)。 您也可以使用 _controlfp_s
來遮罩或取消遮罩浮點例外狀況。
如果 mask
的值等於 0,_controlfp_s
會取得浮點控制字組,並將擷取到的值儲存至 currentControl
。
如果 mask
為非零,則會設定控制字組的新值:針對 mask
中所設定的任何位元 (即等於 1),會使用 new
中的對應位元來更新控制字組。 換句話說, fpcntrl = ((fpcntrl & ~mask) | (newControl & mask))
其中 fpcntrl
是浮點控制字。 在此案例中,會在 currentControl
變更完成之後設定為 值;它不是舊的控件字位值。
注意
根據預設,執行階段程式庫會遮罩所有浮點例外狀況。
_controlfp_s
與 Intel (x86)、x64 和 ARM 平臺上的 _control87
函式幾乎完全相同。 如果您的目標是 x86、x64 或 ARM 平臺,您可以使用 _control87
或 _controlfp_s
。
和 _controlfp_s
之間的差異_control87
在於如何處理反正規值。 針對 Intel (x86)、x64 和 ARM 平臺, _control87
可以設定及清除 DENORMAL OPERAND
例外狀況遮罩。 _controlfp_s
不會修改例外狀況 DENORMAL OPERAND
遮罩。 這個範例示範差異:
_control87( _EM_INVALID, _MCW_EM );
// DENORMAL is unmasked by this call.
unsigned int current_word = 0;
_controlfp_s( ¤t_word, _EM_INVALID, _MCW_EM );
// DENORMAL exception mask remains unchanged.
下列「十六進位值」表格顯示遮罩常數 (mask
) 和新控制項值 (newControl
) 的可能值。 使用下面所列的可攜式常數 (_MCW_EM
、_EM_INVALID
等) 作為這些函式的引數,而不是明確地提供十六進位值。
Intel (x86)衍生的平臺支持 DENORMAL
硬體中的輸入和輸出值。 x86 行為是保留 DENORMAL
值。 具有 SSE2 支援的 ARM 平臺和 x64 平臺可讓 DENORMAL
操作數和結果排清,或強制為零。 _controlfp_s
、_controlfp
和 _control87
函式提供遮罩來變更此行為。 下列範例示範如何使用此遮罩:
unsigned int current_word = 0;
_controlfp_s(¤t_word, _DN_SAVE, _MCW_DN);
// Denormal values preserved on ARM platforms and on x64 processors with
// SSE2 support. NOP on x86 platforms.
_controlfp_s(¤t_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 暫存器。 在 x64 架構上,只會影響儲存在 MXCSR 快取器的 SSE2 控制字組。 在 Intel (x86) 平台上,_controlfp_s
會影響 x87 和 SSE2 (如果有的話) 的控制字組。 這兩個控制字可能會彼此不一致(例如,因為先前呼叫 __control87_2
,例如):如果兩個控制字組之間不一致,_controlfp_s
請在 中currentControl
設定 EM_AMBIGUOUS
旗標。 傳回的控制字可能不會正確表示這兩個浮點控件字的狀態,這是一個警告。
在 ARM 和 x64 架構上,不支援變更無限模式或浮點精確度。 如果在 x64 平臺上使用有效位數控制遮罩,函式會引發判斷提示,並叫用無效的參數處理程式,如參數驗證中所述。
如果未正確設定遮罩,此函式會產生無效的參數例外狀況,如參數驗證中所述。 若允許繼續執行,此函式會傳回 EINVAL
,並將 errno
設為 EINVAL
。
當您使用 /clr
[Common Language Runtime 編譯] 進行編譯時,會忽略此函式,因為 Common Language Runtime (CLR) 僅支援預設浮點精確度。
根據預設,此函式的全域狀態會限定於應用程式。 若要變更此行為,請參閱 CRT 中的全域狀態。
遮罩常數和值
針對 _MCW_EM
遮罩,清除它會設定例外狀況,以允許硬體例外狀況;設定它則會隱藏例外狀況。 如果發生 _EM_UNDERFLOW
或 _EM_OVERFLOW
,則除非執行下一個浮點指令,否則不會擲回任何硬體例外狀況。 若要在 或 _EM_OVERFLOW
之後_EM_UNDERFLOW
立即產生硬體例外狀況,請呼叫 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 |
需求
常式 | 必要的標頭 |
---|---|
_controlfp_s |
<float.h> |
如需相容性詳細資訊,請參閱相容性。
範例
// 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
另請參閱
數學與浮點支援
_clear87
, _clearfp
_status87
、 、 _statusfp
_statusfp2
_control87
、 、 _controlfp
__control87_2