_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 _controlfp
bity w zwróconej wartości wskazują stan sterowania zmiennoprzecinkowego. Aby uzyskać pełną definicję bitów zwracanych przez _control87
program , zobacz FLOAT.H
.
W przypadku __control87_2
parametru 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 new
mask
jest 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 (mask
new
) są wyświetlane w tabeli Formant maski wyrazów i wartości. 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. 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