Condividi tramite


_controlfp_s

Ottiene e imposta la parola di controllo a virgola mobile. Questa versione di _control87, _controlfpinclude __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( &current_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(&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.

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