다음을 통해 공유


_control87, , _controlfp__control87_2

부동 소수점 제어 단어를 가져와서 설정합니다. 보다 안전한 버전을 _controlfp 사용할 수 있습니다._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
);

매개 변수

new
새 제어 단어 비트 값입니다.

mask
설정할 새 제어 단어 비트의 마스크입니다.

x86_cw
x87 부동 소수점 유닛에 대한 제어 단어로 채워집니다. 0(NULL)을 전달하여 SSE2 제어 단어만 설정할 수 있습니다.

sse2_cw
SSE 부동 소수점 유닛에 대한 제어 단어입니다. 0(NULL)을 전달하여 x87 제어 단어만 설정할 수 있습니다.

반환 값

_control87_controlfp의 경우 반환되는 값의 비트는 부동 소수점 제어 상태를 나타냅니다. 반환 _control87되는 비트의 전체 정의는 다음을 참조하세요 FLOAT.H.

__control87_2의 경우 반환 값은 성공을 나타내는 1입니다.

설명

_control87 함수는 부동 소수점 제어 단어를 가져와서 설정합니다. 부동 소수점 컨트롤 단어를 사용하면 프로그램에서 플랫폼에 따라 정밀도, 반올림 및 무한대 모드를 변경할 수 있습니다. _control87를 사용하여 부동 소수점 예외를 마스크 또는 마스크 해제할 수도 있습니다. mask의 값이 0인 경우 _control87은 부동 소수점 제어 단어를 가져옵니다. mask가 0이 아닌 경우 새 제어 단어의 새 값이 설정됩니다. mask에서 켜져 있는 모든 비트(즉, 1과 같음)의 경우 new의 해당 비트가 제어 단어를 업데이트하는 데 사용됩니다. 즉, fpcntrl = ((fpcntrl & ~mask) | (new & mask)) 부동 소수점 제어 단어는 어디에 있습니다 fpcntrl .

참고 항목

기본적으로 런타임 라이브러리는 모든 부동 소수점 예외를 마스킹합니다.

_controlfp 는 플랫폼 독립적이며 이식 가능한 버전 _control87 으로, 함수와 _control87 거의 동일합니다. 코드가 둘 이상의 플랫폼을 대상으로 하는 경우 사용 _controlfp 하거나 _controlfp_s. _control87_controlfp 간의 차이는 DENORMAL 값을 처리하는 방법에 있습니다. x86, x64, ARM 및 ARM64 플랫폼의 _control87 경우 예외 마스크를 DENORMAL OPERAND 설정하고 지울 수 있습니다. _controlfp 는 예외 마스크를 DENORMAL OPERAND 수정하지 않습니다. 이 예제에서는 다음과 같은 차이를 보여 줍니다.

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

마스크 상수() 및 새 컨트롤 값(masknew)에 대한 가능한 값이 Control 단어 마스크 및 값 테이블에 표시됩니다. 16진수 값을 명시적으로 제공하는 대신 아래에 나열된 이식 가능 상수(_MCW_EM, _EM_INVALID 등)를 이러한 함수의 인수로 사용하세요.

Intel x86 파생 플랫폼은 하드웨어의 DENORMAL 입력 및 출력 값을 지원합니다. x86 동작은 값을 유지하는 DENORMAL 것입니다. ARM 및 ARM64 플랫폼과 SSE2를 지원하는 x64 플랫폼을 사용하면 DENORMAL 피연산자와 결과를 플러시하거나 강제로 0으로 설정할 수 있습니다. _controlfp_control87 함수는 이 동작을 변경하는 마스크를 제공합니다. 다음 예제에서는 이 마스크의 사용을 보여 줍니다.

_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.

ARM 및 ARM64 플랫폼에서 _control87 는 FPSCR 레지스터에 해당 및 _controlfp 함수가 적용됩니다. MXCSR 레지스터에 저장된 SSE2 컨트롤 단어만 x64 플랫폼의 영향을 받습니다. x86 플랫폼에서 x87 및 _controlfp SSE2의 컨트롤 단어(있는 경우)에 영향을 줍니다_control87.

