_control87
, _controlfp
, __control87_2
Ottiene e imposta la parola di controllo a virgola mobile. È disponibile una versione più sicura di _controlfp
. Vedere _controlfp_s
.
Sintassi
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
);
Parametri
new
Valori di bit della parola di controllo nuova.
mask
Maschera di bit della parola di controllo nuova da impostare.
x86_cw
Compilato con la parola di controllo per l'unità di calcolo in virgola mobile x87. Passare a 0 (NULL
) per impostare solo la parola di controllo SSE2.
sse2_cw
Parola di controllo per l'unità di calcolo in virgola mobile SSE. Passare 0 (NULL
) per impostare solo la parola di controllo x87.
Valore restituito
Per _control87
e _controlfp
, i bit del valore restituito indicano lo stato del controllo a virgola mobile. Per una definizione completa dei bit restituiti da _control87
, vedere FLOAT.H
.
Per __control87_2
, il valore restituito è 1, che indica l'esito positivo.
Osservazioni:
La funzione _control87
ottiene e imposta la parola di controllo a virgola mobile. La parola di controllo a virgola mobile consente al programma di modificare le modalità precisione, arrotondamento e infinito, a seconda della piattaforma. È anche possibile usare _control87
per mascherare o annullare il mascheramento delle eccezioni a virgola mobile. Se il valore per mask
è uguale a 0, _control87
ottiene la parola di controllo a virgola mobile. Se mask
è diverso da zero, viene impostato un nuovo valore per la parola di controllo: per ogni bit impostato (vale a dire, uguale a 1) in mask
, il bit corrispondente in new
viene usato per aggiornare la parola di controllo. In altre parole, fpcntrl = ((fpcntrl & ~mask) | (new & mask))
dove fpcntrl
è la parola di controllo a virgola mobile.
Nota
Per impostazione predefinita, le librerie di runtime mascherano tutte le eccezioni a virgola mobile.
_controlfp
è una versione portatile indipendente dalla piattaforma di _control87
quasi identica alla _control87
funzione. Se il codice è destinato a più piattaforme, usare _controlfp
o _controlfp_s
. La differenza tra _control87
e _controlfp
risiede nella modalità di gestione dei valori DENORMAL
. Per le piattaforme x86, x64, ARM e ARM64, _control87
è possibile impostare e cancellare la DENORMAL OPERAND
maschera eccezioni. _controlfp
non modifica la DENORMAL OPERAND
maschera di eccezione. In questo esempio viene illustrata la differenza:
_control87( _EM_INVALID, _MCW_EM );
// DENORMAL is unmasked by this call
_controlfp( _EM_INVALID, _MCW_EM );
// DENORMAL exception mask remains unchanged
I valori possibili per la costante mask (mask
) e i nuovi valori di controllo (new
) vengono visualizzati nella tabella Maschera di parole di controllo e valori. Usare le costanti portabili elencate di seguito (_MCW_EM
, _EM_INVALID
e così via) come argomenti per le funzioni, anziché specificare in modo esplicito i valori esadecimali.
Le piattaforme derivate da Intel x86 supportano i DENORMAL
valori di input e output nell'hardware. Il comportamento x86 consiste nel mantenere DENORMAL
i valori. Le piattaforme ARM e ARM64 e le piattaforme x64 con supporto SSE2 consentono DENORMAL
di scaricare gli operandi e i risultati o forzare a zero. Le funzioni _controlfp
e _control87
offrono una maschera per modificare questo comportamento. Nell'esempio seguente viene illustrato l'uso di questa maschera.
_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.
Nelle piattaforme ARM e ARM64 le _control87
funzioni e _controlfp
si applicano al registro FPSCR. Solo la parola di controllo SSE2 archiviata nel registro MXCSR è interessata dalle piattaforme x64. Nelle piattaforme _control87
x86 e _controlfp
influiscono sulle parole di controllo sia per x87 che per SSE2, se presenti.
La funzione __control87_2
consente di controllare le unità di calcolo in virgola mobile x87 e SSE2 sia insieme che separatamente. Per influire su entrambe le unità, passare gli indirizzi di due interi a x86_cw
e sse2_cw
. Se si vuole influire solo su un'unità, passare un indirizzo per tale parametro, ma passare 0 (NULL
) per l'altro. Se 0 viene passato per uno di questi parametri, la funzione non ha alcun effetto su tale unità di calcolo a virgola mobile. È utile quando una parte del codice usa l'unità a virgola mobile x87 e un'altra parte usa l'unità a virgola mobile SSE2.
Se si utilizza __control87_2
per impostare valori diversi per le parole di controllo a virgola mobile, _control87
è possibile che non _controlfp
sia possibile restituire una singola parola di controllo per rappresentare lo stato di entrambe le unità a virgola mobile. In questo caso, queste funzioni impostano il EM_AMBIGUOUS
flag nel valore intero restituito per indicare un'incoerenza tra le due parole di controllo. Il EM_AMBIGUOUS
flag è un avviso che indica che la parola di controllo restituita potrebbe non rappresentare accuratamente lo stato di entrambe le parole di controllo a virgola mobile.
Nelle piattaforme ARM, ARM64 e x64, la modifica della modalità infinito o la precisione a virgola mobile non è supportata. Se la maschera di controllo di precisione viene usata nella piattaforma x64, la funzione genera un'asserzione e viene richiamato il gestore di parametri non validi, come descritto in Convalida dei parametri.
Nota
__control87_2
non è supportato nelle piattaforme ARM, ARM64 o x64. Se si usa __control87_2
e si compila il programma per le piattaforme ARM, ARM64 o x64, il compilatore genera un errore.
Queste funzioni vengono ignorate quando si usa /clr
(Compilazione Common Language Runtime) per la compilazione. Common Language Runtime (CLR) supporta solo la precisione a virgola mobile predefinita.
Controllare le maschere e i valori delle parole
Per la maschera _MCW_EM
, la sua cancellazione comporta l'impostazione dell'eccezione, che consente l'eccezione hardware; la sua impostazione consente di nascondere l'eccezione. Se si verifica un _EM_UNDERFLOW
o _EM_OVERFLOW
, non viene generata alcuna eccezione hardware fino a quando non viene eseguita l'istruzione a virgola mobile successiva. Per generare un'eccezione hardware immediatamente dopo _EM_UNDERFLOW
o _EM_OVERFLOW
, chiamare l'istruzione FWAIT
MASM.
Maschera | Valore hex | Costante | Valore hex |
---|---|---|---|
_MCW_DN (Controllo denormalizzato) |
0x03000000 | _DN_SAVE _DN_FLUSH |
0x00000000 0x01000000 |
_MCW_EM (Maschera eccezione interruzione) |
0x0008001F | _EM_INVALID _EM_DENORMAL _EM_ZERODIVIDE _EM_OVERFLOW _EM_UNDERFLOW _EM_INEXACT |
0x00000010 0x00080000 0x00000008 0x00000004 0x00000002 0x00000001 |
_MCW_IC (Controllo infinito)Non supportato nelle piattaforme ARM o x64. |
0x00040000 | _IC_AFFINE _IC_PROJECTIVE |
0x00040000 0x00000000 |
_MCW_RC (Controllo arrotondamento) |
0x00000300 | _RC_CHOP _RC_UP _RC_DOWN _RC_NEAR |
0x00000300 0x00000200 0x00000100 0x00000000 |
_MCW_PC (Controllo precisione)Non supportato nelle piattaforme ARM o x64. |
0x00030000 | _PC_24 (24 bit)_PC_53 (53 bit)_PC_64 (64 bit) |
0x00020000 0x00010000 0x00000000 |
Requisiti
Ciclo | Intestazione obbligatoria |
---|---|
_control87 , _controlfp , _control87_2 |
<float.h> |
Per altre informazioni sulla compatibilità, vedere Compatibility (Compatibilità).
Esempio
// 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
Vedi anche
Supporto matematico e a virgola mobile
_clear87
, _clearfp
_status87
, _statusfp
, _statusfp2
_controlfp_s