_control87
, , _controlfp
, __control87_2
Obtiene y establece la palabra de control de punto flotante. Hay disponible una versión más segura de _controlfp
; vea _controlfp_s
.
Sintaxis
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
);
Parámetros
new
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.
x86_cw
Se llena con la palabra de control de la unidad de punto flotante x87. Pase 0 (NULL
) para establecer solo la palabra de control de SSE2.
sse2_cw
Palabra de control de la unidad de punto flotante de SSE. Pase 0 (NULL
) para establecer solo la palabra de control de x87.
Valor devuelto
En el caso de _control87
y _controlfp
, los bits del valor devuelto indican el estado de control del punto flotante. Para ver una definición completa de los bits que devuelve _control87
, vea FLOAT.H
.
En el caso de __control87_2
, el valor devuelto es 1, que indica que la operación ha sido correcta.
Comentarios
La función _control87
obtiene y establece la palabra de control de punto flotante. La palabra de control de punto flotante permite que el programa cambie los modos de precisión, redondeo e infinito, en función de la plataforma. También puede utilizar _control87
para aplicar o quitar una máscara a excepciones de punto flotante. Si el valor de mask
es igual a 0, _control87
obtiene la palabra de control de punto flotante. Si mask
es distinto de cero, se establece un nuevo valor para la palabra de control: en el caso de cualquier bit que esté activado (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) | (new & mask))
donde fpcntrl
es la palabra de control de punto flotante.
Nota:
De forma predeterminada, las bibliotecas en tiempo de ejecución aplican máscaras a todas las excepciones de punto flotante.
_controlfp
es una versión portátil independiente de la plataforma de _control87
que es casi idéntica a la función _control87
. Si el código tiene como destino más de una plataforma, use _controlfp
o _controlfp_s
. La diferencia entre _control87
y _controlfp
es cómo tratan los valores DENORMAL
. Para las plataformas x86, x64, ARM y ARM64, _control87
puede establecer y borrar la máscara de excepción DENORMAL OPERAND
. _controlfp
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
_controlfp( _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 (new
) se muestran en la siguiente tabla de control de máscaras de palabras y valores. 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
. Las plataformas ARM y ARM64, así como las de x64 compatibles con SSE2, permiten que los operandos y resultados DENORMAL
se vacíen o se fuercen para convertirse en cero. Las funciones _controlfp
y _control87
proporcionan una máscara para cambiar este comportamiento. En el siguiente ejemplo se muestra la forma de usar esta máscara.
_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.
En las plataformas ARM y ARM64, las funciones _control87
y _controlfp
se aplican al registro de FPSCR. En las plataformas x64 solo se ve afectada la palabra de control de SSE2 almacenada en el registro de MXCSR. En las plataformas x86, _control87
y _controlfp
afectan a las palabras de control de x87 y SSE2, si existen.
La función __control87_2
permite controlar las unidades de punto flotantes de x87 y SSE2 juntas o por separado. Si quiere que se vean afectadas las dos unidades, pase las direcciones de dos enteros a x86_cw
y sse2_cw
. Si quiere que solo se vea afectada una unidad, pase una dirección para ese parámetro y pase 0 (NULL
) para el otro. Si se pasa 0 para uno de estos parámetros, la función no tiene ningún efecto en esa unidad de punto flotante. Es útil en situaciones en la que parte del código usa la unidad de punto flotante x87 y otra parte usa la unidad de punto flotante SSE2.
Si usa __control87_2
a fin de establecer valores distintos para las palabras de control de punto flotante, es posible que _control87
o _controlfp
no puedan devolver una sola palabra de control para representar el estado de las dos unidades de punto flotante. En ese caso, estas funciones establecen la marca EM_AMBIGUOUS
en el valor entero devuelto para indicar que hay una incoherencia entre las dos palabras de control. La marca EM_AMBIGUOUS
es una advertencia de que la palabra de control devuelta podría no representar con precisión el estado de las dos palabras de control de punto flotante.
En las plataformas ARM, ARM64 y x64, no se admite cambiar el modo infinito ni la precisión de punto flotante. Si la máscara de control de precisión se usa 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.
Nota:
__control87_2
no se admite en las plataformas ARM, ARM64 o x64. Si usa __control87_2
y compila el programa para las plataformas ARM, ARM64 o x64, el compilador genera un error.
Estas funciones se ignoran cuando usa /clr
(compilación de Common Language Runtime) para compilar. Common Language Runtime (CLR) solo admite la precisión de punto flotante predeterminada.
Control de máscaras de palabras y valores
En el caso de la máscara _MCW_EM
, si se borra la máscara 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 de MASM FWAIT
.
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 |
---|---|
_control87 , , _controlfp , _control87_2 |
<float.h> |
Para obtener más información sobre compatibilidad, consulte Compatibilidad.
Ejemplo
// 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
Vea también
Compatibilidad con cálculos matemáticos y el punto flotante
_clear87
, _clearfp
_status87
, , _statusfp
, _statusfp2
_controlfp_s