__control87_2 함수를 사용하여 x87 및 SSE2 부동 소수점 유닛을 함께 또는 별도로 제어할 수 있습니다. 두 단위 모두에 영향을 주려면 두 x86_cw 정수의 주소를 전달합니다 sse2_cw. 한 단위에만 영향을 주려면 해당 매개 변수에 대한 주소를 전달하지만 다른 단위로는 0을NULL 전달합니다. 이러한 매개 변수 중 하나에 대해 0을 전달하면 함수가 부동 소수점 유닛에는 영향을 주지 않습니다. 코드의 일부가 x87 부동 소수점 단위를 사용하고 다른 부분에서는 SSE2 부동 소수점 단위를 사용하는 경우에 유용합니다.

부동 소수점 컨트롤 단어 _control87 _controlfp 에 대해 다른 값을 설정하는 데 사용하는 __control87_2 경우 두 부동 소수점 단위의 상태를 나타내는 단일 컨트롤 단어를 반환하지 못할 수도 있습니다. 이러한 경우 이러한 함수는 반환된 정수 값의 플래그를 설정 EM_AMBIGUOUS 하여 두 컨트롤 단어 간의 불일치를 나타냅니다. 플래그는 EM_AMBIGUOUS 반환된 컨트롤 단어가 두 부동 소수점 컨트롤 단어의 상태를 정확하게 나타내지 않을 수 있다는 경고입니다.

ARM, ARM64 및 x64 플랫폼에서는 무한대 모드 또는 부동 소수점 정밀도 변경이 지원되지 않습니다. x64 플랫폼에서 전체 자릿수 제어 마스크를 사용하는 경우 함수는 어설션을 발생시키고 매개 변수 유효성 검사에 설명된 대로 잘못된 매개 변수 처리기가 호출됩니다.

참고 항목

__control87_2 는 ARM, ARM64 또는 x64 플랫폼에서 지원되지 않습니다. ARM, ARM64 또는 x64 플랫폼에 대한 프로그램을 사용하고 __control87_2 컴파일하면 컴파일러에서 오류가 발생합니다.

이러한 함수는 컴파일에 사용할 /clr 때 무시됩니다(공용 언어 런타임 컴파일) . CLR(공용 언어 런타임)은 기본 부동 소수점 정밀도만 지원합니다.

단어 마스크 및 값 제어

_MCW_EM 마스크의 경우 마스크를 지우면 예외가 설정되며, 이를 통해 하드웨어 예외가 허용됩니다. 마스크를 설정하면 예외가 숨겨집니다. _EM_UNDERFLOW 또는 _EM_OVERFLOW가 발생하면 다음 부동 소수점 명령이 실행될 때까지 하드웨어 예외가 throw됩니다. _EM_UNDERFLOW 또는 _EM_OVERFLOW 직후에 하드웨어 예외를 생성하려면 FWAIT MASM 명령을 호출하세요.

마스크 16진수 값 상수 16진수 값
_MCW_DN(비정상 제어) 0x03000000 _DN_SAVE

_DN_FLUSH
0x00000000

0x01000000
_MCW_EM(인터럽트 예외 마스크) 0x0008001F _EM_INVALID

_EM_DENORMAL

_EM_ZERODIVIDE

_EM_OVERFLOW

_EM_UNDERFLOW

_EM_INEXACT
0x00000010

0x00080000

0x00000008

0x00000004

0x00000002

0x00000001
_MCW_IC(무한대 제어)

(ARM 또는 x64 플랫폼에서는 지원되지 않습니다.)
0x00040000 _IC_AFFINE

_IC_PROJECTIVE
0x00040000

0x00000000
_MCW_RC(반올림 제어) 0x00000300 _RC_CHOP

_RC_UP

_RC_DOWN

_RC_NEAR
0x00000300

0x00000200

0x00000100

0x00000000
_MCW_PC(정밀도 제어)

(ARM 또는 x64 플랫폼에서는 지원되지 않습니다.)
0x00030000 _PC_24(24비트)

_PC_53(53비트)

_PC_64(64비트)
0x00020000

0x00010000

0x00000000

요구 사항

루틴에서 반환된 값 필수 헤더
_control87, , _controlfp_control87_2 <float.h>

호환성에 대한 자세한 내용은 호환성을 참조하세요.

예시

// 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

참고 항목

수학 및 부동 소수점 지원
_clear87, _clearfp
_status87, , _statusfp_statusfp2
_controlfp_s