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
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; };
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; };
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
529 typedef HALF_ARITHMETIC_TYPE internal_t;
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();
564 #if HALF_ENABLE_CPP11_CMATH
566 #elif defined(_MSC_VER)
567 return ::_isnan(
static_cast<double>(arg)) != 0;
580 #if HALF_ENABLE_CPP11_CMATH
583 return arg < T() || (arg == T() && T(1)/arg < T());
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);
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)
644 throw std::domain_error(HALF_ERRHANDLING_THROW_INVALID);
646 #ifdef HALF_ERRHANDLING_THROW_DIVBYZERO
647 if(flags & FE_DIVBYZERO)
648 throw std::domain_error(HALF_ERRHANDLING_THROW_DIVBYZERO);
650 #ifdef HALF_ERRHANDLING_THROW_OVERFLOW
651 if(flags & FE_OVERFLOW)
652 throw std::overflow_error(HALF_ERRHANDLING_THROW_OVERFLOW);
654 #ifdef HALF_ERRHANDLING_THROW_UNDERFLOW
655 if(flags & FE_UNDERFLOW)
656 throw std::underflow_error(HALF_ERRHANDLING_THROW_UNDERFLOW);
658 #ifdef HALF_ERRHANDLING_THROW_INEXACT
659 if(flags & FE_INEXACT)
660 throw std::range_error(HALF_ERRHANDLING_THROW_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;
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)
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));
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];
983 return rounded<R,false>(base_table[sexp]+(fbits>>i), (m>>(i-1))&1, (((
static_cast<uint32>(1)<<(i-1))-1)&m)!=0);
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);
1033 unsigned int hbits =
static_cast<unsigned>(
builtin_signbit(value)) << 15;
1037 return hbits | 0x7FFF;
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) ;
1089 return (
exp>24) ? rounded<R,false>(
bits, (value>>(
exp-25))&1, (((1<<(
exp-25))-1)&value)!=0) :
bits;
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));
1261 #if HALF_ENABLE_F16C_INTRINSICS
1262 return _mm_cvtsd_f64(_mm_cvtps_pd(_mm_cvtph_ps(_mm_cvtsi32_si128(value))));
1265 unsigned int abs = value & 0x7FFF;
1268 hi |= 0x3F000000 <<
static_cast<unsigned>(
abs>=0x7C00);
1269 for(;
abs<0x400;
abs<<=1,hi-=0x100000) ;
1272 bits<double>::type dbits =
static_cast<bits<double>::type
>(hi) << 32;
1274 std::memcpy(&out, &dbits,
sizeof(
double));
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;
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;
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);
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);
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);
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);
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);
1486 for(
uint32 bit=
static_cast<uint32>(1)<<F; bit; bit>>=2)
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];
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);
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)
1571 mx = tx; my = ty; mz -= (angles[i]^sign) - sign;
1573 return std::make_pair(my, mx);
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)
1595 mx = tx; my = ty; mz += (angles[i]^sign) - sign;
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;
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;
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);
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;
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);
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)
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);
1734 return fixed2half<R,30,false,false,true>(m,
exp, sign, 1);
1749 return overflow<R>();
1751 return underflow<R>();
1754 return fixed2half<R,15,false,false,false>(m,
exp-1, 0, r!=0);
1769 int i = my >= mx, s;
1772 return overflow<R>(sign);
1774 return underflow<R>(sign);
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;
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));
1850 m =
static_cast<uint32>((
abs&0x3FF)|0x400) << 21;
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);
1875 uint32 m = a.
m - ((d<32) ? (b.
m>>d) : 0);
1878 for(;
m<0x80000000;
m<<=1,--
exp) ;
1899 int i = a.
m >= b.
m, s;
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 /
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);
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;
2073 operator float()
const {
return detail::half2float<float>(
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
2236 friend long long llround(
half);
2237 friend long long llrint(
half);
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 {};
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");
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");
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;
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
2444 typedef size_t result_type;
2449 result_type operator()(argument_type arg)
const {
return hash<half_float::detail::uint16>()(arg.data_&-
static_cast<unsigned>(arg.data_!=0x8000)); }
2490 return !detail::compsignal(x.
data_, y.
data_) &&
2502 return !detail::compsignal(x.
data_, y.
data_) &&
2514 return !detail::compsignal(x.
data_, y.
data_) &&
2526 return !detail::compsignal(x.
data_, y.
data_) &&
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;
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_);
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) ;
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;
2828 for(; absx<0x400; absx<<=1,--
exp) ;
2829 for(; absy<0x400; absy<<=1,--
exp) ;
2832 exp += (absx>>10) + (absy>>10) + i;
2837 for(; absz<0x400; absz<<=1,--expz) ;
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));
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_))));
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>());
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_))));
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>(
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_))));
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>());
3018 m = (m<<(e-14)) & 0x7FFFFFFF;
3027 m = detail::divide64(0x80000000, m, 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_))));
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_))));
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_))));
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);
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_));
3164 if(!
abs ||
abs >= 0x7C00)
3165 return (
abs>0x7C00) ?
half(detail::binary, detail::signal(arg.
data_)) : arg;
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_))));
3213 return half(detail::binary, (
abs>0x7C00) ? detail::signal(arg.
data_) : (arg.
data_>0x8000) ? detail::invalid() : arg.
data_);
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;
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_))));
3270 if(!
abs ||
abs == 0x3C00 ||
abs >= 0x7C00)
3271 return (
abs>0x7C00) ?
half(detail::binary, detail::signal(arg.
data_)) : arg;
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;
3295 m = detail::divide64(0x80000000, m, s);
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_)) :
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) ;
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)));
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));
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_))));
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));
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);
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_))));
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));
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);
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_))));
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));
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));
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);
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));
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)
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));
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));
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_))));
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);
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_))));
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_))));
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));
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);
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_))));
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));
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_))));
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_))));
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));
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_))));
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));
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_)); }
4102 inline long lround(
half arg) {
return detail::half2int<std::round_to_nearest,false,false,long>(arg.
data_); }
4118 inline long lrint(
half arg) {
return detail::half2int<half::round_style,true,true,long>(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;
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));
4250 if(!
abs ||
abs >= 0x7C00)
4252 detail::raise(FE_INVALID);
4253 return !
abs ? FP_ILOGB0 : (
abs==0x7C00) ? INT_MAX : FP_ILOGBNAN;
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);
4294 if(
fabs > 0x7C00 || tabs > 0x7C00)
4295 return half(detail::binary, detail::signal(from.
data_, to.
data_));
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);
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 :
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
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 & operator*=(half rhs)
friend void sincos(half, half *, half *)
half & operator+=(float rhs)
friend half nanh(const char *)
detail::uint16 data_
Internal binary representation.
HALF_CONSTEXPR half() HALF_NOEXCEPT
friend half nearbyint(half)
friend half pow(half, half)
friend half remquo(half, half, int *)
friend std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &, half)
friend half atan2(half, half)
friend half modf(half, half *)
friend half operator*(half, half)
friend half nexttoward(half, long double)
friend HALF_CONSTEXPR bool isgreaterequal(half, half)
static const std::float_round_style round_style
Rounding mode to use.
friend half nextafter(half, half)
friend HALF_CONSTEXPR half copysign(half, half)
friend half operator/(half, half)
half & operator-=(half rhs)
half & operator*=(float rhs)
half & operator+=(half rhs)
friend HALF_CONSTEXPR half operator-(half)
friend HALF_CONSTEXPR bool isnan(half)
friend half scalbln(half, long)
friend half frexp(half, int *)
friend HALF_CONSTEXPR half fabs(half)
friend HALF_CONSTEXPR bool islessgreater(half, half)
friend HALF_CONSTEXPR bool isnormal(half)
friend half fdim(half, half)
friend HALF_CONSTEXPR int fpclassify(half)
friend HALF_CONSTEXPR_NOERR bool operator==(half, half)
friend HALF_CONSTEXPR bool isfinite(half)
friend HALF_CONSTEXPR bool isgreater(half, half)
friend half fmod(half, half)
friend HALF_CONSTEXPR bool signbit(half)
friend half remainder(half, half)
friend HALF_CONSTEXPR_NOERR half fmax(half, half)
half & operator=(float rhs)
half & operator/=(half rhs)
friend HALF_CONSTEXPR_NOERR bool operator<=(half, half)
half & operator-=(float rhs)
friend HALF_CONSTEXPR bool isless(half, half)
friend HALF_CONSTEXPR_NOERR bool operator>=(half, half)
friend half hypot(half, half)
friend std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &, half &)
friend HALF_CONSTEXPR_NOERR bool operator!=(half, half)
friend HALF_CONSTEXPR_NOERR bool operator<(half, half)
half & operator/=(float rhs)
friend half operator+(half, half)
friend HALF_CONSTEXPR_NOERR half fmin(half, half)
friend HALF_CONSTEXPR bool isinf(half)
friend half fma(half, half, half)
friend HALF_CONSTEXPR bool islessequal(half, half)
friend HALF_CONSTEXPR_NOERR bool operator>(half, half)
unsigned short uint16
Unsigned integer of (at least) 16 bits width.
unsigned int integral(unsigned int value)
bool builtin_signbit(T arg)
unsigned int hypot_post(uint32 r, int exp)
bool builtin_isnan(T arg)
HALF_CONSTEXPR_NOERR unsigned int check_underflow(unsigned int arg)
unsigned int fixed2half(uint32 m, int exp=14, unsigned int sign=0, int s=0)
unsigned int mod(unsigned int x, unsigned int y, int *quo=NULL)
HALF_CONSTEXPR_CONST binary_t binary
Tag for binary construction.
HALF_CONSTEXPR_NOERR unsigned int select(unsigned int x, unsigned int HALF_UNUSED_NOERR(y))
float half2float_impl(unsigned int value, float, true_type)
HALF_CONSTEXPR_NOERR unsigned int overflow(unsigned int sign=0)
unsigned long uint32
Fastest unsigned integer of (at least) 32 bits width.
uint32 multiply64(uint32 x, uint32 y)
long int32
Fastest unsigned integer of (at least) 32 bits width.
T half2int(unsigned int value)
uint32 mulhi(uint32 x, uint32 y)
HALF_CONSTEXPR_NOERR bool compsignal(unsigned int x, unsigned int y)
unsigned int float2half(T value)
std::pair< uint32, uint32 > hyperbolic_args(unsigned int abs, int &exp, unsigned int n=32)
HALF_CONSTEXPR_NOERR unsigned int underflow(unsigned int sign=0)
HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int nan)
HALF_CONSTEXPR_NOERR unsigned int invalid()
unsigned int gamma(unsigned int arg)
uint32 arithmetic_shift(uint32 arg, int i)
std::pair< uint32, uint32 > atan2_args(unsigned int abs)
T half2float(unsigned int value)
uint32 divide64(uint32 x, uint32 y, int &s)
uint32 angle_arg(unsigned int abs, int &k)
unsigned int log2_post(uint32 m, int ilog, int exp, unsigned int sign=0)
unsigned int area(unsigned int arg)
HALF_CONSTEXPR_NOERR unsigned int rounded(unsigned int value, int g, int s)
unsigned int float2half_impl(float value, true_type)
uint32 sign_mask(uint32 arg)
bool builtin_isinf(T arg)
unsigned int int2half(T value)
unsigned int tangent_post(uint32 my, uint32 mx, int exp, unsigned int sign=0)
unsigned int exp2_post(uint32 m, int exp, bool esign, unsigned int sign=0, unsigned int n=32)
HALF_CONSTEXPR_NOERR unsigned int pole(unsigned int sign=0)
#define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
int feclearexcept(int excepts)
HALF_CONSTEXPR half fabs(half arg)
half nextafter(half from, half to)
half hypot(half x, half y)
HALF_CONSTEXPR bool isunordered(half x, half y)
half fdim(half x, half y)
half remquo(half x, half y, int *quo)
int fegetexceptflag(int *flagp, int excepts)
HALF_CONSTEXPR half copysign(half x, half y)
HALF_CONSTEXPR bool isfinite(half arg)
int fesetexceptflag(const int *flagp, int excepts)
HALF_CONSTEXPR half abs(half arg)
half fma(half x, half y, half z)
HALF_CONSTEXPR_NOERR half fmin(half x, half y)
half ldexp(half arg, int exp)
HALF_CONSTEXPR_NOERR bool operator!=(half x, half y)
HALF_CONSTEXPR_NOERR half fmax(half x, half y)
HALF_CONSTEXPR_NOERR bool operator<(half x, half y)
HALF_CONSTEXPR half operator-(half arg)
half fmod(half x, half y)
half scalbn(half arg, int exp)
HALF_CONSTEXPR int fpclassify(half arg)
HALF_CONSTEXPR_NOERR bool operator>=(half x, half y)
std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &in, half &arg)
half nexttoward(half from, long double to)
HALF_CONSTEXPR bool isgreater(half x, half y)
HALF_CONSTEXPR half operator+(half arg)
std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &out, half arg)
HALF_CONSTEXPR bool signbit(half arg)
HALF_CONSTEXPR bool isnan(half arg)
HALF_CONSTEXPR_NOERR bool operator<=(half x, half y)
half operator*(half x, half y)
HALF_CONSTEXPR bool isnormal(half arg)
half atan2(half y, half x)
int feraiseexcept(int excepts)
HALF_CONSTEXPR bool isless(half x, half y)
half scalbln(half arg, long exp)
HALF_CONSTEXPR_NOERR bool operator==(half x, half y)
HALF_CONSTEXPR bool isinf(half arg)
HALF_CONSTEXPR_NOERR bool operator>(half x, half y)
void sincos(half arg, half *sin, half *cos)
half frexp(half arg, int *exp)
HALF_CONSTEXPR bool islessgreater(half x, half y)
half hypot(half x, half y, half z)
HALF_CONSTEXPR bool islessequal(half x, half y)
half nanh(const char *arg)
half modf(half arg, half *iptr)
void fethrowexcept(int excepts, const char *msg="")
HALF_CONSTEXPR bool isgreaterequal(half x, half y)
int fetestexcept(int excepts)
half remainder(half x, half y)
half operator/(half x, half y)
Extensions to the C++ standard library.
Tag type for binary construction.
Type traits for floating-point bits.
Helper for tag dispatching.
Class for 1.31 unsigned floating-point computation.
uint32 m
mantissa as 1.31.
friend f31 operator-(f31 a, f31 b)
friend f31 operator*(f31 a, f31 b)
HALF_CONSTEXPR f31(uint32 mant, int e)
friend f31 operator/(f31 a, f31 b)
friend f31 operator+(f31 a, f31 b)
Type traits for floating-point types.