Partager via


_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))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 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
_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 mathématique et à virgule flottante
_clear87, _clearfp
_status87, _statusfp, _statusfp2
_controlfp_s