표준 라이브러리 헤더 <fenv.h>

표준 라이브러리 헤더 <fenv.h> (C99)

부동소수점 연산은 단순히 "값"만 계산하는 게 아니에요. 넘침(overflow) 같은 예외 상태나 반올림 방향 같은 **환경(environment)**도 연산 결과에 영향을 줘요. 평소에는 몰라도 되는 이런 상태를 직접 읽고 바꿔야 할 때가 있는데, 그때 필요한 게 <fenv.h>예요. 부동소수점 환경 라이브러리의 일부로, 예외 플래그와 반올림 모드를 다루는 타입·함수·매크로를 제공해요.

출처: cppreference

본문

타입(Types)

타입 설명
fenv_t 부동소수점 환경 전체를 나타내는 타입
fexcept_t 모든 부동소수점 상태 플래그를 한데 묶어 나타내는 타입

함수(Functions)

함수 설명
feclearexcept (C99) 지정한 부동소수점 상태 플래그를 지움
fetestexcept (C99) 지정한 상태 플래그 중 어떤 것이 설정됐는지 판별
feraiseexcept (C99) 지정한 부동소수점 예외를 발생시킴
fegetexceptflag / fesetexceptflag (C99) 부동소수점 환경과 상태 플래그 상태를 서로 복사
fegetround / fesetround (C99) 반올림 방향을 가져오거나 설정
fegetenv / fesetenv (C99) 현재 부동소수점 환경을 저장하거나 복원
feholdexcept (C99) 환경을 저장하고 모든 상태 플래그를 지운 뒤 이후 오류를 무시
feupdateenv (C99) 부동소수점 환경을 복원하고 이전에 발생한 예외를 다시 발생시킴

매크로(Macros)

매크로 설명
FE_ALL_EXCEPT, FE_DIVBYZERO, FE_INEXACT, FE_INVALID, FE_OVERFLOW, FE_UNDERFLOW (C99) 부동소수점 예외 종류
FE_DOWNWARD, FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD (C99) 부동소수점 반올림 방향
FE_DFL_ENV (C99) 기본 부동소수점 환경

시그니처(Synopsis)

#define __STDC_VERSION_FENV_H__ 202311L

#define FE_ALL_EXCEPT /* see description */
#define FE_DIVBYZERO /* see description */
#define FE_INEXACT /* see description */
#define FE_INVALID /* see description */
#define FE_OVERFLOW /* see description */
#define FE_UNDERFLOW /* see description */
#define FE_DOWNWARD /* see description */
#define FE_TONEARESTFROMZERO /* see description */
#define FE_TONEAREST /* see description */
#define FE_TOWARDZERO /* see description */
#define FE_UPWARD /* see description */
#define FE_DFL_ENV /* see description */
#define FE_DFL_MODE /* see description */

#define fenv_t /* see description */
#define fexcept_t /* see description */
#define femode_t /* see description */

#pragma STDC FENV_ACCESS /*on-off-switch*/
#pragma STDC FENV_ROUND direction
#pragma STDC FENV_ROUND FE_DYNAMIC

// functions
int feclearexcept(int excepts);
int fegetexceptflag(fexcept_t* flagp, int excepts);
int feraiseexcept(int excepts);
int fesetexcept(int excepts);
int fesetexceptflag(const fexcept_t* flagp, int excepts);
int fetestexceptflag(const fexcept_t* flagp, int excepts);
int fetestexcept(int excepts);
int fegetmode(femode_t* modep);
int fegetround(void);
int fesetmode(const femode_t* modep);
int fesetround(int rnd);
int fegetenv(fenv_t* envp);
int feholdexcept(fenv_t* envp);
int fesetenv(const fenv_t* envp);
int feupdateenv(const fenv_t* envp);

// Only if the implementation defines __STDC_IEC_60559_DFP__:
#define FE_DEC_DOWNWARD /* implementation-defined */
#define FE_DEC_TONEARESTFROMZERO /* implementation-defined */
#define FE_DEC_TONEAREST /* implementation-defined */
#define FE_DEC_TOWARDZERO /* implementation-defined */
#define FE_DEC_UPWARD /* implementation-defined */

#pragma STDC FENV_DEC_ROUND /*dec-direction*/
int fe_dec_getround(void);
int fe_dec_setround(int rnd);

// Only if the implementation follows the recommended practice from F.2.2:
#define FE_SNANS_ALWAYS_SIGNAL /* implementation-defined */

pragma로 FENV 접근을 켜면 컴파일러가 부동소수점 환경을 건드리는 연산을 최적화로 없애지 않아요. 예외 플래그를 검사하는 코드를 쓸 때 필요한 설정이죠.

더 알아보기

  • <math.h>: 대부분의 수학 함수가 오류를 어떻게 보고하는지(math_errhandling)를 여기서 함께 봐요.
  • 부동소수점 환경 동작 방식을 자세히 보려면 언어 수준의 부동소수점 문서를 참고해요.