// Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #pragma once #include #include #include #include // macros for _Feraise argument #define _FE_DIVBYZERO 0x04 #define _FE_INVALID 0x01 #define _FE_OVERFLOW 0x08 #define _FE_UNDERFLOW 0x10 // float properties #define _D0 3 // little-endian, small long doubles #define _D1 2 #define _D2 1 #define _D3 0 // IEEE 754 double properties #define HUGE_EXP static_cast(_DMAX * 900L / 1000) // IEEE 754 float properties #define FHUGE_EXP static_cast(_FMAX * 900L / 1000) #define _F0 1 // little-endian #define _F1 0 // IEEE 754 long double properties #define LHUGE_EXP static_cast(_LMAX * 900L / 1000) #define _L0 3 // little-endian, 64-bit long doubles #define _L1 2 #define _L2 1 #define _L3 0 #define DSIGN(x) (reinterpret_cast<_Dval*>(&(x))->_Sh[_D0] & _DSIGN) #define FSIGN(x) (reinterpret_cast<_Fval*>(&(x))->_Sh[_F0] & _FSIGN) #define LSIGN(x) (reinterpret_cast<_Lval*>(&(x))->_Sh[_L0] & _LSIGN) // return values for _Stopfx/_Stoflt #define FL_ERR 0 #define FL_DEC 1 #define FL_HEX 2 #define FL_INF 3 #define FL_NAN 4 #define FL_NEG 8 // macros for _Dtest return (0 => ZERO) #define _DENORM (-2) // C9X only #define _FINITE (-1) _EXTERN_C_UNLESS_PURE void __CLRCALL_PURE_OR_CDECL _Feraise(int) noexcept; union _Dconst { // pun float types as integer array unsigned short _Word[8]; // TRANSITION, ABI: Twice as large as necessary. float _Float; double _Double; long double _Long_double; }; _CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _Dtest(double*) noexcept; extern _CRTIMP2_PURE _Dconst _Denorm; extern _CRTIMP2_PURE _Dconst _Hugeval; extern _CRTIMP2_PURE _Dconst _Inf; extern _CRTIMP2_PURE _Dconst _Nan; extern _CRTIMP2_PURE _Dconst _Snan; _CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _FDtest(float*) noexcept; extern _CRTIMP2_PURE _Dconst _FDenorm; extern _CRTIMP2_PURE _Dconst _FInf; extern _CRTIMP2_PURE _Dconst _FNan; extern _CRTIMP2_PURE _Dconst _FSnan; extern _CRTIMP2_PURE _Dconst _LDenorm; extern _CRTIMP2_PURE _Dconst _LInf; extern _CRTIMP2_PURE _Dconst _LNan; extern _CRTIMP2_PURE _Dconst _LSnan; int _Stopfx(const char**, char**) noexcept; _In_range_(0, maxsig) int _Stoflt( const char*, const char*, char**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig) noexcept; _In_range_(0, maxsig) int _Stoxflt( const char*, const char*, char**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig) noexcept; int _WStopfx(const wchar_t**, wchar_t**) noexcept; _In_range_(0, maxsig) int _WStoflt( const wchar_t*, const wchar_t*, wchar_t**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig) noexcept; _In_range_(0, maxsig) int _WStoxflt( const wchar_t*, const wchar_t*, wchar_t**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig) noexcept; // double declarations union _Dval { // pun floating type as integer array unsigned short _Sh[8]; double _Val; }; unsigned short* _Pmsw(double*) noexcept; short _Dint(double*, short) noexcept; short _Dnorm(_Dval*) noexcept; short _Dscale(double*, long) noexcept; short _Dunscale(short*, double*) noexcept; double _Poly(double, const double*, int) noexcept; extern const _Dconst _Eps; extern const _Dconst _Rteps; extern const double _Xbig; double _Xp_getw(const double*, int) noexcept; double* _Xp_setn(double*, int, long) noexcept; double* _Xp_setw(double*, int, double) noexcept; double* _Xp_addh(double*, int, double) noexcept; double* _Xp_mulh(double*, int, double) noexcept; double* _Xp_movx(double*, int, const double*) noexcept; double* _Xp_addx(double*, int, const double*, int) noexcept; double* _Xp_ldexpx(double*, int, int) noexcept; double* _Xp_mulx(double*, int, const double*, int, double*) noexcept; // float declarations union _Fval { // pun floating type as integer array unsigned short _Sh[8]; float _Val; }; unsigned short* _FPmsw(float*) noexcept; short _FDint(float*, short) noexcept; short _FDnorm(_Fval*) noexcept; short _FDscale(float*, long) noexcept; short _FDunscale(short*, float*) noexcept; extern const _Dconst _FEps; extern const _Dconst _FRteps; extern const float _FXbig; float _FXp_getw(const float*, int) noexcept; float* _FXp_setn(float*, int, long) noexcept; float* _FXp_setw(float*, int, float) noexcept; float* _FXp_addh(float*, int, float) noexcept; float* _FXp_mulh(float*, int, float) noexcept; float* _FXp_movx(float*, int, const float*) noexcept; float* _FXp_addx(float*, int, const float*, int) noexcept; float* _FXp_ldexpx(float*, int, int) noexcept; float* _FXp_mulx(float*, int, const float*, int, float*) noexcept; // long double declarations union _Lval { // pun floating type as integer array unsigned short _Sh[8]; long double _Val; }; unsigned short* _LPmsw(long double*) noexcept; short _LDint(long double*, short) noexcept; short _LDscale(long double*, long) noexcept; short _LDunscale(short*, long double*) noexcept; long double _LPoly(long double, const long double*, int) noexcept; extern const _Dconst _LEps; extern const _Dconst _LRteps; extern const long double _LXbig; long double _LXp_getw(const long double*, int) noexcept; long double* _LXp_setn(long double*, int, long) noexcept; long double* _LXp_setw(long double*, int, long double) noexcept; long double* _LXp_addh(long double*, int, long double) noexcept; long double* _LXp_mulh(long double*, int, long double) noexcept; long double* _LXp_movx(long double*, int, const long double*) noexcept; long double* _LXp_addx(long double*, int, const long double*, int) noexcept; long double* _LXp_ldexpx(long double*, int, int) noexcept; long double* _LXp_mulx(long double*, int, const long double*, int, long double*) noexcept; _END_EXTERN_C_UNLESS_PURE // raise IEEE 754 exceptions #ifndef _M_CEE_PURE #pragma float_control(except, on, push) #endif template [[nodiscard]] T _Xfe_overflow(const T sign) noexcept { static_assert(_STD is_floating_point_v, "Expected is_floating_point_v."); constexpr T huge = _STD numeric_limits::max(); return _STD copysign(huge, sign) * huge; } template [[nodiscard]] T _Xfe_underflow(const T sign) noexcept { static_assert(_STD is_floating_point_v, "Expected is_floating_point_v."); constexpr T tiny = _STD numeric_limits::min(); return _STD copysign(tiny, sign) * tiny; } #ifndef _M_CEE_PURE #pragma float_control(pop) #endif