_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ą _control87programu , 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 masknew 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( &current_word, _EM_INVALID, _MCW_EM );
// DENORMAL exception mask remains unchanged.

Możliwe wartości stałej maski () i nowych wartości kontrolnych (masknewControl) są wyświetlane w poniższej tabeli Wartości szesnastkowe. Użyj przenośnych stałych wymienionych poniżej (_MCW_EM, _EM_INVALIDi 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, _controlfpi _control87 zapewniają maskę, aby zmienić to zachowanie. W poniższym przykładzie pokazano użycie tej maski:

unsigned int current_word = 0;
_controlfp_s(&current_word, _DN_SAVE, _MCW_DN);
// Denormal values preserved on ARM platforms and on x64 processors with
// SSE2 support. NOP on x86 platforms.
_controlfp_s(&current_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 currentControlelemecie . 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