_controlfp_s
Obtiene y establece la palabra de control de punto flotante. Esta versión de , _controlfp
, __control87_2
tiene mejoras de seguridad, como se describe en Características de _control87
seguridad de CRT.
Sintaxis
errno_t _controlfp_s(
unsigned int *currentControl,
unsigned int newControl,
unsigned int mask
);
Parámetros
currentControl
Valor actual del bit de palabra de control.
newControl
Valores de bit de la nueva palabra de control.
mask
Máscara de los bits de la nueva palabra de control que se va a definir.
Valor devuelto
Cero si se ejecuta correctamente, o un código de error del valor errno
.
Comentarios
La función _controlfp_s
es una versión independiente de la plataforma y más segura de _control87
, que inserta la palabra de control de punto flotante en la dirección almacenada en currentControl
y la establece mediante newControl
. Los bits de los valores indican el estado de control de punto flotante. El estado de control de punto flotante permite que el programa cambie los modos de precisión, redondeo e infinito en el paquete matemático de punto flotante, en función de la plataforma. También puede utilizar _controlfp_s
para aplicar o quitar una máscara a excepciones de punto flotante.
Si el valor de mask
es igual a 0, _controlfp_s
obtiene la palabra de control de punto flotante y almacena el valor recuperado en currentControl
.
Si mask
es distinto de cero, se establece un nuevo valor para la palabra de control: en el caso de cualquier bit que esté establecido (es decir, que sea igual a 1) en mask
, se usa el bit correspondiente de new
para actualizar la palabra de control. Dicho de otro modo, fpcntrl = ((fpcntrl & ~mask) | (newControl & mask))
donde fpcntrl
es la palabra de control de punto flotante. En este escenario, currentControl
se establece en el valor después de que se complete el cambio; no es el valor anterior de bits de la palabra de control.
Nota:
De forma predeterminada, las bibliotecas en tiempo de ejecución aplican máscaras a todas las excepciones de punto flotante.
_controlfp_s
es casi idéntica a la función _control87
de las plataformas Intel (x86), x64 y ARM. Si usa como destino las plataformas x86, x64 o ARM, puede usar _control87
o _controlfp_s
.
La diferencia entre _control87
y _controlfp_s
es cómo tratan los valores desnormalizados. En el caso de las plataformas Intel (x86), x64 y ARM, _control87
puede establecer y borrar la máscara de la excepción DENORMAL OPERAND
. _controlfp_s
no modifica la máscara de excepción DENORMAL OPERAND
. En este ejemplo se muestra la diferencia:
_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.
Los valores posibles de la constante de máscara (mask
) y los nuevos valores de control (newControl
) se muestran en la siguiente tabla de valores hexadecimales. Use las constantes portables que se indican a continuación (_MCW_EM
, _EM_INVALID
, etc.) como argumentos para estas funciones, en lugar de proporcionar los valores hexadecimales explícitamente.
Las plataformas derivadas de Intel (x86) admiten los valores de entrada y salida DENORMAL
en el hardware. El comportamiento de x86 consiste en conservar los valores DENORMAL
. La plataforma ARM y las plataformas de x64 compatibles con SSE2 permiten que los operandos DENORMAL
y los resultados se vacíen o se conviertan en cero. Las funciones _controlfp_s
, _controlfp
y _control87
proporcionan una máscara para cambiar este comportamiento. En el siguiente ejemplo se muestra la forma de usar esta máscara:
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.
En las plataformas ARM, la función _controlfp_s
se aplica el registro de FPSCR. En arquitecturas x64, solo se ve afectada la palabra de control de SSE2 almacenada en el registro de MXCSR. En plataformas Intel (x86), _controlfp_s
afecta a las palabras de control de x87 y SSE2, si existen. Es posible que las dos palabras de control no concuerden (como consecuencia de una llamada anterior a __control87_2
, por ejemplo); si hay alguna incoherencia entre las dos palabras de control, _controlfp_s
establece la marca EM_AMBIGUOUS
en currentControl
. Se trata de una advertencia de que la palabra de control devuelta podría no representar el estado de ambas palabras de control de punto flotante con precisión.
En las arquitecturas de ARM y x64 no se puede cambiar el modo de infinito ni la precisión de punto flotante. Si se usa la máscara de control de precisión en la plataforma x64, la función genera una aserción y se invoca el controlador de parámetros no válidos, como se describe en Validación de parámetros.
Si la máscara no se ha ajustado correctamente, esta función genera una excepción de parámetro no válida, como se describe en Validación de parámetros. Si la ejecución puede continuar, la función devuelve EINVAL
y establece errno
en EINVAL
.
Esta función se omite cuando se usa /clr
(Common Language Runtime Compilation) para compilar, porque Common Language Runtime (CLR) solo admite la precisión de punto flotante predeterminada.
De manera predeterminada, el estado global de esta función está limitado a la aplicación. Para cambiar este comportamiento, consulte Estado global en CRT.
Enmascaramiento de constantes y valores
En el caso de la máscara _MCW_EM
, si se borra se establece la excepción, con lo que se permite la excepción de hardware. Si se establece la máscara, se oculta la excepción. Si se produce una constante _EM_UNDERFLOW
o _EM_OVERFLOW
, no se genera ninguna excepción de hardware hasta que se ejecute la instrucción de punto flotante siguiente. Para generar una excepción de hardware inmediatamente después de _EM_UNDERFLOW
o _EM_OVERFLOW
, llame a la instrucción FWAIT MASM
.
Mask | Valor hexadecimal | Constante | Valor hexadecimal |
---|---|---|---|
_MCW_DN (control desnormalizado) |
0x03000000 | _DN_SAVE _DN_FLUSH |
0x00000000 0x01000000 |
_MCW_EM (máscara de excepción de interrupción) |
0x0008001F | _EM_INVALID _EM_DENORMAL _EM_ZERODIVIDE _EM_OVERFLOW _EM_UNDERFLOW _EM_INEXACT |
0x00000010 0x00080000 0x00000008 0x00000004 0x00000002 0x00000001 |
_MCW_IC (control de infinito)(No se admite en las plataformas ARM o x64). |
0x00040000 | _IC_AFFINE _IC_PROJECTIVE |
0x00040000 0x00000000 |
_MCW_RC (control de redondeo) |
0x00000300 | _RC_CHOP _RC_UP _RC_DOWN _RC_NEAR |
0x00000300 0x00000200 0x00000100 0x00000000 |
_MCW_PC (control de precisión)(No se admite en las plataformas ARM o x64). |
0x00030000 | _PC_24 (24 bits)_PC_53 (53 bits)_PC_64 (64 bits) |
0x00020000 0x00010000 0x00000000 |
Requisitos
Routine | Encabezado necesario |
---|---|
_controlfp_s |
<float.h> |
Para obtener más información sobre compatibilidad, consulte Compatibilidad.
Ejemplo
// 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
Vea también
Compatibilidad con cálculos matemáticos y el punto flotante
_clear87
, _clearfp
_status87
, , _statusfp
, _statusfp2
_control87
, , _controlfp
, __control87_2