Share via


_controlfp_s

Obtient et définit le mot de contrôle à virgule flottante. Cette version de , _controlfp__control87_2a des améliorations de _control87sé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))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( &current_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(&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.

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 Constante 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 mathématique et à virgule flottante
_clear87, _clearfp
_status87, _statusfp, _statusfp2
_control87, _controlfp, __control87_2