_controlfp_s
Obtient et définit le mot de contrôle à virgule flottante. Cette version de , _controlfp
__control87_2
a des améliorations de _control87
sécurité, comme décrit dans les fonctionnalités de sécurité dans le CRT.
Syntaxe
errno_t _controlfp_s(
unsigned int *currentControl,
unsigned int newControl,
unsigned int mask
);
Paramètres
currentControl
Valeur en bits du mot de contrôle actuelle.
newControl
Nouvelles valeurs en bits du mot de contrôle.
mask
Masque des bits du nouveau mot de contrôle à définir.
Valeur retournée
Zéro en cas de réussite, ou un code d’erreur de valeur errno
.
Notes
La fonction _controlfp_s
est une version de _control87
indépendante de la plateforme et plus sûre, qui obtient le mot de contrôle à virgule flottante dans l’adresse stockée dans currentControl
et le définit à l’aide de newControl
. Les bits contenus dans les valeurs indiquent l’état de contrôle à virgule flottante. L’état de contrôle à virgule flottante permet au programme de modifier les modes de précision, d’arrondi et d’infini dans le package mathématique à virgule flottante, selon la plateforme. Vous pouvez également utiliser _controlfp_s
pour masquer ou démasquer les exceptions de virgule flottante.
Si la valeur de mask
est égale à 0, _controlfp_s
obtient le mot de contrôle à virgule flottante et stocke la valeur récupérée dans currentControl
.
Si mask
est différent de zéro, une nouvelle valeur pour le mot de contrôle est définie : pour tout bit défini (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) | (newControl & mask))
où fpcntrl
est le mot de contrôle à virgule flottante. Dans ce scénario, currentControl
est défini sur la valeur une fois la modification terminée ; il ne s’agit pas de l’ancienne valeur de bits de mot de contrôle.
Remarque
Par défaut, les bibliothèques d’exécution masquent toutes les exceptions de virgule flottante.
_controlfp_s
est presque identique à la _control87
fonction sur les plateformes Intel (x86), x64 et ARM. Si vous ciblez des plateformes x86, x64 ou ARM, vous pouvez utiliser _control87
ou _controlfp_s
.
La différence entre _control87
et _controlfp_s
est dans la façon dont elles traitent les valeurs dénormales. Pour Les plateformes Intel (x86), x64 et ARM, _control87
peuvent définir et effacer le masque d’exception DENORMAL OPERAND
. _controlfp_s
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.
unsigned int current_word = 0;
_controlfp_s( ¤t_word, _EM_INVALID, _MCW_EM );
// DENORMAL exception mask remains unchanged.
Les valeurs possibles pour la constante du masque (mask
) et les nouvelles valeurs de contrôle (newControl
) sont indiquées dans le tableau Valeurs hexadécimales ci-après. 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. La plateforme ARM 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_s
, _controlfp
et _control87
fournissent un masque pour modifier ce comportement. L’exemple suivant illustre l’utilisation de ce masque :
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.
Sur les plateformes ARM, la fonction _controlfp_s
s’applique au registre FPSCR. Sur les architectures x64, seul le mot de contrôle SSE2 stocké dans le registre MXCSR est affecté. Sur les plateformes Intel (x86), _controlfp_s
affecte les mots de contrôle pour les unités x87 et SSE2, le cas échéant. Il est possible que les deux mots de contrôle soient incohérents les uns avec les autres (en raison d’un appel précédent à __control87_2
, par exemple) ; s’il existe une incohérence entre les deux mots de contrôle, _controlfp_s
définit l’indicateur EM_AMBIGUOUS
.currentControl
Il s’agit d’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 architectures ARM 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.
Si le masque n’est pas défini correctement, cette fonction génère une exception de paramètre non valide, comme décrit dans la validation des paramètres. Si l'exécution est autorisée à se poursuivre, cette fonction retourne EINVAL
et affecte la valeur errno
à EINVAL
.
Cette fonction est ignorée lorsque vous utilisez /clr
(Compilation Common Language Runtime) pour compiler, car le Common Language Runtime (CLR) prend uniquement en charge la précision à virgule flottante par défaut.
Par défaut, l’état global de cette fonction est limité à l’application. Pour modifier ce comportement, consultez État global dans le CRT.
Masquer les constantes et les valeurs
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 FWAIT MASM
.
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 |
---|---|
_controlfp_s |
<float.h> |
Pour plus d’informations sur la compatibilité, consultez Compatibility.
Exemple
// 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
Voir aussi
Prise en charge des fonctions mathématiques et à virgule flottante
_clear87
, _clearfp
_status87
, , _statusfp
_statusfp2
_control87
, , _controlfp
__control87_2