_control87, _controlfp, __control87_2

Pobiera i ustawia zmiennoprzecinkowe słowo sterujące. Dostępna jest bezpieczniejsza _controlfp wersja. Zobacz _controlfp_s.

Składnia

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

Parametry

new
Nowe wartości bitów wyrazów kontrolnych.

mask
Maskuj dla nowych bitów słów kontrolnych do ustawienia.

x86_cw
Wypełniony słowem kontrolnym jednostki zmiennoprzecinkowej x87. Przekaż wartość 0 (NULL), aby ustawić tylko słowo sterujące SSE2.

sse2_cw
Słowo sterujące dla jednostki zmiennoprzecinkowe SSE. Przekaż wartość 0 (NULL), aby ustawić tylko wyraz kontrolny x87.

Wartość zwracana

Dla _control87 i _controlfpbity w zwróconej wartości wskazują stan sterowania zmiennoprzecinkowego. Aby uzyskać pełną definicję bitów zwracanych przez _control87program , zobacz FLOAT.H.

W przypadku __control87_2parametru zwracana wartość to 1, co oznacza powodzenie.

Uwagi

Funkcja _control87 pobiera i ustawia słowo sterujące zmiennoprzecinkowe. Słowo sterujące zmiennoprzecinkowe umożliwia programowi zmianę dokładności, zaokrągleń i trybów nieskończoności w zależności od platformy. Można również użyć _control87 do maskowania lub maskowania wyjątków zmiennoprzecinkowych. Jeśli wartość parametru mask jest równa 0, _control87 pobiera zmiennoprzecinkowe słowo sterujące. Jeśli mask element jest inny niżzerowy, jest ustawiona nowa wartość dla wyrazu sterującego: dla każdego bitu, który jest włączony (czyli równy 1) w , odpowiedni bit w newmaskjest używany do aktualizowania wyrazu kontrolki. Innymi słowy, fpcntrl = ((fpcntrl & ~mask) | (new & mask)) gdzie fpcntrl to słowo sterujące zmiennoprzecinkowe.

Uwaga

Domyślnie biblioteki czasu wykonywania maskuje wszystkie wyjątki zmiennoprzecinkowe.

_controlfp jest niezależną od platformy, przenośną wersją _control87 , która jest niemal identyczna z funkcją _control87 . Jeśli kod jest przeznaczony dla więcej niż jednej platformy, użyj polecenia _controlfp lub _controlfp_s. Różnica między elementami _control87 i _controlfp polega na tym, jak traktują DENORMAL wartości. W przypadku platform _control87 x86, x64, ARM i ARM64 można ustawić i wyczyścić maskę wyjątków DENORMAL OPERAND . _controlfp 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
_controlfp( _EM_INVALID, _MCW_EM );
// DENORMAL exception mask remains unchanged

Możliwe wartości dla stałej maski () i nowych wartości kontrolnych (masknew) są wyświetlane w tabeli Formant maski wyrazów i wartości. 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. Platformy ARM i ARM64 oraz platformy x64 z obsługą protokołu SSE2 umożliwiają DENORMAL opróżnianie operandów i wyników lub wymuszone na zero. Funkcje _controlfp i _control87 zapewniają maskę, aby zmienić to zachowanie. W poniższym przykładzie pokazano użycie tej maski.

_controlfp(_DN_SAVE, _MCW_DN);
// Denormal values preserved on ARM platforms and on x64 processors with
// SSE2 support. NOP on x86 platforms.
_controlfp(_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 _control87 ARM i ARM64 funkcje i _controlfp mają zastosowanie do rejestru FPSCR. Na platformach x64 ma wpływ tylko słowo sterujące SSE2 przechowywane w rejestrze MXCSR. Na platformach _control87 x86 i _controlfp mają wpływ na słowa sterujące zarówno x87, jak i SSE2, jeśli istnieją.

Funkcja __control87_2 umożliwia sterowanie jednostkami zmiennoprzecinkowymi x87 i SSE2 lub oddzielnie. Aby wpłynąć na obie jednostki, przekaż adresy dwóch liczb całkowitych do x86_cw i sse2_cw. Jeśli chcesz mieć wpływ tylko na jedną jednostkę, przekaż adres dla tego parametru, ale przekaż wartość 0 (NULL) dla drugiej. Jeśli wartość 0 zostanie przekazana dla jednego z tych parametrów, funkcja nie ma wpływu na tę jednostkę zmiennoprzecinkową. Jest to przydatne, gdy część kodu używa jednostki zmiennoprzecinkowej x87, a inna część używa jednostki zmiennoprzecinkowe SSE2.

Jeśli używasz __control87_2 polecenia , aby ustawić różne wartości dla słów kontrolnych zmiennoprzecinkowych, _control87 lub _controlfp może nie być w stanie zwrócić pojedynczego wyrazu sterującego do reprezentowania stanu obu jednostek zmiennoprzecinkowych. W takim przypadku te funkcje ustawiają flagę EM_AMBIGUOUS w zwróconej wartości całkowitej, aby wskazać niespójność między dwoma wyrazami sterującymi. Flaga EM_AMBIGUOUS jest ostrzeżeniem, że zwrócony wyraz kontrolny może nie reprezentować stanu obu słów kontrolnych zmiennoprzecinkowych dokładnie.

Na platformach ARM, ARM64 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.

Uwaga

__control87_2 nie jest obsługiwany na platformach ARM, ARM64 lub x64. Jeśli używasz __control87_2 i kompilujesz program dla platform ARM, ARM64 lub x64, kompilator generuje błąd.

Te funkcje są ignorowane podczas kompilowania /clr (kompilacja środowiska uruchomieniowego języka wspólnego). Środowisko uruchomieniowe języka wspólnego (CLR) obsługuje tylko domyślną precyzję zmiennoprzecinkową.

Kontroluj maski wyrazów i wartości

W przypadku maski wyczyszczenie _MCW_EM maski powoduje ustawienie wyjątku, który zezwala na wyjątek sprzętowy; ustawienie maski 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
_control87, _controlfp, _control87_2 <float.h>

Aby uzyskać więcej informacji o zgodności, zobacz Zgodność.

Przykład

// crt_cntrl87.c
// processor: x86
// compile by using: cl /W4 /arch:IA32 crt_cntrl87.c
// 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 = 0;
    int result;

    // Show original x87 control word and do calculation.
    result = __control87_2(0, 0, &control_word_x87, 0 );
    printf( "Original: 0x%.8x\n", control_word_x87 );
    printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );

    // Set precision to 24 bits and recalculate.
    result = __control87_2(_PC_24, MCW_PC, &control_word_x87, 0 );
    printf( "24-bit:   0x%.8x\n", control_word_x87 );
    printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );

    // Restore default precision-control bits and recalculate.
    result = __control87_2( _CW_DEFAULT, MCW_PC, &control_word_x87, 0 );
    printf( "Default:  0x%.8x\n", control_word_x87 );
    printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
}
Original: 0x0009001f
0.1 * 0.1 = 1.000000000000000e-02
24-bit:   0x000a001f
0.1 * 0.1 = 9.999999776482582e-03
Default:  0x0009001f
0.1 * 0.1 = 1.000000000000000e-02

Zobacz też

Obsługa obliczeń matematycznych i zmiennoprzecinkowych
_clear87, _clearfp
_status87, _statusfp, _statusfp2
_controlfp_s