_controlfp_s
Ottiene e imposta la parola di controllo a virgola mobile. Questa versione di _control87
, _controlfp
include __control87_2
miglioramenti per la sicurezza, come descritto in Funzionalità di sicurezza in CRT.
Sintassi
errno_t _controlfp_s(
unsigned int *currentControl,
unsigned int newControl,
unsigned int mask
);
Parametri
currentControl
Il valore di bit della parola di controllo corrente.
newControl
Valori di bit della parola di controllo nuova.
mask
Maschera di bit della parola di controllo nuova da impostare.
Valore restituito
Zero se l'esito è positivo oppure un codice di errore con valore errno
.
Osservazioni:
La funzione _controlfp_s
è una versione indipendente dalla piattaforma e più sicura di _control87
, che ottiene la parola di controllo a virgola mobile nell'indirizzo archiviato in currentControl
e viene impostata usando newControl
. I bit dei valori indicano lo stato di controllo a virgola mobile. Lo stato di controllo a virgola mobile consente al programma di modificare le modalità di precisione, arrotondamento e infinito nel pacchetto matematico a virgola mobile, a seconda della piattaforma. È anche possibile usare _controlfp_s
per mascherare o annullare il mascheramento delle eccezioni a virgola mobile.
Se il valore per mask
è uguale a 0, _controlfp_s
ottiene la parola di controllo a virgola mobile e archivia il valore recuperato in currentControl
.
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) | (newControl & mask))
dove fpcntrl
è la parola di controllo a virgola mobile. In questo scenario, currentControl
viene impostato sul valore al termine della modifica. Non è il valore di bit della parola di controllo precedente.
Nota
Per impostazione predefinita, le librerie di runtime mascherano tutte le eccezioni a virgola mobile.
_controlfp_s
è quasi identico alla _control87
funzione nelle piattaforme Intel (x86), x64 e ARM. Se si usa piattaforme x86, x64 o ARM, è possibile usare _control87
o _controlfp_s
.
La differenza tra _control87
e _controlfp_s
è nel modo in cui trattano i valori denormali. Per le piattaforme Intel (x86), x64 e ARM, _control87
è possibile impostare e cancellare la DENORMAL OPERAND
maschera eccezioni. _controlfp_s
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.
unsigned int current_word = 0;
_controlfp_s( ¤t_word, _EM_INVALID, _MCW_EM );
// DENORMAL exception mask remains unchanged.
I valori possibili per la costante maschera (mask
) e i nuovi valori di controllo (newControl
) vengono visualizzati nella tabella dei valori esadecimali seguente. 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. La piattaforma ARM e le piattaforme x64 con supporto SSE2 consentono DENORMAL
di scaricare gli operandi e i risultati oppure forzare a zero. Le funzioni _controlfp_s
, _controlfp
e _control87
offrono una maschera per modificare questo comportamento. Nell'esempio seguente viene illustrato l'uso di questa maschera:
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.
Sulle piattaforme ARM, la funzione _controlfp_s
viene applicata al registro FPSCR. Nelle architetture x64 è interessata solo la parola di controllo SSE2 archiviata nel registro MXCSR. Sulle piattaforme Intel (x86) _controlfp_s
interessa le parole di controllo per x87 e SSE2, se presenti. È possibile che le due parole di controllo siano incoerenti tra loro (a causa di una chiamata precedente a __control87_2
, ad esempio); se esiste una incoerenza tra le due parole di controllo, _controlfp_s
imposta il EM_AMBIGUOUS
flag in currentControl
. Si tratta di 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 architetture ARM e x64 la modifica della modalità infinito o la precisione a virgola mobile non è supportata. Se la maschera di controllo 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.
Se la maschera non è impostata correttamente, questa funzione genera un'eccezione di parametro non valida, come descritto in Convalida dei parametri. Se l'esecuzione può continuare, la funzione restituisce EINVAL
e imposta errno
su EINVAL
.
Questa funzione viene ignorata quando si usa /clr
(Compilazione Common Language Runtime) per la compilazione perché Common Language Runtime (CLR) supporta solo la precisione a virgola mobile predefinita.
Per impostazione predefinita, lo stato globale di questa funzione è limitato all'applicazione. Per modificare questo comportamento, vedere Stato globale in CRT.
Maschera costanti e valori
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 |
---|---|
_controlfp_s |
<float.h> |
Per altre informazioni sulla compatibilità, vedere Compatibility (Compatibilità).
Esempio
// 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
Vedi anche
Supporto matematico e a virgola mobile
_clear87
, _clearfp
_status87
, _statusfp
, _statusfp2
_control87
, _controlfp
, __control87_2