28 #define HALF_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
30 #if defined(__INTEL_COMPILER)
31 #define HALF_ICC_VERSION __INTEL_COMPILER
33 #define HALF_ICC_VERSION __ICC
35 #define HALF_ICC_VERSION __ICL
37 #define HALF_ICC_VERSION 0
41 #define MU_HALF_FE_INVALID 0x01
42 #define MU_HALF_FE_DIVBYZERO 0x04
43 #define MU_HALF_FE_OVERFLOW 0x08
44 #define MU_HALF_FE_UNDERFLOW 0x10
45 #define MU_HALF_FE_INEXACT 0x20
46 #define MU_HALF_FE_ALL_EXCEPT (MU_HALF_FE_INEXACT | MU_HALF_FE_DIVBYZERO | MU_HALF_FE_UNDERFLOW | MU_HALF_FE_OVERFLOW | MU_HALF_FE_INVALID)
49 #if defined(__clang__)
50 #if __has_feature(cxx_static_assert) && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
51 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
53 #if __has_feature(cxx_constexpr) && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
54 #define HALF_ENABLE_CPP11_CONSTEXPR 1
56 #if __has_feature(cxx_noexcept) && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
57 #define HALF_ENABLE_CPP11_NOEXCEPT 1
59 #if __has_feature(cxx_user_literals) && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
60 #define HALF_ENABLE_CPP11_USER_LITERALS 0
62 #if __has_feature(cxx_thread_local) && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
63 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
65 #if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) && !defined(HALF_ENABLE_CPP11_LONG_LONG)
66 #define HALF_ENABLE_CPP11_LONG_LONG 1
68 #elif HALF_ICC_VERSION && defined(__INTEL_CXX11_MODE__)
69 #if HALF_ICC_VERSION >= 1500 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
70 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
72 #if HALF_ICC_VERSION >= 1500 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
73 #define HALF_ENABLE_CPP11_USER_LITERALS 0
75 #if HALF_ICC_VERSION >= 1400 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
76 #define HALF_ENABLE_CPP11_CONSTEXPR 1
78 #if HALF_ICC_VERSION >= 1400 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
79 #define HALF_ENABLE_CPP11_NOEXCEPT 1
81 #if HALF_ICC_VERSION >= 1110 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
82 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
84 #if HALF_ICC_VERSION >= 1110 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
85 #define HALF_ENABLE_CPP11_LONG_LONG 1
87 #elif defined(__GNUC__)
88 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
89 #if HALF_GCC_VERSION >= 408 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
90 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
92 #if HALF_GCC_VERSION >= 407 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
93 #define HALF_ENABLE_CPP11_USER_LITERALS 0
95 #if HALF_GCC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
96 #define HALF_ENABLE_CPP11_CONSTEXPR 1
98 #if HALF_GCC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
99 #define HALF_ENABLE_CPP11_NOEXCEPT 1
101 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
102 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
104 #if !defined(HALF_ENABLE_CPP11_LONG_LONG)
105 #define HALF_ENABLE_CPP11_LONG_LONG 1
108 #define HALF_TWOS_COMPLEMENT_INT 1
109 #elif defined(_MSC_VER)
110 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
111 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
113 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
114 #define HALF_ENABLE_CPP11_USER_LITERALS 0
116 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
117 #define HALF_ENABLE_CPP11_CONSTEXPR 1
119 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
120 #define HALF_ENABLE_CPP11_NOEXCEPT 1
122 #if _MSC_VER >= 1600 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
123 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
125 #if _MSC_VER >= 1310 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
126 #define HALF_ENABLE_CPP11_LONG_LONG 1
128 #define HALF_TWOS_COMPLEMENT_INT 1
129 #define HALF_POP_WARNINGS 1
130 #pragma warning(push)
131 #pragma warning(disable : 4099 4127 4146)
136 #if defined(_LIBCPP_VERSION)
137 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
138 #ifndef HALF_ENABLE_CPP11_TYPE_TRAITS
139 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
141 #ifndef HALF_ENABLE_CPP11_CSTDINT
142 #define HALF_ENABLE_CPP11_CSTDINT 1
144 #ifndef HALF_ENABLE_CPP11_CMATH
145 #define HALF_ENABLE_CPP11_CMATH 0
147 #ifndef HALF_ENABLE_CPP11_HASH
148 #define HALF_ENABLE_CPP11_HASH 1
150 #ifndef HALF_ENABLE_CPP11_CFENV
151 #define HALF_ENABLE_CPP11_CFENV 1
154 #elif defined(__GLIBCXX__)
155 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
157 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
158 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
160 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CSTDINT)
161 #define HALF_ENABLE_CPP11_CSTDINT 1
163 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CMATH)
164 #define HALF_ENABLE_CPP11_CMATH 1
166 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_HASH)
167 #define HALF_ENABLE_CPP11_HASH 1
169 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CFENV)
170 #define HALF_ENABLE_CPP11_CFENV 1
173 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
174 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
176 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CSTDINT)
177 #define HALF_ENABLE_CPP11_CSTDINT 1
179 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CMATH)
180 #define HALF_ENABLE_CPP11_CMATH 1
182 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_HASH)
183 #define HALF_ENABLE_CPP11_HASH 1
185 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CFENV)
186 #define HALF_ENABLE_CPP11_CFENV 1
190 #elif defined(_CPPLIB_VER)
191 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
192 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
194 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_CSTDINT)
195 #define HALF_ENABLE_CPP11_CSTDINT 1
197 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_HASH)
198 #define HALF_ENABLE_CPP11_HASH 1
200 #if _CPPLIB_VER >= 610 && !defined(HALF_ENABLE_CPP11_CMATH)
201 #define HALF_ENABLE_CPP11_CMATH 1
203 #if _CPPLIB_VER >= 610 && !defined(HALF_ENABLE_CPP11_CFENV)
204 #define HALF_ENABLE_CPP11_CFENV 1
207 #undef HALF_GCC_VERSION
208 #undef HALF_ICC_VERSION
211 #if defined(HALF_ERRHANDLING_THROW_INVALID) || defined(HALF_ERRHANDLING_THROW_DIVBYZERO) || defined(HALF_ERRHANDLING_THROW_OVERFLOW) || defined(HALF_ERRHANDLING_THROW_UNDERFLOW) || defined(HALF_ERRHANDLING_THROW_INEXACT)
212 #define HALF_ERRHANDLING_THROWS 1
216 #define HALF_ERRHANDLING (HALF_ERRHANDLING_FLAGS || HALF_ERRHANDLING_ERRNO || HALF_ERRHANDLING_FENV || HALF_ERRHANDLING_THROWS)
219 #define HALF_UNUSED_NOERR(name) name
221 #define HALF_UNUSED_NOERR(name)
225 #if HALF_ENABLE_CPP11_CONSTEXPR
226 #define HALF_CONSTEXPR constexpr
227 #define HALF_CONSTEXPR_CONST constexpr
229 #define HALF_CONSTEXPR_NOERR
231 #define HALF_CONSTEXPR_NOERR constexpr
234 #define HALF_CONSTEXPR
235 #define HALF_CONSTEXPR_CONST const
236 #define HALF_CONSTEXPR_NOERR
240 #if HALF_ENABLE_CPP11_NOEXCEPT
241 #define HALF_NOEXCEPT noexcept
242 #define HALF_NOTHROW noexcept
244 #define HALF_NOEXCEPT
245 #define HALF_NOTHROW throw()
249 #if HALF_ENABLE_CPP11_THREAD_LOCAL
250 #define HALF_THREAD_LOCAL thread_local
252 #define HALF_THREAD_LOCAL static
266 #if HALF_ENABLE_CPP11_TYPE_TRAITS
267 #include <type_traits>
269 #if HALF_ENABLE_CPP11_CSTDINT
272 #if HALF_ERRHANDLING_ERRNO
275 #if HALF_ENABLE_CPP11_CFENV
278 #if HALF_ENABLE_CPP11_HASH
279 #include <functional>
290 #undef isgreaterequal
296 #ifndef HALF_ENABLE_F16C_INTRINSICS
303 #define HALF_ENABLE_F16C_INTRINSICS __F16C__
305 #if HALF_ENABLE_F16C_INTRINSICS
306 #include <immintrin.h>
309 #ifdef HALF_DOXYGEN_ONLY
315 #define HALF_ARITHMETIC_TYPE (undefined)
320 #define HALF_ERRHANDLING_FLAGS 0
327 #define HALF_ERRHANDLING_ERRNO 0
335 #define HALF_ERRHANDLING_FENV 0
340 #define HALF_ERRHANDLING_THROW_INVALID (undefined)
345 #define HALF_ERRHANDLING_THROW_DIVBYZERO (undefined)
350 #define HALF_ERRHANDLING_THROW_OVERFLOW (undefined)
355 #define HALF_ERRHANDLING_THROW_UNDERFLOW (undefined)
360 #define HALF_ERRHANDLING_THROW_INEXACT (undefined)
363 #ifndef HALF_ERRHANDLING_OVERFLOW_TO_INEXACT
367 #define HALF_ERRHANDLING_OVERFLOW_TO_INEXACT 1
370 #ifndef HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
377 #define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT 1
398 #ifndef HALF_ROUND_STYLE
399 #define HALF_ROUND_STYLE 1
407 #define HUGE_VALH std::numeric_limits<half_float::half>::infinity()
414 #define FP_FAST_FMAH 1
421 #define HLF_ROUNDS HALF_ROUND_STYLE
424 #define FP_ILOGB0 INT_MIN
427 #define FP_ILOGBNAN INT_MAX
430 #define FP_SUBNORMAL 0
439 #define FP_INFINITE 3
445 #if !HALF_ENABLE_CPP11_CFENV && !defined(MU_HALF_FE_ALL_EXCEPT)
446 #define MU_HALF_FE_INVALID 0x10
447 #define MU_HALF_FE_DIVBYZERO 0x08
448 #define MU_HALF_FE_OVERFLOW 0x04
449 #define MU_HALF_FE_UNDERFLOW 0x02
450 #define MU_HALF_FE_INEXACT 0x01
451 #define MU_HALF_FE_ALL_EXCEPT (MU_HALF_FE_INVALID | MU_HALF_FE_DIVBYZERO | MU_HALF_FE_OVERFLOW | MU_HALF_FE_UNDERFLOW | MU_HALF_FE_INEXACT)
460 #if HALF_ENABLE_CPP11_USER_LITERALS
469 half operator"" _h(
long double);
477 #if HALF_ENABLE_CPP11_TYPE_TRAITS
479 template <
bool B,
typename T,
typename F>
486 struct bool_type : std::integral_constant<bool, B>
493 template <
typename T>
494 struct is_float : std::is_floating_point<T>
499 template <
bool,
typename T,
typename>
504 template <
typename T,
typename F>
523 template <
typename T>
527 template <
typename T>
531 template <
typename T>
550 template <
typename T>
555 template <
typename T>
559 template <
typename T>
563 template <
typename T>
568 #if HALF_ENABLE_CPP11_CSTDINT
570 typedef std::uint_least16_t
uint16;
573 typedef std::uint_fast32_t
uint32;
576 typedef std::int_fast32_t
int32;
582 typedef std::uint_least32_t
type;
589 typedef std::uint_least64_t
type;
603 struct bits<float> :
conditional<std::numeric_limits<unsigned int>::digits >= 32, unsigned int, unsigned long>
607 #if HALF_ENABLE_CPP11_LONG_LONG
610 struct bits<double> :
conditional<std::numeric_limits<unsigned long>::digits >= 64, unsigned long, unsigned long long>
618 typedef unsigned long type;
623 #ifdef HALF_ARITHMETIC_TYPE
625 typedef HALF_ARITHMETIC_TYPE internal_t;
644 template <
typename T>
647 #if HALF_ENABLE_CPP11_CMATH
649 #elif defined(_MSC_VER)
650 return !::_finite(
static_cast<double>(arg)) && !::_isnan(
static_cast<double>(arg));
652 return arg == std::numeric_limits<T>::infinity() || arg == -std::numeric_limits<T>::infinity();
661 template <
typename T>
664 #if HALF_ENABLE_CPP11_CMATH
666 #elif defined(_MSC_VER)
667 return ::_isnan(
static_cast<double>(arg)) != 0;
678 template <
typename T>
681 #if HALF_ENABLE_CPP11_CMATH
684 return arg < T() || (arg == T() && T(1) / arg < T());
694 static const int N = std::numeric_limits<uint32>::digits - 1;
695 #if HALF_TWOS_COMPLEMENT_INT
696 return static_cast<int32>(arg) >> N;
698 return -((arg >> N) & 1);
708 #if HALF_TWOS_COMPLEMENT_INT
709 return static_cast<int32>(arg) >> i;
711 return static_cast<int32>(arg) / (
static_cast<int32>(1) << i) - ((arg >> (std::numeric_limits<uint32>::digits - 1)) & 1);
735 #if HALF_ERRHANDLING_FLAGS
738 #if HALF_ERRHANDLING_ERRNO
744 #if HALF_ERRHANDLING_FENV && HALF_ENABLE_CPP11_CFENV
747 #ifdef HALF_ERRHANDLING_THROW_INVALID
749 throw std::domain_error(HALF_ERRHANDLING_THROW_INVALID);
751 #ifdef HALF_ERRHANDLING_THROW_DIVBYZERO
753 throw std::domain_error(HALF_ERRHANDLING_THROW_DIVBYZERO);
755 #ifdef HALF_ERRHANDLING_THROW_OVERFLOW
757 throw std::overflow_error(HALF_ERRHANDLING_THROW_OVERFLOW);
759 #ifdef HALF_ERRHANDLING_THROW_UNDERFLOW
761 throw std::underflow_error(HALF_ERRHANDLING_THROW_UNDERFLOW);
763 #ifdef HALF_ERRHANDLING_THROW_INEXACT
765 throw std::range_error(HALF_ERRHANDLING_THROW_INEXACT);
767 #if HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
771 #if HALF_ERRHANDLING_OVERFLOW_TO_INEXACT
789 return (x & 0x7FFF) > 0x7C00 || (y & 0x7FFF) > 0x7C00;
812 raise(
MU_HALF_FE_INVALID, ((x & 0x7FFF) > 0x7C00 && !(x & 0x200)) || ((y & 0x7FFF) > 0x7C00 && !(y & 0x200)));
814 return ((x & 0x7FFF) > 0x7C00) ? (x | 0x200) : (y | 0x200);
826 raise(
MU_HALF_FE_INVALID, ((x & 0x7FFF) > 0x7C00 && !(x & 0x200)) || ((y & 0x7FFF) > 0x7C00 && !(y & 0x200)) || ((z & 0x7FFF) > 0x7C00 && !(z & 0x200)));
828 return ((x & 0x7FFF) > 0x7C00) ? (x | 0x200) : ((y & 0x7FFF) > 0x7C00) ? (y | 0x200)
840 return (((y & 0x7FFF) > 0x7C00) && !(y & 0x200)) ?
signal(y) : x;
866 return sign | 0x7C00;
875 #if HALF_ERRHANDLING && !HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
890 template <std::
float_round_style R>
896 return (R == std::round_toward_infinity) ? (sign + 0x7C00 - (sign >> 15)) : (R == std::round_toward_neg_infinity) ? (sign + 0x7BFF + (sign >> 15))
897 : (R == std::round_toward_zero) ? (sign | 0x7BFF)
906 template <std::
float_round_style R>
912 return (R == std::round_toward_infinity) ? (sign + 1 - (sign >> 15)) : (R == std::round_toward_neg_infinity) ? (sign + (sign >> 15))
926 template <std::
float_round_style R,
bool I>
930 value += (R == std::round_to_nearest) ? (g & (s | value)) : (R == std::round_toward_infinity) ? (~(value >> 15) & (g | s))
931 : (R == std::round_toward_neg_infinity) ? ((value >> 15) & (g | s))
933 if ((value & 0x7C00) == 0x7C00)
935 else if (value & 0x7C00)
941 return (R == std::round_to_nearest) ? (value + (g & (s | value))) : (R == std::round_toward_infinity) ? (value + (~(value >> 15) & (g | s)))
942 : (R == std::round_toward_neg_infinity) ? (value + ((value >> 15) & (g | s)))
955 template <std::
float_round_style R,
bool E,
bool I>
956 unsigned int integral(
unsigned int value)
958 unsigned int abs = value & 0x7FFF;
962 return ((R == std::round_to_nearest) ? (0x3C00 & -
static_cast<unsigned>(
abs >= (0x3800 + E))) : (R == std::round_toward_infinity) ? (0x3C00 & -(~(value >> 15) & (
abs != 0)))
963 : (R == std::round_toward_neg_infinity) ? (0x3C00 & -
static_cast<unsigned>(value > 0x8000))
968 return (
abs > 0x7C00) ?
signal(value) : value;
969 unsigned int exp = 25 - (
abs >> 10), mask = (1 <<
exp) - 1;
971 return (((R == std::round_to_nearest) ? ((1 << (
exp - 1)) - (~(value >>
exp) & E)) : (R == std::round_toward_infinity) ? (mask & ((value >> 15) - 1))
972 : (R == std::round_toward_neg_infinity) ? (mask & -(value >> 15))
992 template <std::
float_round_style R,
unsigned int F,
bool S,
bool N,
bool I>
998 m = (m ^ msign) - msign;
999 sign = msign & 0x8000;
1002 for (; m < (static_cast<uint32>(1) << F) &&
exp; m <<= 1, --
exp)
1005 return rounded<R, I>(sign + (m >> (F - 10 -
exp)), (m >> (F - 11 -
exp)) & 1, s | ((m & ((
static_cast<uint32>(1) << (F - 11 -
exp)) - 1)) != 0));
1006 return rounded<R, I>(sign + (
exp << 10) + (m >> (F - 10)), (m >> (F - 11)) & 1, s | ((m & ((
static_cast<uint32>(1) << (F - 11)) - 1)) != 0));
1017 template <std::
float_round_style R>
1020 #if HALF_ENABLE_F16C_INTRINSICS
1021 return _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_set_ss(value),
1022 (R == std::round_to_nearest) ? _MM_FROUND_TO_NEAREST_INT : (R == std::round_toward_zero) ? _MM_FROUND_TO_ZERO
1023 : (R == std::round_toward_infinity) ? _MM_FROUND_TO_POS_INF
1024 : (R == std::round_toward_neg_infinity) ? _MM_FROUND_TO_NEG_INF
1025 : _MM_FROUND_CUR_DIRECTION));
1028 std::memcpy(&fbits, &value,
sizeof(
float));
1030 unsigned int sign = (fbits >> 16) & 0x8000;
1031 fbits &= 0x7FFFFFFF;
1032 if (fbits >= 0x7F800000)
1033 return sign | 0x7C00 | ((fbits > 0x7F800000) ? (0x200 | ((fbits >> 13) & 0x3FF)) : 0);
1034 if (fbits >= 0x47800000)
1035 return overflow<R>(sign);
1036 if (fbits >= 0x38800000)
1037 return rounded<R, false>(sign | (((fbits >> 23) - 112) << 10) | ((fbits >> 13) & 0x3FF), (fbits >> 12) & 1, (fbits & 0xFFF) != 0);
1038 if (fbits >= 0x33000000)
1040 int i = 125 - (fbits >> 23);
1041 fbits = (fbits & 0x7FFFFF) | 0x800000;
1042 return rounded<R, false>(sign | (fbits >> (i + 1)), (fbits >> i) & 1, (fbits & ((
static_cast<uint32>(1) << i) - 1)) != 0);
1045 return underflow<R>(sign);
1048 static const uint16 base_table[512] = {
1561 static const unsigned char shift_table[256] = {
1818 int sexp = fbits >> 23,
exp = sexp & 0xFF, i = shift_table[
exp];
1821 return rounded<R, false>(base_table[sexp] + (fbits >> i), (m >> (i - 1)) & 1, (((
static_cast<uint32>(1) << (i - 1)) - 1) & m) != 0);
1833 template <std::
float_round_style R>
1836 #if HALF_ENABLE_F16C_INTRINSICS
1837 if (R == std::round_indeterminate)
1838 return _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_cvtpd_ps(_mm_set_sd(value)), _MM_FROUND_CUR_DIRECTION));
1841 std::memcpy(&dbits, &value,
sizeof(
double));
1842 uint32 hi = dbits >> 32, lo = dbits & 0xFFFFFFFF;
1843 unsigned int sign = (hi >> 16) & 0x8000;
1845 if (hi >= 0x7FF00000)
1846 return sign | 0x7C00 | ((dbits & 0xFFFFFFFFFFFFF) ? (0x200 | ((hi >> 10) & 0x3FF)) : 0);
1847 if (hi >= 0x40F00000)
1848 return overflow<R>(sign);
1849 if (hi >= 0x3F100000)
1850 return rounded<R, false>(sign | (((hi >> 20) - 1008) << 10) | ((hi >> 10) & 0x3FF), (hi >> 9) & 1, ((hi & 0x1FF) | lo) != 0);
1851 if (hi >= 0x3E600000)
1853 int i = 1018 - (hi >> 20);
1854 hi = (hi & 0xFFFFF) | 0x100000;
1855 return rounded<R, false>(sign | (hi >> (i + 1)), (hi >> i) & 1, ((hi & ((
static_cast<uint32>(1) << i) - 1)) | lo) != 0);
1858 return underflow<R>(sign);
1870 template <std::
float_round_style R,
typename T>
1873 unsigned int hbits =
static_cast<unsigned>(
builtin_signbit(value)) << 15;
1877 return hbits | 0x7FFF;
1879 return hbits | 0x7C00;
1883 return overflow<R>(hbits);
1889 hbits |= ((
exp + 13) << 10);
1892 int m =
std::abs(
static_cast<int>(ival));
1893 return rounded<R, false>(hbits + (m >> 1), m & 1, frac != T());
1904 template <std::
float_round_style R,
typename T>
1907 return float2half_impl<R>(value,
bool_type<std::numeric_limits<T>::is_iec559 &&
sizeof(
typename bits<T>::type) ==
sizeof(T)>());
1917 template <std::
float_round_style R,
typename T>
1920 unsigned int bits =
static_cast<unsigned>(value < 0) << 15;
1926 return overflow<R>(
bits);
1927 unsigned int m =
static_cast<unsigned int>(value),
exp = 24;
1928 for (; m < 0x400; m <<= 1, --
exp)
1930 for (; m > 0x7FF; m >>= 1, ++
exp)
1933 return (
exp > 24) ? rounded<R, false>(
bits, (value >> (
exp - 25)) & 1, (((1 << (
exp - 25)) - 1) & value) != 0) :
bits;
1942 #if HALF_ENABLE_F16C_INTRINSICS
1943 return _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128(value)));
1947 int abs = value & 0x7FFF;
1950 fbits |= 0x38000000 <<
static_cast<unsigned>(
abs >= 0x7C00);
1951 for (;
abs < 0x400;
abs <<= 1, fbits -= 0x800000)
4070 static const unsigned short offset_table[64] = {
4135 bits<float>::type fbits = mantissa_table[offset_table[value >> 10] + (value & 0x3FF)] + exponent_table[value >> 10];
4138 std::memcpy(&out, &fbits,
sizeof(
float));
4148 #if HALF_ENABLE_F16C_INTRINSICS
4149 return _mm_cvtsd_f64(_mm_cvtps_pd(_mm_cvtph_ps(_mm_cvtsi32_si128(value))));
4152 unsigned int abs = value & 0x7FFF;
4155 hi |= 0x3F000000 <<
static_cast<unsigned>(
abs >= 0x7C00);
4156 for (;
abs < 0x400;
abs <<= 1, hi -= 0x100000)
4162 std::memcpy(&out, &dbits,
sizeof(
double));
4171 template <
typename T>
4175 unsigned int abs = value & 0x7FFF;
4177 out = (std::numeric_limits<T>::has_signaling_NaN && !(
abs & 0x200)) ? std::numeric_limits<T>::signaling_NaN() : std::numeric_limits<T>::has_quiet_NaN ? std::numeric_limits<T>::quiet_NaN()
4179 else if (
abs == 0x7C00)
4180 out = std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : std::numeric_limits<T>::max();
4181 else if (
abs > 0x3FF)
4182 out =
ldexp(
static_cast<T
>((
abs & 0x3FF) | 0x400), (
abs >> 10) - 25);
4184 out =
ldexp(
static_cast<T
>(
abs), -24);
4185 return (value & 0x8000) ? -out : out;
4192 template <
typename T>
4207 template <std::
float_round_style R,
bool E,
bool I,
typename T>
4210 unsigned int abs = value & 0x7FFF;
4214 return (value & 0x8000) ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max();
4219 return (R == std::round_toward_infinity) ? T(~(value >> 15) & (
abs != 0)) : (R == std::round_toward_neg_infinity) ? -T(value > 0x8000)
4222 int exp = 25 - (
abs >> 10);
4223 unsigned int m = (value & 0x3FF) | 0x400;
4224 int32 i =
static_cast<int32>((
exp <= 0) ? (m << -
exp) : ((m + ((R == std::round_to_nearest) ? ((1 << (
exp - 1)) - (~(m >>
exp) & E)) : (R == std::round_toward_infinity) ? (((1 <<
exp) - 1) & ((value >> 15) - 1))
4225 : (R == std::round_toward_neg_infinity) ? (((1 <<
exp) - 1) & -(value >> 15))
4228 if ((!std::numeric_limits<T>::is_signed && (value & 0x8000)) || (std::numeric_limits<T>::digits < 16 &&
4229 ((value & 0x8000) ? (-i < std::numeric_limits<T>::min()) : (i > std::numeric_limits<T>::max()))))
4231 else if (I &&
exp > 0 && (m & ((1 <<
exp) - 1)))
4233 return static_cast<T
>((value & 0x8000) ? -i : i);
4245 template <std::
float_round_style R>
4248 uint32 xy = (x >> 16) * (y & 0xFFFF), yx = (x & 0xFFFF) * (y >> 16), c = (xy & 0xFFFF) + (yx & 0xFFFF) + (((x & 0xFFFF) * (y & 0xFFFF)) >> 16);
4249 return (x >> 16) * (y >> 16) + (xy >> 16) + (yx >> 16) + (c >> 16) +
4250 ((R == std::round_to_nearest) ? ((c >> 15) & 1) : (R == std::round_toward_infinity) ? ((c & 0xFFFF) != 0)
4260 #if HALF_ENABLE_CPP11_LONG_LONG
4261 return static_cast<uint32>((
static_cast<unsigned long long>(x) *
static_cast<unsigned long long>(y) + 0x80000000) >> 32);
4263 return mulhi<std::round_to_nearest>(x, y);
4274 #if HALF_ENABLE_CPP11_LONG_LONG
4275 unsigned long long xx =
static_cast<unsigned long long>(x) << 32;
4276 return s = (xx % y != 0),
static_cast<uint32>(xx / y);
4280 for (
unsigned int i = 0; i < 32; ++i)
4290 return s = rem > 1, div;
4301 template <
bool Q,
bool R>
4302 unsigned int mod(
unsigned int x,
unsigned int y,
int* quo = NULL)
4307 int absx = x, absy = y, expx = 0, expy = 0;
4308 for (; absx < 0x400; absx <<= 1, --expx)
4310 for (; absy < 0x400; absy <<= 1, --expy)
4314 int mx = (absx & 0x3FF) | 0x400, my = (absy & 0x3FF) | 0x400;
4315 for (
int d = expx - expy; d; --d)
4325 q <<= static_cast<int>(Q);
4336 q &= (1 << (std::numeric_limits<int>::digits - 1)) - 1;
4340 for (; mx < 0x400; mx <<= 1, --expy)
4342 x = (expy > 0) ? ((expy << 10) | (mx & 0x3FF)) : (mx >> (1 - expy));
4349 a = (x < 0x400) ? (x << 1) : (x + 0x400);
4357 if (a > b || (a == b && (q & 1)))
4359 int exp = (y >> 10) + (y <= 0x3FF), d =
exp - (x >> 10) - (x <= 0x3FF);
4360 int m = (((y & 0x3FF) | ((y > 0x3FF) << 10)) << 1) - (((x & 0x3FF) | ((x > 0x3FF) << 10)) << (1 - d));
4361 for (; m < 0x800 && exp > 1; m <<= 1, --
exp)
4363 x = 0x8000 + ((
exp - 1) << 10) + (m >> 1);
4377 template <
unsigned int F>
4384 for (
uint32 bit =
static_cast<uint32>(1) << F; bit; bit >>= 2)
4404 static const uint32 logs[] = {
4439 uint32 mx = 0x80000000, my = 0;
4440 for (
unsigned int i = 1; i < n; ++i)
4442 uint32 mz = my + logs[i];
4459 static const uint32 logs[] = {
4492 if (m == 0x40000000)
4494 uint32 mx = 0x40000000, my = 0;
4495 for (
unsigned int i = 1; i < n; ++i)
4497 uint32 mz = mx + (mx >> i);
4512 inline std::pair<uint32, uint32>
sincos(
uint32 mz,
unsigned int n = 31)
4514 static const uint32 angles[] = {
4546 uint32 mx = 0x26DD3B6A, my = 0;
4547 for (
unsigned int i = 0; i < n; ++i)
4554 mz -= (angles[i] ^ sign) - sign;
4556 return std::make_pair(my, mx);
4567 static const uint32 angles[] = {
4600 for (
unsigned int i = 0; i < n; ++i)
4607 mz += (angles[i] ^ sign) - sign;
4619 int exp = (
abs >> 10) + (
abs <= 0x3FF) - 15;
4621 return k = 0, m << (
exp + 20);
4622 #if HALF_ENABLE_CPP11_LONG_LONG
4623 unsigned long long y = m * 0xA2F9836E4E442, mask = (1ULL << (62 -
exp)) - 1, yi = (y + (mask >> 1)) & ~mask, f = y - yi;
4625 k =
static_cast<int>(yi >> (62 -
exp));
4626 return (
multiply64(
static_cast<uint32>((sign ? -f : f) >> (31 -
exp)), 0xC90FDAA2) ^ sign) - sign;
4628 uint32 yh = m * 0xA2F98 + mulhi<std::round_toward_zero>(m, 0x36E4E442), yl = (m * 0x36E4E442) & 0xFFFFFFFF;
4629 uint32 mask = (
static_cast<uint32>(1) << (30 -
exp)) - 1, yi = (yh + (mask >> 1)) & ~mask, sign = -
static_cast<uint32>(yi > yh);
4630 k =
static_cast<int>(yi >> (30 -
exp));
4631 uint32 fh = (yh ^ sign) + (yi ^ ~sign) - ~sign, fl = (yl ^ sign) - sign;
4632 return (
multiply64((
exp > -1) ? (((fh << (1 +
exp)) & 0xFFFFFFFF) | ((fl & 0xFFFFFFFF) >> (31 -
exp))) : fh, 0xC90FDAA2) ^ sign) - sign;
4639 inline std::pair<uint32, uint32>
atan2_args(
unsigned int abs)
4645 uint32 my = ((
abs & 0x3FF) | 0x400) << 5, r = my * my;
4647 r = 0x40000000 - ((rexp > -31) ? ((r >> -rexp) | ((r & ((
static_cast<uint32>(1) << -rexp) - 1)) != 0)) : 1);
4648 for (rexp = 0; r < 0x40000000; r <<= 1, --rexp)
4650 uint32 mx = sqrt<30>(r, rexp);
4653 return std::make_pair((d < -14) ? ((my >> (-d - 14)) + ((my >> (-d - 15)) & 1)) : (my << (14 + d)), (mx << 14) + (r << 13) / mx);
4655 return std::make_pair(my << 14, (d > 14) ? ((mx >> (d - 14)) + ((mx >> (d - 15)) & 1)) : ((d == 14) ? mx : ((mx << (14 - d)) + (r << (13 - d)) / mx)));
4656 return std::make_pair(my << 13, (mx << 13) + (r << 12) / mx);
4667 int e = (
abs >> 10) + (
abs <= 0x3FF);
4675 exp = mx >> (45 - e);
4676 mx = (mx << (e - 14)) & 0x7FFFFFFF;
4679 int d =
exp << 1, s;
4680 if (mx > 0x80000000)
4688 return std::make_pair(mx, (d < 31) ? ((my >> d) | ((my & ((
static_cast<uint32>(1) << d) - 1)) != 0)) : 1);
4702 template <std::
float_round_style R>
4703 unsigned int exp2_post(
uint32 m,
int exp,
bool esign,
unsigned int sign = 0,
unsigned int n = 32)
4709 return underflow<R>(sign);
4710 else if (
exp == -25)
4711 return rounded<R, false>(sign, 1, m != 0);
4714 return overflow<R>(sign);
4721 return fixed2half<R, 31, false, false, true>(m,
exp + 14, sign, s);
4735 template <std::
float_round_style R, u
int32 L>
4739 m = (((
static_cast<uint32>(ilog) << 27) + (m >> 4)) ^ msign) - msign;
4742 for (; m < 0x80000000; m <<= 1, --
exp)
4747 sign ^= msign & 0x8000;
4749 return underflow<R>(sign);
4751 return fixed2half<R, 30, false, false, true>(m,
exp, sign, 1);
4762 template <std::
float_round_style R>
4766 if ((
exp += i) > 46)
4767 return overflow<R>();
4769 return underflow<R>();
4770 r = (r >> i) | (r & i);
4772 return fixed2half<R, 15, false, false, false>(m,
exp - 1, 0, r != 0);
4785 template <std::
float_round_style R>
4788 int i = my >= mx, s;
4791 return overflow<R>(sign);
4793 return underflow<R>(sign);
4795 return fixed2half<R, 30, false, false, true>(m,
exp, sign, s);
4807 template <std::
float_round_style R,
bool S>
4808 unsigned int area(
unsigned int arg)
4810 int abs = arg & 0x7FFF, expx = (
abs >> 10) + (
abs <= 0x3FF) - 15, expy = -15, ilog, i;
4812 for (;
abs < 0x400;
abs <<= 1, --expy)
4815 r = ((
abs & 0x3FF) | 0x400) << 5;
4818 expy = 2 * expy + i;
4824 r = 0x40000000 + ((expy > -30) ? ((r >> -expy) | ((r & ((
static_cast<uint32>(1) << -expy) - 1)) != 0)) : 1);
4829 r += 0x40000000 >> expy;
4831 r = (r >> i) | (r & i);
4837 r -= 0x40000000 >> expy;
4838 for (; r < 0x40000000; r <<= 1, --expy)
4841 my = sqrt<30>(r, expy);
4842 my = (my << 15) + (r << 14) / my;
4855 static const int G = S && (R == std::round_to_nearest);
4856 return log2_post<R, 0xB8AA3B2A>(
log2(my >> i, 26 + S + G) + (G << 3), ilog + i, 17, arg & (
static_cast<unsigned>(S) << 15));
4878 m =
static_cast<uint32>((
abs & 0x3FF) | 0x400) << 21;
4891 uint32 m = a.
m + ((d < 32) ? (b.
m >> d) : 0);
4892 int i = (
m & 0xFFFFFFFF) < a.
m;
4893 return f31(((
m + i) >> i) | 0x80000000, a.
exp + i);
4903 uint32 m = a.
m - ((d < 32) ? (b.
m >> d) : 0);
4906 for (;
m < 0x80000000;
m <<= 1, --
exp)
4928 int i = a.
m >= b.
m, s;
4947 template <std::
float_round_style R,
bool C>
4948 unsigned int erf(
unsigned int arg)
4950 unsigned int abs = arg & 0x7FFF, sign = arg & 0x8000;
4951 f31 x(
abs), x2 = x * x *
f31(0xB8AA3B29, 0), t =
f31(0x80000000, 0) / (
f31(0x80000000, 0) +
f31(0xA7BA054A, -2) * x), t2 = t * t;
4952 f31 e = ((
f31(0x87DC2213, 0) * t2 +
f31(0xB5F0E2AE, 0)) * t2 +
f31(0x82790637, -2) - (
f31(0xBA00E2B8, 0) * t2 +
f31(0x91A98E62, -2)) * t) * t /
4954 return (!C || sign) ? fixed2half<R, 31, false, true, true>(0x80000000 - (e.
m >> (C - e.
exp)), 14 + C, sign & (C - 1U)) : (e.
exp < -25) ? underflow<R>()
4955 : fixed2half<R, 30, false, false, true>(e.
m >> 1, e.
exp + 14, 0, e.
m & 1);
4967 template <std::
float_round_style R,
bool L>
4968 unsigned int gamma(
unsigned int arg)
4976 static const f31 pi(0xC90FDAA2, 1), lbe(0xB8AA3B29, 0);
4977 unsigned int abs = arg & 0x7FFF, sign = arg & 0x8000;
4978 bool bsign = sign != 0;
4979 f31 z(
abs), x = sign ? (z +
f31(0x80000000, 0)) : z, t = x +
f31(0x94CCCCCD, 2), s =
f31(0xA06C9901, 1) +
f31(0xBBE654E2, -7) / (x +
f31(0x80000000, 2)) +
f31(0xA1CE6098, 6) / (x +
f31(0x80000000, 1)) +
f31(0xE1868CB7, 7) / x -
f31(0x8625E279, 8) / (x +
f31(0x80000000, 0)) -
f31(0xA03E158F, 2) / (x +
f31(0xC0000000, 1));
4980 int i = (s.exp >= 2) + (s.exp >= 4) + (s.exp >= 8) + (s.exp >= 16);
4981 s =
f31((
static_cast<uint32>(s.exp) << (31 - i)) + (
log2(s.m >> 1, 28) >> i), i) / lbe;
4982 if (x.
exp != -1 || x.
m != 0x80000000)
4984 i = (t.exp >= 2) + (t.exp >= 4) + (t.exp >= 8);
4985 f31 l =
f31((
static_cast<uint32>(t.exp) << (31 - i)) + (
log2(t.m >> 1, 30) >> i), i) / lbe;
4986 s = (x.
exp < -1) ? (s - (
f31(0x80000000, -1) - x) * l) : (s + (x -
f31(0x80000000, -1)) * l);
4988 s = x.
exp ? (s - t) : (t - s);
4993 sign &= (L | ((z.m >> (31 - z.exp)) & 1)) - 1;
4994 for (z =
f31((z.m << (1 + z.exp)) & 0xFFFFFFFF, -1); z.
m < 0x80000000; z.m <<= 1, --z.exp)
4998 z =
f31(0x80000000, 0) - z;
5002 z.
m =
sincos(z.m >> (1 - z.exp), 30).first;
5003 for (z.exp = 1; z.m < 0x80000000; z.m <<= 1, --z.exp)
5007 z =
f31(0x80000000, 0);
5013 f31 l(0x92868247, 0);
5017 z =
f31(-((
static_cast<uint32>(z.exp) << 26) + (m >> 5)), 5);
5018 for (; z.m < 0x80000000; z.m <<= 1, --z.exp)
5022 sign =
static_cast<unsigned>(x.
exp && (l.
exp < s.exp || (l.
exp == s.exp && l.
m < s.m))) << 15;
5023 s = sign ? (s - l) : x.
exp ? (l - s)
5028 sign =
static_cast<unsigned>(x.
exp == 0) << 15;
5030 return underflow<R>(sign);
5032 return overflow<R>(sign);
5046 m = (s.m << s.exp) & 0x7FFFFFFF;
5047 s.exp = (s.m >> (31 - s.exp));
5051 s =
f31(0x80000000, 0) / s;
5058 return underflow<R>(sign);
5060 else if (z.exp > 0 && !(z.m & ((1 << (31 - z.exp)) - 1)))
5061 return ((s.exp + 14) << 10) + (s.m >> 21);
5063 return overflow<R>(sign);
5065 return fixed2half<R, 31, false, false, true>(s.m, s.exp + 14, sign);
5069 template <
typename,
typename, std::
float_round_style>
5113 operator float()
const
5115 return detail::half2float<float>(data_);
5124 data_ =
static_cast<detail::uint16>(detail::float2half<round_style>(rhs));
5139 return *
this = *
this + rhs;
5149 return *
this = *
this - rhs;
5159 return *
this = *
this * rhs;
5169 return *
this = *
this / rhs;
5178 return *
this = *
this + rhs;
5187 return *
this = *
this - rhs;
5196 return *
this = *
this * rhs;
5205 return *
this = *
this / rhs;
5251 static const std::float_round_style round_style = (std::float_round_style)(
HALF_ROUND_STYLE);
5262 #ifndef HALF_DOXYGEN_ONLY
5326 #ifdef HALF_ENABLE_CPP11_LONG_LONG
5327 friend long long llround(
half);
5328 friend long long llrint(
half);
5349 template <
typename,
typename, std::
float_round_style>
5351 friend class std::numeric_limits<
half>;
5352 #if HALF_ENABLE_CPP11_HASH
5353 friend struct std::hash<
half>;
5355 #if HALF_ENABLE_CPP11_USER_LITERALS
5356 friend half literal::operator
"" _h(
long double);
5361 #if HALF_ENABLE_CPP11_USER_LITERALS
5371 inline half operator"" _h(
long double value)
5386 template <
typename T,
typename U, std::
float_round_style R = (std::
float_round_style)(HALF_ROUND_STYLE)>
5390 template <
typename U, std::
float_round_style R>
5393 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
5394 static_assert(std::is_arithmetic<U>::value,
"half_cast from non-arithmetic type unsupported");
5412 template <
typename T, std::
float_round_style R>
5415 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
5416 static_assert(std::is_arithmetic<T>::value,
"half_cast to non-arithmetic type unsupported");
5427 return half2float<T>(arg.data_);
5431 return half2int<R, true, true, T>(arg.data_);
5434 template <std::
float_round_style R>
5490 #if HALF_ERRHANDLING_THROWS
5582 #if HALF_ENABLE_CPP11_HASH
5594 typedef size_t result_type;
5599 result_type operator()(argument_type arg)
const
5601 return hash<half_float::detail::uint16>()(arg.data_ & -
static_cast<unsigned>(arg.data_ != 0x8000));
5621 return !
detail::compsignal(x.data_, y.data_) && (x.data_ == y.data_ || !((x.data_ | y.data_) & 0x7FFF));
5632 return detail::compsignal(x.data_, y.data_) || (x.data_ != y.data_ && ((x.data_ | y.data_) & 0x7FFF));
5644 ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) < ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15));
5656 ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) > ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15));
5668 ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) <= ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15));
5680 ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) >= ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15));
5713 #ifdef HALF_ARITHMETIC_TYPE
5714 return half(
detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_) + detail::half2float<detail::internal_t>(y.data_)));
5716 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF;
5717 bool sub = ((x.data_ ^ y.data_) & 0x8000) != 0;
5718 if (absx >= 0x7C00 || absy >= 0x7C00)
5723 return absy ? y :
half(
detail::binary, (half::round_style == std::round_toward_neg_infinity) ? (x.data_ | y.data_) : (x.data_ & y.data_));
5726 unsigned int sign = ((sub && absy > absx) ? y.data_ : x.data_) & 0x8000;
5728 std::swap(absx, absy);
5729 int exp = (absx >> 10) + (absx <= 0x3FF), d =
exp - (absy >> 10) - (absy <= 0x3FF), mx = ((absx & 0x3FF) | ((absx > 0x3FF) << 10)) << 3, my;
5732 my = ((absy & 0x3FF) | ((absy > 0x3FF) << 10)) << 3;
5733 my = (my >> d) | ((my & ((1 << d) - 1)) != 0);
5740 return half(
detail::binary,
static_cast<unsigned>(half::round_style == std::round_toward_neg_infinity) << 15);
5741 for (; mx < 0x2000 && exp > 1; mx <<= 1, --
exp)
5748 if ((
exp += i) > 30)
5750 mx = (mx >> i) | (mx & i);
5752 return half(
detail::binary, detail::rounded<half::round_style, false>(sign + ((
exp - 1) << 10) + (mx >> 3), (mx >> 2) & 1, (mx & 0x3) != 0));
5765 #ifdef HALF_ARITHMETIC_TYPE
5766 return half(
detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_) - detail::half2float<detail::internal_t>(y.data_)));
5781 #ifdef HALF_ARITHMETIC_TYPE
5782 return half(
detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_) * detail::half2float<detail::internal_t>(y.data_)));
5784 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF,
exp = -16;
5785 unsigned int sign = (x.data_ ^ y.data_) & 0x8000;
5786 if (absx >= 0x7C00 || absy >= 0x7C00)
5791 for (; absx < 0x400; absx <<= 1, --
exp)
5793 for (; absy < 0x400; absy <<= 1, --
exp)
5796 int i = m >> 21, s = m & i;
5797 exp += (absx >> 10) + (absy >> 10) + i;
5802 return half(
detail::binary, detail::fixed2half<half::round_style, 20, false, false, false>(m >> i,
exp, sign, s));
5816 #ifdef HALF_ARITHMETIC_TYPE
5817 return half(
detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_) / detail::half2float<detail::internal_t>(y.data_)));
5819 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF,
exp = 14;
5820 unsigned int sign = (x.data_ ^ y.data_) & 0x8000;
5821 if (absx >= 0x7C00 || absy >= 0x7C00)
5823 : (sign | ((absx == 0x7C00) ? 0x7C00 : 0)));
5828 for (; absx < 0x400; absx <<= 1, --
exp)
5830 for (; absy < 0x400; absy <<= 1, ++
exp)
5832 detail::uint32 mx = (absx & 0x3FF) | 0x400, my = (absy & 0x3FF) | 0x400;
5834 exp += (absx >> 10) - (absy >> 10) - i;
5841 return half(
detail::binary, detail::fixed2half<half::round_style, 11, false, false, false>(mx / my,
exp, sign, mx % my != 0));
5918 unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000;
5919 if (absx >= 0x7C00 || absy >= 0x7C00)
5939 unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000;
5940 if (absx >= 0x7C00 || absy >= 0x7C00)
5959 unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, value = x.data_ & 0x8000;
5960 if (absx >= 0x7C00 || absy >= 0x7C00)
5962 : (*quo = 0, x.data_));
5965 bool qsign = ((value ^ y.data_) & 0x8000) != 0;
5968 value ^= detail::mod<true, true>(absx, absy, &q);
5984 #ifdef HALF_ARITHMETIC_TYPE
5985 detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_), fz = detail::half2float<detail::internal_t>(z.data_);
5986 #if HALF_ENABLE_CPP11_CMATH && FP_FAST_FMA
5992 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF,
exp = -15;
5993 unsigned int sign = (x.data_ ^ y.data_) & 0x8000;
5994 bool sub = ((sign ^ z.data_) & 0x8000) != 0;
5995 if (absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
6000 return absz ? z :
half(
detail::binary, (half::round_style == std::round_toward_neg_infinity) ? (z.data_ | sign) : (z.data_ & sign));
6001 for (; absx < 0x400; absx <<= 1, --
exp)
6003 for (; absy < 0x400; absy <<= 1, --
exp)
6007 exp += (absx >> 10) + (absy >> 10) + i;
6012 for (; absz < 0x400; absz <<= 1, --expz)
6016 if (expz >
exp || (expz ==
exp && mz > m))
6019 std::swap(
exp, expz);
6021 sign = z.data_ & 0x8000;
6024 mz = (d < 23) ? ((mz >> d) | ((mz & ((
static_cast<detail::uint32>(1) << d) - 1)) != 0)) : 1;
6029 return half(
detail::binary,
static_cast<unsigned>(half::round_style == std::round_toward_neg_infinity) << 15);
6030 for (; m < 0x800000; m <<= 1, --
exp)
6037 m = (m >> i) | (m & i);
6045 return half(
detail::binary, detail::fixed2half<half::round_style, 23, false, false, false>(m,
exp - 1, sign));
6083 return (x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) <= (y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) ?
half(
detail::binary, 0) : (x - y);
6092 unsigned int value = 0x7FFF;
6094 value ^=
static_cast<unsigned>(*arg++) & 0xFF;
6113 #ifdef HALF_ARITHMETIC_TYPE
6114 return half(
detail::binary, detail::float2half<half::round_style>(
std::exp(detail::half2float<detail::internal_t>(arg.data_))));
6116 int abs = arg.data_ & 0x7FFF, e = (
abs >> 10) + (
abs <= 0x3FF),
exp;
6122 return half(
detail::binary, (arg.data_ & 0x8000) ? detail::underflow<half::round_style>() : detail::overflow<half::round_style>());
6131 exp = m >> (45 - e);
6132 m = (m << (e - 14)) & 0x7FFFFFFF;
6134 return half(
detail::binary, detail::exp2_post<half::round_style>(m,
exp, (arg.data_ & 0x8000) != 0, 0, 26));
6148 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
6151 int abs = arg.data_ & 0x7FFF, e = (
abs >> 10) + (
abs <= 0x3FF),
exp = (
abs & 0x3FF) + ((
abs > 0x3FF) << 10);
6157 return half(
detail::binary, (arg.data_ & 0x8000) ? detail::underflow<half::round_style>() : detail::overflow<half::round_style>());
6173 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
6176 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000, e = (
abs >> 10) + (
abs <= 0x3FF),
exp;
6182 return half(
detail::binary, (arg.data_ & 0x8000) ? detail::rounded<half::round_style, true>(0xBBFF, 1, 1) : detail::overflow<half::round_style>());
6191 exp = m >> (45 - e);
6192 m = (m << (e - 14)) & 0x7FFFFFFF;
6203 m = 0x80000000 - ((m >>
exp) | ((m & ((
static_cast<detail::uint32>(1) <<
exp) - 1)) != 0) | s);
6207 m -= (
exp < 31) ? (0x80000000 >>
exp) : 1;
6208 for (
exp += 14; m < 0x80000000 &&
exp; m <<= 1, --
exp)
6212 return half(
detail::binary, detail::rounded<half::round_style, true>(sign + (
exp << 10) + (m >> 21), (m >> 20) & 1, (m & 0xFFFFF) != 0));
6227 #ifdef HALF_ARITHMETIC_TYPE
6228 return half(
detail::binary, detail::float2half<half::round_style>(
std::log(detail::half2float<detail::internal_t>(arg.data_))));
6230 int abs = arg.data_ & 0x7FFF,
exp = -15;
6233 if (arg.data_ & 0x8000)
6255 #ifdef HALF_ARITHMETIC_TYPE
6258 int abs = arg.data_ & 0x7FFF,
exp = -15;
6261 if (arg.data_ & 0x8000)
6294 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
6297 int abs = arg.data_ & 0x7FFF,
exp = -15, s = 0;
6300 if (arg.data_ & 0x8000)
6311 unsigned int value =
static_cast<unsigned>(
exp < 0) << 15, m =
std::abs(
exp) << 6;
6312 for (
exp = 18; m < 0x400; m <<= 1, --
exp)
6319 for (
exp = 14; m < 0x8000000 &&
exp; m <<= 1, --
exp)
6321 for (; m > 0xFFFFFFF; m >>= 1, ++
exp)
6323 return half(
detail::binary, detail::fixed2half<half::round_style, 27, false, false, true>(m,
exp, sign & 0x8000, s));
6339 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
6342 if (arg.data_ >= 0xBC00)
6345 int abs = arg.data_ & 0x7FFF,
exp = -15;
6346 if (!
abs ||
abs >= 0x7C00)
6352 if (arg.data_ & 0x8000)
6354 m = 0x40000000 - (m >> -
exp);
6355 for (
exp = 0; m < 0x40000000; m <<= 1, --
exp)
6362 m = 0x40000000 + (m >> -
exp);
6367 m += 0x40000000 >>
exp;
6392 #ifdef HALF_ARITHMETIC_TYPE
6395 int abs = arg.data_ & 0x7FFF,
exp = 15;
6396 if (!
abs || arg.data_ >= 0x7C00)
6402 return half(
detail::binary, detail::rounded<half::round_style, false>((
exp << 10) + (m & 0x3FF), r > m, r != 0));
6415 #ifdef HALF_ARITHMETIC_TYPE
6416 return half(
detail::binary, detail::float2half<half::round_style>(detail::internal_t(1) /
std::sqrt(detail::half2float<detail::internal_t>(arg.data_))));
6418 unsigned int abs = arg.data_ & 0x7FFF, bias = 0x4000;
6419 if (!
abs || arg.data_ >= 0x7C00)
6423 for (;
abs < 0x400;
abs <<= 1, bias -= 0x400)
6425 unsigned int frac = (
abs += bias) & 0x7FF;
6428 if ((half::round_style == std::round_to_nearest && (frac == 0x3FE || frac == 0x76C)) ||
6429 (half::round_style != std::round_to_nearest && (frac == 0x15A || frac == 0x3FC || frac == 0x401 || frac == 0x402 || frac == 0x67B)))
6431 detail::uint32 f = 0x17376 -
abs, mx = (
abs & 0x3FF) | 0x400, my = ((f >> 1) & 0x3FF) | 0x400, mz = my * my;
6432 int expy = (f >> 11) - 31, expx = 32 - (
abs >> 10), i = mz >> 21;
6433 for (mz = 0x60000000 - (((mz >> i) * mx) >> (expx - 2 * expy - i)); mz < 0x40000000; mz <<= 1, --expy)
6435 i = (my *= mz >> 10) >> 31;
6437 my = (my >> (20 + i)) + 1;
6438 i = (mz = my * my) >> 21;
6439 for (mz = 0x60000000 - (((mz >> i) * mx) >> (expx - 2 * expy - i)); mz < 0x40000000; mz <<= 1, --expy)
6441 i = (my *= (mz >> 10) + 1) >> 31;
6442 return half(
detail::binary, detail::fixed2half<half::round_style, 30, false, false, true>(my >> i, expy + i + 14));
6456 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
6459 int abs = arg.data_ & 0x7FFF,
exp = -15;
6460 if (!
abs ||
abs == 0x3C00 ||
abs >= 0x7C00)
6464 detail::uint32 ilog =
exp + (
abs >> 10), sign =
detail::sign_mask(ilog), f, m = (((ilog << 27) + (detail::log2(static_cast<detail::uint32>((
abs & 0x3FF) | 0x400) << 20, 24) >> 4)) ^ sign) - sign;
6465 for (
exp = 2; m < 0x80000000; m <<= 1, --
exp)
6478 f = (m <<
exp) & 0x7FFFFFFF;
6481 m =
detail::exp2(f, (half::round_style == std::round_to_nearest) ? 29 : 26);
6491 return half(
detail::binary, (half::round_style == std::round_to_nearest) ? detail::fixed2half<half::round_style, 31, false, false, false>(m,
exp + 14, arg.data_ & 0x8000) : detail::fixed2half<half::round_style, 23, false, false, false>((m + 0x80) >> 8,
exp + 14, arg.data_ & 0x8000));
6506 #ifdef HALF_ARITHMETIC_TYPE
6507 detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_);
6508 #if HALF_ENABLE_CPP11_CMATH
6514 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, expx = 0, expy = 0;
6515 if (absx >= 0x7C00 || absy >= 0x7C00)
6523 std::swap(absx, absy);
6524 for (; absx < 0x400; absx <<= 1, --expx)
6526 for (; absy < 0x400; absy <<= 1, --expy)
6528 detail::uint32 mx = (absx & 0x3FF) | 0x400, my = (absy & 0x3FF) | 0x400;
6531 int ix = mx >> 21, iy = my >> 21;
6532 expx = 2 * (expx + (absx >> 10)) - 15 + ix;
6533 expy = 2 * (expy + (absy >> 10)) - 15 + iy;
6536 int d = expx - expy;
6537 my = (d < 30) ? ((my >> d) | ((my & ((
static_cast<detail::uint32>(1) << d) - 1)) != 0)) : 1;
6554 #ifdef HALF_ARITHMETIC_TYPE
6555 detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_), fz = detail::half2float<detail::internal_t>(z.data_);
6558 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, expx = 0, expy = 0, expz = 0;
6565 if (absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
6570 std::swap(absy, absz);
6572 std::swap(absx, absy);
6574 std::swap(absy, absz);
6575 for (; absx < 0x400; absx <<= 1, --expx)
6577 for (; absy < 0x400; absy <<= 1, --expy)
6579 for (; absz < 0x400; absz <<= 1, --expz)
6581 detail::uint32 mx = (absx & 0x3FF) | 0x400, my = (absy & 0x3FF) | 0x400, mz = (absz & 0x3FF) | 0x400;
6585 int ix = mx >> 21, iy = my >> 21, iz = mz >> 21;
6586 expx = 2 * (expx + (absx >> 10)) - 15 + ix;
6587 expy = 2 * (expy + (absy >> 10)) - 15 + iy;
6588 expz = 2 * (expz + (absz >> 10)) - 15 + iz;
6592 int d = expy - expz;
6593 mz = (d < 30) ? ((mz >> d) | ((mz & ((
static_cast<detail::uint32>(1) << d) - 1)) != 0)) : 1;
6595 if (my & 0x80000000)
6597 my = (my >> 1) | (my & 1);
6601 std::swap(expx, expy);
6605 my = (d < 30) ? ((my >> d) | ((my & ((
static_cast<detail::uint32>(1) << d) - 1)) != 0)) : 1;
6622 #ifdef HALF_ARITHMETIC_TYPE
6623 return half(
detail::binary, detail::float2half<half::round_style>(
std::pow(detail::half2float<detail::internal_t>(x.data_), detail::half2float<detail::internal_t>(y.data_))));
6625 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF,
exp = -15;
6626 if (!absy || x.data_ == 0x3C00)
6628 bool is_int = absy >= 0x6400 || (absy >= 0x3C00 && !(absy & ((1 << (25 - (absy >> 10))) - 1)));
6629 unsigned int sign = x.data_ & (
static_cast<unsigned>((absy < 0x6800) && is_int && ((absy >> (25 - (absy >> 10))) & 1)) << 15);
6630 if (absx >= 0x7C00 || absy >= 0x7C00)
6632 : (0x7C00 & -((y.data_ >> 15) ^ (absx > 0x3C00))))
6633 : (sign | (0x7C00 & ((y.data_ >> 15) - 1U))));
6636 if ((x.data_ & 0x8000) && !is_int)
6638 if (x.data_ == 0xBC00)
6651 for (; absx < 0x400; absx <<= 1, --
exp)
6653 detail::uint32 ilog =
exp + (absx >> 10), msign =
detail::sign_mask(ilog), f, m = (((ilog << 27) + ((detail::log2(static_cast<detail::uint32>((absx & 0x3FF) | 0x400) << 20) + 8) >> 4)) ^ msign) - msign;
6654 for (
exp = -11; m < 0x80000000; m <<= 1, --
exp)
6656 for (; absy < 0x400; absy <<= 1, --
exp)
6660 exp += (absy >> 10) + i;
6669 f = (m <<
exp) & 0x7FFFFFFF;
6672 return half(
detail::binary, detail::exp2_post<half::round_style>(f,
exp, ((msign & 1) ^ (y.data_ >> 15)) != 0, sign));
6692 #ifdef HALF_ARITHMETIC_TYPE
6693 detail::internal_t f = detail::half2float<detail::internal_t>(arg.data_);
6697 int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15, k;
6705 else if (
abs < 0x2500)
6712 if (half::round_style != std::round_to_nearest)
6717 *
sin =
half(
detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x1D07, 1, 1));
6721 *
sin =
half(
detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x3BFF, 1, 1));
6725 *
sin =
half(
detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x3BFE, 1, 1));
6729 *
sin =
half(
detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x0FE6, 1, 1));
6738 sc = std::make_pair(sc.second, -sc.first);
6741 sc = std::make_pair(-sc.first, -sc.second);
6744 sc = std::make_pair(-sc.second, sc.first);
6748 *
cos =
half(
detail::binary, detail::fixed2half<half::round_style, 30, true, true, true>(sc.second));
6763 #ifdef HALF_ARITHMETIC_TYPE
6764 return half(
detail::binary, detail::float2half<half::round_style>(
std::sin(detail::half2float<detail::internal_t>(arg.data_))));
6766 int abs = arg.data_ & 0x7FFF, k;
6772 return half(
detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
6773 if (half::round_style != std::round_to_nearest)
6777 return half(
detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x1D07, 1, 1));
6779 return half(
detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x3BFE, 1, 1));
6781 return half(
detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x0FE6, 1, 1));
6785 return half(
detail::binary, detail::fixed2half<half::round_style, 30, true, true, true>((((k & 1) ? sc.second : sc.first) ^ sign) - sign));
6799 #ifdef HALF_ARITHMETIC_TYPE
6800 return half(
detail::binary, detail::float2half<half::round_style>(
std::cos(detail::half2float<detail::internal_t>(arg.data_))));
6802 int abs = arg.data_ & 0x7FFF, k;
6809 if (half::round_style != std::round_to_nearest &&
abs == 0x598C)
6813 return half(
detail::binary, detail::fixed2half<half::round_style, 30, true, true, true>((((k & 1) ? sc.first : sc.second) ^ sign) - sign));
6827 #ifdef HALF_ARITHMETIC_TYPE
6828 return half(
detail::binary, detail::float2half<half::round_style>(
std::tan(detail::half2float<detail::internal_t>(arg.data_))));
6830 int abs = arg.data_ & 0x7FFF,
exp = 13, k;
6836 return half(
detail::binary, detail::rounded<half::round_style, true>(arg.data_, 0, 1));
6837 if (half::round_style != std::round_to_nearest)
6841 return half(
detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x07E6, 1, 1));
6843 return half(
detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x4B62, 1, 1));
6847 sc = std::make_pair(-sc.second, sc.first);
6849 detail::uint32 my = (sc.first ^ signy) - signy, mx = (sc.second ^ signx) - signx;
6850 for (; my < 0x80000000; my <<= 1, --
exp)
6852 for (; mx < 0x80000000; mx <<= 1, ++
exp)
6854 return half(
detail::binary, detail::tangent_post<half::round_style>(my, mx,
exp, (signy ^ signx ^ arg.data_) & 0x8000));
6868 #ifdef HALF_ARITHMETIC_TYPE
6871 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
6876 : detail::rounded<half::round_style, true>(sign | 0x3E48, 0, 1));
6878 return half(
detail::binary, detail::rounded<half::round_style, true>(arg.data_, 0, 1));
6879 if (half::round_style != std::round_to_nearest && (
abs == 0x2B44 ||
abs == 0x2DC3))
6880 return half(
detail::binary, detail::rounded<half::round_style, true>(arg.data_ + 1, 1, 1));
6883 return half(
detail::binary, detail::fixed2half<half::round_style, 30, false, true, true>(m, 14, sign));
6897 #ifdef HALF_ARITHMETIC_TYPE
6900 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15;
6905 : sign ? detail::rounded<half::round_style, true>(0x4248, 0, 1)
6909 return half(
detail::binary, detail::fixed2half<half::round_style, 31, false, true, true>(sign ? (0xC90FDAA2 - m) : m, 15, 0, sign));
6923 #ifdef HALF_ARITHMETIC_TYPE
6926 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
6932 return half(
detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
6936 return half(
detail::binary, detail::fixed2half<half::round_style, 30, false, true, true>(m, 14, sign));
6952 #ifdef HALF_ARITHMETIC_TYPE
6953 return half(
detail::binary, detail::float2half<half::round_style>(
std::atan2(detail::half2float<detail::internal_t>(y.data_), detail::half2float<detail::internal_t>(x.data_))));
6955 unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, signx = x.data_ >> 15, signy = y.data_ & 0x8000;
6956 if (absx >= 0x7C00 || absy >= 0x7C00)
6958 if (absx > 0x7C00 || absy > 0x7C00)
6961 return half(
detail::binary, (absx < 0x7C00) ? detail::rounded<half::round_style, true>(signy | 0x3E48, 0, 1) : signx ? detail::rounded<half::round_style, true>(signy | 0x40B6, 0, 1)
6962 : detail::rounded<half::round_style, true>(signy | 0x3A48, 0, 1));
6966 return signx ?
half(
detail::binary, detail::rounded<half::round_style, true>(signy | 0x4248, 0, 1)) : y;
6968 return half(
detail::binary, detail::rounded<half::round_style, true>(signy | 0x3E48, 0, 1));
6969 int d = (absy >> 10) + (absy <= 0x3FF) - (absx >> 10) - (absx <= 0x3FF);
6970 if (d > (signx ? 18 : 12))
6971 return half(
detail::binary, detail::rounded<half::round_style, true>(signy | 0x3E48, 0, 1));
6972 if (signx && d < -11)
6973 return half(
detail::binary, detail::rounded<half::round_style, true>(signy | 0x4248, 0, 1));
6974 if (!signx && d < ((half::round_style == std::round_toward_zero) ? -15 : -9))
6976 for (; absy < 0x400; absy <<= 1, --d)
6978 detail::uint32 mx = ((absx << 1) & 0x7FF) | 0x800, my = ((absy << 1) & 0x7FF) | 0x800;
6984 return half(
detail::binary, detail::fixed2half<half::round_style, 11, false, false, true>(my / mx, d + 14, signy, my % mx != 0));
6988 ((absx & 0x3FF) | ((absx > 0x3FF) << 10)) << (19 - ((d > 0) ? d : (d < 0) ? 0
6990 return half(
detail::binary, detail::fixed2half<half::round_style, 31, false, true, true>(signx ? (0xC90FDAA2 - m) : m, 15, signy, signx));
7009 #ifdef HALF_ARITHMETIC_TYPE
7012 int abs = arg.data_ & 0x7FFF,
exp;
7013 if (!
abs ||
abs >= 0x7C00)
7016 return half(
detail::binary, detail::rounded<half::round_style, true>(arg.data_, 0, 1));
7019 for (
exp += 13; m < 0x80000000 &&
exp; m <<= 1, --
exp)
7021 unsigned int sign = arg.data_ & 0x8000;
7024 return half(
detail::binary, detail::fixed2half<half::round_style, 31, false, false, true>(m,
exp, sign));
7038 #ifdef HALF_ARITHMETIC_TYPE
7041 int abs = arg.data_ & 0x7FFF,
exp;
7047 detail::uint32 m = mm.first + mm.second, i = (~m & 0xFFFFFFFF) >> 31;
7048 m = (m >> i) | (m & i) | 0x80000000;
7049 if ((
exp += 13 + i) > 29)
7065 #ifdef HALF_ARITHMETIC_TYPE
7068 int abs = arg.data_ & 0x7FFF,
exp;
7074 return half(
detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x3BFF, 1, 1));
7076 return half(
detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
7077 if (half::round_style != std::round_to_nearest &&
abs == 0x2D3F)
7078 return half(
detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 3, 0, 1));
7080 detail::uint32 my = mm.first - mm.second - (half::round_style != std::round_to_nearest), mx = mm.first + mm.second, i = (~mx & 0xFFFFFFFF) >> 31;
7081 for (
exp = 13; my < 0x80000000; my <<= 1, --
exp)
7083 mx = (mx >> i) | 0x80000000;
7084 return half(
detail::binary, detail::tangent_post<half::round_style>(my, mx,
exp - i, arg.data_ & 0x8000));
7098 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7101 int abs = arg.data_ & 0x7FFF;
7102 if (!
abs ||
abs >= 0x7C00)
7105 return half(
detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
7106 if (half::round_style != std::round_to_nearest)
7110 return half(
detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 13, 1, 1));
7112 return half(
detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 197, 1, 1));
7128 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7131 int abs = arg.data_ & 0x7FFF;
7132 if ((arg.data_ & 0x8000) ||
abs < 0x3C00)
7136 if (arg.data_ >= 0x7C00)
7153 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7156 int abs = arg.data_ & 0x7FFF,
exp = 0;
7163 return half(
detail::binary, detail::rounded<half::round_style, true>(arg.data_, 0, 1));
7165 for (; mx < 0x80000000; mx <<= 1, ++
exp)
7167 int i = my >= mx, s;
7187 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7188 return half(
detail::binary, detail::float2half<half::round_style>(
std::erf(detail::half2float<detail::internal_t>(arg.data_))));
7190 unsigned int abs = arg.data_ & 0x7FFF;
7191 if (!
abs ||
abs >= 0x7C00)
7194 return half(
detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x3BFF, 1, 1));
7209 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7212 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
7218 return half(
detail::binary, detail::rounded<half::round_style, true>((sign >> 1) - (sign >> 15), sign >> 15, 1));
7234 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7237 int abs = arg.data_ & 0x7FFF;
7240 if (!
abs || arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(
abs & ((1 << (25 - (
abs >> 10))) - 1))))
7242 if (arg.data_ == 0x3C00 || arg.data_ == 0x4000)
7259 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7262 unsigned int abs = arg.data_ & 0x7FFF;
7267 if (arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(
abs & ((1 << (25 - (
abs >> 10))) - 1))))
7269 if (arg.data_ >= 0xCA80)
7271 if (arg.data_ <= 0x100 || (arg.data_ >= 0x4900 && arg.data_ < 0x8000))
7273 if (arg.data_ == 0x3C00)
7292 return half(
detail::binary, detail::integral<std::round_toward_infinity, true, true>(arg.data_));
7303 return half(
detail::binary, detail::integral<std::round_toward_neg_infinity, true, true>(arg.data_));
7314 return half(
detail::binary, detail::integral<std::round_toward_zero, true, true>(arg.data_));
7325 return half(
detail::binary, detail::integral<std::round_to_nearest, false, true>(arg.data_));
7335 return detail::half2int<std::round_to_nearest, false, false, long>(arg.data_);
7346 return half(
detail::binary, detail::integral<half::round_style, true, true>(arg.data_));
7357 return detail::half2int<half::round_style, true, true, long>(arg.data_);
7367 return half(
detail::binary, detail::integral<half::round_style, true, false>(arg.data_));
7369 #if HALF_ENABLE_CPP11_LONG_LONG
7375 inline long long llround(
half arg)
7377 return detail::half2int<std::round_to_nearest, false, false, long long>(arg.data_);
7386 inline long long llrint(half arg)
7388 return detail::half2int<half::round_style, true, true, long long>(arg.data_);
7406 unsigned int abs = arg.data_ & 0x7FFF;
7407 if (
abs >= 0x7C00 || !
abs)
7411 *
exp += (
abs >> 10) - 14;
7426 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
7427 if (
abs >= 0x7C00 || !
abs)
7438 unsigned int m = (
abs & 0x3FF) | 0x400;
7439 return half(
detail::binary, detail::rounded<half::round_style, false>(sign | (m >> (1 -
exp)), (m >> -
exp) & 1, (m & ((1 << -
exp) - 1)) != 0));
7478 unsigned int abs = arg.data_ & 0x7FFF;
7482 return *iptr = arg, arg;
7487 return iptr->data_ = arg.data_ & 0x8000, arg;
7488 unsigned int exp =
abs >> 10, mask = (1 << (25 -
exp)) - 1, m = arg.data_ & mask;
7489 iptr->data_ = arg.data_ & ~mask;
7492 for (; m < 0x400; m <<= 1, --
exp)
7507 int abs = arg.data_ & 0x7FFF,
exp;
7508 if (!
abs ||
abs >= 0x7C00)
7527 int abs = arg.data_ & 0x7FFF,
exp;
7534 unsigned int value =
static_cast<unsigned>(
exp < 0) << 15;
7538 for (
exp = 18; m < 0x400; m <<= 1, --
exp)
7540 value |= (
exp << 10) + m;
7555 int fabs = from.data_ & 0x7FFF, tabs = to.data_ & 0x7FFF;
7556 if (
fabs > 0x7C00 || tabs > 0x7C00)
7558 if (from.data_ == to.data_ || !(
fabs | tabs))
7565 unsigned int out = from.data_ + (((from.data_ >> 15) ^
static_cast<unsigned>((from.data_ ^ (0x8000 | (0x8000 - (from.data_ >> 15)))) < (to.data_ ^ (0x8000 | (0x8000 - (to.data_ >> 15)))))) << 1) - 1;
7581 int fabs = from.data_ & 0x7FFF;
7584 long double lfrom =
static_cast<long double>(from);
7586 return half(
static_cast<float>(to));
7592 unsigned int out = from.data_ + (((from.data_ >> 15) ^
static_cast<unsigned>(lfrom < to)) << 1) - 1;
7624 : ((arg.data_ & 0x7FFF) < 0x7C00) ?
FP_NORMAL
7636 return (arg.data_ & 0x7C00) != 0x7C00;
7646 return (arg.data_ & 0x7FFF) == 0x7C00;
7656 return (arg.data_ & 0x7FFF) > 0x7C00;
7666 return ((arg.data_ & 0x7C00) != 0) && ((arg.data_ & 0x7C00) != 0x7C00);
7676 return (arg.data_ & 0x8000) != 0;
7692 return ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) > ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15)) && !
isnan(x) && !
isnan(y);
7703 return ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) >= ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15)) && !
isnan(x) && !
isnan(y);
7714 return ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) < ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15)) && !
isnan(x) && !
isnan(y);
7725 return ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) <= ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15)) && !
isnan(x) && !
isnan(y);
7736 return x.data_ != y.data_ && ((x.data_ | y.data_) & 0x7FFF) && !
isnan(x) && !
isnan(y);
7768 template <
typename T,
typename U>
7788 template <
typename T, std::
float_round_style R,
typename U>
7881 inline void fethrowexcept([[maybe_unused]]
int excepts, [[maybe_unused]]
const char* msg =
"")
7897 #undef HALF_UNUSED_NOERR
7898 #undef HALF_CONSTEXPR
7899 #undef HALF_CONSTEXPR_CONST
7900 #undef HALF_CONSTEXPR_NOERR
7901 #undef HALF_NOEXCEPT
7903 #undef HALF_THREAD_LOCAL
7904 #undef HALF_TWOS_COMPLEMENT_INT
7905 #ifdef HALF_POP_WARNINGS
7906 #pragma warning(pop)
7907 #undef HALF_POP_WARNINGS
friend void sincos(half, half *, half *)
friend half nanh(const char *)
friend half nearbyint(half)
friend half pow(half, half)
half & operator-=(float rhs)
half & operator=(float rhs)
friend half remquo(half, half, int *)
HALF_CONSTEXPR half() HALF_NOEXCEPT
friend half atan2(half, half)
half & operator/=(float rhs)
friend half modf(half, half *)
friend half operator*(half, half)
friend half nexttoward(half, long double)
friend HALF_CONSTEXPR bool isgreaterequal(half, half)
friend half nextafter(half, half)
friend HALF_CONSTEXPR half copysign(half, half)
friend half operator/(half, half)
half & operator/=(half rhs)
friend HALF_CONSTEXPR half operator-(half)
friend HALF_CONSTEXPR bool isnan(half)
friend half scalbln(half, long)
friend half frexp(half, int *)
friend HALF_CONSTEXPR half fabs(half)
friend HALF_CONSTEXPR bool islessgreater(half, half)
friend HALF_CONSTEXPR bool isnormal(half)
friend half fdim(half, half)
friend HALF_CONSTEXPR int fpclassify(half)
half & operator*=(half rhs)
friend HALF_CONSTEXPR_NOERR bool operator==(half, half)
half & operator+=(float rhs)
half & operator+=(half rhs)
friend HALF_CONSTEXPR bool isfinite(half)
friend HALF_CONSTEXPR bool isgreater(half, half)
friend half fmod(half, half)
friend HALF_CONSTEXPR bool signbit(half)
half & operator*=(float rhs)
friend half remainder(half, half)
friend HALF_CONSTEXPR_NOERR half fmax(half, half)
friend HALF_CONSTEXPR_NOERR bool operator<=(half, half)
friend HALF_CONSTEXPR bool isless(half, half)
friend HALF_CONSTEXPR_NOERR bool operator>=(half, half)
friend half hypot(half, half)
half & operator-=(half rhs)
friend HALF_CONSTEXPR_NOERR bool operator!=(half, half)
friend HALF_CONSTEXPR_NOERR bool operator<(half, half)
friend half operator+(half, half)
friend HALF_CONSTEXPR_NOERR half fmin(half, half)
friend HALF_CONSTEXPR bool isinf(half)
friend half fma(half, half, half)
friend HALF_CONSTEXPR bool islessequal(half, half)
friend HALF_CONSTEXPR_NOERR bool operator>(half, half)
static HALF_CONSTEXPR half_float::half max() HALF_NOTHROW
Largest finite value.
static HALF_CONSTEXPR half_float::half quiet_NaN() HALF_NOTHROW
Quiet NaN.
static HALF_CONSTEXPR half_float::half min() HALF_NOTHROW
Smallest positive normal value.
static HALF_CONSTEXPR half_float::half round_error() HALF_NOTHROW
Maximum rounding error in ULP (units in the last place).
static HALF_CONSTEXPR half_float::half infinity() HALF_NOTHROW
Positive infinity.
static HALF_CONSTEXPR half_float::half epsilon() HALF_NOTHROW
Difference between 1 and next representable value.
static HALF_CONSTEXPR half_float::half lowest() HALF_NOTHROW
Smallest finite value.
static HALF_CONSTEXPR half_float::half signaling_NaN() HALF_NOTHROW
Signaling NaN.
static HALF_CONSTEXPR half_float::half denorm_min() HALF_NOTHROW
Smallest positive subnormal value.
#define HALF_CONSTEXPR_NOERR
#define MU_HALF_FE_UNDERFLOW
#define HALF_CONSTEXPR_CONST
#define HALF_THREAD_LOCAL
#define MU_HALF_FE_DIVBYZERO
#define MU_HALF_FE_OVERFLOW
#define MU_HALF_FE_INVALID
#define HALF_UNUSED_NOERR(name)
#define MU_HALF_FE_INEXACT
#define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
bool_type< false > false_type
HALF_CONSTEXPR_CONST binary_t binary
Tag for binary construction.
std::pair< uint32, uint32 > hyperbolic_args(unsigned int abs, int &exp, unsigned int n=32)
unsigned int integral(unsigned int value)
uint32 exp2(uint32 m, unsigned int n=32)
bool builtin_signbit(T arg)
unsigned int hypot_post(uint32 r, int exp)
bool builtin_isnan(T arg)
unsigned short uint16
Unsigned integer of (at least) 16 bits width.
std::pair< uint32, uint32 > atan2_args(unsigned int abs)
HALF_CONSTEXPR_NOERR unsigned int check_underflow(unsigned int arg)
unsigned int fixed2half(uint32 m, int exp=14, unsigned int sign=0, int s=0)
unsigned int mod(unsigned int x, unsigned int y, int *quo=NULL)
uint32 sqrt(uint32 &r, int &exp)
HALF_CONSTEXPR_NOERR unsigned int select(unsigned int x, unsigned int HALF_UNUSED_NOERR(y))
float half2float_impl(unsigned int value, float, true_type)
HALF_CONSTEXPR_NOERR unsigned int overflow(unsigned int sign=0)
uint32 multiply64(uint32 x, uint32 y)
T half2int(unsigned int value)
uint32 mulhi(uint32 x, uint32 y)
bool_type< true > true_type
HALF_CONSTEXPR_NOERR bool compsignal(unsigned int x, unsigned int y)
uint32 atan2(uint32 my, uint32 mx, unsigned int n=31)
long int32
Fastest unsigned integer of (at least) 32 bits width.
unsigned int float2half(T value)
HALF_CONSTEXPR_NOERR unsigned int underflow(unsigned int sign=0)
HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int nan)
HALF_CONSTEXPR_NOERR unsigned int invalid()
unsigned int gamma(unsigned int arg)
std::pair< uint32, uint32 > sincos(uint32 mz, unsigned int n=31)
uint32 arithmetic_shift(uint32 arg, int i)
uint32 log2(uint32 m, unsigned int n=32)
T half2float(unsigned int value)
uint32 divide64(uint32 x, uint32 y, int &s)
void raise(int HALF_UNUSED_NOERR(flags), bool HALF_UNUSED_NOERR(cond)=true)
uint32 angle_arg(unsigned int abs, int &k)
unsigned int log2_post(uint32 m, int ilog, int exp, unsigned int sign=0)
unsigned int area(unsigned int arg)
HALF_CONSTEXPR_NOERR unsigned int rounded(unsigned int value, int g, int s)
unsigned long uint32
Fastest unsigned integer of (at least) 32 bits width.
unsigned int float2half_impl(float value, true_type)
uint32 sign_mask(uint32 arg)
bool builtin_isinf(T arg)
unsigned int erf(unsigned int arg)
unsigned int int2half(T value)
unsigned int tangent_post(uint32 my, uint32 mx, int exp, unsigned int sign=0)
unsigned int exp2_post(uint32 m, int exp, bool esign, unsigned int sign=0, unsigned int n=32)
HALF_CONSTEXPR_NOERR unsigned int pole(unsigned int sign=0)
int feclearexcept(int excepts)
HALF_CONSTEXPR half fabs(half arg)
half nextafter(half from, half to)
half hypot(half x, half y)
HALF_CONSTEXPR bool isunordered(half x, half y)
half fdim(half x, half y)
half remquo(half x, half y, int *quo)
int fegetexceptflag(int *flagp, int excepts)
HALF_CONSTEXPR half copysign(half x, half y)
HALF_CONSTEXPR bool isfinite(half arg)
int fesetexceptflag(const int *flagp, int excepts)
HALF_CONSTEXPR half abs(half arg)
half fma(half x, half y, half z)
HALF_CONSTEXPR_NOERR half fmin(half x, half y)
half ldexp(half arg, int exp)
HALF_CONSTEXPR_NOERR bool operator!=(half x, half y)
HALF_CONSTEXPR_NOERR half fmax(half x, half y)
HALF_CONSTEXPR_NOERR bool operator<(half x, half y)
HALF_CONSTEXPR half operator-(half arg)
half fmod(half x, half y)
half scalbn(half arg, int exp)
HALF_CONSTEXPR int fpclassify(half arg)
HALF_CONSTEXPR_NOERR bool operator>=(half x, half y)
half nexttoward(half from, long double to)
HALF_CONSTEXPR bool isgreater(half x, half y)
HALF_CONSTEXPR half operator+(half arg)
HALF_CONSTEXPR bool signbit(half arg)
void fethrowexcept([[maybe_unused]] int excepts, [[maybe_unused]] const char *msg="")
HALF_CONSTEXPR bool isnan(half arg)
HALF_CONSTEXPR_NOERR bool operator<=(half x, half y)
half operator*(half x, half y)
HALF_CONSTEXPR bool isnormal(half arg)
half atan2(half y, half x)
int feraiseexcept(int excepts)
HALF_CONSTEXPR bool isless(half x, half y)
half scalbln(half arg, long exp)
HALF_CONSTEXPR_NOERR bool operator==(half x, half y)
HALF_CONSTEXPR bool isinf(half arg)
HALF_CONSTEXPR_NOERR bool operator>(half x, half y)
void sincos(half arg, half *sin, half *cos)
half frexp(half arg, int *exp)
HALF_CONSTEXPR bool islessgreater(half x, half y)
half hypot(half x, half y, half z)
HALF_CONSTEXPR bool islessequal(half x, half y)
half nanh(const char *arg)
half modf(half arg, half *iptr)
HALF_CONSTEXPR bool isgreaterequal(half x, half y)
int fetestexcept(int excepts)
half remainder(half x, half y)
half operator/(half x, half y)
Extensions to the C++ standard library.
Tag type for binary construction.
Type traits for floating-point bits.
Helper for tag dispatching.
Class for 1.31 unsigned floating-point computation.
friend f31 operator-(f31 a, f31 b)
friend f31 operator*(f31 a, f31 b)
friend f31 operator/(f31 a, f31 b)
friend f31 operator+(f31 a, f31 b)
HALF_CONSTEXPR f31(uint32 mant, int e)
uint32 m
mantissa as 1.31.
static half cast(half arg)
Type traits for floating-point types.