_control87, _controlfp, __control87_2
Ottiene e imposta la parola di controllo a virgola mobile. È disponibile una versione più sicura di _controlfp; vedere _controlfp_s.
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
Nuovi valori di bit di parola di controllo.mask
Maschera da impostare per i nuovi bit di parola di controllo.x86_cw
Compilato con la parola di controllo dell'unità a virgola mobile x87. Passare 0 (NULL) per impostare solo la parola di controllo SSE2.sse2_cw
Parola di controllo dell'unità a virgola mobile SSE. Passare 0 (NULL) per impostare solo la parola di controllo x87.
Valore restituito
Per _control87 e _controlfp, i bit nel valore restituito indicano lo stato del controllo a virgola mobile. Per una definizione completa dei bit che sono restituiti da _control87, vedere FLOAT.H.
Per __control87_2, il valore restituito è 1, che indica un esito positivo.
Note
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 la precisione, l'arrotondamento e le modalità di infinito nel pacchetto matematica a virgola mobile a seconda della piattaforma. È inoltre possibile utilizzare _control87 per mascherare o smascherare eccezioni di virgola mobile. Se il valore di mask è uguale a 0, _control87 otterrà 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 attivo (che è uguale a 1) in mask, il corrispondente bit in new viene utilizzato per aggiornare la parola di controllo. Ovvero, 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 indipendente dalla piattaforma e portabile di _control87. È quasi identica alla funzione _control87 su Intel (x86), in x64 per le piattaforme ARM. Se le piattaforme di destinazione sono x86 x64, oppure per le piattaforme ARM utilizzare _control87 oppure _controlfp.
La differenza tra _control87 e _controlfp è in come vengono esaminati i valori di DENORMAL. Per le piattaforme Intel (x86) x64 e per le piattaforme ARM, _control87 possono impostare e rimuovere la maschera dell'eccezione DENORMAL OPERAND. _controlfp non modifica la maschera di eccezione DENORMAL OPERAND. Nell'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 della maschera (mask) e i nuovi valori del controllo (new) sono riportati nella seguente tabella di valori esadecimali. Utilizzare le costanti portabili elencate di seguito (_MCW_EM, _EM_INVALID, e così via) come argomenti per queste funzioni, invece di fornire i valori esadecimali in modo esplicito.
Le piattaforme Intel (x86) derivate supportano i valori DENORMAL di input e output a livello hardware. Il comportamento x86 prevede di mantenere i valori DENORMAL. La piattaforma di ARM e le piattaforme x64 consentono il supporto SSE2 consentendo agli operandi e ai risultati DENORMAL di essere svuotati oppure impostati a zero. Le funzioni _control87 e _controlfp forniscono una maschera per modificare questo comportamento. Nell'esempio seguente viene illustrato l'utilizzo 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.
Su piattaforme ARM, le funzioni _controlfp e _control87 vengono applicate al registro FPSCR. Nelle architetture x64, solo la parola di controllo SSE2 viene archiviata nel registro MXCSR essendo l'unico interessato. Su piattaforme Intel (x86), _control87 e _controlfp influiscono sulle parole di controllo sia x87 che SSE2, se presenti. La funzione __control87_2 permette che sia le unità in virgola mobile x87 e che le unità in virgola mobile SSE2 siano controllate insieme o separatamente. Se si desidera modificare entrambe le unità, passare gli indirizzi di due interi a x86_cw e a sse2_cw. Se si desidera modificare solo un'unità, passare un indirizzo per tale parametro ma passare 0 (NULL) per l'altro. Se viene passato 0 per uno di questi parametri, la funzione non ha alcun effetto su quell'unità a virgola mobile. Questa funzionalità può essere utile nelle situazioni in cui una parte del codice utilizza l'unità a virgola mobile x87 e un'altra parte del codice utilizza l'unità a virgola mobile SSE2. Se si utilizza __control87_2 in una parte del programma e si impostano valori diversi per le parole di controllo a virgola mobile, e quindi si utilizza _control87 o _controlfp per modificare ulteriormente la parola di controllo, allora _control87 e _controlfp potrebbero non essere in grado di restituire una singola parola di controllo per rappresentare lo stato di entrambe le unità a virgola mobile. In questo caso, queste funzioni impostano il flag EM_AMBIGUOUS del valore intero restituito per indicare che c'è un'incoerenza tra le due parole di controllo. Si tratta di un avviso relativo al fatto che la parola di controllo restituita potrebbe non rappresentare con precisione lo stato di entrambe le parole di controllo a virgola mobile.
In ARM e nelle architetture x64, non è possibile modificare la modalità di infinito o la precisione dei valori a virgola mobile. Se la maschera del controllo viene utilizzata sulla piattaforma x64, la funzione genera un'asserzione e il gestore di parametro non valido viene invocato come descritto in Convalida dei parametri.
Nota
__control87_2 non è supportato su ARM o sulle architetture x64.Se si utilizza __control87_2 e si compila il programma per ARM o l'architettura x64, il compilatore genera un errore.
Queste funzioni sono ignorate durante la compilazione quando si utilizza /clr (Compilazione Common Language Runtime) o /clr:pure per compilare, poiché il common language runtime (CLR) supporta solamente la precisione a virgola mobile predefinita.
Valori esadecimali
Per la maschera _MCW_EM, la cancellazione della maschera imposta l'eccezione, che abilita l'eccezione hardware, l'impostazione della maschera nasconde l'eccezione. Se si verifica _EM_UNDERFLOW o _EM_OVERFLOW, non viene generata nessuna eccezione hardware fino all'esecuzione della prossima istruzione a virgola mobile. Per generare un'eccezione hardware subito dopo _EM_UNDERFLOW o _EM_OVERFLOW, chiamare l'istruzione FWAIT MASM.
Maschera |
Valore esadecimale |
Costante |
Valore esadecimale |
---|---|---|---|
_MCW_DN (Controllo non normale) |
0x03000000 |
_DN_SAVE _DN_FLUSH |
0x00000000 0x01000000 |
_MCW_EM (Maschera dell'eccezione di interruzione) |
0x0008001F |
_EM_INVALID _EM_DENORMAL _EM_ZERODIVIDE _EM_OVERFLOW _EM_UNDERFLOW _EM_INEXACT |
0x00000010 0x00080000 0x00000008 0x00000004 0x00000002 0x00000001 |
_MCW_IC (Controllo dell'infinito) (Di supporto su ARM o nelle piattaforme x64 ). |
0x00040000 |
_IC_AFFINE _IC_PROJECTIVE |
0x00040000 0x00000000 |
_MCW_RC (Controllo di arrotondamento) |
0x00000300 |
_RC_CHOP _RC_UP _RC_DOWN _RC_NEAR |
0x00000300 0x00000200 0x00000100 0x00000000 |
_MCW_PC (Controllo di precisione) (Di supporto su ARM o nelle piattaforme x64 ). |
0x00030000 |
_PC_24 (24 bit) _PC_53 (53 bit) _PC_64 (64 bit) |
0x00020000 0x00010000 0x00000000 |
Requisiti
Routine |
Intestazione obbligatoria |
---|---|
_control87, _controlfp, _control87_2 |
<float.h> |
Per ulteriori informazioni di compatibilità, vedere Compatibilità.
Esempio
// crt_cntrl87.c
// processor: x86
// 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;
// Show original x87 control word and do calculation.
control_word_x87 = __control87_2(0, 0,
&control_word_x87, 0);
printf( "Original: 0x%.4x\n", control_word_x87 );
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
// Set precision to 24 bits and recalculate.
control_word_x87 = __control87_2(_PC_24, MCW_PC,
&control_word_x87, 0);
printf( "24-bit: 0x%.4x\n", control_word_x87 );
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
// Restore default precision-control bits and recalculate.
control_word_x87 = __control87_2( _CW_DEFAULT, MCW_PC,
&control_word_x87, 0 );
printf( "Default: 0x%.4x\n", control_word_x87 );
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
}
Output
Original: 0x0001
0.1 * 0.1 = 1.000000000000000e-002
24-bit: 0x0001
0.1 * 0.1 = 9.999999776482582e-003
Default: 0x0001
0.1 * 0.1 = 1.000000000000000e-002
Equivalente .NET Framework
Non applicabile. Per chiamare la funzione standard C, utilizzare PInvoke. Per ulteriori informazioni, vedere Esempi di platform invoke.