/*** *fenv.h - definitions and declarations for floating point environment library * * Copyright (c) Microsoft Corporation. All rights reserved. * *Purpose: * This file contains constant definitions and external subroutine * declarations for the floating point environment subroutine library. * * [Public] * ****/ #pragma once #ifndef _FENV #define _FENV #include /* * Currently, all MS C compilers for Win32 platforms default to 8 byte * alignment. */ #pragma pack(push,_CRT_PACKING) #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #if !defined(_M_CEE) || defined(_CRTBLD) typedef unsigned long fexcept_t; typedef struct fenv_t { unsigned long _Fe_ctl, _Fe_stat; } fenv_t; #define FE_INEXACT _SW_INEXACT /* _EM_INEXACT 0x00000001 inexact (precision) */ #define FE_UNDERFLOW _SW_UNDERFLOW /* _EM_UNDERFLOW 0x00000002 underflow */ #define FE_OVERFLOW _SW_OVERFLOW /* _EM_OVERFLOW 0x00000004 overflow */ #define FE_DIVBYZERO _SW_ZERODIVIDE /* _EM_ZERODIVIDE 0x00000008 zero divide */ #define FE_INVALID _SW_INVALID /* _EM_INVALID 0x00000010 invalid */ #define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) _CRTIMP int __cdecl fegetenv(_Inout_ fenv_t *); _CRTIMP int __cdecl fesetenv(_In_ const fenv_t *); _CRTIMP int __cdecl feclearexcept(_In_ int); _CRTIMP int __cdecl feholdexcept(_Inout_ fenv_t *); _CRTIMP int __cdecl fetestexcept(_In_ int); _CRTIMP int __cdecl fegetexceptflag(_Inout_ fexcept_t *, _In_ int); _CRTIMP int __cdecl fesetexceptflag(_In_ const fexcept_t *, _In_ int); __declspec(selectany) extern const fenv_t _Fenv0 = {0, 0}; #define FE_DFL_ENV (&_Fenv0) #endif /* !defined(_M_CEE) || defined(_CRTBLD) */ #define FE_TONEAREST 0x0000 #define FE_UPWARD 0x0100 #define FE_DOWNWARD 0x0200 #define FE_TOWARDZERO 0x0300 #define FE_ROUND_MASK 0x0300 _CRTIMP int __cdecl fegetround(void); _CRTIMP int __cdecl fesetround(_In_ int); #if !defined(_M_CEE) && !defined(_CRTBLD) /* * feraiseexcept is inline in this header so that it will be compiled with * the /arch setting specified in the consuming application, rather than the * /arch:IA32 setting which is the default for the CRT library itself. * * feupdateenv is inline because it calls feraiseexcept. */ __inline int __CRTDECL feraiseexcept(_In_ int _Except) { #define __DBL_BIG 1e+300 /* may raise inexact too */ static struct { int _Except_Val; double _Num, _Denom; } const _Table[] = { /* raise exception by evaluating num / denom */ {FE_INVALID, 0.0, 0.0}, {FE_DIVBYZERO, 1.0, 0.0}, {FE_OVERFLOW, __DBL_BIG, 1.0 / __DBL_BIG}, {FE_UNDERFLOW, 1.0 / __DBL_BIG, __DBL_BIG}, {FE_INEXACT, 2.0, 3.0} }; fexcept_t _Flags = 0; double _Ans = 0.0; int _N; if ((_Except &= FE_ALL_EXCEPT) == 0) { return 0; } /* get the current status flags */ fegetexceptflag(&_Flags, FE_ALL_EXCEPT); _Except &= ~_Flags; _Flags |= _Except; /* set the new status flags */ fesetexceptflag(&_Flags, FE_ALL_EXCEPT); /* raise the exceptions not masked */ for (_N = 0; _N < sizeof(_Table) / sizeof(_Table[0]); ++_N) { if ((_Except & _Table[_N]._Except_Val) != 0) { _Ans = _Table[_N]._Num / _Table[_N]._Denom; } } return 0; } __inline int __CRTDECL feupdateenv(_In_ const fenv_t *_Penv) { int _Except = fetestexcept(FE_ALL_EXCEPT); if (fesetenv(_Penv) != 0 || feraiseexcept(_Except) != 0) { return 1; } return 0; } #endif /* !defined(_M_CEE) && !defined(_CRTBLD) */ #ifdef __cplusplus } #endif /* __cplusplus */ #pragma pack(pop) #endif /* _FENV */