_controlfp_s
Pobiera i ustawia zmiennoprzecinkowe słowo sterujące. Ta wersja programu __control87_2
_controlfp
_control87
, ma ulepszenia zabezpieczeń zgodnie z opisem w temacie Funkcje zabezpieczeń w narzędziu CRT.
Składnia
errno_t _controlfp_s(
unsigned int *currentControl,
unsigned int newControl,
unsigned int mask
);
Parametry
currentControl
Bieżąca wartość bitowa słowa kontrolnego.
newControl
Nowe wartości bitów wyrazów kontrolnych.
mask
Maskuj dla nowych bitów słów kontrolnych do ustawienia.
Wartość zwracana
Zero w przypadku powodzenia errno
lub kod błędu wartości.
Uwagi
Funkcja _controlfp_s
jest niezależną od platformy i bezpieczniejszą wersją _control87
programu , która pobiera zmiennoprzecinkowe słowo sterujące do adresu przechowywanego w currentControl
pliku i ustawia go przy użyciu polecenia newControl
. Bity w wartościach wskazują stan sterowania zmiennoprzecinkowego. Stan sterowania zmiennoprzecinkowego umożliwia programowi zmianę trybów precyzji, zaokrąglania i nieskończoności w pakiecie matematycznym zmiennoprzecinkowym, w zależności od platformy. Można również użyć _controlfp_s
do maskowania lub maskowania wyjątków zmiennoprzecinkowych.
Jeśli wartość parametru mask
jest równa 0, _controlfp_s
pobiera zmiennoprzecinkowe słowo sterujące i przechowuje pobraną wartość w pliku currentControl
.
Jeśli mask
jest niezerowa, zostanie ustawiona nowa wartość słowa sterującego: dla każdego bitu ustawionego (czyli równego 1) w elemecie , odpowiedni bit w mask
new
jest używany do aktualizowania słowa sterującego. Innymi słowy, fpcntrl = ((fpcntrl & ~mask) | (newControl & mask))
gdzie fpcntrl
to słowo sterujące zmiennoprzecinkowe. W tym scenariuszu currentControl
wartość jest ustawiona na wartość po zakończeniu zmiany. Nie jest to stara wartość bitowa słowa-kontrolka.
Uwaga
Domyślnie biblioteki czasu wykonywania maskuje wszystkie wyjątki zmiennoprzecinkowe.
_controlfp_s
funkcja jest niemal identyczna z funkcją _control87
na platformach Intel (x86), x64 i ARM. Jeśli używasz platform x86, x64 lub ARM, możesz użyć polecenia _control87
lub _controlfp_s
.
Różnica między _control87
i _controlfp_s
polega na tym, jak traktują wartości denormalne. W przypadku platform _control87
Intel (x86), x64 i ARM można ustawić i wyczyścić maskę wyjątków DENORMAL OPERAND
. _controlfp_s
nie modyfikuje maski wyjątków DENORMAL OPERAND
. W tym przykładzie przedstawiono różnicę:
_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.
Możliwe wartości stałej maski () i nowych wartości kontrolnych (mask
newControl
) są wyświetlane w poniższej tabeli Wartości szesnastkowe. Użyj przenośnych stałych wymienionych poniżej (_MCW_EM
, _EM_INVALID
i tak dalej) jako argumentów dla tych funkcji, zamiast jawnego podawania wartości szesnastkowe.
Platformy pochodne Intel (x86) obsługują DENORMAL
wartości wejściowe i wyjściowe w sprzęcie. Zachowanie x86 polega na zachowaniu DENORMAL
wartości. Platforma ARM i platformy x64, które obsługują SSE2, umożliwiają DENORMAL
opróżnianie operandów i wyników lub wymuszone do zera. Funkcje _controlfp_s
, _controlfp
i _control87
zapewniają maskę, aby zmienić to zachowanie. W poniższym przykładzie pokazano użycie tej maski:
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.
Na platformach _controlfp_s
ARM funkcja ma zastosowanie do rejestru FPSCR. W architekturach x64 dotyczy to tylko słowa sterującego SSE2 przechowywanego w rejestrze MXCSR. Na platformach _controlfp_s
Intel (x86) wpływa na słowa sterujące zarówno dla x87, jak i SSE2, jeśli są obecne. Dwa wyrazy sterujące mogą być ze sobą niespójne (na przykład z powodu poprzedniego wywołania metody __control87_2
, na przykład), jeśli występuje niespójność między dwoma wyrazami sterującymi, _controlfp_s
ustawia flagę EM_AMBIGUOUS
w currentControl
elemecie . Jest to ostrzeżenie, że zwrócony wyraz kontrolny może nie reprezentować stanu obu słów kontrolnych zmiennoprzecinkowych dokładnie.
W architekturach ARM i x64 zmiana trybu nieskończoności lub precyzja zmiennoprzecinkowa nie jest obsługiwana. Jeśli na platformie x64 jest używana maska kontrolki precyzji, funkcja zgłasza asercji i wywoływana jest nieprawidłowa procedura obsługi parametrów, zgodnie z opisem w temacie Weryfikacja parametrów.
Jeśli maska nie jest ustawiona poprawnie, ta funkcja generuje nieprawidłowy wyjątek parametru, zgodnie z opisem w temacie Weryfikacja parametru. Jeśli wykonanie jest dozwolone do kontynuowania, ta funkcja zwraca EINVAL
i ustawia wartość errno
.EINVAL
Ta funkcja jest ignorowana podczas kompilowania /clr
(kompilacja środowiska uruchomieniowego języka wspólnego), ponieważ środowisko uruchomieniowe języka wspólnego (CLR) obsługuje tylko domyślną precyzję zmiennoprzecinkową.
Domyślnie stan globalny tej funkcji jest zakresem aplikacji. Aby zmienić to zachowanie, zobacz Stan globalny w CRT.
Maskuj stałe i wartości
W przypadku maski wyczyszczenie _MCW_EM
ustawia wyjątek, który zezwala na wyjątek sprzętowy; ustawienie powoduje ukrycie wyjątku. Jeśli wystąpi wyjątek _EM_UNDERFLOW
sprzętowy lub _EM_OVERFLOW
nie zostanie zgłoszony żaden wyjątek sprzętowy do momentu wykonania kolejnej instrukcji zmiennoprzecinkowych. Aby wygenerować wyjątek sprzętowy bezpośrednio po _EM_UNDERFLOW
lub _EM_OVERFLOW
, wywołaj instrukcję FWAIT MASM
.
Maska | Wartość szesnastkowy | Stała | Wartość szesnastkowy |
---|---|---|---|
_MCW_DN (Denormal control) |
0x03000000 | _DN_SAVE _DN_FLUSH |
0x00000000 0x01000000 |
_MCW_EM (Maska wyjątków przerwania) |
0x0008001F | _EM_INVALID _EM_DENORMAL _EM_ZERODIVIDE _EM_OVERFLOW _EM_UNDERFLOW _EM_INEXACT |
0x00000010 0x00080000 0x00000008 0x00000004 0x00000002 0x00000001 |
_MCW_IC (Kontrolka Nieskończoność)(Nieobsługiwane na platformach ARM lub x64). |
0x00040000 | _IC_AFFINE _IC_PROJECTIVE |
0x00040000 0x00000000 |
_MCW_RC (Kontrolka zaokrąglania) |
0x00000300 | _RC_CHOP _RC_UP _RC_DOWN _RC_NEAR |
0x00000300 0x00000200 0x00000100 0x00000000 |
_MCW_PC (Kontrolka precyzji)(Nieobsługiwane na platformach ARM lub x64). |
0x00030000 | _PC_24 (24 bity)_PC_53 (53 bity)_PC_64 (64 bity) |
0x00020000 0x00010000 0x00000000 |
Wymagania
Procedura | Wymagany nagłówek |
---|---|
_controlfp_s |
<float.h> |
Aby uzyskać więcej informacji o zgodności, zobacz Zgodność.
Przykład
// 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
Zobacz też
Obsługa obliczeń matematycznych i zmiennoprzecinkowych
_clear87
, _clearfp
_status87
, , _statusfp
_statusfp2
_control87
, , _controlfp
__control87_2