_control87
, , _controlfp
__control87_2
Obtient et définit le mot de contrôle à virgule flottante. Une version plus sécurisée est _controlfp
disponible ._controlfp_s
Syntaxe
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
);
Paramètres
new
Nouvelles valeurs en bits du mot de contrôle.
mask
Masque des bits du nouveau mot de contrôle à définir.
x86_cw
Renseigné avec le mot de contrôle pour l’unité de virgule flottante x87. Passez la valeur 0 (NULL
) pour définir le mot de contrôle SSE2 uniquement.
sse2_cw
Mot de contrôle pour l’unité de virgule flottante SSE. Passez la valeur 0 (NULL
) pour définir le mot de contrôle x87 uniquement.
Valeur retournée
Pour _control87
et _controlfp
, les bits contenus dans la valeur retournée indiquent l’état de contrôle à virgule flottante. Pour obtenir une définition complète des bits retournés par _control87
, consultez FLOAT.H
.
Pour __control87_2
, la valeur de retour est 1, qui indique une réussite.
Notes
La fonction _control87
obtient et définit le mot de contrôle à virgule flottante. Le mot de contrôle à virgule flottante permet au programme de modifier la précision, l’arrondi et les modes infinis, en fonction de la plateforme. Vous pouvez également utiliser _control87
pour masquer ou démasquer les exceptions de virgule flottante. Si la valeur de mask
est égale à 0, _control87
obtient le mot de contrôle à virgule flottante. Si mask
est différent de zéro, une nouvelle valeur pour le mot de contrôle est définie : pour tout bit activé (autrement dit, égal à 1) dans mask
, le bit correspondant dans new
est utilisé pour mettre à jour le mot de contrôle. En d’autres termes, fpcntrl = ((fpcntrl & ~mask) | (new & mask))
où fpcntrl
est le mot de contrôle à virgule flottante.
Remarque
Par défaut, les bibliothèques d’exécution masquent toutes les exceptions de virgule flottante.
_controlfp
est une version portable indépendante de la plateforme de _control87
ce qui est presque identique à la _control87
fonction. Si votre code cible plusieurs plateformes, utilisez _controlfp
ou _controlfp_s
. La différence entre _control87
et _controlfp
réside dans la manière dont elles traitent les valeurs DENORMAL
. Pour les plateformes x86, x64, ARM et ARM64, _control87
peuvent définir et effacer le masque d’exception DENORMAL OPERAND
. _controlfp
ne modifie pas le DENORMAL OPERAND
masque d’exception. Cet exemple illustre la différence :
_control87( _EM_INVALID, _MCW_EM );
// DENORMAL is unmasked by this call
_controlfp( _EM_INVALID, _MCW_EM );
// DENORMAL exception mask remains unchanged
Les valeurs possibles pour la constante de masque (mask
) et les nouvelles valeurs de contrôle (new
) sont affichées dans le tableau masque et valeurs du mot De contrôle. Utilisez l’une des constantes portables répertoriées ci-dessous (_MCW_EM
, _EM_INVALID
, et ainsi de suite) en tant qu’arguments de ces fonctions, au lieu de fournir les valeurs hexadécimales explicitement.
Les plateformes dérivées d’Intel x86 prennent en charge les valeurs d’entrée et de sortie dans le DENORMAL
matériel. Le comportement x86 consiste à conserver des DENORMAL
valeurs. Les plateformes ARM et ARM64 et les plateformes x64 qui prennent en charge SSE2 permettent DENORMAL
aux opérandes et aux résultats d’être vidés ou forcés à zéro. Les fonctions _controlfp
et _control87
fournissent un masque pour modifier ce comportement. L’exemple suivant illustre l’utilisation de ce masque.
_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.
Sur les plateformes ARM et ARM64, les _control87
fonctions s’appliquent _controlfp
au registre FPSCR. Seul le mot de contrôle SSE2 stocké dans le registre MXCSR est affecté sur les plateformes x64. Sur les plateformes x86 et _control87
_controlfp
affecter les mots de contrôle pour les x87 et SSE2, le cas échéant.
La fonction __control87_2
permet de contrôler les unités de virgule flottante x87 et SSE2 ensemble ou séparément. Pour affecter les deux unités, transmettez les adresses de deux entiers à x86_cw
et sse2_cw
. Si vous souhaitez affecter une seule unité, transmettez une adresse pour ce paramètre, mais transmettez 0 (NULL
) pour l’autre. Si 0 est passé pour l’un de ces paramètres, la fonction n’a aucun effet sur cette unité de virgule flottante. Il est utile quand une partie de votre code utilise l’unité à virgule flottante x87 et qu’une autre partie utilise l’unité à virgule flottante SSE2.
Si vous utilisez __control87_2
pour définir des valeurs différentes pour les mots de contrôle à virgule flottante, ou _control87
_controlfp
si vous ne pouvez pas retourner un mot de contrôle unique pour représenter l’état des deux unités à virgule flottante. Dans ce cas, ces fonctions définissent l’indicateur EM_AMBIGUOUS
dans la valeur entière retournée pour indiquer une incohérence entre les deux mots de contrôle. L’indicateur EM_AMBIGUOUS
est un avertissement indiquant que le mot de contrôle retourné peut ne pas représenter l’état des deux mots de contrôle à virgule flottante avec précision.
Sur les plateformes ARM, ARM64 et x64, la modification du mode infini ou de la précision à virgule flottante n’est pas prise en charge. Si le masque de contrôle de précision est utilisé sur la plateforme x64, la fonction déclenche une assertion et le gestionnaire de paramètres non valide est appelé, comme décrit dans la validation des paramètres.
Remarque
__control87_2
n’est pas pris en charge sur les plateformes ARM, ARM64 ou x64. Si vous utilisez __control87_2
et compilez votre programme pour les plateformes ARM, ARM64 ou x64, le compilateur génère une erreur.
Ces fonctions sont ignorées lorsque vous utilisez /clr
(compilation Common Language Runtime) pour compiler. Le Common Language Runtime (CLR) prend uniquement en charge la précision à virgule flottante par défaut.
Contrôler les masques et valeurs de mots
Concernant le masque _MCW_EM
, désactiver ce dernier définit l’exception, ce qui permet l’exception matérielle, tandis que le définir masque l’exception. Si un _EM_UNDERFLOW
ou _EM_OVERFLOW
se produit, aucune exception de matériel n’est levée tant que l’instruction à virgule flottante suivante n’est pas exécutée. Pour générer une exception matérielle immédiatement après _EM_UNDERFLOW
ou _EM_OVERFLOW
, appelez l’instruction MASM FWAIT
.
Mask | Valeur hexadécimale | Constant | Valeur hexadécimale |
---|---|---|---|
_MCW_DN (contrôle de la dénormalisation) |
0x03000000 | _DN_SAVE _DN_FLUSH |
0x00000000 0x01000000 |
_MCW_EM (masque d’exception d’interruption) |
0x0008001F | _EM_INVALID _EM_DENORMAL _EM_ZERODIVIDE _EM_OVERFLOW _EM_UNDERFLOW _EM_INEXACT |
0x00000010 0x00080000 0x00000008 0x00000004 0x00000002 0x00000001 |
_MCW_IC (Contrôle de l’infini)(Non pris en charge sur les plateformes ARM ou x64.) |
0x00040000 | _IC_AFFINE _IC_PROJECTIVE |
0x00040000 0x00000000 |
_MCW_RC (Contrôle de l’arrondi) |
0x00000300 | _RC_CHOP _RC_UP _RC_DOWN _RC_NEAR |
0x00000300 0x00000200 0x00000100 0x00000000 |
_MCW_PC (Contrôle de la précision)(Non pris en charge sur les plateformes ARM ou x64.) |
0x00030000 | _PC_24 (24 bits)_PC_53 (53 bits)_PC_64 (64 bits) |
0x00020000 0x00010000 0x00000000 |
Spécifications
Routine | En-tête requis |
---|---|
_control87 , , _controlfp _control87_2 |
<float.h> |
Pour plus d’informations sur la compatibilité, consultez Compatibility.
Exemple
// 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
Voir aussi
Prise en charge des fonctions mathématiques et à virgule flottante
_clear87
, _clearfp
_status87
, , _statusfp
_statusfp2
_controlfp_s