Compartilhar via


_control87, _controlfp, __control87_2

Obtém e define a palavra de controle de ponto flutuante. Um versão mais segura de _controlfp está disponível; consulte _controlfp_s.

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 da nova palavra de controle.

  • mask
    Máscara para os bits da nova palavra de controle a ser definida.

  • x86_cw
    Preenchido com a palavra de controle para a unidade x87 de ponto flutuante. Passe 0 (NULL) para definir somente a palavra de controle do SSE2.

  • sse2_cw
    Controle a palavra para a unidade de ponto flutuante do SSE. Passe 0 (NULL) para definir somente a palavra de controle do x87.

Valor de retorno

Para _control87 e _controlfp, os bits no valor retornado indicam o estado de controle do ponto flutuante. Para uma definição completa dos bits que são retornados por _control87, consulte FLOAT.H.

Para __control87_2, o valor de retorno é 1, que indica êxito.

Comentários

A função _control87 obtém e define a palavra de controle do ponto flutuante. A palavra de controle de ponto flutuante permite que o programa altere a precisão, o arredondamento e os modos infinitos no pacote de matemática de ponto flutuante, dependendo da plataforma. Também é possível usar _control87 para mascarar ou desmascarar exceções de ponto flutuante. Se o valor da mask for igual a 0, _control87 obterá a palavra de controle de ponto flutuante. Se mask for diferente de zero, um novo valor para a palavra de controle é definido: Para qualquer bit que estiver ligado (ou seja, igual a 1) em mask, o bit correspondente em new é usado para atualizar a palavra de controle. Em outras palavras, fpcntrl = ((fpcntrl & ~mask) | (new & mask)) onde fpcntrl é a palavra de controle de ponto flutuante.

Dica

Por padrão, as bibliotecas em tempo de execução mascaram todas as exceções de ponto flutuante.

_controlfp é uma versão portátil independente de plataforma de _control87. É quase idêntico à função de _control87 na plataformas Intel (x86), x64 e ARM. Se você estiver definindo plataformas x86, x64, ou plataformas ARM como plataformas de destino, use _control87 ou _controlfp.

A diferença entre _control87 e _controlfp está na maneira como manipulam os valores DENORMAL. Para Intel (x86), x64, e as plataformas ARM, _control87 podem definir e limpar a máscara de exceção DENORMAL OPERAND. _controlfp não modifica a máscara de exceção DENORMAL OPERAND. Esse exemplo demonstra a diferença:

_control87( _EM_INVALID, _MCW_EM ); 
// DENORMAL is unmasked by this call
_controlfp( _EM_INVALID, _MCW_EM ); 
// DENORMAL exception mask remains unchanged

Os valores possíveis para a constante de máscara (mask) e os novos valores de controle (new) são mostrados na tabela de valores hexadecimais a seguir. Use constantes portáteis listadas abaixo (_MCW_EM, _EM_INVALID, e assim por diante) como argumentos para essas funções, em vez de fornecer os valores hexadecimais explicitamente.

As plataformas derivadas de Intel (x86) suportam valores de entrada e saída de DENORMAL no hardware. O comportamento do x86 é preservar valores DENORMAL. A plataforma ARM e as plataformas x64 que têm suporte SSE2 ativam os operandos e os resultados DENORMAL a serem liberados ou forçados para zero. As funções _controlfp e _control87 fornecem uma máscara para alterar esse comportamento. O exemplo a seguir demonstra o uso dessa 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.

Em plataformas ARM, as funções _control87 e _controlfp aplicam-se ao registro FPSCR. Em arquiteturas x64, somente a palavra de controle do SSE2 armazenada no registro MXCSR é afetado. Em plataformas Intel (x86), _control87 e _controlfp afetam as palavras de controle do x87 e SSE2, se presentes. A função __control87_2 permite que as unidades de ponto flutuante do x87 e do SSE2 sejam controladas em conjunto ou separadamente. Se você deseja afetar ambas as unidades, passe endereços de dois inteiros para x86_cw e sse2_cw. Se você deseja afetar somente uma unidade, passe um endereço para esse parâmetro, mas passe 0 (NULL) para outro. Se 0 for passado para um desses parâmetros, a função não terá efeito na unidade de ponto flutuante. Essa funcionalidade pode ser útil em situações onde parte do código usa a unidade de ponto flutuante x87 e outra parte do código usa a unidade de ponto flutuante SSE2. Se você usar __control87_2 em uma parte de um programa e definir valores diferentes para a palavra de controle de ponto flutuante e, em seguida, usar _control87 ou _controlfp para manipular mais palavras de controle, _control87 e _controlfp não poderão retornar uma única palavra de controle para representar o estado de ambas as unidades de ponto flutuante. Em tais casos, essas funções definem o sinalizador de EM_AMBIGUOUS no valor inteiro retornado para indicar que há uma inconsistência entre as duas palavras de controle. Esse é um aviso de que a palavra de controle retornada pode não representar o estado das palavras de controle de ponto flutuante precisamente.

