25 #define HALF_GCC_VERSION (__GNUC__*100+__GNUC_MINOR__)
27 #if defined(__INTEL_COMPILER)
28 #define HALF_ICC_VERSION __INTEL_COMPILER
30 #define HALF_ICC_VERSION __ICC
32 #define HALF_ICC_VERSION __ICL
34 #define HALF_ICC_VERSION 0
38 #if defined(__clang__)
39 #if __has_feature(cxx_static_assert) && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
40 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
42 #if __has_feature(cxx_constexpr) && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
43 #define HALF_ENABLE_CPP11_CONSTEXPR 1
45 #if __has_feature(cxx_noexcept) && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
46 #define HALF_ENABLE_CPP11_NOEXCEPT 1
48 #if __has_feature(cxx_user_literals) && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
49 #define HALF_ENABLE_CPP11_USER_LITERALS 1
51 #if __has_feature(cxx_thread_local) && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
52 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
54 #if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) && !defined(HALF_ENABLE_CPP11_LONG_LONG)
55 #define HALF_ENABLE_CPP11_LONG_LONG 1
57 #elif HALF_ICC_VERSION && defined(__INTEL_CXX11_MODE__)
58 #if HALF_ICC_VERSION >= 1500 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
59 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
61 #if HALF_ICC_VERSION >= 1500 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
62 #define HALF_ENABLE_CPP11_USER_LITERALS 1
64 #if HALF_ICC_VERSION >= 1400 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
65 #define HALF_ENABLE_CPP11_CONSTEXPR 1
67 #if HALF_ICC_VERSION >= 1400 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
68 #define HALF_ENABLE_CPP11_NOEXCEPT 1
70 #if HALF_ICC_VERSION >= 1110 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
71 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
73 #if HALF_ICC_VERSION >= 1110 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
74 #define HALF_ENABLE_CPP11_LONG_LONG 1
76 #elif defined(__GNUC__)
77 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
78 #if HALF_GCC_VERSION >= 408 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
79 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
81 #if HALF_GCC_VERSION >= 407 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
82 #define HALF_ENABLE_CPP11_USER_LITERALS 1
84 #if HALF_GCC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
85 #define HALF_ENABLE_CPP11_CONSTEXPR 1
87 #if HALF_GCC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
88 #define HALF_ENABLE_CPP11_NOEXCEPT 1
90 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
91 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
93 #if !defined(HALF_ENABLE_CPP11_LONG_LONG)
94 #define HALF_ENABLE_CPP11_LONG_LONG 1
97 #define HALF_TWOS_COMPLEMENT_INT 1
98 #elif defined(_MSC_VER)
99 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
100 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
102 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
103 #define HALF_ENABLE_CPP11_USER_LITERALS 1
105 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
106 #define HALF_ENABLE_CPP11_CONSTEXPR 1
108 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
109 #define HALF_ENABLE_CPP11_NOEXCEPT 1
111 #if _MSC_VER >= 1600 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
112 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
114 #if _MSC_VER >= 1310 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
115 #define HALF_ENABLE_CPP11_LONG_LONG 1
117 #define HALF_TWOS_COMPLEMENT_INT 1
118 #define HALF_POP_WARNINGS 1
119 #pragma warning(push)
120 #pragma warning(disable : 4099 4127 4146)
125 #if defined(_LIBCPP_VERSION)
126 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
127 #ifndef HALF_ENABLE_CPP11_TYPE_TRAITS
128 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
130 #ifndef HALF_ENABLE_CPP11_CSTDINT
131 #define HALF_ENABLE_CPP11_CSTDINT 1
133 #ifndef HALF_ENABLE_CPP11_CMATH
134 #define HALF_ENABLE_CPP11_CMATH 1
136 #ifndef HALF_ENABLE_CPP11_HASH
137 #define HALF_ENABLE_CPP11_HASH 1
139 #ifndef HALF_ENABLE_CPP11_CFENV
140 #define HALF_ENABLE_CPP11_CFENV 1
143 #elif defined(__GLIBCXX__)
144 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
146 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
147 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
149 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CSTDINT)
150 #define HALF_ENABLE_CPP11_CSTDINT 1
152 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CMATH)
153 #define HALF_ENABLE_CPP11_CMATH 1
155 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_HASH)
156 #define HALF_ENABLE_CPP11_HASH 1
158 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CFENV)
159 #define HALF_ENABLE_CPP11_CFENV 1
162 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
163 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
165 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CSTDINT)
166 #define HALF_ENABLE_CPP11_CSTDINT 1
168 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CMATH)
169 #define HALF_ENABLE_CPP11_CMATH 1
171 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_HASH)
172 #define HALF_ENABLE_CPP11_HASH 1
174 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CFENV)
175 #define HALF_ENABLE_CPP11_CFENV 1
179 #elif defined(_CPPLIB_VER)
180 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
181 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
183 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_CSTDINT)
184 #define HALF_ENABLE_CPP11_CSTDINT 1
186 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_HASH)
187 #define HALF_ENABLE_CPP11_HASH 1
189 #if _CPPLIB_VER >= 610 && !defined(HALF_ENABLE_CPP11_CMATH)
190 #define HALF_ENABLE_CPP11_CMATH 1
192 #if _CPPLIB_VER >= 610 && !defined(HALF_ENABLE_CPP11_CFENV)
193 #define HALF_ENABLE_CPP11_CFENV 1
196 #undef HALF_GCC_VERSION
197 #undef HALF_ICC_VERSION
200 #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)
201 #define HALF_ERRHANDLING_THROWS 1
205 #define HALF_ERRHANDLING (HALF_ERRHANDLING_FLAGS||HALF_ERRHANDLING_ERRNO||HALF_ERRHANDLING_FENV||HALF_ERRHANDLING_THROWS)
208 #define HALF_UNUSED_NOERR(name) name
210 #define HALF_UNUSED_NOERR(name)
214 #if HALF_ENABLE_CPP11_CONSTEXPR
215 #define HALF_CONSTEXPR constexpr
216 #define HALF_CONSTEXPR_CONST constexpr
218 #define HALF_CONSTEXPR_NOERR
220 #define HALF_CONSTEXPR_NOERR constexpr
223 #define HALF_CONSTEXPR
224 #define HALF_CONSTEXPR_CONST const
225 #define HALF_CONSTEXPR_NOERR
229 #if HALF_ENABLE_CPP11_NOEXCEPT
230 #define HALF_NOEXCEPT noexcept
231 #define HALF_NOTHROW noexcept
233 #define HALF_NOEXCEPT
234 #define HALF_NOTHROW throw()
238 #if HALF_ENABLE_CPP11_THREAD_LOCAL
239 #define HALF_THREAD_LOCAL thread_local
241 #define HALF_THREAD_LOCAL static
254 #if HALF_ENABLE_CPP11_TYPE_TRAITS
255 #include <type_traits>
257 #if HALF_ENABLE_CPP11_CSTDINT
260 #if HALF_ERRHANDLING_ERRNO
263 #if HALF_ENABLE_CPP11_CFENV
266 #if HALF_ENABLE_CPP11_HASH
267 #include <functional>
271 #ifndef HALF_ENABLE_F16C_INTRINSICS
278 #define HALF_ENABLE_F16C_INTRINSICS __F16C__
280 #if HALF_ENABLE_F16C_INTRINSICS
281 #include <immintrin.h>
284 #ifdef HALF_DOXYGEN_ONLY
290 #define HALF_ARITHMETIC_TYPE (undefined)
295 #define HALF_ERRHANDLING_FLAGS 0
302 #define HALF_ERRHANDLING_ERRNO 0
310 #define HALF_ERRHANDLING_FENV 0
315 #define HALF_ERRHANDLING_THROW_INVALID (undefined)
320 #define HALF_ERRHANDLING_THROW_DIVBYZERO (undefined)
325 #define HALF_ERRHANDLING_THROW_OVERFLOW (undefined)
330 #define HALF_ERRHANDLING_THROW_UNDERFLOW (undefined)
335 #define HALF_ERRHANDLING_THROW_INEXACT (undefined)
338 #ifndef HALF_ERRHANDLING_OVERFLOW_TO_INEXACT
342 #define HALF_ERRHANDLING_OVERFLOW_TO_INEXACT 1
345 #ifndef HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
352 #define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT 1
373 #ifndef HALF_ROUND_STYLE
374 #define HALF_ROUND_STYLE 1
382 #define HUGE_VALH std::numeric_limits<half_float::half>::infinity()
389 #define FP_FAST_FMAH 1
396 #define HLF_ROUNDS HALF_ROUND_STYLE
399 #define FP_ILOGB0 INT_MIN
402 #define FP_ILOGBNAN INT_MAX
405 #define FP_SUBNORMAL 0
414 #define FP_INFINITE 3
420 #if !HALF_ENABLE_CPP11_CFENV && !defined(FE_ALL_EXCEPT)
421 #define FE_INVALID 0x10
422 #define FE_DIVBYZERO 0x08
423 #define FE_OVERFLOW 0x04
424 #define FE_UNDERFLOW 0x02
425 #define FE_INEXACT 0x01
426 #define FE_ALL_EXCEPT (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW|FE_INEXACT)
436 #if HALF_ENABLE_CPP11_USER_LITERALS
445 half operator "" _h(
long double);
453 #if HALF_ENABLE_CPP11_TYPE_TRAITS
455 template<
bool B,
typename T,
typename F>
struct conditional : std::conditional<B,T,F> {};
458 template<
bool B>
struct bool_type : std::integral_constant<bool,B> {};
459 using std::true_type;
460 using std::false_type;
463 template<
typename T>
struct is_float : std::is_floating_point<T> {};
466 template<
bool,
typename T,
typename>
struct conditional {
typedef T type; };
467 template<
typename T,
typename F>
struct conditional<false,T,F> {
typedef F type; };
470 template<
bool>
struct bool_type {};
471 typedef bool_type<true> true_type;
472 typedef bool_type<false> false_type;
475 template<
typename>
struct is_float : false_type {};
476 template<
typename T>
struct is_float<const T> : is_float<T> {};
477 template<
typename T>
struct is_float<volatile T> : is_float<T> {};
478 template<
typename T>
struct is_float<const volatile T> : is_float<T> {};
479 template<>
struct is_float<float> : true_type {};
480 template<>
struct is_float<double> : true_type {};
481 template<>
struct is_float<long double> : true_type {};
485 template<
typename T>
struct bits {
typedef unsigned char type; };
486 template<
typename T>
struct bits<const T> : bits<T> {};
487 template<
typename T>
struct bits<volatile T> : bits<T> {};
488 template<
typename T>
struct bits<const volatile T> : bits<T> {};
490 #if HALF_ENABLE_CPP11_CSTDINT
492 typedef std::uint_least16_t uint16;
495 typedef std::uint_fast32_t uint32;
498 typedef std::int_fast32_t int32;
501 template<>
struct bits<float> {
typedef std::uint_least32_t type; };
504 template<>
struct bits<double> {
typedef std::uint_least64_t type; };
507 typedef unsigned short uint16;
510 typedef unsigned long uint32;
516 template<>
struct bits<float> : conditional<std::numeric_limits<unsigned int>::digits>=32,unsigned int,unsigned long> {};
518 #if HALF_ENABLE_CPP11_LONG_LONG
520 template<>
struct bits<double> : conditional<std::numeric_limits<unsigned long>::digits>=64,unsigned long,unsigned long long> {};
523 template<>
struct bits<double> {
typedef unsigned long type; };
527 #ifdef HALF_ARITHMETIC_TYPE
536 HALF_CONSTEXPR_CONST binary_t binary = binary_t();
546 template<
typename T>
bool builtin_isinf(T arg)
548 #if HALF_ENABLE_CPP11_CMATH
550 #elif defined(_MSC_VER)
551 return !::_finite(
static_cast<double>(arg)) && !::_isnan(
static_cast<double>(arg));
553 return arg == std::numeric_limits<T>::infinity() || arg == -std::numeric_limits<T>::infinity();
562 template<
typename T>
bool builtin_isnan(T arg)
564 #if HALF_ENABLE_CPP11_CMATH
566 #elif defined(_MSC_VER)
567 return ::_isnan(
static_cast<double>(arg)) != 0;
578 template<
typename T>
bool builtin_signbit(T arg)
580 #if HALF_ENABLE_CPP11_CMATH
583 return arg < T() || (arg == T() && T(1)/arg < T());
591 inline uint32 sign_mask(uint32 arg)
593 static const int N = std::numeric_limits<uint32>::digits - 1;
594 #if HALF_TWOS_COMPLEMENT_INT
595 return static_cast<int32
>(arg) >> N;
597 return -((arg>>N)&1);
605 inline uint32 arithmetic_shift(uint32 arg,
int i)
607 #if HALF_TWOS_COMPLEMENT_INT
608 return static_cast<int32
>(arg) >> i;
610 return static_cast<int32
>(arg)/(
static_cast<int32
>(1)<<i) - ((arg>>(std::numeric_limits<uint32>::digits-1))&1);
620 inline int& errflags() { HALF_THREAD_LOCAL
int flags = 0;
return flags; }
625 inline void raise(
int HALF_UNUSED_NOERR(flags),
bool HALF_UNUSED_NOERR(cond) =
true)
630 #if HALF_ERRHANDLING_FLAGS
633 #if HALF_ERRHANDLING_ERRNO
634 if(flags & FE_INVALID)
636 else if(flags & (FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW))
639 #if HALF_ERRHANDLING_FENV && HALF_ENABLE_CPP11_CFENV
642 #ifdef HALF_ERRHANDLING_THROW_INVALID
643 if(flags & FE_INVALID)
646 #ifdef HALF_ERRHANDLING_THROW_DIVBYZERO
647 if(flags & FE_DIVBYZERO)
650 #ifdef HALF_ERRHANDLING_THROW_OVERFLOW
651 if(flags & FE_OVERFLOW)
654 #ifdef HALF_ERRHANDLING_THROW_UNDERFLOW
655 if(flags & FE_UNDERFLOW)
658 #ifdef HALF_ERRHANDLING_THROW_INEXACT
659 if(flags & FE_INEXACT)
662 #if HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
663 if((flags & FE_UNDERFLOW) && !(flags & FE_INEXACT))
666 #if HALF_ERRHANDLING_OVERFLOW_TO_INEXACT
667 if((flags & FE_OVERFLOW) && !(flags & FE_INEXACT))
679 inline HALF_CONSTEXPR_NOERR
bool compsignal(
unsigned int x,
unsigned int y)
682 raise(FE_INVALID, (x&0x7FFF)>0x7C00 || (y&0x7FFF)>0x7C00);
684 return (x&0x7FFF) > 0x7C00 || (y&0x7FFF) > 0x7C00;
691 inline HALF_CONSTEXPR_NOERR
unsigned int signal(
unsigned int nan)
694 raise(FE_INVALID, !(nan&0x200));
704 inline HALF_CONSTEXPR_NOERR
unsigned int signal(
unsigned int x,
unsigned int y)
707 raise(FE_INVALID, ((x&0x7FFF)>0x7C00 && !(x&0x200)) || ((y&0x7FFF)>0x7C00 && !(y&0x200)));
709 return ((x&0x7FFF)>0x7C00) ? (x|0x200) : (y|0x200);
718 inline HALF_CONSTEXPR_NOERR
unsigned int signal(
unsigned int x,
unsigned int y,
unsigned int z)
721 raise(FE_INVALID, ((x&0x7FFF)>0x7C00 && !(x&0x200)) || ((y&0x7FFF)>0x7C00 && !(y&0x200)) || ((z&0x7FFF)>0x7C00 && !(z&0x200)));
723 return ((x&0x7FFF)>0x7C00) ? (x|0x200) : ((y&0x7FFF)>0x7C00) ? (y|0x200) : (z|0x200);
731 inline HALF_CONSTEXPR_NOERR
unsigned int select(
unsigned int x,
unsigned int HALF_UNUSED_NOERR(y))
734 return (((y&0x7FFF)>0x7C00) && !(y&0x200)) ? signal(y) : x;
743 inline HALF_CONSTEXPR_NOERR
unsigned int invalid()
755 inline HALF_CONSTEXPR_NOERR
unsigned int pole(
unsigned int sign = 0)
760 return sign | 0x7C00;
767 inline HALF_CONSTEXPR_NOERR
unsigned int check_underflow(
unsigned int arg)
769 #if HALF_ERRHANDLING && !HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
770 raise(FE_UNDERFLOW, !(arg&0x7C00));
784 template<std::
float_round_style R> HALF_CONSTEXPR_NOERR
unsigned int overflow(
unsigned int sign = 0)
789 return (R==std::round_toward_infinity) ? (sign+0x7C00-(sign>>15)) :
790 (R==std::round_toward_neg_infinity) ? (sign+0x7BFF+(sign>>15)) :
791 (R==std::round_toward_zero) ? (sign|0x7BFF) :
800 template<std::
float_round_style R> HALF_CONSTEXPR_NOERR
unsigned int underflow(
unsigned int sign = 0)
805 return (R==std::round_toward_infinity) ? (sign+1-(sign>>15)) :
806 (R==std::round_toward_neg_infinity) ? (sign+(sign>>15)) :
820 template<std::
float_round_style R,
bool I> HALF_CONSTEXPR_NOERR
unsigned int rounded(
unsigned int value,
int g,
int s)
823 value += (R==std::round_to_nearest) ? (g&(s|value)) :
824 (R==std::round_toward_infinity) ? (~(value>>15)&(g|s)) :
825 (R==std::round_toward_neg_infinity) ? ((value>>15)&(g|s)) : 0;
826 if((value&0x7C00) == 0x7C00)
828 else if(value & 0x7C00)
829 raise(FE_INEXACT, I || (g|s)!=0);
834 return (R==std::round_to_nearest) ? (value+(g&(s|value))) :
835 (R==std::round_toward_infinity) ? (value+(~(value>>15)&(g|s))) :
836 (R==std::round_toward_neg_infinity) ? (value+((value>>15)&(g|s))) :
849 template<std::
float_round_style R,
bool E,
bool I>
unsigned int integral(
unsigned int value)
851 unsigned int abs = value & 0x7FFF;
854 raise(FE_INEXACT, I);
855 return ((R==std::round_to_nearest) ? (0x3C00&-
static_cast<unsigned>(
abs>=(0x3800+E))) :
856 (R==std::round_toward_infinity) ? (0x3C00&-(~(value>>15)&(
abs!=0))) :
857 (R==std::round_toward_neg_infinity) ? (0x3C00&-
static_cast<unsigned>(value>0x8000)) :
861 return (
abs>0x7C00) ? signal(value) : value;
862 unsigned int exp = 25 - (
abs>>10), mask = (1<<
exp) - 1;
863 raise(FE_INEXACT, I && (value&mask));
864 return (( (R==std::round_to_nearest) ? ((1<<(
exp-1))-(~(value>>
exp)&E)) :
865 (R==std::round_toward_infinity) ? (mask&((value>>15)-1)) :
866 (R==std::round_toward_neg_infinity) ? (mask&-(value>>15)) :
884 template<std::
float_round_style R,
unsigned int F,
bool S,
bool N,
bool I>
unsigned int fixed2half(uint32 m,
int exp = 14,
unsigned int sign = 0,
int s = 0)
888 uint32 msign = sign_mask(m);
889 m = (m^msign) - msign;
890 sign = msign & 0x8000;
893 for(; m<(static_cast<uint32>(1)<<F) &&
exp; m<<=1,--
exp) ;
895 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));
896 return rounded<R,I>(sign+(
exp<<10)+(m>>(F-10)), (m>>(F-11))&1, s|((m&((
static_cast<uint32
>(1)<<(F-11))-1))!=0));
907 template<std::
float_round_style R>
unsigned int float2half_impl(
float value, true_type)
909 #if HALF_ENABLE_F16C_INTRINSICS
910 return _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_set_ss(value),
911 (R==std::round_to_nearest) ? _MM_FROUND_TO_NEAREST_INT :
912 (R==std::round_toward_zero) ? _MM_FROUND_TO_ZERO :
913 (R==std::round_toward_infinity) ? _MM_FROUND_TO_POS_INF :
914 (R==std::round_toward_neg_infinity) ? _MM_FROUND_TO_NEG_INF :
915 _MM_FROUND_CUR_DIRECTION));
917 bits<float>::type fbits;
918 std::memcpy(&fbits, &value,
sizeof(
float));
920 unsigned int sign = (fbits>>16) & 0x8000;
922 if(fbits >= 0x7F800000)
923 return sign | 0x7C00 | ((fbits>0x7F800000) ? (0x200|((fbits>>13)&0x3FF)) : 0);
924 if(fbits >= 0x47800000)
925 return overflow<R>(sign);
926 if(fbits >= 0x38800000)
927 return rounded<R,false>(sign|(((fbits>>23)-112)<<10)|((fbits>>13)&0x3FF), (fbits>>12)&1, (fbits&0xFFF)!=0);
928 if(fbits >= 0x33000000)
930 int i = 125 - (fbits>>23);
931 fbits = (fbits&0x7FFFFF) | 0x800000;
932 return rounded<R,false>(sign|(fbits>>(i+1)), (fbits>>i)&1, (fbits&((
static_cast<uint32
>(1)<<i)-1))!=0);
935 return underflow<R>(sign);
938 static const uint16 base_table[512] = {
939 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
940 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
941 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
942 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
943 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
944 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
945 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
946 0x0200, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00,
947 0x4000, 0x4400, 0x4800, 0x4C00, 0x5000, 0x5400, 0x5800, 0x5C00, 0x6000, 0x6400, 0x6800, 0x6C00, 0x7000, 0x7400, 0x7800, 0x7BFF,
948 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
949 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
950 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
951 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
952 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
953 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
954 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7C00,
955 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
956 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
957 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
958 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
959 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
960 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
961 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001, 0x8002, 0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100,
962 0x8200, 0x8400, 0x8800, 0x8C00, 0x9000, 0x9400, 0x9800, 0x9C00, 0xA000, 0xA400, 0xA800, 0xAC00, 0xB000, 0xB400, 0xB800, 0xBC00,
963 0xC000, 0xC400, 0xC800, 0xCC00, 0xD000, 0xD400, 0xD800, 0xDC00, 0xE000, 0xE400, 0xE800, 0xEC00, 0xF000, 0xF400, 0xF800, 0xFBFF,
964 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
965 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
966 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
967 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
968 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
969 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
970 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFC00 };
971 static const unsigned char shift_table[256] = {
972 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
973 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
974 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
975 25, 25, 25, 25, 25, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
976 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
977 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
978 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
979 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 13 };
980 int sexp = fbits >> 23,
exp = sexp & 0xFF, i = shift_table[
exp];
982 uint32 m = (fbits|((
exp!=0)<<23)) & -
static_cast<uint32
>(
exp!=0xFF);
983 return rounded<R,false>(base_table[sexp]+(fbits>>i), (m>>(i-1))&1, (((
static_cast<uint32
>(1)<<(i-1))-1)&m)!=0);
995 template<std::
float_round_style R>
unsigned int float2half_impl(
double value, true_type)
997 #if HALF_ENABLE_F16C_INTRINSICS
998 if(R == std::round_indeterminate)
999 return _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_cvtpd_ps(_mm_set_sd(value)), _MM_FROUND_CUR_DIRECTION));
1001 bits<double>::type dbits;
1002 std::memcpy(&dbits, &value,
sizeof(
double));
1003 uint32 hi = dbits >> 32, lo = dbits & 0xFFFFFFFF;
1004 unsigned int sign = (hi>>16) & 0x8000;
1006 if(hi >= 0x7FF00000)
1007 return sign | 0x7C00 | ((dbits&0xFFFFFFFFFFFFF) ? (0x200|((hi>>10)&0x3FF)) : 0);
1008 if(hi >= 0x40F00000)
1009 return overflow<R>(sign);
1010 if(hi >= 0x3F100000)
1011 return rounded<R,false>(sign|(((hi>>20)-1008)<<10)|((hi>>10)&0x3FF), (hi>>9)&1, ((hi&0x1FF)|lo)!=0);
1012 if(hi >= 0x3E600000)
1014 int i = 1018 - (hi>>20);
1015 hi = (hi&0xFFFFF) | 0x100000;
1016 return rounded<R,false>(sign|(hi>>(i+1)), (hi>>i)&1, ((hi&((
static_cast<uint32
>(1)<<i)-1))|lo)!=0);
1019 return underflow<R>(sign);
1031 template<std::
float_round_style R,
typename T>
unsigned int float2half_impl(T value, ...)
1033 unsigned int hbits =
static_cast<unsigned>(builtin_signbit(value)) << 15;
1036 if(builtin_isnan(value))
1037 return hbits | 0x7FFF;
1038 if(builtin_isinf(value))
1039 return hbits | 0x7C00;
1043 return overflow<R>(hbits);
1049 hbits |= ((
exp+13)<<10);
1052 int m =
std::abs(
static_cast<int>(ival));
1053 return rounded<R,false>(hbits+(m>>1), m&1, frac!=T());
1064 template<std::
float_round_style R,
typename T>
unsigned int float2half(T value)
1066 return float2half_impl<R>(value, bool_type<std::numeric_limits<T>::is_iec559&&
sizeof(
typename bits<T>::type)==
sizeof(T)>());
1076 template<std::
float_round_style R,
typename T>
unsigned int int2half(T value)
1078 unsigned int bits =
static_cast<unsigned>(value<0) << 15;
1084 return overflow<R>(bits);
1085 unsigned int m =
static_cast<unsigned int>(value),
exp = 24;
1086 for(; m<0x400; m<<=1,--
exp) ;
1087 for(; m>0x7FF; m>>=1,++
exp) ;
1088 bits |= (
exp<<10) + m;
1089 return (
exp>24) ? rounded<R,false>(bits, (value>>(
exp-25))&1, (((1<<(
exp-25))-1)&value)!=0) : bits;
1096 inline float half2float_impl(
unsigned int value,
float, true_type)
1098 #if HALF_ENABLE_F16C_INTRINSICS
1099 return _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128(value)));
1102 bits<float>::type fbits =
static_cast<bits<float>::type
>(value&0x8000) << 16;
1103 int abs = value & 0x7FFF;
1106 fbits |= 0x38000000 <<
static_cast<unsigned>(
abs>=0x7C00);
1107 for(;
abs<0x400;
abs<<=1,fbits-=0x800000) ;
1108 fbits +=
static_cast<bits<float>::type
>(
abs) << 13;
1111 static const bits<float>::type mantissa_table[2048] = {
1112 0x00000000, 0x33800000, 0x34000000, 0x34400000, 0x34800000, 0x34A00000, 0x34C00000, 0x34E00000, 0x35000000, 0x35100000, 0x35200000, 0x35300000, 0x35400000, 0x35500000, 0x35600000, 0x35700000,
1113 0x35800000, 0x35880000, 0x35900000, 0x35980000, 0x35A00000, 0x35A80000, 0x35B00000, 0x35B80000, 0x35C00000, 0x35C80000, 0x35D00000, 0x35D80000, 0x35E00000, 0x35E80000, 0x35F00000, 0x35F80000,
1114 0x36000000, 0x36040000, 0x36080000, 0x360C0000, 0x36100000, 0x36140000, 0x36180000, 0x361C0000, 0x36200000, 0x36240000, 0x36280000, 0x362C0000, 0x36300000, 0x36340000, 0x36380000, 0x363C0000,
1115 0x36400000, 0x36440000, 0x36480000, 0x364C0000, 0x36500000, 0x36540000, 0x36580000, 0x365C0000, 0x36600000, 0x36640000, 0x36680000, 0x366C0000, 0x36700000, 0x36740000, 0x36780000, 0x367C0000,
1116 0x36800000, 0x36820000, 0x36840000, 0x36860000, 0x36880000, 0x368A0000, 0x368C0000, 0x368E0000, 0x36900000, 0x36920000, 0x36940000, 0x36960000, 0x36980000, 0x369A0000, 0x369C0000, 0x369E0000,
1117 0x36A00000, 0x36A20000, 0x36A40000, 0x36A60000, 0x36A80000, 0x36AA0000, 0x36AC0000, 0x36AE0000, 0x36B00000, 0x36B20000, 0x36B40000, 0x36B60000, 0x36B80000, 0x36BA0000, 0x36BC0000, 0x36BE0000,
1118 0x36C00000, 0x36C20000, 0x36C40000, 0x36C60000, 0x36C80000, 0x36CA0000, 0x36CC0000, 0x36CE0000, 0x36D00000, 0x36D20000, 0x36D40000, 0x36D60000, 0x36D80000, 0x36DA0000, 0x36DC0000, 0x36DE0000,
1119 0x36E00000, 0x36E20000, 0x36E40000, 0x36E60000, 0x36E80000, 0x36EA0000, 0x36EC0000, 0x36EE0000, 0x36F00000, 0x36F20000, 0x36F40000, 0x36F60000, 0x36F80000, 0x36FA0000, 0x36FC0000, 0x36FE0000,
1120 0x37000000, 0x37010000, 0x37020000, 0x37030000, 0x37040000, 0x37050000, 0x37060000, 0x37070000, 0x37080000, 0x37090000, 0x370A0000, 0x370B0000, 0x370C0000, 0x370D0000, 0x370E0000, 0x370F0000,
1121 0x37100000, 0x37110000, 0x37120000, 0x37130000, 0x37140000, 0x37150000, 0x37160000, 0x37170000, 0x37180000, 0x37190000, 0x371A0000, 0x371B0000, 0x371C0000, 0x371D0000, 0x371E0000, 0x371F0000,
1122 0x37200000, 0x37210000, 0x37220000, 0x37230000, 0x37240000, 0x37250000, 0x37260000, 0x37270000, 0x37280000, 0x37290000, 0x372A0000, 0x372B0000, 0x372C0000, 0x372D0000, 0x372E0000, 0x372F0000,
1123 0x37300000, 0x37310000, 0x37320000, 0x37330000, 0x37340000, 0x37350000, 0x37360000, 0x37370000, 0x37380000, 0x37390000, 0x373A0000, 0x373B0000, 0x373C0000, 0x373D0000, 0x373E0000, 0x373F0000,
1124 0x37400000, 0x37410000, 0x37420000, 0x37430000, 0x37440000, 0x37450000, 0x37460000, 0x37470000, 0x37480000, 0x37490000, 0x374A0000, 0x374B0000, 0x374C0000, 0x374D0000, 0x374E0000, 0x374F0000,
1125 0x37500000, 0x37510000, 0x37520000, 0x37530000, 0x37540000, 0x37550000, 0x37560000, 0x37570000, 0x37580000, 0x37590000, 0x375A0000, 0x375B0000, 0x375C0000, 0x375D0000, 0x375E0000, 0x375F0000,
1126 0x37600000, 0x37610000, 0x37620000, 0x37630000, 0x37640000, 0x37650000, 0x37660000, 0x37670000, 0x37680000, 0x37690000, 0x376A0000, 0x376B0000, 0x376C0000, 0x376D0000, 0x376E0000, 0x376F0000,
1127 0x37700000, 0x37710000, 0x37720000, 0x37730000, 0x37740000, 0x37750000, 0x37760000, 0x37770000, 0x37780000, 0x37790000, 0x377A0000, 0x377B0000, 0x377C0000, 0x377D0000, 0x377E0000, 0x377F0000,
1128 0x37800000, 0x37808000, 0x37810000, 0x37818000, 0x37820000, 0x37828000, 0x37830000, 0x37838000, 0x37840000, 0x37848000, 0x37850000, 0x37858000, 0x37860000, 0x37868000, 0x37870000, 0x37878000,
1129 0x37880000, 0x37888000, 0x37890000, 0x37898000, 0x378A0000, 0x378A8000, 0x378B0000, 0x378B8000, 0x378C0000, 0x378C8000, 0x378D0000, 0x378D8000, 0x378E0000, 0x378E8000, 0x378F0000, 0x378F8000,
1130 0x37900000, 0x37908000, 0x37910000, 0x37918000, 0x37920000, 0x37928000, 0x37930000, 0x37938000, 0x37940000, 0x37948000, 0x37950000, 0x37958000, 0x37960000, 0x37968000, 0x37970000, 0x37978000,
1131 0x37980000, 0x37988000, 0x37990000, 0x37998000, 0x379A0000, 0x379A8000, 0x379B0000, 0x379B8000, 0x379C0000, 0x379C8000, 0x379D0000, 0x379D8000, 0x379E0000, 0x379E8000, 0x379F0000, 0x379F8000,
1132 0x37A00000, 0x37A08000, 0x37A10000, 0x37A18000, 0x37A20000, 0x37A28000, 0x37A30000, 0x37A38000, 0x37A40000, 0x37A48000, 0x37A50000, 0x37A58000, 0x37A60000, 0x37A68000, 0x37A70000, 0x37A78000,
1133 0x37A80000, 0x37A88000, 0x37A90000, 0x37A98000, 0x37AA0000, 0x37AA8000, 0x37AB0000, 0x37AB8000, 0x37AC0000, 0x37AC8000, 0x37AD0000, 0x37AD8000, 0x37AE0000, 0x37AE8000, 0x37AF0000, 0x37AF8000,
1134 0x37B00000, 0x37B08000, 0x37B10000, 0x37B18000, 0x37B20000, 0x37B28000, 0x37B30000, 0x37B38000, 0x37B40000, 0x37B48000, 0x37B50000, 0x37B58000, 0x37B60000, 0x37B68000, 0x37B70000, 0x37B78000,
1135 0x37B80000, 0x37B88000, 0x37B90000, 0x37B98000, 0x37BA0000, 0x37BA8000, 0x37BB0000, 0x37BB8000, 0x37BC0000, 0x37BC8000, 0x37BD0000, 0x37BD8000, 0x37BE0000, 0x37BE8000, 0x37BF0000, 0x37BF8000,
1136 0x37C00000, 0x37C08000, 0x37C10000, 0x37C18000, 0x37C20000, 0x37C28000, 0x37C30000, 0x37C38000, 0x37C40000, 0x37C48000, 0x37C50000, 0x37C58000, 0x37C60000, 0x37C68000, 0x37C70000, 0x37C78000,
1137 0x37C80000, 0x37C88000, 0x37C90000, 0x37C98000, 0x37CA0000, 0x37CA8000, 0x37CB0000, 0x37CB8000, 0x37CC0000, 0x37CC8000, 0x37CD0000, 0x37CD8000, 0x37CE0000, 0x37CE8000, 0x37CF0000, 0x37CF8000,
1138 0x37D00000, 0x37D08000, 0x37D10000, 0x37D18000, 0x37D20000, 0x37D28000, 0x37D30000, 0x37D38000, 0x37D40000, 0x37D48000, 0x37D50000, 0x37D58000, 0x37D60000, 0x37D68000, 0x37D70000, 0x37D78000,
1139 0x37D80000, 0x37D88000, 0x37D90000, 0x37D98000, 0x37DA0000, 0x37DA8000, 0x37DB0000, 0x37DB8000, 0x37DC0000, 0x37DC8000, 0x37DD0000, 0x37DD8000, 0x37DE0000, 0x37DE8000, 0x37DF0000, 0x37DF8000,
1140 0x37E00000, 0x37E08000, 0x37E10000, 0x37E18000, 0x37E20000, 0x37E28000, 0x37E30000, 0x37E38000, 0x37E40000, 0x37E48000, 0x37E50000, 0x37E58000, 0x37E60000, 0x37E68000, 0x37E70000, 0x37E78000,
1141 0x37E80000, 0x37E88000, 0x37E90000, 0x37E98000, 0x37EA0000, 0x37EA8000, 0x37EB0000, 0x37EB8000, 0x37EC0000, 0x37EC8000, 0x37ED0000, 0x37ED8000, 0x37EE0000, 0x37EE8000, 0x37EF0000, 0x37EF8000,
1142 0x37F00000, 0x37F08000, 0x37F10000, 0x37F18000, 0x37F20000, 0x37F28000, 0x37F30000, 0x37F38000, 0x37F40000, 0x37F48000, 0x37F50000, 0x37F58000, 0x37F60000, 0x37F68000, 0x37F70000, 0x37F78000,
1143 0x37F80000, 0x37F88000, 0x37F90000, 0x37F98000, 0x37FA0000, 0x37FA8000, 0x37FB0000, 0x37FB8000, 0x37FC0000, 0x37FC8000, 0x37FD0000, 0x37FD8000, 0x37FE0000, 0x37FE8000, 0x37FF0000, 0x37FF8000,
1144 0x38000000, 0x38004000, 0x38008000, 0x3800C000, 0x38010000, 0x38014000, 0x38018000, 0x3801C000, 0x38020000, 0x38024000, 0x38028000, 0x3802C000, 0x38030000, 0x38034000, 0x38038000, 0x3803C000,
1145 0x38040000, 0x38044000, 0x38048000, 0x3804C000, 0x38050000, 0x38054000, 0x38058000, 0x3805C000, 0x38060000, 0x38064000, 0x38068000, 0x3806C000, 0x38070000, 0x38074000, 0x38078000, 0x3807C000,
1146 0x38080000, 0x38084000, 0x38088000, 0x3808C000, 0x38090000, 0x38094000, 0x38098000, 0x3809C000, 0x380A0000, 0x380A4000, 0x380A8000, 0x380AC000, 0x380B0000, 0x380B4000, 0x380B8000, 0x380BC000,
1147 0x380C0000, 0x380C4000, 0x380C8000, 0x380CC000, 0x380D0000, 0x380D4000, 0x380D8000, 0x380DC000, 0x380E0000, 0x380E4000, 0x380E8000, 0x380EC000, 0x380F0000, 0x380F4000, 0x380F8000, 0x380FC000,
1148 0x38100000, 0x38104000, 0x38108000, 0x3810C000, 0x38110000, 0x38114000, 0x38118000, 0x3811C000, 0x38120000, 0x38124000, 0x38128000, 0x3812C000, 0x38130000, 0x38134000, 0x38138000, 0x3813C000,
1149 0x38140000, 0x38144000, 0x38148000, 0x3814C000, 0x38150000, 0x38154000, 0x38158000, 0x3815C000, 0x38160000, 0x38164000, 0x38168000, 0x3816C000, 0x38170000, 0x38174000, 0x38178000, 0x3817C000,
1150 0x38180000, 0x38184000, 0x38188000, 0x3818C000, 0x38190000, 0x38194000, 0x38198000, 0x3819C000, 0x381A0000, 0x381A4000, 0x381A8000, 0x381AC000, 0x381B0000, 0x381B4000, 0x381B8000, 0x381BC000,
1151 0x381C0000, 0x381C4000, 0x381C8000, 0x381CC000, 0x381D0000, 0x381D4000, 0x381D8000, 0x381DC000, 0x381E0000, 0x381E4000, 0x381E8000, 0x381EC000, 0x381F0000, 0x381F4000, 0x381F8000, 0x381FC000,
1152 0x38200000, 0x38204000, 0x38208000, 0x3820C000, 0x38210000, 0x38214000, 0x38218000, 0x3821C000, 0x38220000, 0x38224000, 0x38228000, 0x3822C000, 0x38230000, 0x38234000, 0x38238000, 0x3823C000,
1153 0x38240000, 0x38244000, 0x38248000, 0x3824C000, 0x38250000, 0x38254000, 0x38258000, 0x3825C000, 0x38260000, 0x38264000, 0x38268000, 0x3826C000, 0x38270000, 0x38274000, 0x38278000, 0x3827C000,
1154 0x38280000, 0x38284000, 0x38288000, 0x3828C000, 0x38290000, 0x38294000, 0x38298000, 0x3829C000, 0x382A0000, 0x382A4000, 0x382A8000, 0x382AC000, 0x382B0000, 0x382B4000, 0x382B8000, 0x382BC000,
1155 0x382C0000, 0x382C4000, 0x382C8000, 0x382CC000, 0x382D0000, 0x382D4000, 0x382D8000, 0x382DC000, 0x382E0000, 0x382E4000, 0x382E8000, 0x382EC000, 0x382F0000, 0x382F4000, 0x382F8000, 0x382FC000,
1156 0x38300000, 0x38304000, 0x38308000, 0x3830C000, 0x38310000, 0x38314000, 0x38318000, 0x3831C000, 0x38320000, 0x38324000, 0x38328000, 0x3832C000, 0x38330000, 0x38334000, 0x38338000, 0x3833C000,
1157 0x38340000, 0x38344000, 0x38348000, 0x3834C000, 0x38350000, 0x38354000, 0x38358000, 0x3835C000, 0x38360000, 0x38364000, 0x38368000, 0x3836C000, 0x38370000, 0x38374000, 0x38378000, 0x3837C000,
1158 0x38380000, 0x38384000, 0x38388000, 0x3838C000, 0x38390000, 0x38394000, 0x38398000, 0x3839C000, 0x383A0000, 0x383A4000, 0x383A8000, 0x383AC000, 0x383B0000, 0x383B4000, 0x383B8000, 0x383BC000,
1159 0x383C0000, 0x383C4000, 0x383C8000, 0x383CC000, 0x383D0000, 0x383D4000, 0x383D8000, 0x383DC000, 0x383E0000, 0x383E4000, 0x383E8000, 0x383EC000, 0x383F0000, 0x383F4000, 0x383F8000, 0x383FC000,
1160 0x38400000, 0x38404000, 0x38408000, 0x3840C000, 0x38410000, 0x38414000, 0x38418000, 0x3841C000, 0x38420000, 0x38424000, 0x38428000, 0x3842C000, 0x38430000, 0x38434000, 0x38438000, 0x3843C000,
1161 0x38440000, 0x38444000, 0x38448000, 0x3844C000, 0x38450000, 0x38454000, 0x38458000, 0x3845C000, 0x38460000, 0x38464000, 0x38468000, 0x3846C000, 0x38470000, 0x38474000, 0x38478000, 0x3847C000,
1162 0x38480000, 0x38484000, 0x38488000, 0x3848C000, 0x38490000, 0x38494000, 0x38498000, 0x3849C000, 0x384A0000, 0x384A4000, 0x384A8000, 0x384AC000, 0x384B0000, 0x384B4000, 0x384B8000, 0x384BC000,
1163 0x384C0000, 0x384C4000, 0x384C8000, 0x384CC000, 0x384D0000, 0x384D4000, 0x384D8000, 0x384DC000, 0x384E0000, 0x384E4000, 0x384E8000, 0x384EC000, 0x384F0000, 0x384F4000, 0x384F8000, 0x384FC000,
1164 0x38500000, 0x38504000, 0x38508000, 0x3850C000, 0x38510000, 0x38514000, 0x38518000, 0x3851C000, 0x38520000, 0x38524000, 0x38528000, 0x3852C000, 0x38530000, 0x38534000, 0x38538000, 0x3853C000,
1165 0x38540000, 0x38544000, 0x38548000, 0x3854C000, 0x38550000, 0x38554000, 0x38558000, 0x3855C000, 0x38560000, 0x38564000, 0x38568000, 0x3856C000, 0x38570000, 0x38574000, 0x38578000, 0x3857C000,
1166 0x38580000, 0x38584000, 0x38588000, 0x3858C000, 0x38590000, 0x38594000, 0x38598000, 0x3859C000, 0x385A0000, 0x385A4000, 0x385A8000, 0x385AC000, 0x385B0000, 0x385B4000, 0x385B8000, 0x385BC000,
1167 0x385C0000, 0x385C4000, 0x385C8000, 0x385CC000, 0x385D0000, 0x385D4000, 0x385D8000, 0x385DC000, 0x385E0000, 0x385E4000, 0x385E8000, 0x385EC000, 0x385F0000, 0x385F4000, 0x385F8000, 0x385FC000,
1168 0x38600000, 0x38604000, 0x38608000, 0x3860C000, 0x38610000, 0x38614000, 0x38618000, 0x3861C000, 0x38620000, 0x38624000, 0x38628000, 0x3862C000, 0x38630000, 0x38634000, 0x38638000, 0x3863C000,
1169 0x38640000, 0x38644000, 0x38648000, 0x3864C000, 0x38650000, 0x38654000, 0x38658000, 0x3865C000, 0x38660000, 0x38664000, 0x38668000, 0x3866C000, 0x38670000, 0x38674000, 0x38678000, 0x3867C000,
1170 0x38680000, 0x38684000, 0x38688000, 0x3868C000, 0x38690000, 0x38694000, 0x38698000, 0x3869C000, 0x386A0000, 0x386A4000, 0x386A8000, 0x386AC000, 0x386B0000, 0x386B4000, 0x386B8000, 0x386BC000,
1171 0x386C0000, 0x386C4000, 0x386C8000, 0x386CC000, 0x386D0000, 0x386D4000, 0x386D8000, 0x386DC000, 0x386E0000, 0x386E4000, 0x386E8000, 0x386EC000, 0x386F0000, 0x386F4000, 0x386F8000, 0x386FC000,
1172 0x38700000, 0x38704000, 0x38708000, 0x3870C000, 0x38710000, 0x38714000, 0x38718000, 0x3871C000, 0x38720000, 0x38724000, 0x38728000, 0x3872C000, 0x38730000, 0x38734000, 0x38738000, 0x3873C000,
1173 0x38740000, 0x38744000, 0x38748000, 0x3874C000, 0x38750000, 0x38754000, 0x38758000, 0x3875C000, 0x38760000, 0x38764000, 0x38768000, 0x3876C000, 0x38770000, 0x38774000, 0x38778000, 0x3877C000,
1174 0x38780000, 0x38784000, 0x38788000, 0x3878C000, 0x38790000, 0x38794000, 0x38798000, 0x3879C000, 0x387A0000, 0x387A4000, 0x387A8000, 0x387AC000, 0x387B0000, 0x387B4000, 0x387B8000, 0x387BC000,
1175 0x387C0000, 0x387C4000, 0x387C8000, 0x387CC000, 0x387D0000, 0x387D4000, 0x387D8000, 0x387DC000, 0x387E0000, 0x387E4000, 0x387E8000, 0x387EC000, 0x387F0000, 0x387F4000, 0x387F8000, 0x387FC000,
1176 0x38000000, 0x38002000, 0x38004000, 0x38006000, 0x38008000, 0x3800A000, 0x3800C000, 0x3800E000, 0x38010000, 0x38012000, 0x38014000, 0x38016000, 0x38018000, 0x3801A000, 0x3801C000, 0x3801E000,
1177 0x38020000, 0x38022000, 0x38024000, 0x38026000, 0x38028000, 0x3802A000, 0x3802C000, 0x3802E000, 0x38030000, 0x38032000, 0x38034000, 0x38036000, 0x38038000, 0x3803A000, 0x3803C000, 0x3803E000,
1178 0x38040000, 0x38042000, 0x38044000, 0x38046000, 0x38048000, 0x3804A000, 0x3804C000, 0x3804E000, 0x38050000, 0x38052000, 0x38054000, 0x38056000, 0x38058000, 0x3805A000, 0x3805C000, 0x3805E000,
1179 0x38060000, 0x38062000, 0x38064000, 0x38066000, 0x38068000, 0x3806A000, 0x3806C000, 0x3806E000, 0x38070000, 0x38072000, 0x38074000, 0x38076000, 0x38078000, 0x3807A000, 0x3807C000, 0x3807E000,
1180 0x38080000, 0x38082000, 0x38084000, 0x38086000, 0x38088000, 0x3808A000, 0x3808C000, 0x3808E000, 0x38090000, 0x38092000, 0x38094000, 0x38096000, 0x38098000, 0x3809A000, 0x3809C000, 0x3809E000,
1181 0x380A0000, 0x380A2000, 0x380A4000, 0x380A6000, 0x380A8000, 0x380AA000, 0x380AC000, 0x380AE000, 0x380B0000, 0x380B2000, 0x380B4000, 0x380B6000, 0x380B8000, 0x380BA000, 0x380BC000, 0x380BE000,
1182 0x380C0000, 0x380C2000, 0x380C4000, 0x380C6000, 0x380C8000, 0x380CA000, 0x380CC000, 0x380CE000, 0x380D0000, 0x380D2000, 0x380D4000, 0x380D6000, 0x380D8000, 0x380DA000, 0x380DC000, 0x380DE000,
1183 0x380E0000, 0x380E2000, 0x380E4000, 0x380E6000, 0x380E8000, 0x380EA000, 0x380EC000, 0x380EE000, 0x380F0000, 0x380F2000, 0x380F4000, 0x380F6000, 0x380F8000, 0x380FA000, 0x380FC000, 0x380FE000,
1184 0x38100000, 0x38102000, 0x38104000, 0x38106000, 0x38108000, 0x3810A000, 0x3810C000, 0x3810E000, 0x38110000, 0x38112000, 0x38114000, 0x38116000, 0x38118000, 0x3811A000, 0x3811C000, 0x3811E000,
1185 0x38120000, 0x38122000, 0x38124000, 0x38126000, 0x38128000, 0x3812A000, 0x3812C000, 0x3812E000, 0x38130000, 0x38132000, 0x38134000, 0x38136000, 0x38138000, 0x3813A000, 0x3813C000, 0x3813E000,
1186 0x38140000, 0x38142000, 0x38144000, 0x38146000, 0x38148000, 0x3814A000, 0x3814C000, 0x3814E000, 0x38150000, 0x38152000, 0x38154000, 0x38156000, 0x38158000, 0x3815A000, 0x3815C000, 0x3815E000,
1187 0x38160000, 0x38162000, 0x38164000, 0x38166000, 0x38168000, 0x3816A000, 0x3816C000, 0x3816E000, 0x38170000, 0x38172000, 0x38174000, 0x38176000, 0x38178000, 0x3817A000, 0x3817C000, 0x3817E000,
1188 0x38180000, 0x38182000, 0x38184000, 0x38186000, 0x38188000, 0x3818A000, 0x3818C000, 0x3818E000, 0x38190000, 0x38192000, 0x38194000, 0x38196000, 0x38198000, 0x3819A000, 0x3819C000, 0x3819E000,
1189 0x381A0000, 0x381A2000, 0x381A4000, 0x381A6000, 0x381A8000, 0x381AA000, 0x381AC000, 0x381AE000, 0x381B0000, 0x381B2000, 0x381B4000, 0x381B6000, 0x381B8000, 0x381BA000, 0x381BC000, 0x381BE000,
1190 0x381C0000, 0x381C2000, 0x381C4000, 0x381C6000, 0x381C8000, 0x381CA000, 0x381CC000, 0x381CE000, 0x381D0000, 0x381D2000, 0x381D4000, 0x381D6000, 0x381D8000, 0x381DA000, 0x381DC000, 0x381DE000,
1191 0x381E0000, 0x381E2000, 0x381E4000, 0x381E6000, 0x381E8000, 0x381EA000, 0x381EC000, 0x381EE000, 0x381F0000, 0x381F2000, 0x381F4000, 0x381F6000, 0x381F8000, 0x381FA000, 0x381FC000, 0x381FE000,
1192 0x38200000, 0x38202000, 0x38204000, 0x38206000, 0x38208000, 0x3820A000, 0x3820C000, 0x3820E000, 0x38210000, 0x38212000, 0x38214000, 0x38216000, 0x38218000, 0x3821A000, 0x3821C000, 0x3821E000,
1193 0x38220000, 0x38222000, 0x38224000, 0x38226000, 0x38228000, 0x3822A000, 0x3822C000, 0x3822E000, 0x38230000, 0x38232000, 0x38234000, 0x38236000, 0x38238000, 0x3823A000, 0x3823C000, 0x3823E000,
1194 0x38240000, 0x38242000, 0x38244000, 0x38246000, 0x38248000, 0x3824A000, 0x3824C000, 0x3824E000, 0x38250000, 0x38252000, 0x38254000, 0x38256000, 0x38258000, 0x3825A000, 0x3825C000, 0x3825E000,
1195 0x38260000, 0x38262000, 0x38264000, 0x38266000, 0x38268000, 0x3826A000, 0x3826C000, 0x3826E000, 0x38270000, 0x38272000, 0x38274000, 0x38276000, 0x38278000, 0x3827A000, 0x3827C000, 0x3827E000,
1196 0x38280000, 0x38282000, 0x38284000, 0x38286000, 0x38288000, 0x3828A000, 0x3828C000, 0x3828E000, 0x38290000, 0x38292000, 0x38294000, 0x38296000, 0x38298000, 0x3829A000, 0x3829C000, 0x3829E000,
1197 0x382A0000, 0x382A2000, 0x382A4000, 0x382A6000, 0x382A8000, 0x382AA000, 0x382AC000, 0x382AE000, 0x382B0000, 0x382B2000, 0x382B4000, 0x382B6000, 0x382B8000, 0x382BA000, 0x382BC000, 0x382BE000,
1198 0x382C0000, 0x382C2000, 0x382C4000, 0x382C6000, 0x382C8000, 0x382CA000, 0x382CC000, 0x382CE000, 0x382D0000, 0x382D2000, 0x382D4000, 0x382D6000, 0x382D8000, 0x382DA000, 0x382DC000, 0x382DE000,
1199 0x382E0000, 0x382E2000, 0x382E4000, 0x382E6000, 0x382E8000, 0x382EA000, 0x382EC000, 0x382EE000, 0x382F0000, 0x382F2000, 0x382F4000, 0x382F6000, 0x382F8000, 0x382FA000, 0x382FC000, 0x382FE000,
1200 0x38300000, 0x38302000, 0x38304000, 0x38306000, 0x38308000, 0x3830A000, 0x3830C000, 0x3830E000, 0x38310000, 0x38312000, 0x38314000, 0x38316000, 0x38318000, 0x3831A000, 0x3831C000, 0x3831E000,
1201 0x38320000, 0x38322000, 0x38324000, 0x38326000, 0x38328000, 0x3832A000, 0x3832C000, 0x3832E000, 0x38330000, 0x38332000, 0x38334000, 0x38336000, 0x38338000, 0x3833A000, 0x3833C000, 0x3833E000,
1202 0x38340000, 0x38342000, 0x38344000, 0x38346000, 0x38348000, 0x3834A000, 0x3834C000, 0x3834E000, 0x38350000, 0x38352000, 0x38354000, 0x38356000, 0x38358000, 0x3835A000, 0x3835C000, 0x3835E000,
1203 0x38360000, 0x38362000, 0x38364000, 0x38366000, 0x38368000, 0x3836A000, 0x3836C000, 0x3836E000, 0x38370000, 0x38372000, 0x38374000, 0x38376000, 0x38378000, 0x3837A000, 0x3837C000, 0x3837E000,
1204 0x38380000, 0x38382000, 0x38384000, 0x38386000, 0x38388000, 0x3838A000, 0x3838C000, 0x3838E000, 0x38390000, 0x38392000, 0x38394000, 0x38396000, 0x38398000, 0x3839A000, 0x3839C000, 0x3839E000,
1205 0x383A0000, 0x383A2000, 0x383A4000, 0x383A6000, 0x383A8000, 0x383AA000, 0x383AC000, 0x383AE000, 0x383B0000, 0x383B2000, 0x383B4000, 0x383B6000, 0x383B8000, 0x383BA000, 0x383BC000, 0x383BE000,
1206 0x383C0000, 0x383C2000, 0x383C4000, 0x383C6000, 0x383C8000, 0x383CA000, 0x383CC000, 0x383CE000, 0x383D0000, 0x383D2000, 0x383D4000, 0x383D6000, 0x383D8000, 0x383DA000, 0x383DC000, 0x383DE000,
1207 0x383E0000, 0x383E2000, 0x383E4000, 0x383E6000, 0x383E8000, 0x383EA000, 0x383EC000, 0x383EE000, 0x383F0000, 0x383F2000, 0x383F4000, 0x383F6000, 0x383F8000, 0x383FA000, 0x383FC000, 0x383FE000,
1208 0x38400000, 0x38402000, 0x38404000, 0x38406000, 0x38408000, 0x3840A000, 0x3840C000, 0x3840E000, 0x38410000, 0x38412000, 0x38414000, 0x38416000, 0x38418000, 0x3841A000, 0x3841C000, 0x3841E000,
1209 0x38420000, 0x38422000, 0x38424000, 0x38426000, 0x38428000, 0x3842A000, 0x3842C000, 0x3842E000, 0x38430000, 0x38432000, 0x38434000, 0x38436000, 0x38438000, 0x3843A000, 0x3843C000, 0x3843E000,
1210 0x38440000, 0x38442000, 0x38444000, 0x38446000, 0x38448000, 0x3844A000, 0x3844C000, 0x3844E000, 0x38450000, 0x38452000, 0x38454000, 0x38456000, 0x38458000, 0x3845A000, 0x3845C000, 0x3845E000,
1211 0x38460000, 0x38462000, 0x38464000, 0x38466000, 0x38468000, 0x3846A000, 0x3846C000, 0x3846E000, 0x38470000, 0x38472000, 0x38474000, 0x38476000, 0x38478000, 0x3847A000, 0x3847C000, 0x3847E000,
1212 0x38480000, 0x38482000, 0x38484000, 0x38486000, 0x38488000, 0x3848A000, 0x3848C000, 0x3848E000, 0x38490000, 0x38492000, 0x38494000, 0x38496000, 0x38498000, 0x3849A000, 0x3849C000, 0x3849E000,
1213 0x384A0000, 0x384A2000, 0x384A4000, 0x384A6000, 0x384A8000, 0x384AA000, 0x384AC000, 0x384AE000, 0x384B0000, 0x384B2000, 0x384B4000, 0x384B6000, 0x384B8000, 0x384BA000, 0x384BC000, 0x384BE000,
1214 0x384C0000, 0x384C2000, 0x384C4000, 0x384C6000, 0x384C8000, 0x384CA000, 0x384CC000, 0x384CE000, 0x384D0000, 0x384D2000, 0x384D4000, 0x384D6000, 0x384D8000, 0x384DA000, 0x384DC000, 0x384DE000,
1215 0x384E0000, 0x384E2000, 0x384E4000, 0x384E6000, 0x384E8000, 0x384EA000, 0x384EC000, 0x384EE000, 0x384F0000, 0x384F2000, 0x384F4000, 0x384F6000, 0x384F8000, 0x384FA000, 0x384FC000, 0x384FE000,
1216 0x38500000, 0x38502000, 0x38504000, 0x38506000, 0x38508000, 0x3850A000, 0x3850C000, 0x3850E000, 0x38510000, 0x38512000, 0x38514000, 0x38516000, 0x38518000, 0x3851A000, 0x3851C000, 0x3851E000,
1217 0x38520000, 0x38522000, 0x38524000, 0x38526000, 0x38528000, 0x3852A000, 0x3852C000, 0x3852E000, 0x38530000, 0x38532000, 0x38534000, 0x38536000, 0x38538000, 0x3853A000, 0x3853C000, 0x3853E000,
1218 0x38540000, 0x38542000, 0x38544000, 0x38546000, 0x38548000, 0x3854A000, 0x3854C000, 0x3854E000, 0x38550000, 0x38552000, 0x38554000, 0x38556000, 0x38558000, 0x3855A000, 0x3855C000, 0x3855E000,
1219 0x38560000, 0x38562000, 0x38564000, 0x38566000, 0x38568000, 0x3856A000, 0x3856C000, 0x3856E000, 0x38570000, 0x38572000, 0x38574000, 0x38576000, 0x38578000, 0x3857A000, 0x3857C000, 0x3857E000,
1220 0x38580000, 0x38582000, 0x38584000, 0x38586000, 0x38588000, 0x3858A000, 0x3858C000, 0x3858E000, 0x38590000, 0x38592000, 0x38594000, 0x38596000, 0x38598000, 0x3859A000, 0x3859C000, 0x3859E000,
1221 0x385A0000, 0x385A2000, 0x385A4000, 0x385A6000, 0x385A8000, 0x385AA000, 0x385AC000, 0x385AE000, 0x385B0000, 0x385B2000, 0x385B4000, 0x385B6000, 0x385B8000, 0x385BA000, 0x385BC000, 0x385BE000,
1222 0x385C0000, 0x385C2000, 0x385C4000, 0x385C6000, 0x385C8000, 0x385CA000, 0x385CC000, 0x385CE000, 0x385D0000, 0x385D2000, 0x385D4000, 0x385D6000, 0x385D8000, 0x385DA000, 0x385DC000, 0x385DE000,
1223 0x385E0000, 0x385E2000, 0x385E4000, 0x385E6000, 0x385E8000, 0x385EA000, 0x385EC000, 0x385EE000, 0x385F0000, 0x385F2000, 0x385F4000, 0x385F6000, 0x385F8000, 0x385FA000, 0x385FC000, 0x385FE000,
1224 0x38600000, 0x38602000, 0x38604000, 0x38606000, 0x38608000, 0x3860A000, 0x3860C000, 0x3860E000, 0x38610000, 0x38612000, 0x38614000, 0x38616000, 0x38618000, 0x3861A000, 0x3861C000, 0x3861E000,
1225 0x38620000, 0x38622000, 0x38624000, 0x38626000, 0x38628000, 0x3862A000, 0x3862C000, 0x3862E000, 0x38630000, 0x38632000, 0x38634000, 0x38636000, 0x38638000, 0x3863A000, 0x3863C000, 0x3863E000,
1226 0x38640000, 0x38642000, 0x38644000, 0x38646000, 0x38648000, 0x3864A000, 0x3864C000, 0x3864E000, 0x38650000, 0x38652000, 0x38654000, 0x38656000, 0x38658000, 0x3865A000, 0x3865C000, 0x3865E000,
1227 0x38660000, 0x38662000, 0x38664000, 0x38666000, 0x38668000, 0x3866A000, 0x3866C000, 0x3866E000, 0x38670000, 0x38672000, 0x38674000, 0x38676000, 0x38678000, 0x3867A000, 0x3867C000, 0x3867E000,
1228 0x38680000, 0x38682000, 0x38684000, 0x38686000, 0x38688000, 0x3868A000, 0x3868C000, 0x3868E000, 0x38690000, 0x38692000, 0x38694000, 0x38696000, 0x38698000, 0x3869A000, 0x3869C000, 0x3869E000,
1229 0x386A0000, 0x386A2000, 0x386A4000, 0x386A6000, 0x386A8000, 0x386AA000, 0x386AC000, 0x386AE000, 0x386B0000, 0x386B2000, 0x386B4000, 0x386B6000, 0x386B8000, 0x386BA000, 0x386BC000, 0x386BE000,
1230 0x386C0000, 0x386C2000, 0x386C4000, 0x386C6000, 0x386C8000, 0x386CA000, 0x386CC000, 0x386CE000, 0x386D0000, 0x386D2000, 0x386D4000, 0x386D6000, 0x386D8000, 0x386DA000, 0x386DC000, 0x386DE000,
1231 0x386E0000, 0x386E2000, 0x386E4000, 0x386E6000, 0x386E8000, 0x386EA000, 0x386EC000, 0x386EE000, 0x386F0000, 0x386F2000, 0x386F4000, 0x386F6000, 0x386F8000, 0x386FA000, 0x386FC000, 0x386FE000,
1232 0x38700000, 0x38702000, 0x38704000, 0x38706000, 0x38708000, 0x3870A000, 0x3870C000, 0x3870E000, 0x38710000, 0x38712000, 0x38714000, 0x38716000, 0x38718000, 0x3871A000, 0x3871C000, 0x3871E000,
1233 0x38720000, 0x38722000, 0x38724000, 0x38726000, 0x38728000, 0x3872A000, 0x3872C000, 0x3872E000, 0x38730000, 0x38732000, 0x38734000, 0x38736000, 0x38738000, 0x3873A000, 0x3873C000, 0x3873E000,
1234 0x38740000, 0x38742000, 0x38744000, 0x38746000, 0x38748000, 0x3874A000, 0x3874C000, 0x3874E000, 0x38750000, 0x38752000, 0x38754000, 0x38756000, 0x38758000, 0x3875A000, 0x3875C000, 0x3875E000,
1235 0x38760000, 0x38762000, 0x38764000, 0x38766000, 0x38768000, 0x3876A000, 0x3876C000, 0x3876E000, 0x38770000, 0x38772000, 0x38774000, 0x38776000, 0x38778000, 0x3877A000, 0x3877C000, 0x3877E000,
1236 0x38780000, 0x38782000, 0x38784000, 0x38786000, 0x38788000, 0x3878A000, 0x3878C000, 0x3878E000, 0x38790000, 0x38792000, 0x38794000, 0x38796000, 0x38798000, 0x3879A000, 0x3879C000, 0x3879E000,
1237 0x387A0000, 0x387A2000, 0x387A4000, 0x387A6000, 0x387A8000, 0x387AA000, 0x387AC000, 0x387AE000, 0x387B0000, 0x387B2000, 0x387B4000, 0x387B6000, 0x387B8000, 0x387BA000, 0x387BC000, 0x387BE000,
1238 0x387C0000, 0x387C2000, 0x387C4000, 0x387C6000, 0x387C8000, 0x387CA000, 0x387CC000, 0x387CE000, 0x387D0000, 0x387D2000, 0x387D4000, 0x387D6000, 0x387D8000, 0x387DA000, 0x387DC000, 0x387DE000,
1239 0x387E0000, 0x387E2000, 0x387E4000, 0x387E6000, 0x387E8000, 0x387EA000, 0x387EC000, 0x387EE000, 0x387F0000, 0x387F2000, 0x387F4000, 0x387F6000, 0x387F8000, 0x387FA000, 0x387FC000, 0x387FE000 };
1240 static const bits<float>::type exponent_table[64] = {
1241 0x00000000, 0x00800000, 0x01000000, 0x01800000, 0x02000000, 0x02800000, 0x03000000, 0x03800000, 0x04000000, 0x04800000, 0x05000000, 0x05800000, 0x06000000, 0x06800000, 0x07000000, 0x07800000,
1242 0x08000000, 0x08800000, 0x09000000, 0x09800000, 0x0A000000, 0x0A800000, 0x0B000000, 0x0B800000, 0x0C000000, 0x0C800000, 0x0D000000, 0x0D800000, 0x0E000000, 0x0E800000, 0x0F000000, 0x47800000,
1243 0x80000000, 0x80800000, 0x81000000, 0x81800000, 0x82000000, 0x82800000, 0x83000000, 0x83800000, 0x84000000, 0x84800000, 0x85000000, 0x85800000, 0x86000000, 0x86800000, 0x87000000, 0x87800000,
1244 0x88000000, 0x88800000, 0x89000000, 0x89800000, 0x8A000000, 0x8A800000, 0x8B000000, 0x8B800000, 0x8C000000, 0x8C800000, 0x8D000000, 0x8D800000, 0x8E000000, 0x8E800000, 0x8F000000, 0xC7800000 };
1245 static const unsigned short offset_table[64] = {
1246 0, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1247 0, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024 };
1248 bits<float>::type fbits = mantissa_table[offset_table[value>>10]+(value&0x3FF)] + exponent_table[value>>10];
1251 std::memcpy(&out, &fbits,
sizeof(
float));
1259 inline double half2float_impl(
unsigned int value,
double, true_type)
1261 #if HALF_ENABLE_F16C_INTRINSICS
1262 return _mm_cvtsd_f64(_mm_cvtps_pd(_mm_cvtph_ps(_mm_cvtsi32_si128(value))));
1264 uint32 hi =
static_cast<uint32
>(value&0x8000) << 16;
1265 unsigned int abs = value & 0x7FFF;
1268 hi |= 0x3F000000 <<
static_cast<unsigned>(
abs>=0x7C00);
1269 for(;
abs<0x400;
abs<<=1,hi-=0x100000) ;
1270 hi +=
static_cast<uint32
>(
abs) << 10;
1272 bits<double>::type dbits =
static_cast<bits<double>::type
>(hi) << 32;
1274 std::memcpy(&out, &dbits,
sizeof(
double));
1283 template<
typename T> T half2float_impl(
unsigned int value, T, ...)
1286 unsigned int abs = value & 0x7FFF;
1288 out = (std::numeric_limits<T>::has_signaling_NaN && !(
abs&0x200)) ? std::numeric_limits<T>::signaling_NaN() :
1289 std::numeric_limits<T>::has_quiet_NaN ?
std::numeric_limits<T>::quiet_NaN() : T();
1290 else if(
abs == 0x7C00)
1291 out = std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() :
std::numeric_limits<T>::max();
1292 else if(
abs > 0x3FF)
1296 return (value&0x8000) ? -out : out;
1303 template<
typename T> T half2float(
unsigned int value)
1305 return half2float_impl(value, T(), bool_type<std::numeric_limits<T>::is_iec559&&
sizeof(
typename bits<T>::type)==
sizeof(T)>());
1317 template<std::
float_round_style R,
bool E,
bool I,
typename T> T half2int(
unsigned int value)
1319 unsigned int abs = value & 0x7FFF;
1323 return (value&0x8000) ? std::numeric_limits<T>::min() :
std::numeric_limits<T>::max();
1327 raise(FE_INEXACT, I);
1328 return (R==std::round_toward_infinity) ? T(~(value>>15)&(
abs!=0)) :
1329 (R==
std::round_toward_neg_infinity) ? -T(value>0x8000) :
1332 int exp = 25 - (
abs>>10);
1333 unsigned int m = (value&0x3FF) | 0x400;
1334 int32 i =
static_cast<int32
>((
exp<=0) ? (m<<-
exp) : ((m+(
1335 (R==std::round_to_nearest) ? ((1<<(
exp-1))-(~(m>>
exp)&E)) :
1336 (R==
std::round_toward_infinity) ? (((1<<
exp)-1)&((value>>15)-1)) :
1337 (R==
std::round_toward_neg_infinity) ? (((1<<
exp)-1)&-(value>>15)) : 0))>>
exp));
1338 if((!std::numeric_limits<T>::is_signed && (value&0x8000)) || (std::numeric_limits<T>::digits<16 &&
1339 ((value&0x8000) ? (-i<std::numeric_limits<T>::min()) : (i>std::numeric_limits<T>::max()))))
1341 else if(I &&
exp > 0 && (m&((1<<
exp)-1)))
1343 return static_cast<T
>((value&0x8000) ? -i : i);
1355 template<std::
float_round_style R> uint32 mulhi(uint32 x, uint32 y)
1357 uint32 xy = (x>>16) * (y&0xFFFF), yx = (x&0xFFFF) * (y>>16), c = (xy&0xFFFF) + (yx&0xFFFF) + (((x&0xFFFF)*(y&0xFFFF))>>16);
1358 return (x>>16)*(y>>16) + (xy>>16) + (yx>>16) + (c>>16) +
1359 ((R==std::round_to_nearest) ? ((c>>15)&1) : (R==std::round_toward_infinity) ? ((c&0xFFFF)!=0) : 0);
1366 inline uint32 multiply64(uint32 x, uint32 y)
1368 #if HALF_ENABLE_CPP11_LONG_LONG
1369 return static_cast<uint32
>((
static_cast<unsigned long long>(x)*
static_cast<unsigned long long>(y)+0x80000000)>>32);
1371 return mulhi<std::round_to_nearest>(x, y);
1380 inline uint32 divide64(uint32 x, uint32 y,
int &s)
1382 #if HALF_ENABLE_CPP11_LONG_LONG
1383 unsigned long long xx =
static_cast<unsigned long long>(x) << 32;
1384 return s = (xx%y!=0),
static_cast<uint32
>(xx/y);
1387 uint32 rem = x, div = 0;
1388 for(
unsigned int i=0; i<32; ++i)
1398 return s = rem > 1, div;
1409 template<
bool Q,
bool R>
unsigned int mod(
unsigned int x,
unsigned int y,
int *quo = NULL)
1414 int absx = x, absy = y, expx = 0, expy = 0;
1415 for(; absx<0x400; absx<<=1,--expx) ;
1416 for(; absy<0x400; absy<<=1,--expy) ;
1419 int mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400;
1420 for(
int d=expx-expy; d; --d)
1430 q <<= static_cast<int>(Q);
1441 q &= (1<<(std::numeric_limits<int>::digits-1)) - 1;
1445 for(; mx<0x400; mx<<=1,--expy) ;
1446 x = (expy>0) ? ((expy<<10)|(mx&0x3FF)) : (mx>>(1-expy));
1453 a = (x<0x400) ? (x<<1) : (x+0x400);
1461 if(a > b || (a == b && (q&1)))
1463 int exp = (y>>10) + (y<=0x3FF), d =
exp - (x>>10) - (x<=0x3FF);
1464 int m = (((y&0x3FF)|((y>0x3FF)<<10))<<1) - (((x&0x3FF)|((x>0x3FF)<<10))<<(1-d));
1465 for(; m<0x800 && exp>1; m<<=1,--
exp) ;
1466 x = 0x8000 + ((
exp-1)<<10) + (m>>1);
1480 template<
unsigned int F> uint32
sqrt(uint32 &r,
int &
exp)
1486 for(uint32 bit=
static_cast<uint32
>(1)<<F; bit; bit>>=2)
1504 inline uint32
exp2(uint32 m,
unsigned int n = 32)
1506 static const uint32 logs[] = {
1507 0x80000000, 0x4AE00D1D, 0x2934F098, 0x15C01A3A, 0x0B31FB7D, 0x05AEB4DD, 0x02DCF2D1, 0x016FE50B,
1508 0x00B84E23, 0x005C3E10, 0x002E24CA, 0x001713D6, 0x000B8A47, 0x0005C53B, 0x0002E2A3, 0x00017153,
1509 0x0000B8AA, 0x00005C55, 0x00002E2B, 0x00001715, 0x00000B8B, 0x000005C5, 0x000002E3, 0x00000171,
1510 0x000000B9, 0x0000005C, 0x0000002E, 0x00000017, 0x0000000C, 0x00000006, 0x00000003, 0x00000001 };
1513 uint32 mx = 0x80000000, my = 0;
1514 for(
unsigned int i=1; i<n; ++i)
1516 uint32 mz = my + logs[i];
1531 inline uint32
log2(uint32 m,
unsigned int n = 32)
1533 static const uint32 logs[] = {
1534 0x80000000, 0x4AE00D1D, 0x2934F098, 0x15C01A3A, 0x0B31FB7D, 0x05AEB4DD, 0x02DCF2D1, 0x016FE50B,
1535 0x00B84E23, 0x005C3E10, 0x002E24CA, 0x001713D6, 0x000B8A47, 0x0005C53B, 0x0002E2A3, 0x00017153,
1536 0x0000B8AA, 0x00005C55, 0x00002E2B, 0x00001715, 0x00000B8B, 0x000005C5, 0x000002E3, 0x00000171,
1537 0x000000B9, 0x0000005C, 0x0000002E, 0x00000017, 0x0000000C, 0x00000006, 0x00000003, 0x00000001 };
1540 uint32 mx = 0x40000000, my = 0;
1541 for(
unsigned int i=1; i<n; ++i)
1543 uint32 mz = mx + (mx>>i);
1558 inline std::pair<uint32,uint32>
sincos(uint32 mz,
unsigned int n = 31)
1560 static const uint32 angles[] = {
1561 0x3243F6A9, 0x1DAC6705, 0x0FADBAFD, 0x07F56EA7, 0x03FEAB77, 0x01FFD55C, 0x00FFFAAB, 0x007FFF55,
1562 0x003FFFEB, 0x001FFFFD, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, 0x00008000,
1563 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080,
1564 0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 };
1565 uint32 mx = 0x26DD3B6A, my = 0;
1566 for(
unsigned int i=0; i<n; ++i)
1568 uint32 sign = sign_mask(mz);
1569 uint32 tx = mx - (arithmetic_shift(my, i)^sign) + sign;
1570 uint32 ty = my + (arithmetic_shift(mx, i)^sign) - sign;
1571 mx = tx; my = ty; mz -= (angles[i]^sign) - sign;
1573 return std::make_pair(my, mx);
1582 inline uint32
atan2(uint32 my, uint32 mx,
unsigned int n = 31)
1584 static const uint32 angles[] = {
1585 0x3243F6A9, 0x1DAC6705, 0x0FADBAFD, 0x07F56EA7, 0x03FEAB77, 0x01FFD55C, 0x00FFFAAB, 0x007FFF55,
1586 0x003FFFEB, 0x001FFFFD, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, 0x00008000,
1587 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080,
1588 0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 };
1590 for(
unsigned int i=0; i<n; ++i)
1592 uint32 sign = sign_mask(my);
1593 uint32 tx = mx + (arithmetic_shift(my, i)^sign) - sign;
1594 uint32 ty = my - (arithmetic_shift(mx, i)^sign) + sign;
1595 mx = tx; my = ty; mz += (angles[i]^sign) - sign;
1604 inline uint32 angle_arg(
unsigned int abs,
int &k)
1606 uint32 m = (
abs&0x3FF) | ((
abs>0x3FF)<<10);
1607 int exp = (
abs>>10) + (
abs<=0x3FF) - 15;
1609 return k = 0, m << (
exp+20);
1610 #if HALF_ENABLE_CPP11_LONG_LONG
1611 unsigned long long y = m * 0xA2F9836E4E442, mask = (1ULL<<(62-
exp)) - 1, yi = (y+(mask>>1)) & ~mask, f = y - yi;
1612 uint32 sign = -
static_cast<uint32
>(f>>63);
1613 k =
static_cast<int>(yi>>(62-
exp));
1614 return (multiply64(
static_cast<uint32
>((sign ? -f : f)>>(31-
exp)), 0xC90FDAA2)^sign) - sign;
1616 uint32 yh = m*0xA2F98 + mulhi<std::round_toward_zero>(m, 0x36E4E442), yl = (m*0x36E4E442) & 0xFFFFFFFF;
1617 uint32 mask = (
static_cast<uint32
>(1)<<(30-
exp)) - 1, yi = (yh+(mask>>1)) & ~mask, sign = -
static_cast<uint32
>(yi>yh);
1618 k =
static_cast<int>(yi>>(30-
exp));
1619 uint32 fh = (yh^sign) + (yi^~sign) - ~sign, fl = (yl^sign) - sign;
1620 return (multiply64((
exp>-1) ? (((fh<<(1+
exp))&0xFFFFFFFF)|((fl&0xFFFFFFFF)>>(31-
exp))) : fh, 0xC90FDAA2)^sign) - sign;
1627 inline std::pair<uint32,uint32> atan2_args(
unsigned int abs)
1632 uint32 my = ((
abs&0x3FF)|0x400) << 5, r = my * my;
1634 r = 0x40000000 - ((rexp>-31) ? ((r>>-rexp)|((r&((
static_cast<uint32
>(1)<<-rexp)-1))!=0)) : 1);
1635 for(rexp=0; r<0x40000000; r<<=1,--rexp) ;
1636 uint32 mx = sqrt<30>(r, rexp);
1639 return std::make_pair((d<-14) ? ((my>>(-d-14))+((my>>(-d-15))&1)) : (my<<(14+d)), (mx<<14)+(r<<13)/mx);
1641 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)));
1642 return std::make_pair(my<<13, (mx<<13)+(r<<12)/mx);
1650 inline std::pair<uint32,uint32> hyperbolic_args(
unsigned int abs,
int &
exp,
unsigned int n = 32)
1652 uint32 mx = detail::multiply64(
static_cast<uint32
>((
abs&0x3FF)+((
abs>0x3FF)<<10))<<21, 0xB8AA3B29), my;
1653 int e = (
abs>>10) + (
abs<=0x3FF);
1662 mx = (mx<<(e-14)) & 0x7FFFFFFF;
1665 int d =
exp << 1, s;
1668 my = divide64(0x80000000, mx, s);
1674 return std::make_pair(mx, (d<31) ? ((my>>d)|((my&((
static_cast<uint32
>(1)<<d)-1))!=0)) : 1);
1688 template<std::
float_round_style R>
unsigned int exp2_post(uint32 m,
int exp,
bool esign,
unsigned int sign = 0,
unsigned int n = 32)
1694 return underflow<R>(sign);
1696 return rounded<R,false>(sign, 1, m!=0);
1699 return overflow<R>(sign);
1701 return sign | (((
exp+=15)>0) ? (
exp<<10) : check_underflow(0x200>>-
exp));
1705 m = divide64(0x80000000, m, s);
1706 return fixed2half<R,31,false,false,true>(m,
exp+14, sign, s);
1720 template<std::
float_round_style R,u
int32 L>
unsigned int log2_post(uint32 m,
int ilog,
int exp,
unsigned int sign = 0)
1722 uint32 msign = sign_mask(ilog);
1723 m = (((
static_cast<uint32
>(ilog)<<27)+(m>>4))^msign) - msign;
1726 for(; m<0x80000000; m<<=1,--
exp) ;
1730 sign ^= msign & 0x8000;
1732 return underflow<R>(sign);
1733 m = divide64(m, L, s);
1734 return fixed2half<R,30,false,false,true>(m,
exp, sign, 1);
1745 template<std::
float_round_style R>
unsigned int hypot_post(uint32 r,
int exp)
1749 return overflow<R>();
1751 return underflow<R>();
1753 uint32 m = sqrt<30>(r,
exp+=15);
1754 return fixed2half<R,15,false,false,false>(m,
exp-1, 0, r!=0);
1767 template<std::
float_round_style R>
unsigned int tangent_post(uint32 my, uint32 mx,
int exp,
unsigned int sign = 0)
1769 int i = my >= mx, s;
1772 return overflow<R>(sign);
1774 return underflow<R>(sign);
1775 uint32 m = divide64(my>>(i+1), mx, s);
1776 return fixed2half<R,30,false,false,true>(m,
exp, sign, s);
1788 template<std::
float_round_style R,
bool S>
unsigned int area(
unsigned int arg)
1790 int abs = arg & 0x7FFF, expx = (
abs>>10) + (
abs<=0x3FF) - 15, expy = -15, ilog, i;
1791 uint32 mx =
static_cast<uint32
>((
abs&0x3FF)|((
abs>0x3FF)<<10)) << 20, my, r;
1792 for(;
abs<0x400;
abs<<=1,--expy) ;
1794 r = ((
abs&0x3FF)|0x400) << 5;
1803 r = 0x40000000 + ((expy>-30) ? ((r>>-expy)|((r&((
static_cast<uint32
>(1)<<-expy)-1))!=0)) : 1);
1808 r += 0x40000000 >> expy;
1816 r -= 0x40000000 >> expy;
1817 for(; r<0x40000000; r<<=1,--expy) ;
1819 my = sqrt<30>(r, expy);
1820 my = (my<<15) + (r<<14)/my;
1833 static const int G = S && (R==std::round_to_nearest);
1834 return log2_post<R,0xB8AA3B2A>(
log2(my>>i, 26+S+G)+(G<<3), ilog+i, 17, arg&(
static_cast<unsigned>(S)<<15));
1843 HALF_CONSTEXPR f31(uint32 mant,
int e) : m(mant),
exp(e) {}
1847 f31(
unsigned int abs) :
exp(-15)
1850 m =
static_cast<uint32
>((
abs&0x3FF)|0x400) << 21;
1862 int d = a.exp - b.exp;
1863 uint32 m = a.m + ((d<32) ? (b.m>>d) : 0);
1864 int i = (m&0xFFFFFFFF) < a.m;
1865 return f31(((m+i)>>i)|0x80000000, a.exp+i);
1874 int d = a.exp - b.exp,
exp = a.exp;
1875 uint32 m = a.m - ((d<32) ? (b.m>>d) : 0);
1878 for(; m<0x80000000; m<<=1,--
exp) ;
1888 uint32 m = multiply64(a.m, b.m);
1890 return f31(m<<(1-i), a.exp + b.exp + i);
1899 int i = a.m >= b.m, s;
1900 uint32 m = divide64((a.m+i)>>i, b.m, s);
1901 return f31(m, a.exp - b.exp + i - 1);
1918 template<std::
float_round_style R,
bool C>
unsigned int erf(
unsigned int arg)
1920 unsigned int abs = arg & 0x7FFF, sign = arg & 0x8000;
1921 f31 x(
abs), x2 = x * x * f31(0xB8AA3B29, 0), t = f31(0x80000000, 0) / (f31(0x80000000, 0)+f31(0xA7BA054A, -2)*x), t2 = t * t;
1922 f31 e = ((f31(0x87DC2213, 0)*t2+f31(0xB5F0E2AE, 0))*t2+f31(0x82790637, -2)-(f31(0xBA00E2B8, 0)*t2+f31(0x91A98E62, -2))*t) * t /
1923 ((x2.exp<0) ? f31(
exp2((x2.exp>-32) ? (x2.m>>-x2.exp) : 0, 30), 0) : f31(
exp2((x2.m<<x2.exp)&0x7FFFFFFF, 22), x2.m>>(31-x2.exp)));
1924 return (!C || sign) ? fixed2half<R,31,false,true,true>(0x80000000-(e.m>>(C-e.exp)), 14+C, sign&(C-1U)) :
1925 (e.
exp<-25) ? underflow<R>() : fixed2half<R,30,false,false,true>(e.m>>1, e.
exp+14, 0, e.m&1);
1937 template<std::
float_round_style R,
bool L>
unsigned int gamma(
unsigned int arg)
1944 static const f31 pi(0xC90FDAA2, 1), lbe(0xB8AA3B29, 0);
1945 unsigned int abs = arg & 0x7FFF, sign = arg & 0x8000;
1946 bool bsign = sign != 0;
1947 f31 z(
abs), x = sign ? (z+f31(0x80000000, 0)) : z, t = x + f31(0x94CCCCCD, 2), s =
1948 f31(0xA06C9901, 1) + f31(0xBBE654E2, -7)/(x+f31(0x80000000, 2)) + f31(0xA1CE6098, 6)/(x+f31(0x80000000, 1))
1949 + f31(0xE1868CB7, 7)/x - f31(0x8625E279, 8)/(x+f31(0x80000000, 0)) - f31(0xA03E158F, 2)/(x+f31(0xC0000000, 1));
1950 int i = (s.exp>=2) + (s.exp>=4) + (s.exp>=8) + (s.exp>=16);
1951 s = f31((
static_cast<uint32
>(s.exp)<<(31-i))+(
log2(s.m>>1, 28)>>i), i) / lbe;
1952 if(x.exp != -1 || x.m != 0x80000000)
1954 i = (t.exp>=2) + (t.exp>=4) + (t.exp>=8);
1955 f31 l = f31((
static_cast<uint32
>(t.exp)<<(31-i))+(
log2(t.m>>1, 30)>>i), i) / lbe;
1956 s = (x.exp<-1) ? (s-(f31(0x80000000, -1)-x)*l) : (s+(x-f31(0x80000000, -1))*l);
1958 s = x.exp ? (s-t) : (t-s);
1963 sign &= (L|((z.m>>(31-z.exp))&1)) - 1;
1964 for(z=f31((z.m<<(1+z.exp))&0xFFFFFFFF, -1); z.m<0x80000000; z.m<<=1,--z.exp) ;
1967 z = f31(0x80000000, 0) - z;
1971 z.m =
sincos(z.m>>(1-z.exp), 30).first;
1972 for(z.exp=1; z.m<0x80000000; z.m<<=1,--z.exp) ;
1975 z = f31(0x80000000, 0);
1981 f31 l(0x92868247, 0);
1984 uint32 m =
log2((z.m+1)>>1, 27);
1985 z = f31(-((
static_cast<uint32
>(z.exp)<<26)+(m>>5)), 5);
1986 for(; z.m<0x80000000; z.m<<=1,--z.exp) ;
1989 sign =
static_cast<unsigned>(x.exp&&(l.exp<s.exp||(l.exp==s.exp&&l.m<s.m))) << 15;
1990 s = sign ? (s-l) : x.exp ? (l-s) : (l+s);
1994 sign =
static_cast<unsigned>(x.exp==0) << 15;
1996 return underflow<R>(sign);
1998 return overflow<R>(sign);
2012 m = (s.m<<s.exp) & 0x7FFFFFFF;
2013 s.exp = (s.m>>(31-s.exp));
2017 s = f31(0x80000000, 0) / s;
2024 return underflow<R>(sign);
2026 else if(z.exp > 0 && !(z.m&((1<<(31-z.exp))-1)))
2027 return ((s.exp+14)<<10) + (s.m>>21);
2029 return overflow<R>(sign);
2031 return fixed2half<R,31,false,false,true>(s.m, s.exp+14, sign);
2035 template<
typename,
typename,std::
float_round_style>
struct half_caster;
2064 HALF_CONSTEXPR
half() HALF_NOEXCEPT : data_() {}
2069 explicit half(
float rhs) : data_(static_cast<detail::uint16>(detail::float2half<round_style>(rhs))) {}
2073 operator float()
const {
return detail::half2float<float>(data_); }
2079 half&
operator=(
float rhs) { data_ =
static_cast<detail::uint16
>(detail::float2half<round_style>(rhs));
return *
this; }
2164 static const std::float_round_style round_style = (std::float_round_style)(
HALF_ROUND_STYLE);
2168 HALF_CONSTEXPR
half(detail::binary_t,
unsigned int bits) HALF_NOEXCEPT : data_(
static_cast<detail::uint16
>(bits)) {}
2171 detail::uint16 data_;
2173 #ifndef HALF_DOXYGEN_ONLY
2185 template<
typename charT,
typename traits>
friend std::basic_ostream<charT,traits>&
operator<<(std::basic_ostream<charT,traits>&,
half);
2186 template<
typename charT,
typename traits>
friend std::basic_istream<charT,traits>&
operator>>(std::basic_istream<charT,traits>&,
half&);
2235 #ifdef HALF_ENABLE_CPP11_LONG_LONG
2258 template<
typename,
typename,std::
float_round_style>
friend struct detail::half_caster;
2259 friend class std::numeric_limits<
half>;
2260 #if HALF_ENABLE_CPP11_HASH
2261 friend struct std::hash<
half>;
2263 #if HALF_ENABLE_CPP11_USER_LITERALS
2264 friend half literal::operator
"" _h(
long double);
2269 #if HALF_ENABLE_CPP11_USER_LITERALS
2279 inline half operator "" _h(
long double value) {
return half(detail::binary, detail::float2half<half::round_style>(value)); }
2291 template<
typename T,
typename U,std::
float_round_style R=(std::
float_round_style)(HALF_ROUND_STYLE)>
struct half_caster {};
2292 template<
typename U,std::
float_round_style R>
struct half_caster<half,U,R>
2294 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
2295 static_assert(std::is_arithmetic<U>::value,
"half_cast from non-arithmetic type unsupported");
2298 static half cast(U arg) {
return cast_impl(arg, is_float<U>()); };
2301 static half cast_impl(U arg, true_type) {
return half(binary, float2half<R>(arg)); }
2302 static half cast_impl(U arg, false_type) {
return half(binary, int2half<R>(arg)); }
2304 template<
typename T,std::
float_round_style R>
struct half_caster<T,half,R>
2306 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
2307 static_assert(std::is_arithmetic<T>::value,
"half_cast to non-arithmetic type unsupported");
2310 static T cast(half arg) {
return cast_impl(arg, is_float<T>()); }
2313 static T cast_impl(half arg, true_type) {
return half2float<T>(arg.data_); }
2314 static T cast_impl(half arg, false_type) {
return half2int<R,true,true,T>(arg.data_); }
2316 template<std::
float_round_style R>
struct half_caster<half,half,R>
2318 static half cast(half arg) {
return arg; }
2332 static HALF_CONSTEXPR_CONST
bool is_specialized =
true;
2335 static HALF_CONSTEXPR_CONST
bool is_signed =
true;
2338 static HALF_CONSTEXPR_CONST
bool is_integer =
false;
2341 static HALF_CONSTEXPR_CONST
bool is_exact =
false;
2344 static HALF_CONSTEXPR_CONST
bool is_modulo =
false;
2347 static HALF_CONSTEXPR_CONST
bool is_bounded =
true;
2350 static HALF_CONSTEXPR_CONST
bool is_iec559 =
true;
2353 static HALF_CONSTEXPR_CONST
bool has_infinity =
true;
2356 static HALF_CONSTEXPR_CONST
bool has_quiet_NaN =
true;
2359 static HALF_CONSTEXPR_CONST
bool has_signaling_NaN =
true;
2362 static HALF_CONSTEXPR_CONST float_denorm_style has_denorm = denorm_present;
2365 static HALF_CONSTEXPR_CONST
bool has_denorm_loss =
false;
2367 #if HALF_ERRHANDLING_THROWS
2368 static HALF_CONSTEXPR_CONST
bool traps =
true;
2371 static HALF_CONSTEXPR_CONST
bool traps =
false;
2375 static HALF_CONSTEXPR_CONST
bool tinyness_before =
false;
2378 static HALF_CONSTEXPR_CONST float_round_style round_style = half_float::half::round_style;
2381 static HALF_CONSTEXPR_CONST
int digits = 11;
2384 static HALF_CONSTEXPR_CONST
int digits10 = 3;
2387 static HALF_CONSTEXPR_CONST
int max_digits10 = 5;
2390 static HALF_CONSTEXPR_CONST
int radix = 2;
2393 static HALF_CONSTEXPR_CONST
int min_exponent = -13;
2396 static HALF_CONSTEXPR_CONST
int min_exponent10 = -4;
2399 static HALF_CONSTEXPR_CONST
int max_exponent = 16;
2402 static HALF_CONSTEXPR_CONST
int max_exponent10 = 4;
2418 {
return half_float::half(half_float::detail::binary, (round_style==std::round_to_nearest) ? 0x3800 : 0x3C00); }
2433 #if HALF_ENABLE_CPP11_HASH
2468 return !detail::compsignal(x.data_, y.data_) && (x.data_==y.data_ || !((x.data_|y.data_)&0x7FFF));
2479 return detail::compsignal(x.data_, y.data_) || (x.data_!=y.data_ && ((x.data_|y.data_)&0x7FFF));
2490 return !detail::compsignal(x.data_, y.data_) &&
2491 ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) < ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15));
2502 return !detail::compsignal(x.data_, y.data_) &&
2503 ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) > ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15));
2514 return !detail::compsignal(x.data_, y.data_) &&
2515 ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) <= ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15));
2526 return !detail::compsignal(x.data_, y.data_) &&
2527 ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) >= ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15));
2554 #ifdef HALF_ARITHMETIC_TYPE
2555 return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_)+detail::half2float<detail::internal_t>(y.data_)));
2557 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF;
2558 bool sub = ((x.data_^y.data_)&0x8000) != 0;
2559 if(absx >= 0x7C00 || absy >= 0x7C00)
2560 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) : (absy!=0x7C00) ? x.data_ :
2561 (sub && absx==0x7C00) ? detail::invalid() : y.data_);
2563 return absy ? y :
half(detail::binary, (half::round_style==std::round_toward_neg_infinity) ? (x.data_|y.data_) : (x.data_&y.data_));
2566 unsigned int sign = ((sub && absy>absx) ? y.data_ : x.data_) & 0x8000;
2568 std::swap(absx, absy);
2569 int exp = (absx>>10) + (absx<=0x3FF), d =
exp - (absy>>10) - (absy<=0x3FF), mx = ((absx&0x3FF)|((absx>0x3FF)<<10)) << 3, my;
2572 my = ((absy&0x3FF)|((absy>0x3FF)<<10)) << 3;
2573 my = (my>>d) | ((my&((1<<d)-1))!=0);
2580 return half(detail::binary,
static_cast<unsigned>(half::round_style==std::round_toward_neg_infinity)<<15);
2581 for(; mx<0x2000 && exp>1; mx<<=1,--
exp) ;
2588 return half(detail::binary, detail::overflow<half::round_style>(sign));
2589 mx = (mx>>i) | (mx&i);
2591 return half(detail::binary, detail::rounded<half::round_style,false>(sign+((
exp-1)<<10)+(mx>>3), (mx>>2)&1, (mx&0x3)!=0));
2604 #ifdef HALF_ARITHMETIC_TYPE
2605 return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_)-detail::half2float<detail::internal_t>(y.data_)));
2620 #ifdef HALF_ARITHMETIC_TYPE
2621 return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_)*detail::half2float<detail::internal_t>(y.data_)));
2623 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF,
exp = -16;
2624 unsigned int sign = (x.data_^y.data_) & 0x8000;
2625 if(absx >= 0x7C00 || absy >= 0x7C00)
2626 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2627 ((absx==0x7C00 && !absy)||(absy==0x7C00 && !absx)) ? detail::invalid() : (sign|0x7C00));
2629 return half(detail::binary, sign);
2630 for(; absx<0x400; absx<<=1,--
exp) ;
2631 for(; absy<0x400; absy<<=1,--
exp) ;
2632 detail::uint32 m =
static_cast<detail::uint32
>((absx&0x3FF)|0x400) *
static_cast<detail::uint32
>((absy&0x3FF)|0x400);
2633 int i = m >> 21, s = m & i;
2634 exp += (absx>>10) + (absy>>10) + i;
2636 return half(detail::binary, detail::overflow<half::round_style>(sign));
2638 return half(detail::binary, detail::underflow<half::round_style>(sign));
2639 return half(detail::binary, detail::fixed2half<half::round_style,20,false,false,false>(m>>i,
exp, sign, s));
2653 #ifdef HALF_ARITHMETIC_TYPE
2654 return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_)/detail::half2float<detail::internal_t>(y.data_)));
2656 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF,
exp = 14;
2657 unsigned int sign = (x.data_^y.data_) & 0x8000;
2658 if(absx >= 0x7C00 || absy >= 0x7C00)
2659 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2660 (absx==absy) ? detail::invalid() : (sign|((absx==0x7C00) ? 0x7C00 : 0)));
2662 return half(detail::binary, absy ? sign : detail::invalid());
2664 return half(detail::binary, detail::pole(sign));
2665 for(; absx<0x400; absx<<=1,--
exp) ;
2666 for(; absy<0x400; absy<<=1,++
exp) ;
2667 detail::uint32 mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400;
2669 exp += (absx>>10) - (absy>>10) - i;
2671 return half(detail::binary, detail::overflow<half::round_style>(sign));
2673 return half(detail::binary, detail::underflow<half::round_style>(sign));
2676 return half(detail::binary, detail::fixed2half<half::round_style,11,false,false,false>(mx/my,
exp, sign, mx%my!=0));
2690 template<
typename charT,
typename traits> std::basic_ostream<charT,traits>&
operator<<(std::basic_ostream<charT,traits> &out, half arg)
2692 #ifdef HALF_ARITHMETIC_TYPE
2693 return out << detail::half2float<detail::internal_t>(arg.data_);
2695 return out << detail::half2float<float>(arg.data_);
2708 template<
typename charT,
typename traits> std::basic_istream<charT,traits>&
operator>>(std::basic_istream<charT,traits> &in,
half &arg)
2710 #ifdef HALF_ARITHMETIC_TYPE
2711 detail::internal_t f;
2716 arg.data_ = detail::float2half<half::round_style>(f);
2745 unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000;
2746 if(absx >= 0x7C00 || absy >= 0x7C00)
2747 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2748 (absx==0x7C00) ? detail::invalid() : x.data_);
2750 return half(detail::binary, detail::invalid());
2754 return half(detail::binary, sign);
2755 return half(detail::binary, sign|detail::mod<false,false>(absx, absy));
2766 unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000;
2767 if(absx >= 0x7C00 || absy >= 0x7C00)
2768 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2769 (absx==0x7C00) ? detail::invalid() : x.data_);
2771 return half(detail::binary, detail::invalid());
2773 return half(detail::binary, sign);
2774 return half(detail::binary, sign^detail::mod<false,true>(absx, absy));
2786 unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, value = x.data_ & 0x8000;
2787 if(absx >= 0x7C00 || absy >= 0x7C00)
2788 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2789 (absx==0x7C00) ? detail::invalid() : (*quo = 0, x.data_));
2791 return half(detail::binary, detail::invalid());
2792 bool qsign = ((value^y.data_)&0x8000) != 0;
2795 value ^= detail::mod<true, true>(absx, absy, &q);
2796 return *quo = qsign ? -q : q,
half(detail::binary, value);
2811 #ifdef HALF_ARITHMETIC_TYPE
2812 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_);
2813 #if HALF_ENABLE_CPP11_CMATH && FP_FAST_FMA
2814 return half(detail::binary, detail::float2half<half::round_style>(
std::fma(fx, fy, fz)));
2816 return half(detail::binary, detail::float2half<half::round_style>(fx*fy+fz));
2819 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF,
exp = -15;
2820 unsigned int sign = (x.data_^y.data_) & 0x8000;
2821 bool sub = ((sign^z.data_)&0x8000) != 0;
2822 if(absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
2823 return (absx>0x7C00 || absy>0x7C00 || absz>0x7C00) ?
half(detail::binary, detail::signal(x.data_, y.data_, z.data_)) :
2824 (absx==0x7C00) ?
half(detail::binary, (!absy || (sub && absz==0x7C00)) ? detail::invalid() : (sign|0x7C00)) :
2825 (absy==0x7C00) ?
half(detail::binary, (!absx || (sub && absz==0x7C00)) ? detail::invalid() : (sign|0x7C00)) : z;
2827 return absz ? z :
half(detail::binary, (half::round_style==std::round_toward_neg_infinity) ? (z.data_|sign) : (z.data_&sign));
2828 for(; absx<0x400; absx<<=1,--
exp) ;
2829 for(; absy<0x400; absy<<=1,--
exp) ;
2830 detail::uint32 m =
static_cast<detail::uint32
>((absx&0x3FF)|0x400) *
static_cast<detail::uint32
>((absy&0x3FF)|0x400);
2832 exp += (absx>>10) + (absy>>10) + i;
2837 for(; absz<0x400; absz<<=1,--expz) ;
2839 detail::uint32 mz =
static_cast<detail::uint32
>((absz&0x3FF)|0x400) << 13;
2840 if(expz >
exp || (expz ==
exp && mz > m))
2843 std::swap(
exp, expz);
2845 sign = z.data_ & 0x8000;
2848 mz = (d<23) ? ((mz>>d)|((mz&((
static_cast<detail::uint32
>(1)<<d)-1))!=0)) : 1;
2853 return half(detail::binary,
static_cast<unsigned>(half::round_style==std::round_toward_neg_infinity)<<15);
2854 for(; m<0x800000; m<<=1,--
exp) ;
2865 return half(detail::binary, detail::overflow<half::round_style>(sign));
2867 return half(detail::binary, detail::underflow<half::round_style>(sign));
2868 return half(detail::binary, detail::fixed2half<half::round_style,23,false,false,false>(m,
exp-1, sign));
2880 return half(detail::binary, (!
isnan(y) && (
isnan(x) || (x.data_^(0x8000|(0x8000-(x.data_>>15)))) <
2881 (y.data_^(0x8000|(0x8000-(y.data_>>15)))))) ? detail::select(y.data_, x.data_) : detail::select(x.data_, y.data_));
2892 return half(detail::binary, (!
isnan(y) && (
isnan(x) || (x.data_^(0x8000|(0x8000-(x.data_>>15)))) >
2893 (y.data_^(0x8000|(0x8000-(y.data_>>15)))))) ? detail::select(y.data_, x.data_) : detail::select(x.data_, y.data_));
2907 return half(detail::binary, detail::signal(x.data_, y.data_));
2908 return (x.data_^(0x8000|(0x8000-(x.data_>>15)))) <= (y.data_^(0x8000|(0x8000-(y.data_>>15)))) ?
half(detail::binary, 0) : (x-y);
2917 unsigned int value = 0x7FFF;
2919 value ^=
static_cast<unsigned>(*arg++) & 0xFF;
2920 return half(detail::binary, value);
2938 #ifdef HALF_ARITHMETIC_TYPE
2939 return half(detail::binary, detail::float2half<half::round_style>(
std::exp(detail::half2float<detail::internal_t>(arg.data_))));
2941 int abs = arg.data_ & 0x7FFF, e = (
abs>>10) + (
abs<=0x3FF),
exp;
2943 return half(detail::binary, 0x3C00);
2945 return half(detail::binary, (
abs==0x7C00) ? (0x7C00&((arg.data_>>15)-1U)) : detail::signal(arg.data_));
2947 return half(detail::binary, (arg.data_&0x8000) ? detail::underflow<half::round_style>() : detail::overflow<half::round_style>());
2948 detail::uint32 m = detail::multiply64(
static_cast<detail::uint32
>((
abs&0x3FF)+((
abs>0x3FF)<<10))<<21, 0xB8AA3B29);
2957 m = (m<<(e-14)) & 0x7FFFFFFF;
2959 return half(detail::binary, detail::exp2_post<half::round_style>(m,
exp, (arg.data_&0x8000)!=0, 0, 26));
2973 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
2974 return half(detail::binary, detail::float2half<half::round_style>(
std::exp2(detail::half2float<detail::internal_t>(arg.data_))));
2976 int abs = arg.data_ & 0x7FFF, e = (
abs>>10) + (
abs<=0x3FF),
exp = (
abs&0x3FF) + ((
abs>0x3FF)<<10);
2978 return half(detail::binary, 0x3C00);
2980 return half(detail::binary, (
abs==0x7C00) ? (0x7C00&((arg.data_>>15)-1U)) : detail::signal(arg.data_));
2982 return half(detail::binary, (arg.data_&0x8000) ? detail::underflow<half::round_style>() : detail::overflow<half::round_style>());
2983 return half(detail::binary, detail::exp2_post<half::round_style>(
2984 (
static_cast<detail::uint32
>(
exp)<<(6+e))&0x7FFFFFFF,
exp>>(25-e), (arg.data_&0x8000)!=0, 0, 28));
2999 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3000 return half(detail::binary, detail::float2half<half::round_style>(
std::expm1(detail::half2float<detail::internal_t>(arg.data_))));
3002 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000, e = (
abs>>10) + (
abs<=0x3FF),
exp;
3006 return half(detail::binary, (
abs==0x7C00) ? (0x7C00+(sign>>1)) : detail::signal(arg.data_));
3008 return half(detail::binary, (arg.data_&0x8000) ? detail::rounded<half::round_style,true>(0xBBFF, 1, 1) : detail::overflow<half::round_style>());
3009 detail::uint32 m = detail::multiply64(
static_cast<detail::uint32
>((
abs&0x3FF)+((
abs>0x3FF)<<10))<<21, 0xB8AA3B29);
3018 m = (m<<(e-14)) & 0x7FFFFFFF;
3027 m = detail::divide64(0x80000000, m, s);
3029 m = 0x80000000 - ((m>>
exp)|((m&((
static_cast<detail::uint32
>(1)<<
exp)-1))!=0)|s);
3033 m -= (
exp<31) ? (0x80000000>>
exp) : 1;
3034 for(
exp+=14; m<0x80000000 &&
exp; m<<=1,--
exp) ;
3036 return half(detail::binary, detail::overflow<half::round_style>());
3037 return half(detail::binary, detail::rounded<half::round_style,true>(sign+(
exp<<10)+(m>>21), (m>>20)&1, (m&0xFFFFF)!=0));
3052 #ifdef HALF_ARITHMETIC_TYPE
3053 return half(detail::binary, detail::float2half<half::round_style>(
std::log(detail::half2float<detail::internal_t>(arg.data_))));
3055 int abs = arg.data_ & 0x7FFF,
exp = -15;
3057 return half(detail::binary, detail::pole(0x8000));
3058 if(arg.data_ & 0x8000)
3059 return half(detail::binary, (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3061 return (
abs==0x7C00) ? arg :
half(detail::binary, detail::signal(arg.data_));
3064 return half(detail::binary, detail::log2_post<half::round_style,0xB8AA3B2A>(
3080 #ifdef HALF_ARITHMETIC_TYPE
3081 return half(detail::binary, detail::float2half<half::round_style>(
std::log10(detail::half2float<detail::internal_t>(arg.data_))));
3083 int abs = arg.data_ & 0x7FFF,
exp = -15;
3085 return half(detail::binary, detail::pole(0x8000));
3086 if(arg.data_ & 0x8000)
3087 return half(detail::binary, (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3089 return (
abs==0x7C00) ? arg :
half(detail::binary, detail::signal(arg.data_));
3092 case 0x4900:
return half(detail::binary, 0x3C00);
3093 case 0x5640:
return half(detail::binary, 0x4000);
3094 case 0x63D0:
return half(detail::binary, 0x4200);
3095 case 0x70E2:
return half(detail::binary, 0x4400);
3099 return half(detail::binary, detail::log2_post<half::round_style,0xD49A784C>(
3115 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3116 return half(detail::binary, detail::float2half<half::round_style>(
std::log2(detail::half2float<detail::internal_t>(arg.data_))));
3118 int abs = arg.data_ & 0x7FFF,
exp = -15, s = 0;
3120 return half(detail::binary, detail::pole(0x8000));
3121 if(arg.data_ & 0x8000)
3122 return half(detail::binary, (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3124 return (
abs==0x7C00) ? arg :
half(detail::binary, detail::signal(arg.data_));
3126 return half(detail::binary, 0);
3131 unsigned int value =
static_cast<unsigned>(
exp<0) << 15, m =
std::abs(
exp) << 6;
3132 for(
exp=18; m<0x400; m<<=1,--
exp) ;
3133 return half(detail::binary, value+(
exp<<10)+m);
3135 detail::uint32 ilog =
exp, sign = detail::sign_mask(ilog), m =
3136 (((ilog<<27)+(detail::log2(static_cast<detail::uint32>((
abs&0x3FF)|0x400)<<20, 28)>>4))^sign) - sign;
3138 return half(detail::binary, 0);
3139 for(
exp=14; m<0x8000000 &&
exp; m<<=1,--
exp) ;
3140 for(; m>0xFFFFFFF; m>>=1,++
exp)
3142 return half(detail::binary, detail::fixed2half<half::round_style,27,false,false,true>(m,
exp, sign&0x8000, s));
3158 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3159 return half(detail::binary, detail::float2half<half::round_style>(
std::log1p(detail::half2float<detail::internal_t>(arg.data_))));
3161 if(arg.data_ >= 0xBC00)
3162 return half(detail::binary, (arg.data_==0xBC00) ? detail::pole(0x8000) : (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3163 int abs = arg.data_ & 0x7FFF,
exp = -15;
3164 if(!
abs ||
abs >= 0x7C00)
3165 return (
abs>0x7C00) ?
half(detail::binary, detail::signal(arg.data_)) : arg;
3168 detail::uint32 m =
static_cast<detail::uint32
>((
abs&0x3FF)|0x400) << 20;
3169 if(arg.data_ & 0x8000)
3171 m = 0x40000000 - (m>>-
exp);
3172 for(
exp=0; m<0x40000000; m<<=1,--
exp) ;
3178 m = 0x40000000 + (m>>-
exp);
3183 m += 0x40000000 >>
exp;
3189 return half(detail::binary, detail::log2_post<half::round_style,0xB8AA3B2A>(
detail::log2(m),
exp, 17));
3208 #ifdef HALF_ARITHMETIC_TYPE
3209 return half(detail::binary, detail::float2half<half::round_style>(
std::sqrt(detail::half2float<detail::internal_t>(arg.data_))));
3211 int abs = arg.data_ & 0x7FFF,
exp = 15;
3212 if(!
abs || arg.data_ >= 0x7C00)
3213 return half(detail::binary, (
abs>0x7C00) ? detail::signal(arg.data_) : (arg.data_>0x8000) ? detail::invalid() : arg.data_);
3215 detail::uint32 r =
static_cast<detail::uint32
>((
abs&0x3FF)|0x400) << 10, m = detail::sqrt<20>(r,
exp+=
abs>>10);
3216 return half(detail::binary, detail::rounded<half::round_style,false>((
exp<<10)+(m&0x3FF), r>m, r!=0));
3229 #ifdef HALF_ARITHMETIC_TYPE
3230 return half(detail::binary, detail::float2half<half::round_style>(detail::internal_t(1)/
std::sqrt(detail::half2float<detail::internal_t>(arg.data_))));
3232 unsigned int abs = arg.data_ & 0x7FFF, bias = 0x4000;
3233 if(!
abs || arg.data_ >= 0x7C00)
3234 return half(detail::binary, (
abs>0x7C00) ? detail::signal(arg.data_) : (arg.data_>0x8000) ?
3235 detail::invalid() : !
abs ? detail::pole(arg.data_&0x8000) : 0);
3236 for(;
abs<0x400;
abs<<=1,bias-=0x400) ;
3237 unsigned int frac = (
abs+=bias) & 0x7FF;
3239 return half(detail::binary, 0x7A00-(
abs>>1));
3240 if((half::round_style == std::round_to_nearest && (frac == 0x3FE || frac == 0x76C)) ||
3241 (half::round_style != std::round_to_nearest && (frac == 0x15A || frac == 0x3FC || frac == 0x401 || frac == 0x402 || frac == 0x67B)))
3242 return pow(arg,
half(detail::binary, 0xB800));
3243 detail::uint32 f = 0x17376 -
abs, mx = (
abs&0x3FF) | 0x400, my = ((f>>1)&0x3FF) | 0x400, mz = my * my;
3244 int expy = (f>>11) - 31, expx = 32 - (
abs>>10), i = mz >> 21;
3245 for(mz=0x60000000-(((mz>>i)*mx)>>(expx-2*expy-i)); mz<0x40000000; mz<<=1,--expy) ;
3246 i = (my*=mz>>10) >> 31;
3248 my = (my>>(20+i)) + 1;
3249 i = (mz=my*my) >> 21;
3250 for(mz=0x60000000-(((mz>>i)*mx)>>(expx-2*expy-i)); mz<0x40000000; mz<<=1,--expy) ;
3251 i = (my*=(mz>>10)+1) >> 31;
3252 return half(detail::binary, detail::fixed2half<half::round_style,30,false,false,true>(my>>i, expy+i+14));
3266 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3267 return half(detail::binary, detail::float2half<half::round_style>(
std::cbrt(detail::half2float<detail::internal_t>(arg.data_))));
3269 int abs = arg.data_ & 0x7FFF,
exp = -15;
3270 if(!
abs ||
abs == 0x3C00 ||
abs >= 0x7C00)
3271 return (
abs>0x7C00) ?
half(detail::binary, detail::signal(arg.data_)) : arg;
3273 detail::uint32 ilog =
exp + (
abs>>10), sign = detail::sign_mask(ilog), f, m =
3274 (((ilog<<27)+(detail::log2(static_cast<detail::uint32>((
abs&0x3FF)|0x400)<<20, 24)>>4))^sign) - sign;
3275 for(
exp=2; m<0x80000000; m<<=1,--
exp) ;
3276 m = detail::multiply64(m, 0xAAAAAAAB);
3287 f = (m<<
exp) & 0x7FFFFFFF;
3290 m =
detail::exp2(f, (half::round_style==std::round_to_nearest) ? 29 : 26);
3295 m = detail::divide64(0x80000000, m, s);
3300 return half(detail::binary, (half::round_style==std::round_to_nearest) ?
3301 detail::fixed2half<half::round_style,31,false,false,false>(m,
exp+14, arg.data_&0x8000) :
3302 detail::fixed2half<half::round_style,23,false,false,false>((m+0x80)>>8,
exp+14, arg.data_&0x8000));
3317 #ifdef HALF_ARITHMETIC_TYPE
3318 detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_);
3319 #if HALF_ENABLE_CPP11_CMATH
3320 return half(detail::binary, detail::float2half<half::round_style>(
std::hypot(fx, fy)));
3322 return half(detail::binary, detail::float2half<half::round_style>(
std::sqrt(fx*fx+fy*fy)));
3325 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, expx = 0, expy = 0;
3326 if(absx >= 0x7C00 || absy >= 0x7C00)
3327 return half(detail::binary, (absx==0x7C00) ? detail::select(0x7C00, y.data_) :
3328 (absy==0x7C00) ? detail::select(0x7C00, x.data_) : detail::signal(x.data_, y.data_));
3330 return half(detail::binary, absy ? detail::check_underflow(absy) : 0);
3332 return half(detail::binary, detail::check_underflow(absx));
3334 std::swap(absx, absy);
3335 for(; absx<0x400; absx<<=1,--expx) ;
3336 for(; absy<0x400; absy<<=1,--expy) ;
3337 detail::uint32 mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400;
3340 int ix = mx >> 21, iy = my >> 21;
3341 expx = 2*(expx+(absx>>10)) - 15 + ix;
3342 expy = 2*(expy+(absy>>10)) - 15 + iy;
3345 int d = expx - expy;
3346 my = (d<30) ? ((my>>d)|((my&((
static_cast<detail::uint32
>(1)<<d)-1))!=0)) : 1;
3347 return half(detail::binary, detail::hypot_post<half::round_style>(mx+my, expx));
3363 #ifdef HALF_ARITHMETIC_TYPE
3364 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_);
3365 return half(detail::binary, detail::float2half<half::round_style>(
std::sqrt(fx*fx+fy*fy+fz*fz)));
3367 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, expx = 0, expy = 0, expz = 0;
3374 if(absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
3375 return half(detail::binary, (absx==0x7C00) ? detail::select(0x7C00, detail::select(y.data_, z.data_)) :
3376 (absy==0x7C00) ? detail::select(0x7C00, detail::select(x.data_, z.data_)) :
3377 (absz==0x7C00) ? detail::select(0x7C00, detail::select(x.data_, y.data_)) :
3378 detail::signal(x.data_, y.data_, z.data_));
3380 std::swap(absy, absz);
3382 std::swap(absx, absy);
3384 std::swap(absy, absz);
3385 for(; absx<0x400; absx<<=1,--expx) ;
3386 for(; absy<0x400; absy<<=1,--expy) ;
3387 for(; absz<0x400; absz<<=1,--expz) ;
3388 detail::uint32 mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400, mz = (absz&0x3FF) | 0x400;
3392 int ix = mx >> 21, iy = my >> 21, iz = mz >> 21;
3393 expx = 2*(expx+(absx>>10)) - 15 + ix;
3394 expy = 2*(expy+(absy>>10)) - 15 + iy;
3395 expz = 2*(expz+(absz>>10)) - 15 + iz;
3399 int d = expy - expz;
3400 mz = (d<30) ? ((mz>>d)|((mz&((
static_cast<detail::uint32
>(1)<<d)-1))!=0)) : 1;
3404 my = (my>>1) | (my&1);
3408 std::swap(expx, expy);
3412 my = (d<30) ? ((my>>d)|((my&((
static_cast<detail::uint32
>(1)<<d)-1))!=0)) : 1;
3413 return half(detail::binary, detail::hypot_post<half::round_style>(mx+my, expx));
3429 #ifdef HALF_ARITHMETIC_TYPE
3430 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_))));
3432 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF,
exp = -15;
3433 if(!absy || x.data_ == 0x3C00)
3434 return half(detail::binary, detail::select(0x3C00, (x.data_==0x3C00) ? y.data_ : x.data_));
3435 bool is_int = absy >= 0x6400 || (absy>=0x3C00 && !(absy&((1<<(25-(absy>>10)))-1)));
3436 unsigned int sign = x.data_ & (
static_cast<unsigned>((absy<0x6800)&&is_int&&((absy>>(25-(absy>>10)))&1))<<15);
3437 if(absx >= 0x7C00 || absy >= 0x7C00)
3438 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
3439 (absy==0x7C00) ? ((absx==0x3C00) ? 0x3C00 : (!absx && y.data_==0xFC00) ? detail::pole() :
3440 (0x7C00&-((y.data_>>15)^(absx>0x3C00)))) : (sign|(0x7C00&((y.data_>>15)-1U))));
3442 return half(detail::binary, (y.data_&0x8000) ? detail::pole(sign) : sign);
3443 if((x.data_&0x8000) && !is_int)
3444 return half(detail::binary, detail::invalid());
3445 if(x.data_ == 0xBC00)
3446 return half(detail::binary, sign|0x3C00);
3449 case 0x3800:
return sqrt(x);
3450 case 0x3C00:
return half(detail::binary, detail::check_underflow(x.data_));
3451 case 0x4000:
return x * x;
3452 case 0xBC00:
return half(detail::binary, 0x3C00) / x;
3454 for(; absx<0x400; absx<<=1,--
exp) ;
3455 detail::uint32 ilog =
exp + (absx>>10), msign = detail::sign_mask(ilog), f, m =
3456 (((ilog<<27)+((detail::log2(static_cast<detail::uint32>((absx&0x3FF)|0x400)<<20)+8)>>4))^msign) - msign;
3457 for(
exp=-11; m<0x80000000; m<<=1,--
exp) ;
3458 for(; absy<0x400; absy<<=1,--
exp) ;
3459 m = detail::multiply64(m,
static_cast<detail::uint32
>((absy&0x3FF)|0x400)<<21);
3461 exp += (absy>>10) + i;
3470 f = (m<<
exp) & 0x7FFFFFFF;
3473 return half(detail::binary, detail::exp2_post<half::round_style>(f,
exp, ((msign&1)^(y.data_>>15))!=0, sign));
3493 #ifdef HALF_ARITHMETIC_TYPE
3494 detail::internal_t f = detail::half2float<detail::internal_t>(arg.data_);
3495 *
sin =
half(detail::binary, detail::float2half<half::round_style>(
std::sin(f)));
3496 *
cos =
half(detail::binary, detail::float2half<half::round_style>(
std::cos(f)));
3498 int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15, k;
3500 *
sin = *
cos =
half(detail::binary, (
abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3504 *
cos =
half(detail::binary, 0x3C00);
3506 else if(
abs < 0x2500)
3508 *
sin =
half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-1, 1, 1));
3509 *
cos =
half(detail::binary, detail::rounded<half::round_style,true>(0x3BFF, 1, 1));
3513 if(half::round_style != std::round_to_nearest)
3518 *
sin =
half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x1D07, 1, 1));
3519 *
cos =
half(detail::binary, detail::rounded<half::round_style,true>(0xBBFF, 1, 1));
3522 *
sin =
half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x3BFF, 1, 1));
3523 *
cos =
half(detail::binary, detail::rounded<half::round_style,true>(0x80FC, 1, 1));
3526 *
sin =
half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x3BFE, 1, 1));
3527 *
cos =
half(detail::binary, detail::rounded<half::round_style,true>(0x27FF, 1, 1));
3530 *
sin =
half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x0FE6, 1, 1));
3531 *
cos =
half(detail::binary, detail::rounded<half::round_style,true>(0x3BFF, 1, 1));
3535 std::pair<detail::uint32,detail::uint32> sc =
detail::sincos(detail::angle_arg(
abs, k), 28);
3538 case 1: sc = std::make_pair(sc.second, -sc.first);
break;
3539 case 2: sc = std::make_pair(-sc.first, -sc.second);
break;
3540 case 3: sc = std::make_pair(-sc.second, sc.first);
break;
3542 *
sin =
half(detail::binary, detail::fixed2half<half::round_style,30,true,true,true>((sc.first^-
static_cast<detail::uint32
>(sign))+sign));
3543 *
cos =
half(detail::binary, detail::fixed2half<half::round_style,30,true,true,true>(sc.second));
3558 #ifdef HALF_ARITHMETIC_TYPE
3559 return half(detail::binary, detail::float2half<half::round_style>(
std::sin(detail::half2float<detail::internal_t>(arg.data_))));
3561 int abs = arg.data_ & 0x7FFF, k;
3565 return half(detail::binary, (
abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3567 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-1, 1, 1));
3568 if(half::round_style != std::round_to_nearest)
3571 case 0x48B7:
return half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x1D07, 1, 1));
3572 case 0x6A64:
return half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x3BFE, 1, 1));
3573 case 0x6D8C:
return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x0FE6, 1, 1));
3575 std::pair<detail::uint32,detail::uint32> sc =
detail::sincos(detail::angle_arg(
abs, k), 28);
3576 detail::uint32 sign = -
static_cast<detail::uint32
>(((k>>1)&1)^(arg.data_>>15));
3577 return half(detail::binary, detail::fixed2half<half::round_style,30,true,true,true>((((k&1) ? sc.second : sc.first)^sign) - sign));
3591 #ifdef HALF_ARITHMETIC_TYPE
3592 return half(detail::binary, detail::float2half<half::round_style>(
std::cos(detail::half2float<detail::internal_t>(arg.data_))));
3594 int abs = arg.data_ & 0x7FFF, k;
3596 return half(detail::binary, 0x3C00);
3598 return half(detail::binary, (
abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3600 return half(detail::binary, detail::rounded<half::round_style,true>(0x3BFF, 1, 1));
3601 if(half::round_style != std::round_to_nearest &&
abs == 0x598C)
3602 return half(detail::binary, detail::rounded<half::round_style,true>(0x80FC, 1, 1));
3603 std::pair<detail::uint32,detail::uint32> sc =
detail::sincos(detail::angle_arg(
abs, k), 28);
3604 detail::uint32 sign = -
static_cast<detail::uint32
>(((k>>1)^k)&1);
3605 return half(detail::binary, detail::fixed2half<half::round_style,30,true,true,true>((((k&1) ? sc.first : sc.second)^sign) - sign));
3619 #ifdef HALF_ARITHMETIC_TYPE
3620 return half(detail::binary, detail::float2half<half::round_style>(
std::tan(detail::half2float<detail::internal_t>(arg.data_))));
3622 int abs = arg.data_ & 0x7FFF,
exp = 13, k;
3626 return half(detail::binary, (
abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3628 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_, 0, 1));
3629 if(half::round_style != std::round_to_nearest)
3632 case 0x658C:
return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x07E6, 1, 1));
3633 case 0x7330:
return half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x4B62, 1, 1));
3635 std::pair<detail::uint32,detail::uint32> sc =
detail::sincos(detail::angle_arg(
abs, k), 30);
3637 sc = std::make_pair(-sc.second, sc.first);
3638 detail::uint32 signy = detail::sign_mask(sc.first), signx = detail::sign_mask(sc.second);
3639 detail::uint32 my = (sc.first^signy) - signy, mx = (sc.second^signx) - signx;
3640 for(; my<0x80000000; my<<=1,--
exp) ;
3641 for(; mx<0x80000000; mx<<=1,++
exp) ;
3642 return half(detail::binary, detail::tangent_post<half::round_style>(my, mx,
exp, (signy^signx^arg.data_)&0x8000));
3656 #ifdef HALF_ARITHMETIC_TYPE
3657 return half(detail::binary, detail::float2half<half::round_style>(
std::asin(detail::half2float<detail::internal_t>(arg.data_))));
3659 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
3663 return half(detail::binary, (
abs>0x7C00) ? detail::signal(arg.data_) : (
abs>0x3C00) ? detail::invalid() :
3664 detail::rounded<half::round_style,true>(sign|0x3E48, 0, 1));
3666 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_, 0, 1));
3667 if(half::round_style != std::round_to_nearest && (
abs == 0x2B44 ||
abs == 0x2DC3))
3668 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_+1, 1, 1));
3669 std::pair<detail::uint32,detail::uint32> sc = detail::atan2_args(
abs);
3670 detail::uint32 m =
detail::atan2(sc.first, sc.second, (half::round_style==std::round_to_nearest) ? 27 : 26);
3671 return half(detail::binary, detail::fixed2half<half::round_style,30,false,true,true>(m, 14, sign));
3685 #ifdef HALF_ARITHMETIC_TYPE
3686 return half(detail::binary, detail::float2half<half::round_style>(
std::acos(detail::half2float<detail::internal_t>(arg.data_))));
3688 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15;
3690 return half(detail::binary, detail::rounded<half::round_style,true>(0x3E48, 0, 1));
3692 return half(detail::binary, (
abs>0x7C00) ? detail::signal(arg.data_) : (
abs>0x3C00) ? detail::invalid() :
3693 sign ? detail::rounded<half::round_style,true>(0x4248, 0, 1) : 0);
3694 std::pair<detail::uint32,detail::uint32> cs = detail::atan2_args(
abs);
3696 return half(detail::binary, detail::fixed2half<half::round_style,31,false,true,true>(sign ? (0xC90FDAA2-m) : m, 15, 0, sign));
3710 #ifdef HALF_ARITHMETIC_TYPE
3711 return half(detail::binary, detail::float2half<half::round_style>(
std::atan(detail::half2float<detail::internal_t>(arg.data_))));
3713 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
3717 return half(detail::binary, (
abs==0x7C00) ? detail::rounded<half::round_style,true>(sign|0x3E48, 0, 1) : detail::signal(arg.data_));
3719 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-1, 1, 1));
3721 detail::uint32 my = (
abs&0x3FF) | ((
abs>0x3FF)<<10);
3722 detail::uint32 m = (
exp>15) ?
detail::atan2(my<<19, 0x20000000>>(
exp-15), (half::round_style==std::round_to_nearest) ? 26 : 24) :
3723 detail::atan2(my<<(
exp+4), 0x20000000, (half::round_style==std::round_to_nearest) ? 30 : 28);
3724 return half(detail::binary, detail::fixed2half<half::round_style,30,false,true,true>(m, 14, sign));
3740 #ifdef HALF_ARITHMETIC_TYPE
3741 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_))));
3743 unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, signx = x.data_ >> 15, signy = y.data_ & 0x8000;
3744 if(absx >= 0x7C00 || absy >= 0x7C00)
3746 if(absx > 0x7C00 || absy > 0x7C00)
3747 return half(detail::binary, detail::signal(x.data_, y.data_));
3749 return half(detail::binary, (absx<0x7C00) ? detail::rounded<half::round_style,true>(signy|0x3E48, 0, 1) :
3750 signx ? detail::rounded<half::round_style,true>(signy|0x40B6, 0, 1) :
3751 detail::rounded<half::round_style,true>(signy|0x3A48, 0, 1));
3752 return (x.data_==0x7C00) ?
half(detail::binary, signy) :
half(detail::binary, detail::rounded<half::round_style,true>(signy|0x4248, 0, 1));
3755 return signx ?
half(detail::binary, detail::rounded<half::round_style,true>(signy|0x4248, 0, 1)) : y;
3757 return half(detail::binary, detail::rounded<half::round_style,true>(signy|0x3E48, 0, 1));
3758 int d = (absy>>10) + (absy<=0x3FF) - (absx>>10) - (absx<=0x3FF);
3759 if(d > (signx ? 18 : 12))
3760 return half(detail::binary, detail::rounded<half::round_style,true>(signy|0x3E48, 0, 1));
3761 if(signx && d < -11)
3762 return half(detail::binary, detail::rounded<half::round_style,true>(signy|0x4248, 0, 1));
3763 if(!signx && d < ((half::round_style==std::round_toward_zero) ? -15 : -9))
3765 for(; absy<0x400; absy<<=1,--d) ;
3766 detail::uint32 mx = ((absx<<1)&0x7FF) | 0x800, my = ((absy<<1)&0x7FF) | 0x800;
3770 return half(detail::binary, detail::underflow<half::round_style>(signy));
3772 return half(detail::binary, detail::fixed2half<half::round_style,11,false,false,true>(my/mx, d+14, signy, my%mx!=0));
3774 detail::uint32 m =
detail::atan2( ((absy&0x3FF)|((absy>0x3FF)<<10))<<(19+((d<0) ? d : (d>0) ? 0 : -1)),
3775 ((absx&0x3FF)|((absx>0x3FF)<<10))<<(19-((d>0) ? d : (d<0) ? 0 : 1)));
3776 return half(detail::binary, detail::fixed2half<half::round_style,31,false,true,true>(signx ? (0xC90FDAA2-m) : m, 15, signy, signx));
3795 #ifdef HALF_ARITHMETIC_TYPE
3796 return half(detail::binary, detail::float2half<half::round_style>(
std::sinh(detail::half2float<detail::internal_t>(arg.data_))));
3798 int abs = arg.data_ & 0x7FFF,
exp;
3799 if(!
abs ||
abs >= 0x7C00)
3800 return (
abs>0x7C00) ?
half(detail::binary, detail::signal(arg.data_)) : arg;
3802 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_, 0, 1));
3803 std::pair<detail::uint32,detail::uint32> mm = detail::hyperbolic_args(
abs,
exp, (half::round_style==std::round_to_nearest) ? 29 : 27);
3804 detail::uint32 m = mm.first - mm.second;
3805 for(
exp+=13; m<0x80000000 &&
exp; m<<=1,--
exp) ;
3806 unsigned int sign = arg.data_ & 0x8000;
3808 return half(detail::binary, detail::overflow<half::round_style>(sign));
3809 return half(detail::binary, detail::fixed2half<half::round_style,31,false,false,true>(m,
exp, sign));
3823 #ifdef HALF_ARITHMETIC_TYPE
3824 return half(detail::binary, detail::float2half<half::round_style>(
std::cosh(detail::half2float<detail::internal_t>(arg.data_))));
3826 int abs = arg.data_ & 0x7FFF,
exp;
3828 return half(detail::binary, 0x3C00);
3830 return half(detail::binary, (
abs>0x7C00) ? detail::signal(arg.data_) : 0x7C00);
3831 std::pair<detail::uint32,detail::uint32> mm = detail::hyperbolic_args(
abs,
exp, (half::round_style==std::round_to_nearest) ? 23 : 26);
3832 detail::uint32 m = mm.first + mm.second, i = (~m&0xFFFFFFFF) >> 31;
3833 m = (m>>i) | (m&i) | 0x80000000;
3834 if((
exp+=13+i) > 29)
3835 return half(detail::binary, detail::overflow<half::round_style>());
3836 return half(detail::binary, detail::fixed2half<half::round_style,31,false,false,true>(m,
exp));
3850 #ifdef HALF_ARITHMETIC_TYPE
3851 return half(detail::binary, detail::float2half<half::round_style>(
std::tanh(detail::half2float<detail::internal_t>(arg.data_))));
3853 int abs = arg.data_ & 0x7FFF,
exp;
3857 return half(detail::binary, (
abs>0x7C00) ? detail::signal(arg.data_) : (arg.data_-0x4000));
3859 return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x3BFF, 1, 1));
3861 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-1, 1, 1));
3862 if(half::round_style != std::round_to_nearest &&
abs == 0x2D3F)
3863 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-3, 0, 1));
3864 std::pair<detail::uint32,detail::uint32> mm = detail::hyperbolic_args(
abs,
exp, 27);
3865 detail::uint32 my = mm.first - mm.second - (half::round_style!=std::round_to_nearest), mx = mm.first + mm.second, i = (~mx&0xFFFFFFFF) >> 31;
3866 for(
exp=13; my<0x80000000; my<<=1,--
exp) ;
3867 mx = (mx>>i) | 0x80000000;
3868 return half(detail::binary, detail::tangent_post<half::round_style>(my, mx,
exp-i, arg.data_&0x8000));
3882 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3883 return half(detail::binary, detail::float2half<half::round_style>(
std::asinh(detail::half2float<detail::internal_t>(arg.data_))));
3885 int abs = arg.data_ & 0x7FFF;
3886 if(!
abs ||
abs >= 0x7C00)
3887 return (
abs>0x7C00) ?
half(detail::binary, detail::signal(arg.data_)) : arg;
3889 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-1, 1, 1));
3890 if(half::round_style != std::round_to_nearest)
3893 case 0x32D4:
return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-13, 1, 1));
3894 case 0x3B5B:
return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-197, 1, 1));
3896 return half(detail::binary, detail::area<half::round_style,true>(arg.data_));
3910 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3911 return half(detail::binary, detail::float2half<half::round_style>(
std::acosh(detail::half2float<detail::internal_t>(arg.data_))));
3913 int abs = arg.data_ & 0x7FFF;
3914 if((arg.data_&0x8000) ||
abs < 0x3C00)
3915 return half(detail::binary, (
abs<=0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3917 return half(detail::binary, 0);
3918 if(arg.data_ >= 0x7C00)
3919 return (
abs>0x7C00) ?
half(detail::binary, detail::signal(arg.data_)) : arg;
3920 return half(detail::binary, detail::area<half::round_style,false>(arg.data_));
3935 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3936 return half(detail::binary, detail::float2half<half::round_style>(
std::atanh(detail::half2float<detail::internal_t>(arg.data_))));
3938 int abs = arg.data_ & 0x7FFF,
exp = 0;
3942 return half(detail::binary, (
abs==0x3C00) ? detail::pole(arg.data_&0x8000) : (
abs<=0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3944 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_, 0, 1));
3945 detail::uint32 m =
static_cast<detail::uint32
>((
abs&0x3FF)|((
abs>0x3FF)<<10)) << ((
abs>>10)+(
abs<=0x3FF)+6), my = 0x80000000 + m, mx = 0x80000000 - m;
3946 for(; mx<0x80000000; mx<<=1,++
exp) ;
3947 int i = my >= mx, s;
3948 return half(detail::binary, detail::log2_post<half::round_style,0xB8AA3B2A>(
detail::log2(
3949 (detail::divide64(my>>i, mx, s)+1)>>1, 27)+0x10,
exp+i-1, 16, arg.data_&0x8000));
3968 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3969 return half(detail::binary, detail::float2half<half::round_style>(
std::erf(detail::half2float<detail::internal_t>(arg.data_))));
3971 unsigned int abs = arg.data_ & 0x7FFF;
3972 if(!
abs ||
abs >= 0x7C00)
3973 return (
abs>=0x7C00) ?
half(detail::binary, (
abs==0x7C00) ? (arg.data_-0x4000) : detail::signal(arg.data_)) : arg;
3975 return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x3BFF, 1, 1));
3976 return half(detail::binary, detail::erf<half::round_style,false>(arg.data_));
3990 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3991 return half(detail::binary, detail::float2half<half::round_style>(
std::erfc(detail::half2float<detail::internal_t>(arg.data_))));
3993 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
3995 return (
abs>=0x7C00) ?
half(detail::binary, (
abs==0x7C00) ? (sign>>1) : detail::signal(arg.data_)) : arg;
3997 return half(detail::binary, 0x3C00);
3999 return half(detail::binary, detail::rounded<half::round_style,true>((sign>>1)-(sign>>15), sign>>15, 1));
4000 return half(detail::binary, detail::erf<half::round_style,true>(arg.data_));
4015 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
4016 return half(detail::binary, detail::float2half<half::round_style>(
std::lgamma(detail::half2float<detail::internal_t>(arg.data_))));
4018 int abs = arg.data_ & 0x7FFF;
4020 return half(detail::binary, (
abs==0x7C00) ? 0x7C00 : detail::signal(arg.data_));
4021 if(!
abs || arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(
abs&((1<<(25-(
abs>>10)))-1))))
4022 return half(detail::binary, detail::pole());
4023 if(arg.data_ == 0x3C00 || arg.data_ == 0x4000)
4024 return half(detail::binary, 0);
4025 return half(detail::binary, detail::gamma<half::round_style,true>(arg.data_));
4040 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
4041 return half(detail::binary, detail::float2half<half::round_style>(
std::tgamma(detail::half2float<detail::internal_t>(arg.data_))));
4043 unsigned int abs = arg.data_ & 0x7FFF;
4045 return half(detail::binary, detail::pole(arg.data_));
4047 return (arg.data_==0x7C00) ? arg :
half(detail::binary, detail::signal(arg.data_));
4048 if(arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(
abs&((1<<(25-(
abs>>10)))-1))))
4049 return half(detail::binary, detail::invalid());
4050 if(arg.data_ >= 0xCA80)
4051 return half(detail::binary, detail::underflow<half::round_style>((1-((
abs>>(25-(
abs>>10)))&1))<<15));
4052 if(arg.data_ <= 0x100 || (arg.data_ >= 0x4900 && arg.data_ < 0x8000))
4053 return half(detail::binary, detail::overflow<half::round_style>());
4054 if(arg.data_ == 0x3C00)
4056 return half(detail::binary, detail::gamma<half::round_style,false>(arg.data_));
4071 inline half ceil(
half arg) {
return half(detail::binary, detail::integral<std::round_toward_infinity,true,true>(arg.data_)); }
4079 inline half floor(
half arg) {
return half(detail::binary, detail::integral<std::round_toward_neg_infinity,true,true>(arg.data_)); }
4087 inline half trunc(
half arg) {
return half(detail::binary, detail::integral<std::round_toward_zero,true,true>(arg.data_)); }
4095 inline half round(
half arg) {
return half(detail::binary, detail::integral<std::round_to_nearest,false,true>(arg.data_)); }
4102 inline long lround(
half arg) {
return detail::half2int<std::round_to_nearest,false,false,long>(arg.data_); }
4110 inline half rint(
half arg) {
return half(detail::binary, detail::integral<half::round_style,true,true>(arg.data_)); }
4118 inline long lrint(
half arg) {
return detail::half2int<half::round_style,true,true,long>(arg.data_); }
4125 inline half nearbyint(
half arg) {
return half(detail::binary, detail::integral<half::round_style,true,false>(arg.data_)); }
4126 #if HALF_ENABLE_CPP11_LONG_LONG
4132 inline long long llround(
half arg) {
return detail::half2int<std::round_to_nearest,false,false,long long>(arg.data_); }
4140 inline long long llrint(
half arg) {
return detail::half2int<half::round_style,true,true,long long>(arg.data_); }
4157 unsigned int abs = arg.data_ & 0x7FFF;
4158 if(
abs >= 0x7C00 || !
abs)
4159 return (
abs>0x7C00) ?
half(detail::binary, detail::signal(arg.data_)) : arg;
4162 return half(detail::binary, (arg.data_&0x8000)|0x3800|(
abs&0x3FF));
4176 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
4177 if(
abs >= 0x7C00 || !
abs)
4178 return (
abs>0x7C00) ?
half(detail::binary, detail::signal(arg.data_)) : arg;
4182 return half(detail::binary, detail::overflow<half::round_style>(sign));
4184 return half(detail::binary, detail::underflow<half::round_style>(sign));
4186 return half(detail::binary, sign|(
exp<<10)|(
abs&0x3FF));
4187 unsigned int m = (
abs&0x3FF) | 0x400;
4188 return half(detail::binary, detail::rounded<half::round_style,false>(sign|(m>>(1-
exp)), (m>>-
exp)&1, (m&((1<<-
exp)-1))!=0));
4221 unsigned int abs = arg.data_ & 0x7FFF;
4224 arg =
half(detail::binary, detail::signal(arg.data_));
4225 return *iptr = arg, arg;
4228 return *iptr = arg,
half(detail::binary, arg.data_&0x8000);
4230 return iptr->data_ = arg.data_ & 0x8000, arg;
4231 unsigned int exp =
abs >> 10, mask = (1<<(25-
exp)) - 1, m = arg.data_ & mask;
4232 iptr->data_ = arg.data_ & ~mask;
4234 return half(detail::binary, arg.data_&0x8000);
4235 for(; m<0x400; m<<=1,--
exp) ;
4236 return half(detail::binary, (arg.data_&0x8000)|(
exp<<10)|(m&0x3FF));
4249 int abs = arg.data_ & 0x7FFF,
exp;
4250 if(!
abs ||
abs >= 0x7C00)
4252 detail::raise(FE_INVALID);
4253 return !
abs ? FP_ILOGB0 : (
abs==0x7C00) ? INT_MAX : FP_ILOGBNAN;
4267 int abs = arg.data_ & 0x7FFF,
exp;
4269 return half(detail::binary, detail::pole(0x8000));
4271 return half(detail::binary, (
abs==0x7C00) ? 0x7C00 : detail::signal(arg.data_));
4273 unsigned int value =
static_cast<unsigned>(
exp<0) << 15;
4277 for(
exp=18; m<0x400; m<<=1,--
exp) ;
4278 value |= (
exp<<10) + m;
4280 return half(detail::binary, value);
4293 int fabs = from.data_ & 0x7FFF, tabs = to.data_ & 0x7FFF;
4294 if(
fabs > 0x7C00 || tabs > 0x7C00)
4295 return half(detail::binary, detail::signal(from.data_, to.data_));
4296 if(from.data_ == to.data_ || !(
fabs|tabs))
4301 return half(detail::binary, (to.data_&0x8000)+1);
4303 unsigned int out = from.data_ + (((from.data_>>15)^
static_cast<unsigned>(
4304 (from.data_^(0x8000|(0x8000-(from.data_>>15))))<(to.data_^(0x8000|(0x8000-(to.data_>>15))))))<<1) - 1;
4305 detail::raise(FE_OVERFLOW,
fabs<0x7C00 && (out&0x7C00)==0x7C00);
4307 return half(detail::binary, out);
4320 int fabs = from.data_ & 0x7FFF;
4322 return half(detail::binary, detail::signal(from.data_));
4323 long double lfrom =
static_cast<long double>(from);
4324 if(detail::builtin_isnan(to) || lfrom == to)
4325 return half(
static_cast<float>(to));
4329 return half(detail::binary, (
static_cast<unsigned>(detail::builtin_signbit(to))<<15)+1);
4331 unsigned int out = from.data_ + (((from.data_>>15)^
static_cast<unsigned>(lfrom<to))<<1) - 1;
4332 detail::raise(FE_OVERFLOW, (out&0x7FFF)==0x7C00);
4334 return half(detail::binary, out);
4359 return !(arg.data_&0x7FFF) ? FP_ZERO :
4360 ((arg.data_&0x7FFF)<0x400) ? FP_SUBNORMAL :
4361 ((arg.data_&0x7FFF)<0x7C00) ? FP_NORMAL :
4362 ((arg.data_&0x7FFF)==0x7C00) ? FP_INFINITE :
4371 inline HALF_CONSTEXPR
bool isfinite(
half arg) {
return (arg.data_&0x7C00) != 0x7C00; }
4378 inline HALF_CONSTEXPR
bool isinf(
half arg) {
return (arg.data_&0x7FFF) == 0x7C00; }
4385 inline HALF_CONSTEXPR
bool isnan(
half arg) {
return (arg.data_&0x7FFF) > 0x7C00; }
4392 inline HALF_CONSTEXPR
bool isnormal(
half arg) {
return ((arg.data_&0x7C00)!=0) & ((arg.data_&0x7C00)!=0x7C00); }
4399 inline HALF_CONSTEXPR
bool signbit(
half arg) {
return (arg.data_&0x8000) != 0; }
4414 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);
4425 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);
4436 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);
4447 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);
4458 return x.data_!=y.data_ && ((x.data_|y.data_)&0x7FFF) && !
isnan(x) && !
isnan(y);
4487 template<
typename T,
typename U> T
half_cast(U arg) {
return detail::half_caster<T,U>::cast(arg); }
4503 template<
typename T,std::
float_round_style R,
typename U> T
half_cast(U arg) {
return detail::half_caster<T,U,R>::cast(arg); }
4518 inline int feclearexcept(
int excepts) { detail::errflags() &= ~excepts;
return 0; }
4527 inline int fetestexcept(
int excepts) {
return detail::errflags() & excepts; }
4538 inline int feraiseexcept(
int excepts) { detail::errflags() |= excepts; detail::raise(excepts);
return 0; }
4548 inline int fegetexceptflag(
int *flagp,
int excepts) { *flagp = detail::errflags() & excepts;
return 0; }
4559 inline int fesetexceptflag(
const int *flagp,
int excepts) { detail::errflags() = (detail::errflags()|(*flagp&excepts)) & (*flagp|~excepts);
return 0; }
4574 excepts &= detail::errflags();
4575 if(excepts & (FE_INVALID|FE_DIVBYZERO))
4576 throw std::domain_error(msg);
4577 if(excepts & FE_OVERFLOW)
4578 throw std::overflow_error(msg);
4579 if(excepts & FE_UNDERFLOW)
4580 throw std::underflow_error(msg);
4581 if(excepts & FE_INEXACT)
4582 throw std::range_error(msg);
4588 #undef HALF_UNUSED_NOERR
4589 #undef HALF_CONSTEXPR
4590 #undef HALF_CONSTEXPR_CONST
4591 #undef HALF_CONSTEXPR_NOERR
4592 #undef HALF_NOEXCEPT
4594 #undef HALF_THREAD_LOCAL
4595 #undef HALF_TWOS_COMPLEMENT_INT
4596 #ifdef HALF_POP_WARNINGS
4597 #pragma warning(pop)
4598 #undef HALF_POP_WARNINGS
Half-precision floating-point type.
Definition: half.hpp:2056
half & operator/=(float rhs)
Arithmetic assignment.
Definition: half.hpp:2135
half operator++(int)
Postfix increment.
Definition: half.hpp:2154
half & operator-=(float rhs)
Arithmetic assignment.
Definition: half.hpp:2123
half & operator*=(half rhs)
Arithmetic assignment.
Definition: half.hpp:2104
half & operator/=(half rhs)
Arithmetic assignment.
Definition: half.hpp:2111
half & operator+=(float rhs)
Arithmetic assignment.
Definition: half.hpp:2117
half & operator++()
Prefix increment.
Definition: half.hpp:2144
half & operator+=(half rhs)
Arithmetic assignment.
Definition: half.hpp:2090
half & operator-=(half rhs)
Arithmetic assignment.
Definition: half.hpp:2097
half & operator=(float rhs)
Assignment operator.
Definition: half.hpp:2079
constexpr half() noexcept
Default constructor.
Definition: half.hpp:2064
half & operator*=(float rhs)
Arithmetic assignment.
Definition: half.hpp:2129
half(float rhs)
Conversion constructor.
Definition: half.hpp:2069
half operator--(int)
Postfix decrement.
Definition: half.hpp:2159
half & operator--()
Prefix decrement.
Definition: half.hpp:2149
#define HALF_ERRHANDLING_THROW_UNDERFLOW
Throw C++ exception on underflow errors.
Definition: half.hpp:330
#define HALF_ERRHANDLING_THROW_INVALID
Throw C++ exception on domain errors.
Definition: half.hpp:315
#define HALF_ERRHANDLING_THROW_DIVBYZERO
Throw C++ exception on pole errors.
Definition: half.hpp:320
#define HALF_ERRHANDLING_THROW_INEXACT
Throw C++ exception on rounding errors.
Definition: half.hpp:335
#define HALF_ARITHMETIC_TYPE
Type for internal floating-point computations.
Definition: half.hpp:290
#define HALF_ERRHANDLING_THROW_OVERFLOW
Throw C++ exception on overflow errors.
Definition: half.hpp:325
#define HALF_ROUND_STYLE
Default rounding mode.
Definition: half.hpp:374
#define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
Raise INEXACT exception on underflow.
Definition: half.hpp:352
Main namespace for half-precision functionality.
Definition: half.hpp:433
half asinh(half arg)
Hyperbolic area sine.
Definition: half.hpp:3880
half sinh(half arg)
Hyperbolic sine.
Definition: half.hpp:3793
int feclearexcept(int excepts)
Clear exception flags.
Definition: half.hpp:4518
half nextafter(half from, half to)
Next representable value.
Definition: half.hpp:4291
constexpr bool operator>=(half x, half y)
Comparison for greater equal.
Definition: half.hpp:2524
half atan(half arg)
Arc tangent function.
Definition: half.hpp:3708
half hypot(half x, half y)
Hypotenuse function.
Definition: half.hpp:3315
constexpr bool operator>(half x, half y)
Comparison for greater than.
Definition: half.hpp:2500
half fdim(half x, half y)
Positive difference.
Definition: half.hpp:2904
half remquo(half x, half y, int *quo)
Remainder of division.
Definition: half.hpp:2784
int fegetexceptflag(int *flagp, int excepts)
Save exception flags.
Definition: half.hpp:4548
constexpr bool isfinite(half arg)
Check if finite number.
Definition: half.hpp:4371
int ilogb(half arg)
Extract exponent.
Definition: half.hpp:4247
half lgamma(half arg)
Natural logarithm of gamma function.
Definition: half.hpp:4013
int fesetexceptflag(const int *flagp, int excepts)
Restore exception flags.
Definition: half.hpp:4559
half fma(half x, half y, half z)
Fused multiply add.
Definition: half.hpp:2809
half nearbyint(half arg)
Nearest integer using half's internal rounding mode.
Definition: half.hpp:4125
constexpr bool operator!=(half x, half y)
Comparison for inequality.
Definition: half.hpp:2477
constexpr half abs(half arg)
Absolute value.
Definition: half.hpp:2735
half expm1(half arg)
Exponential minus one.
Definition: half.hpp:2997
half ldexp(half arg, int exp)
Multiply by power of two.
Definition: half.hpp:4211
half sin(half arg)
Sine function.
Definition: half.hpp:3556
half tanh(half arg)
Hyperbolic tangent.
Definition: half.hpp:3848
half rint(half arg)
Nearest integer using half's internal rounding mode.
Definition: half.hpp:4110
T half_cast(U arg)
Cast to or from half-precision floating-point number.
Definition: half.hpp:4487
half fmod(half x, half y)
Remainder of division.
Definition: half.hpp:2743
constexpr bool islessgreater(half x, half y)
Quiet comarison for less or greater.
Definition: half.hpp:4456
half log(half arg)
Natural logarithm.
Definition: half.hpp:3050
half cos(half arg)
Cosine function.
Definition: half.hpp:3589
half scalbn(half arg, int exp)
Multiply by power of two.
Definition: half.hpp:4200
half exp2(half arg)
Binary exponential.
Definition: half.hpp:2971
constexpr bool isless(half x, half y)
Quiet comparison for less than.
Definition: half.hpp:4434
half atanh(half arg)
Hyperbolic area tangent.
Definition: half.hpp:3933
long long llround(half arg)
Nearest integer.
Definition: half.hpp:4132
half nexttoward(half from, long double to)
Next representable value.
Definition: half.hpp:4318
half round(half arg)
Nearest integer.
Definition: half.hpp:4095
constexpr half fmax(half x, half y)
Maximum of half expressions.
Definition: half.hpp:2878
half log2(half arg)
Binary logarithm.
Definition: half.hpp:3113
half asin(half arg)
Arc sine.
Definition: half.hpp:3654
half sqrt(half arg)
Square root.
Definition: half.hpp:3206
constexpr bool operator<(half x, half y)
Comparison for less than.
Definition: half.hpp:2488
half trunc(half arg)
Nearest integer not greater in magnitude than half value.
Definition: half.hpp:4087
half erfc(half arg)
Complementary error function.
Definition: half.hpp:3988
constexpr bool operator==(half x, half y)
Comparison for equality.
Definition: half.hpp:2466
half tan(half arg)
Tangent function.
Definition: half.hpp:3617
half log10(half arg)
Common logarithm.
Definition: half.hpp:3078
half rsqrt(half arg)
Inverse square root.
Definition: half.hpp:3227
half floor(half arg)
Nearest integer not greater than half value.
Definition: half.hpp:4079
half acosh(half arg)
Hyperbolic area cosine.
Definition: half.hpp:3908
constexpr bool isnan(half arg)
Check for NaN.
Definition: half.hpp:4385
constexpr half operator-(half arg)
Negation.
Definition: half.hpp:2543
constexpr bool operator<=(half x, half y)
Comparison for less equal.
Definition: half.hpp:2512
half operator*(half x, half y)
Multiplication.
Definition: half.hpp:2618
long long llrint(half arg)
Nearest integer using half's internal rounding mode.
Definition: half.hpp:4140
half atan2(half y, half x)
Arc tangent function.
Definition: half.hpp:3738
int feraiseexcept(int excepts)
Raise exception flags.
Definition: half.hpp:4538
constexpr half fmin(half x, half y)
Minimum of half expressions.
Definition: half.hpp:2890
half scalbln(half arg, long exp)
Multiply by power of two.
Definition: half.hpp:4174
half tgamma(half arg)
Gamma function.
Definition: half.hpp:4038
constexpr bool signbit(half arg)
Check sign.
Definition: half.hpp:4399
long lrint(half arg)
Nearest integer using half's internal rounding mode.
Definition: half.hpp:4118
std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &in, half &arg)
Input operator.
Definition: half.hpp:2708
constexpr bool isinf(half arg)
Check for infinity.
Definition: half.hpp:4378
constexpr half copysign(half x, half y)
Take sign.
Definition: half.hpp:4342
half cosh(half arg)
Hyperbolic cosine.
Definition: half.hpp:3821
half logb(half arg)
Extract exponent.
Definition: half.hpp:4265
std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &out, half arg)
Output operator.
Definition: half.hpp:2690
constexpr bool islessequal(half x, half y)
Quiet comparison for less equal.
Definition: half.hpp:4445
half erf(half arg)
Error function.
Definition: half.hpp:3966
void sincos(half arg, half *sin, half *cos)
Compute sine and cosine simultaneously.
Definition: half.hpp:3491
half ceil(half arg)
Nearest integer not less than half value.
Definition: half.hpp:4071
half frexp(half arg, int *exp)
Decompress floating-point number.
Definition: half.hpp:4154
constexpr bool isunordered(half x, half y)
Quiet check if unordered.
Definition: half.hpp:4467
half log1p(half arg)
Natural logarithm plus one.
Definition: half.hpp:3156
half hypot(half x, half y, half z)
Hypotenuse function.
Definition: half.hpp:3361
constexpr int fpclassify(half arg)
Classify floating-point value.
Definition: half.hpp:4357
long lround(half arg)
Nearest integer.
Definition: half.hpp:4102
half acos(half arg)
Arc cosine function.
Definition: half.hpp:3683
constexpr bool isgreater(half x, half y)
Quiet comparison for greater than.
Definition: half.hpp:4412
half pow(half x, half y)
Power function.
Definition: half.hpp:3427
half nanh(const char *arg)
Get NaN value.
Definition: half.hpp:2915
half modf(half arg, half *iptr)
Extract integer and fractional parts.
Definition: half.hpp:4219
half cbrt(half arg)
Cubic root.
Definition: half.hpp:3264
constexpr bool isgreaterequal(half x, half y)
Quiet comparison for greater equal.
Definition: half.hpp:4423
void fethrowexcept(int excepts, const char *msg="")
Throw C++ exceptions based on set exception flags.
Definition: half.hpp:4572
int fetestexcept(int excepts)
Test exception flags.
Definition: half.hpp:4527
half exp(half arg)
Exponential function.
Definition: half.hpp:2936
constexpr bool isnormal(half arg)
Check if normal number.
Definition: half.hpp:4392
half remainder(half x, half y)
Remainder of division.
Definition: half.hpp:2764
half operator/(half x, half y)
Division.
Definition: half.hpp:2651
constexpr half fabs(half arg)
Absolute value.
Definition: half.hpp:2729
constexpr half operator+(half arg)
Identity.
Definition: half.hpp:2538
Extensions to the C++ standard library.
Definition: half.hpp:2325
size_t result_type
Function return type.
Definition: half.hpp:2444
half_float::half argument_type
Type of function argument.
Definition: half.hpp:2441
result_type operator()(argument_type arg) const
Compute hash function.
Definition: half.hpp:2449