#pragma once
#ifndef _FENV
#define _FENV
#include <corecrt.h>
#include <float.h>
#pragma warning(push)
#pragma warning(disable: _UCRT_DISABLED_WARNINGS)
_UCRT_DISABLE_CLANG_WARNINGS
_CRT_BEGIN_C_HEADER
#define FE_TONEAREST _RC_NEAR
#define FE_UPWARD _RC_UP
#define FE_DOWNWARD _RC_DOWN
#define FE_TOWARDZERO _RC_CHOP
#define FE_ROUND_MASK _MCW_RC
_ACRTIMP int __cdecl fegetround(void);
_ACRTIMP int __cdecl fesetround(_In_ int _Round);
#if !defined _M_CEE
typedef unsigned long fexcept_t;
typedef struct fenv_t
{
unsigned long _Fe_ctl, _Fe_stat;
} fenv_t;
#define FE_INEXACT _SW_INEXACT
#define FE_UNDERFLOW _SW_UNDERFLOW
#define FE_OVERFLOW _SW_OVERFLOW
#define FE_DIVBYZERO _SW_ZERODIVIDE
#define FE_INVALID _SW_INVALID
#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
_ACRTIMP int __cdecl fegetenv(_Out_ fenv_t* _Env);
_ACRTIMP int __cdecl fesetenv(_In_ fenv_t const* _Env);
_ACRTIMP int __cdecl feclearexcept(_In_ int _Flags);
_ACRTIMP _Success_(return == 0) int __cdecl feholdexcept(_Out_ fenv_t* _Env);
_ACRTIMP int __cdecl fetestexcept(_In_ int _Flags);
_ACRTIMP int __cdecl fegetexceptflag(_Out_ fexcept_t* _Except, _In_ int _TestFlags);
_ACRTIMP int __cdecl fesetexceptflag(_In_ fexcept_t const* _Except, _In_ int _SetFlags);
#if !defined __midl
#ifdef __cplusplus
#define CPP_EXTERN extern
#else
#define CPP_EXTERN
#endif
#if defined _M_IX86
CPP_EXTERN __declspec(selectany) const fenv_t _Fenv1 = { 0x3f3f103f, 0 };
#elif defined _M_X64
CPP_EXTERN __declspec(selectany) const fenv_t _Fenv1 = { 0x3f00003f, 0 };
#else
CPP_EXTERN __declspec(selectany) const fenv_t _Fenv1 = { 0x0000003f, 0 };
#endif
#endif
#define FE_DFL_ENV (&_Fenv1)
#if _CRT_FUNCTIONS_REQUIRED
#if !defined(_BEGIN_PRAGMA_OPTIMIZE_DISABLE)
#define _BEGIN_PRAGMA_OPTIMIZE_DISABLE(flags, bug, reason) \
__pragma(optimize(flags, off))
#define _BEGIN_PRAGMA_OPTIMIZE_ENABLE(flags, bug, reason) \
__pragma(optimize(flags, on))
#define _END_PRAGMA_OPTIMIZE() \
__pragma(optimize("", on))
#endif
_BEGIN_PRAGMA_OPTIMIZE_DISABLE("", MSFT:4499495, "If optimizations are on, the floating-point exception might not get triggered (because the compiler optimizes it out), breaking the function.")
__inline int __CRTDECL feraiseexcept(_In_ int _Except)
{
static struct
{
int _Except_Val;
double _Num;
double _Denom;
} const _Table[] =
{
{FE_INVALID, 0.0, 0.0 },
{FE_DIVBYZERO, 1.0, 0.0 },
{FE_OVERFLOW, 1e+300, 1e-300 },
{FE_UNDERFLOW, 1e-300, 1e+300 },
{FE_INEXACT, 2.0, 3.0 }
};
double _Ans = 0.0;
(void) _Ans;
size_t _Index;
if ((_Except &= FE_ALL_EXCEPT) == 0)
{
return 0;
}
for (_Index = 0; _Index < sizeof(_Table) / sizeof(_Table[0]); ++_Index)
{
if ((_Except & _Table[_Index]._Except_Val) != 0)
{
_Ans = _Table[_Index]._Num / _Table[_Index]._Denom;
#if defined _M_IX86 && _M_IX86_FP == 0 && !defined _M_HYBRID_X86_ARM64
#ifdef _MSC_VER
__asm fwait;
#else
__asm__ __volatile__("fwait");
#endif
#endif
}
}
return 0;
}
_END_PRAGMA_OPTIMIZE()
__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
#endif
_CRT_END_C_HEADER
_UCRT_RESTORE_CLANG_WARNINGS
#pragma warning(pop)
#endif