_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_INVALIDe 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 S edizione Standard 2 consentono DENORMAL di scaricare gli operandi e i risultati oppure 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 S edizione Standard 2 archiviata nel registro MXCSR è interessata dalle piattaforme x64. Nelle piattaforme _control87 x86 e _controlfp influiscono sulle parole di controllo sia per x87 che per S edizione Standard 2, 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 parte del codice usa l'unità a virgola mobile x87 e un'altra parte usa l'unità a virgola mobile S edizione Standard 2.

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