Nas arquiteturas ARM e x64, não há suporte para a alteração do modo infinito ou do ponto flutuante de precisão. Se a máscara de controle de precisão for usada na plataforma de x64, a função gerará uma declaração e o manipulador de parâmetro inválido será chamado, conforme descrito em Validação do parâmetro.

Dica

__control87_2 não tem suporte nas arquiteturas de ARM ou x64.Se você usar __control87_2 e compilar o programa para arquiteturas ARM ou x64, o compilador gerará um erro.

Essas funções são ignoradas quando você usa /clr (compilação do Common Language Runtime) ou /clr:pure para compilar porque o CLR (Common Language Runtime) oferece suporte somente à precisão do ponto flutuante padrão.

Valores hexadecimais

Para a máscara de _MCW_EM, limpar a mascara definirá a exceção, que permite a exceção de hardware; configurar a máscara ocultará a exceção. Se _EM_UNDERFLOW ou _EM_OVERFLOW ocorrer, nenhuma exceção de hardware será lançada até que a declaração de ponto flutuante seguinte seja executada. Para gerar uma exceção de hardware imediatamente depois de _EM_UNDERFLOW ou _EM_OVERFLOW, chame a instrução MASM FWAIT.

Máscara

Valor hex.

Constante

Valor hex.

_MCW_DN (controle de Anormal)

0x03000000

_DN_SAVE

_DN_FLUSH

0x00000000

0x01000000

_MCW_EM (máscara de exceção de interrupção)

0x0008001F

_EM_INVALID

_EM_DENORMAL

_EM_ZERODIVIDE

_EM_OVERFLOW

_EM_UNDERFLOW

_EM_INEXACT

0x00000010

0x00080000

0x00000008

0x00000004

0x00000002

0x00000001

_MCW_IC (controle de Infinito)

(Não suportado em plataformas do x64 ou ARM.)

0x00040000

_IC_AFFINE

_IC_PROJECTIVE

0x00040000

0x00000000

_MCW_RC (controle de Arredondamento)

0x00000300

_RC_CHOP

_RC_UP

_RC_DOWN

_RC_NEAR

0x00000300

0x00000200

0x00000100

0x00000000

_MCW_PC (controle de Precisão)

(Não suportado em plataformas do x64 ou ARM.)

0x00030000

_PC_24 (24 bits)

_PC_53 (53 bits)

_PC_64 (64 bits)

0x00020000

0x00010000

0x00000000

Requisitos

Rotina

Cabeçalho necessário

_control87, _controlfp, _control87_2

<float.h>

Para obter mais informações de compatibilidade, consulte Compatibilidade.

Exemplo

// crt_cntrl87.c
// processor: x86
// 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;

    // Show original x87 control word and do calculation.
    control_word_x87 = __control87_2(0, 0,
                                     &control_word_x87, 0);
    printf( "Original: 0x%.4x\n", control_word_x87 );
    printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );

    // Set precision to 24 bits and recalculate.
    control_word_x87 = __control87_2(_PC_24, MCW_PC,
                                     &control_word_x87, 0);
    printf( "24-bit:   0x%.4x\n", control_word_x87 );
    printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );

    // Restore default precision-control bits and recalculate.
    control_word_x87 = __control87_2( _CW_DEFAULT, MCW_PC, 
                                     &control_word_x87, 0 );
    printf( "Default:  0x%.4x\n", control_word_x87 );
    printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
}

Saída

Original: 0x0001
0.1 * 0.1 = 1.000000000000000e-002
24-bit:   0x0001
0.1 * 0.1 = 9.999999776482582e-003
Default:  0x0001
0.1 * 0.1 = 1.000000000000000e-002

Equivalência do .NET Framework

Não aplicável. Para chamar a função padrão de C, use PInvoke. Para obter mais informações, consulte Exemplos de invocação de plataforma.

Consulte também

Referência

Suporte de ponto flutuante

_clear87, _clearfp

_status87, _statusfp, _statusfp2

_controlfp_s