MU Library
half.hpp
Go to the documentation of this file.
1 // SPDX-License-Identifier: Apache-2.0
2 // Copyright 2024 XCENA Inc.
3 
4 // half - IEEE 754-based half-precision floating-point library.
5 //
6 // Copyright (c) 2012-2021 Christian Rau <rauy@users.sourceforge.net>
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
9 // files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
10 // modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
11 // Software is furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
16 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 
20 // Version 2.2.0
21 
24 
25 #ifndef HALF_HALF_HPP
26 #define HALF_HALF_HPP
27 
28 #define HALF_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
29 
30 #if defined(__INTEL_COMPILER)
31 #define HALF_ICC_VERSION __INTEL_COMPILER
32 #elif defined(__ICC)
33 #define HALF_ICC_VERSION __ICC
34 #elif defined(__ICL)
35 #define HALF_ICC_VERSION __ICL
36 #else
37 #define HALF_ICC_VERSION 0
38 #endif
39 
40 // Redefine FE Flags For MU-picolibc
41 #define MU_HALF_FE_INVALID 0x01
42 #define MU_HALF_FE_DIVBYZERO 0x04
43 #define MU_HALF_FE_OVERFLOW 0x08
44 #define MU_HALF_FE_UNDERFLOW 0x10
45 #define MU_HALF_FE_INEXACT 0x20
46 #define MU_HALF_FE_ALL_EXCEPT (MU_HALF_FE_INEXACT | MU_HALF_FE_DIVBYZERO | MU_HALF_FE_UNDERFLOW | MU_HALF_FE_OVERFLOW | MU_HALF_FE_INVALID)
47 
48 // check C++11 language features
49 #if defined(__clang__) // clang
50 #if __has_feature(cxx_static_assert) && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
51 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
52 #endif
53 #if __has_feature(cxx_constexpr) && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
54 #define HALF_ENABLE_CPP11_CONSTEXPR 1
55 #endif
56 #if __has_feature(cxx_noexcept) && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
57 #define HALF_ENABLE_CPP11_NOEXCEPT 1
58 #endif
59 #if __has_feature(cxx_user_literals) && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
60 #define HALF_ENABLE_CPP11_USER_LITERALS 0
61 #endif
62 #if __has_feature(cxx_thread_local) && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
63 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
64 #endif
65 #if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) && !defined(HALF_ENABLE_CPP11_LONG_LONG)
66 #define HALF_ENABLE_CPP11_LONG_LONG 1
67 #endif
68 #elif HALF_ICC_VERSION && defined(__INTEL_CXX11_MODE__) // Intel C++
69 #if HALF_ICC_VERSION >= 1500 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
70 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
71 #endif
72 #if HALF_ICC_VERSION >= 1500 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
73 #define HALF_ENABLE_CPP11_USER_LITERALS 0
74 #endif
75 #if HALF_ICC_VERSION >= 1400 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
76 #define HALF_ENABLE_CPP11_CONSTEXPR 1
77 #endif
78 #if HALF_ICC_VERSION >= 1400 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
79 #define HALF_ENABLE_CPP11_NOEXCEPT 1
80 #endif
81 #if HALF_ICC_VERSION >= 1110 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
82 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
83 #endif
84 #if HALF_ICC_VERSION >= 1110 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
85 #define HALF_ENABLE_CPP11_LONG_LONG 1
86 #endif
87 #elif defined(__GNUC__) // gcc
88 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
89 #if HALF_GCC_VERSION >= 408 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
90 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
91 #endif
92 #if HALF_GCC_VERSION >= 407 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
93 #define HALF_ENABLE_CPP11_USER_LITERALS 0
94 #endif
95 #if HALF_GCC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
96 #define HALF_ENABLE_CPP11_CONSTEXPR 1
97 #endif
98 #if HALF_GCC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
99 #define HALF_ENABLE_CPP11_NOEXCEPT 1
100 #endif
101 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
102 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
103 #endif
104 #if !defined(HALF_ENABLE_CPP11_LONG_LONG)
105 #define HALF_ENABLE_CPP11_LONG_LONG 1
106 #endif
107 #endif
108 #define HALF_TWOS_COMPLEMENT_INT 1
109 #elif defined(_MSC_VER) // Visual C++
110 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
111 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
112 #endif
113 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
114 #define HALF_ENABLE_CPP11_USER_LITERALS 0
115 #endif
116 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
117 #define HALF_ENABLE_CPP11_CONSTEXPR 1
118 #endif
119 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
120 #define HALF_ENABLE_CPP11_NOEXCEPT 1
121 #endif
122 #if _MSC_VER >= 1600 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
123 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
124 #endif
125 #if _MSC_VER >= 1310 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
126 #define HALF_ENABLE_CPP11_LONG_LONG 1
127 #endif
128 #define HALF_TWOS_COMPLEMENT_INT 1
129 #define HALF_POP_WARNINGS 1
130 #pragma warning(push)
131 #pragma warning(disable : 4099 4127 4146) // struct vs class, constant in if, negative unsigned
132 #endif
133 
134 // check C++11 library features
135 #include <utility>
136 #if defined(_LIBCPP_VERSION) // libc++
137 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
138 #ifndef HALF_ENABLE_CPP11_TYPE_TRAITS
139 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
140 #endif
141 #ifndef HALF_ENABLE_CPP11_CSTDINT
142 #define HALF_ENABLE_CPP11_CSTDINT 1
143 #endif
144 #ifndef HALF_ENABLE_CPP11_CMATH
145 #define HALF_ENABLE_CPP11_CMATH 0
146 #endif
147 #ifndef HALF_ENABLE_CPP11_HASH
148 #define HALF_ENABLE_CPP11_HASH 1
149 #endif
150 #ifndef HALF_ENABLE_CPP11_CFENV
151 #define HALF_ENABLE_CPP11_CFENV 1
152 #endif
153 #endif
154 #elif defined(__GLIBCXX__) // libstdc++
155 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
156 #ifdef __clang__
157 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
158 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
159 #endif
160 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CSTDINT)
161 #define HALF_ENABLE_CPP11_CSTDINT 1
162 #endif
163 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CMATH)
164 #define HALF_ENABLE_CPP11_CMATH 1
165 #endif
166 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_HASH)
167 #define HALF_ENABLE_CPP11_HASH 1
168 #endif
169 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CFENV)
170 #define HALF_ENABLE_CPP11_CFENV 1
171 #endif
172 #else
173 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
174 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
175 #endif
176 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CSTDINT)
177 #define HALF_ENABLE_CPP11_CSTDINT 1
178 #endif
179 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CMATH)
180 #define HALF_ENABLE_CPP11_CMATH 1
181 #endif
182 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_HASH)
183 #define HALF_ENABLE_CPP11_HASH 1
184 #endif
185 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CFENV)
186 #define HALF_ENABLE_CPP11_CFENV 1
187 #endif
188 #endif
189 #endif
190 #elif defined(_CPPLIB_VER) // Dinkumware/Visual C++
191 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
192 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
193 #endif
194 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_CSTDINT)
195 #define HALF_ENABLE_CPP11_CSTDINT 1
196 #endif
197 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_HASH)
198 #define HALF_ENABLE_CPP11_HASH 1
199 #endif
200 #if _CPPLIB_VER >= 610 && !defined(HALF_ENABLE_CPP11_CMATH)
201 #define HALF_ENABLE_CPP11_CMATH 1
202 #endif
203 #if _CPPLIB_VER >= 610 && !defined(HALF_ENABLE_CPP11_CFENV)
204 #define HALF_ENABLE_CPP11_CFENV 1
205 #endif
206 #endif
207 #undef HALF_GCC_VERSION
208 #undef HALF_ICC_VERSION
209 
210 // any error throwing C++ exceptions?
211 #if defined(HALF_ERRHANDLING_THROW_INVALID) || defined(HALF_ERRHANDLING_THROW_DIVBYZERO) || defined(HALF_ERRHANDLING_THROW_OVERFLOW) || defined(HALF_ERRHANDLING_THROW_UNDERFLOW) || defined(HALF_ERRHANDLING_THROW_INEXACT)
212 #define HALF_ERRHANDLING_THROWS 1
213 #endif
214 
215 // any error handling enabled?
216 #define HALF_ERRHANDLING (HALF_ERRHANDLING_FLAGS || HALF_ERRHANDLING_ERRNO || HALF_ERRHANDLING_FENV || HALF_ERRHANDLING_THROWS)
217 
218 #if HALF_ERRHANDLING
219 #define HALF_UNUSED_NOERR(name) name
220 #else
221 #define HALF_UNUSED_NOERR(name)
222 #endif
223 
224 // support constexpr
225 #if HALF_ENABLE_CPP11_CONSTEXPR
226 #define HALF_CONSTEXPR constexpr
227 #define HALF_CONSTEXPR_CONST constexpr
228 #if HALF_ERRHANDLING
229 #define HALF_CONSTEXPR_NOERR
230 #else
231 #define HALF_CONSTEXPR_NOERR constexpr
232 #endif
233 #else
234 #define HALF_CONSTEXPR
235 #define HALF_CONSTEXPR_CONST const
236 #define HALF_CONSTEXPR_NOERR
237 #endif
238 
239 // support noexcept
240 #if HALF_ENABLE_CPP11_NOEXCEPT
241 #define HALF_NOEXCEPT noexcept
242 #define HALF_NOTHROW noexcept
243 #else
244 #define HALF_NOEXCEPT
245 #define HALF_NOTHROW throw()
246 #endif
247 
248 // support thread storage
249 #if HALF_ENABLE_CPP11_THREAD_LOCAL
250 #define HALF_THREAD_LOCAL thread_local
251 #else
252 #define HALF_THREAD_LOCAL static
253 #endif
254 
255 #include <algorithm>
256 #include <utility>
257 // #include <istream>
258 // #include <ostream>
259 #include <climits>
260 #include <cmath>
261 #include <cstdlib>
262 #include <cstring>
263 #include <limits>
264 #include <stdexcept>
265 
266 #if HALF_ENABLE_CPP11_TYPE_TRAITS
267 #include <type_traits>
268 #endif
269 #if HALF_ENABLE_CPP11_CSTDINT
270 #include <cstdint>
271 #endif
272 #if HALF_ERRHANDLING_ERRNO
273 #include <cerrno>
274 #endif
275 #if HALF_ENABLE_CPP11_CFENV
276 #include <cfenv>
277 #endif
278 #if HALF_ENABLE_CPP11_HASH
279 #include <functional>
280 #endif
281 
282 // ERASED
283 #undef fpclassify
284 #undef isfinite
285 #undef isinf
286 #undef isnan
287 #undef isnormal
288 #undef signbit
289 #undef isgreater
290 #undef isgreaterequal
291 #undef isless
292 #undef islessequal
293 #undef islessgreater
294 #undef isunordered
295 
296 #ifndef HALF_ENABLE_F16C_INTRINSICS
303 #define HALF_ENABLE_F16C_INTRINSICS __F16C__
304 #endif
305 #if HALF_ENABLE_F16C_INTRINSICS
306 #include <immintrin.h>
307 #endif
308 
309 #ifdef HALF_DOXYGEN_ONLY
315 #define HALF_ARITHMETIC_TYPE (undefined)
316 
320 #define HALF_ERRHANDLING_FLAGS 0
321 
327 #define HALF_ERRHANDLING_ERRNO 0
328 
335 #define HALF_ERRHANDLING_FENV 0
336 
340 #define HALF_ERRHANDLING_THROW_INVALID (undefined)
341 
345 #define HALF_ERRHANDLING_THROW_DIVBYZERO (undefined)
346 
350 #define HALF_ERRHANDLING_THROW_OVERFLOW (undefined)
351 
355 #define HALF_ERRHANDLING_THROW_UNDERFLOW (undefined)
356 
360 #define HALF_ERRHANDLING_THROW_INEXACT (undefined)
361 #endif
362 
363 #ifndef HALF_ERRHANDLING_OVERFLOW_TO_INEXACT
367 #define HALF_ERRHANDLING_OVERFLOW_TO_INEXACT 1
368 #endif
369 
370 #ifndef HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
377 #define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT 1
378 #endif
379 
398 #ifndef HALF_ROUND_STYLE
399 #define HALF_ROUND_STYLE 1 // = std::round_to_nearest
400 #endif
401 
407 #define HUGE_VALH std::numeric_limits<half_float::half>::infinity()
408 
414 #define FP_FAST_FMAH 1
415 
421 #define HLF_ROUNDS HALF_ROUND_STYLE
422 
423 #ifndef FP_ILOGB0
424 #define FP_ILOGB0 INT_MIN
425 #endif
426 #ifndef FP_ILOGBNAN
427 #define FP_ILOGBNAN INT_MAX
428 #endif
429 #ifndef FP_SUBNORMAL
430 #define FP_SUBNORMAL 0
431 #endif
432 #ifndef FP_ZERO
433 #define FP_ZERO 1
434 #endif
435 #ifndef FP_NAN
436 #define FP_NAN 2
437 #endif
438 #ifndef FP_INFINITE
439 #define FP_INFINITE 3
440 #endif
441 #ifndef FP_NORMAL
442 #define FP_NORMAL 4
443 #endif
444 
445 #if !HALF_ENABLE_CPP11_CFENV && !defined(MU_HALF_FE_ALL_EXCEPT)
446 #define MU_HALF_FE_INVALID 0x10
447 #define MU_HALF_FE_DIVBYZERO 0x08
448 #define MU_HALF_FE_OVERFLOW 0x04
449 #define MU_HALF_FE_UNDERFLOW 0x02
450 #define MU_HALF_FE_INEXACT 0x01
451 #define MU_HALF_FE_ALL_EXCEPT (MU_HALF_FE_INVALID | MU_HALF_FE_DIVBYZERO | MU_HALF_FE_OVERFLOW | MU_HALF_FE_UNDERFLOW | MU_HALF_FE_INEXACT)
452 #endif
453 
456 namespace half_float
457 {
458 class half;
459 
460 #if HALF_ENABLE_CPP11_USER_LITERALS
467 namespace literal
468 {
469 half operator"" _h(long double);
470 }
471 #endif
472 
475 namespace detail
476 {
477 #if HALF_ENABLE_CPP11_TYPE_TRAITS
479 template <bool B, typename T, typename F>
480 struct conditional : std::conditional<B, T, F>
481 {
482 };
483 
485 template <bool B>
486 struct bool_type : std::integral_constant<bool, B>
487 {
488 };
489 using std::false_type;
490 using std::true_type;
491 
493 template <typename T>
494 struct is_float : std::is_floating_point<T>
495 {
496 };
497 #else
499 template <bool, typename T, typename>
501 {
502  typedef T type;
503 };
504 template <typename T, typename F>
505 struct conditional<false, T, F>
506 {
507  typedef F type;
508 };
509 
511 template <bool>
512 struct bool_type
513 {
514 };
517 
519 template <typename>
521 {
522 };
523 template <typename T>
524 struct is_float<const T> : is_float<T>
525 {
526 };
527 template <typename T>
528 struct is_float<volatile T> : is_float<T>
529 {
530 };
531 template <typename T>
532 struct is_float<const volatile T> : is_float<T>
533 {
534 };
535 template <>
536 struct is_float<float> : true_type
537 {
538 };
539 template <>
540 struct is_float<double> : true_type
541 {
542 };
543 template <>
544 struct is_float<long double> : true_type
545 {
546 };
547 #endif
548 
550 template <typename T>
551 struct bits
552 {
553  typedef unsigned char type;
554 };
555 template <typename T>
556 struct bits<const T> : bits<T>
557 {
558 };
559 template <typename T>
560 struct bits<volatile T> : bits<T>
561 {
562 };
563 template <typename T>
564 struct bits<const volatile T> : bits<T>
565 {
566 };
567 
568 #if HALF_ENABLE_CPP11_CSTDINT
570 typedef std::uint_least16_t uint16;
571 
573 typedef std::uint_fast32_t uint32;
574 
576 typedef std::int_fast32_t int32;
577 
579 template <>
580 struct bits<float>
581 {
582  typedef std::uint_least32_t type;
583 };
584 
586 template <>
587 struct bits<double>
588 {
589  typedef std::uint_least64_t type;
590 };
591 #else
593 typedef unsigned short uint16;
594 
596 typedef unsigned long uint32;
597 
599 typedef long int32;
600 
602 template <>
603 struct bits<float> : conditional<std::numeric_limits<unsigned int>::digits >= 32, unsigned int, unsigned long>
604 {
605 };
606 
607 #if HALF_ENABLE_CPP11_LONG_LONG
609 template <>
610 struct bits<double> : conditional<std::numeric_limits<unsigned long>::digits >= 64, unsigned long, unsigned long long>
611 {
612 };
613 #else
615 template <>
616 struct bits<double>
617 {
618  typedef unsigned long type;
619 };
620 #endif
621 #endif
622 
623 #ifdef HALF_ARITHMETIC_TYPE
625 typedef HALF_ARITHMETIC_TYPE internal_t;
626 #endif
627 
629 struct binary_t
630 {
631 };
632 
635 
638 
644 template <typename T>
645 bool builtin_isinf(T arg)
646 {
647 #if HALF_ENABLE_CPP11_CMATH
648  return std::isinf(arg);
649 #elif defined(_MSC_VER)
650  return !::_finite(static_cast<double>(arg)) && !::_isnan(static_cast<double>(arg));
651 #else
652  return arg == std::numeric_limits<T>::infinity() || arg == -std::numeric_limits<T>::infinity();
653 #endif
654 }
655 
661 template <typename T>
662 bool builtin_isnan(T arg)
663 {
664 #if HALF_ENABLE_CPP11_CMATH
665  return std::isnan(arg);
666 #elif defined(_MSC_VER)
667  return ::_isnan(static_cast<double>(arg)) != 0;
668 #else
669  return arg != arg;
670 #endif
671 }
672 
678 template <typename T>
679 bool builtin_signbit(T arg)
680 {
681 #if HALF_ENABLE_CPP11_CMATH
682  return std::signbit(arg);
683 #else
684  return arg < T() || (arg == T() && T(1) / arg < T());
685 #endif
686 }
687 
692 inline uint32 sign_mask(uint32 arg)
693 {
694  static const int N = std::numeric_limits<uint32>::digits - 1;
695 #if HALF_TWOS_COMPLEMENT_INT
696  return static_cast<int32>(arg) >> N;
697 #else
698  return -((arg >> N) & 1);
699 #endif
700 }
701 
706 inline uint32 arithmetic_shift(uint32 arg, int i)
707 {
708 #if HALF_TWOS_COMPLEMENT_INT
709  return static_cast<int32>(arg) >> i;
710 #else
711  return static_cast<int32>(arg) / (static_cast<int32>(1) << i) - ((arg >> (std::numeric_limits<uint32>::digits - 1)) & 1);
712 #endif
713 }
714 
718 
721 inline int& errflags()
722 {
723  HALF_THREAD_LOCAL int flags = 0;
724  return flags;
725 }
726 
730 inline void raise(int HALF_UNUSED_NOERR(flags), bool HALF_UNUSED_NOERR(cond) = true)
731 {
732 #if HALF_ERRHANDLING
733  if (!cond)
734  return;
735 #if HALF_ERRHANDLING_FLAGS
736  errflags() |= flags;
737 #endif
738 #if HALF_ERRHANDLING_ERRNO
739  if (flags & MU_HALF_FE_INVALID)
740  errno = EDOM;
742  errno = ERANGE;
743 #endif
744 #if HALF_ERRHANDLING_FENV && HALF_ENABLE_CPP11_CFENV
745  std::feraiseexcept(flags);
746 #endif
747 #ifdef HALF_ERRHANDLING_THROW_INVALID
748  if (flags & MU_HALF_FE_INVALID)
749  throw std::domain_error(HALF_ERRHANDLING_THROW_INVALID);
750 #endif
751 #ifdef HALF_ERRHANDLING_THROW_DIVBYZERO
752  if (flags & MU_HALF_FE_DIVBYZERO)
753  throw std::domain_error(HALF_ERRHANDLING_THROW_DIVBYZERO);
754 #endif
755 #ifdef HALF_ERRHANDLING_THROW_OVERFLOW
756  if (flags & MU_HALF_FE_OVERFLOW)
757  throw std::overflow_error(HALF_ERRHANDLING_THROW_OVERFLOW);
758 #endif
759 #ifdef HALF_ERRHANDLING_THROW_UNDERFLOW
760  if (flags & MU_HALF_FE_UNDERFLOW)
761  throw std::underflow_error(HALF_ERRHANDLING_THROW_UNDERFLOW);
762 #endif
763 #ifdef HALF_ERRHANDLING_THROW_INEXACT
764  if (flags & MU_HALF_FE_INEXACT)
765  throw std::range_error(HALF_ERRHANDLING_THROW_INEXACT);
766 #endif
767 #if HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
768  if ((flags & MU_HALF_FE_UNDERFLOW) && !(flags & MU_HALF_FE_INEXACT))
769  raise(MU_HALF_FE_INEXACT);
770 #endif
771 #if HALF_ERRHANDLING_OVERFLOW_TO_INEXACT
772  if ((flags & MU_HALF_FE_OVERFLOW) && !(flags & MU_HALF_FE_INEXACT))
773  raise(MU_HALF_FE_INEXACT);
774 #endif
775 #endif
776 }
777 
784 inline HALF_CONSTEXPR_NOERR bool compsignal(unsigned int x, unsigned int y)
785 {
786 #if HALF_ERRHANDLING
787  raise(MU_HALF_FE_INVALID, (x & 0x7FFF) > 0x7C00 || (y & 0x7FFF) > 0x7C00);
788 #endif
789  return (x & 0x7FFF) > 0x7C00 || (y & 0x7FFF) > 0x7C00;
790 }
791 
796 inline HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int nan)
797 {
798 #if HALF_ERRHANDLING
799  raise(MU_HALF_FE_INVALID, !(nan & 0x200));
800 #endif
801  return nan | 0x200;
802 }
803 
809 inline HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int x, unsigned int y)
810 {
811 #if HALF_ERRHANDLING
812  raise(MU_HALF_FE_INVALID, ((x & 0x7FFF) > 0x7C00 && !(x & 0x200)) || ((y & 0x7FFF) > 0x7C00 && !(y & 0x200)));
813 #endif
814  return ((x & 0x7FFF) > 0x7C00) ? (x | 0x200) : (y | 0x200);
815 }
816 
823 inline HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int x, unsigned int y, unsigned int z)
824 {
825 #if HALF_ERRHANDLING
826  raise(MU_HALF_FE_INVALID, ((x & 0x7FFF) > 0x7C00 && !(x & 0x200)) || ((y & 0x7FFF) > 0x7C00 && !(y & 0x200)) || ((z & 0x7FFF) > 0x7C00 && !(z & 0x200)));
827 #endif
828  return ((x & 0x7FFF) > 0x7C00) ? (x | 0x200) : ((y & 0x7FFF) > 0x7C00) ? (y | 0x200)
829  : (z | 0x200);
830 }
831 
837 inline HALF_CONSTEXPR_NOERR unsigned int select(unsigned int x, unsigned int HALF_UNUSED_NOERR(y))
838 {
839 #if HALF_ERRHANDLING
840  return (((y & 0x7FFF) > 0x7C00) && !(y & 0x200)) ? signal(y) : x;
841 #else
842  return x;
843 #endif
844 }
845 
849 inline HALF_CONSTEXPR_NOERR unsigned int invalid()
850 {
851 #if HALF_ERRHANDLING
852  raise(MU_HALF_FE_INVALID);
853 #endif
854  return 0x7FFF;
855 }
856 
861 inline HALF_CONSTEXPR_NOERR unsigned int pole(unsigned int sign = 0)
862 {
863 #if HALF_ERRHANDLING
864  raise(MU_HALF_FE_DIVBYZERO);
865 #endif
866  return sign | 0x7C00;
867 }
868 
873 inline HALF_CONSTEXPR_NOERR unsigned int check_underflow(unsigned int arg)
874 {
875 #if HALF_ERRHANDLING && !HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
876  raise(MU_HALF_FE_UNDERFLOW, !(arg & 0x7C00));
877 #endif
878  return arg;
879 }
880 
884 
890 template <std::float_round_style R>
891 HALF_CONSTEXPR_NOERR unsigned int overflow(unsigned int sign = 0)
892 {
893 #if HALF_ERRHANDLING
894  raise(MU_HALF_FE_OVERFLOW);
895 #endif
896  return (R == std::round_toward_infinity) ? (sign + 0x7C00 - (sign >> 15)) : (R == std::round_toward_neg_infinity) ? (sign + 0x7BFF + (sign >> 15))
897  : (R == std::round_toward_zero) ? (sign | 0x7BFF)
898  : (sign | 0x7C00);
899 }
900 
906 template <std::float_round_style R>
907 HALF_CONSTEXPR_NOERR unsigned int underflow(unsigned int sign = 0)
908 {
909 #if HALF_ERRHANDLING
910  raise(MU_HALF_FE_UNDERFLOW);
911 #endif
912  return (R == std::round_toward_infinity) ? (sign + 1 - (sign >> 15)) : (R == std::round_toward_neg_infinity) ? (sign + (sign >> 15))
913  : sign;
914 }
915 
926 template <std::float_round_style R, bool I>
927 HALF_CONSTEXPR_NOERR unsigned int rounded(unsigned int value, int g, int s)
928 {
929 #if HALF_ERRHANDLING
930  value += (R == std::round_to_nearest) ? (g & (s | value)) : (R == std::round_toward_infinity) ? (~(value >> 15) & (g | s))
931  : (R == std::round_toward_neg_infinity) ? ((value >> 15) & (g | s))
932  : 0;
933  if ((value & 0x7C00) == 0x7C00)
934  raise(MU_HALF_FE_OVERFLOW);
935  else if (value & 0x7C00)
936  raise(MU_HALF_FE_INEXACT, I || (g | s) != 0);
937  else
938  raise(MU_HALF_FE_UNDERFLOW, !(HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT) || I || (g | s) != 0);
939  return value;
940 #else
941  return (R == std::round_to_nearest) ? (value + (g & (s | value))) : (R == std::round_toward_infinity) ? (value + (~(value >> 15) & (g | s)))
942  : (R == std::round_toward_neg_infinity) ? (value + ((value >> 15) & (g | s)))
943  : value;
944 #endif
945 }
946 
955 template <std::float_round_style R, bool E, bool I>
956 unsigned int integral(unsigned int value)
957 {
958  unsigned int abs = value & 0x7FFF;
959  if (abs < 0x3C00)
960  {
961  raise(MU_HALF_FE_INEXACT, I);
962  return ((R == std::round_to_nearest) ? (0x3C00 & -static_cast<unsigned>(abs >= (0x3800 + E))) : (R == std::round_toward_infinity) ? (0x3C00 & -(~(value >> 15) & (abs != 0)))
963  : (R == std::round_toward_neg_infinity) ? (0x3C00 & -static_cast<unsigned>(value > 0x8000))
964  : 0) |
965  (value & 0x8000);
966  }
967  if (abs >= 0x6400)
968  return (abs > 0x7C00) ? signal(value) : value;
969  unsigned int exp = 25 - (abs >> 10), mask = (1 << exp) - 1;
970  raise(MU_HALF_FE_INEXACT, I && (value & mask));
971  return (((R == std::round_to_nearest) ? ((1 << (exp - 1)) - (~(value >> exp) & E)) : (R == std::round_toward_infinity) ? (mask & ((value >> 15) - 1))
972  : (R == std::round_toward_neg_infinity) ? (mask & -(value >> 15))
973  : 0) +
974  value) &
975  ~mask;
976 }
977 
992 template <std::float_round_style R, unsigned int F, bool S, bool N, bool I>
993 unsigned int fixed2half(uint32 m, int exp = 14, unsigned int sign = 0, int s = 0)
994 {
995  if (S)
996  {
997  uint32 msign = sign_mask(m);
998  m = (m ^ msign) - msign;
999  sign = msign & 0x8000;
1000  }
1001  if (N)
1002  for (; m < (static_cast<uint32>(1) << F) && exp; m <<= 1, --exp)
1003  ;
1004  else if (exp < 0)
1005  return rounded<R, I>(sign + (m >> (F - 10 - exp)), (m >> (F - 11 - exp)) & 1, s | ((m & ((static_cast<uint32>(1) << (F - 11 - exp)) - 1)) != 0));
1006  return rounded<R, I>(sign + (exp << 10) + (m >> (F - 10)), (m >> (F - 11)) & 1, s | ((m & ((static_cast<uint32>(1) << (F - 11)) - 1)) != 0));
1007 }
1008 
1017 template <std::float_round_style R>
1018 unsigned int float2half_impl(float value, true_type)
1020 #if HALF_ENABLE_F16C_INTRINSICS
1021  return _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_set_ss(value),
1022  (R == std::round_to_nearest) ? _MM_FROUND_TO_NEAREST_INT : (R == std::round_toward_zero) ? _MM_FROUND_TO_ZERO
1023  : (R == std::round_toward_infinity) ? _MM_FROUND_TO_POS_INF
1024  : (R == std::round_toward_neg_infinity) ? _MM_FROUND_TO_NEG_INF
1025  : _MM_FROUND_CUR_DIRECTION));
1026 #else
1027  bits<float>::type fbits;
1028  std::memcpy(&fbits, &value, sizeof(float));
1029 #if 1
1030  unsigned int sign = (fbits >> 16) & 0x8000;
1031  fbits &= 0x7FFFFFFF;
1032  if (fbits >= 0x7F800000)
1033  return sign | 0x7C00 | ((fbits > 0x7F800000) ? (0x200 | ((fbits >> 13) & 0x3FF)) : 0);
1034  if (fbits >= 0x47800000)
1035  return overflow<R>(sign);
1036  if (fbits >= 0x38800000)
1037  return rounded<R, false>(sign | (((fbits >> 23) - 112) << 10) | ((fbits >> 13) & 0x3FF), (fbits >> 12) & 1, (fbits & 0xFFF) != 0);
1038  if (fbits >= 0x33000000)
1039  {
1040  int i = 125 - (fbits >> 23);
1041  fbits = (fbits & 0x7FFFFF) | 0x800000;
1042  return rounded<R, false>(sign | (fbits >> (i + 1)), (fbits >> i) & 1, (fbits & ((static_cast<uint32>(1) << i) - 1)) != 0);
1043  }
1044  if (fbits != 0)
1045  return underflow<R>(sign);
1046  return sign;
1047 #else
1048  static const uint16 base_table[512] = {
1049  0x0000,
1050  0x0000,
1051  0x0000,
1052  0x0000,
1053  0x0000,
1054  0x0000,
1055  0x0000,
1056  0x0000,
1057  0x0000,
1058  0x0000,
1059  0x0000,
1060  0x0000,
1061  0x0000,
1062  0x0000,
1063  0x0000,
1064  0x0000,
1065  0x0000,
1066  0x0000,
1067  0x0000,
1068  0x0000,
1069  0x0000,
1070  0x0000,
1071  0x0000,
1072  0x0000,
1073  0x0000,
1074  0x0000,
1075  0x0000,
1076  0x0000,
1077  0x0000,
1078  0x0000,
1079  0x0000,
1080  0x0000,
1081  0x0000,
1082  0x0000,
1083  0x0000,
1084  0x0000,
1085  0x0000,
1086  0x0000,
1087  0x0000,
1088  0x0000,
1089  0x0000,
1090  0x0000,
1091  0x0000,
1092  0x0000,
1093  0x0000,
1094  0x0000,
1095  0x0000,
1096  0x0000,
1097  0x0000,
1098  0x0000,
1099  0x0000,
1100  0x0000,
1101  0x0000,
1102  0x0000,
1103  0x0000,
1104  0x0000,
1105  0x0000,
1106  0x0000,
1107  0x0000,
1108  0x0000,
1109  0x0000,
1110  0x0000,
1111  0x0000,
1112  0x0000,
1113  0x0000,
1114  0x0000,
1115  0x0000,
1116  0x0000,
1117  0x0000,
1118  0x0000,
1119  0x0000,
1120  0x0000,
1121  0x0000,
1122  0x0000,
1123  0x0000,
1124  0x0000,
1125  0x0000,
1126  0x0000,
1127  0x0000,
1128  0x0000,
1129  0x0000,
1130  0x0000,
1131  0x0000,
1132  0x0000,
1133  0x0000,
1134  0x0000,
1135  0x0000,
1136  0x0000,
1137  0x0000,
1138  0x0000,
1139  0x0000,
1140  0x0000,
1141  0x0000,
1142  0x0000,
1143  0x0000,
1144  0x0000,
1145  0x0000,
1146  0x0000,
1147  0x0000,
1148  0x0000,
1149  0x0000,
1150  0x0000,
1151  0x0000,
1152  0x0001,
1153  0x0002,
1154  0x0004,
1155  0x0008,
1156  0x0010,
1157  0x0020,
1158  0x0040,
1159  0x0080,
1160  0x0100,
1161  0x0200,
1162  0x0400,
1163  0x0800,
1164  0x0C00,
1165  0x1000,
1166  0x1400,
1167  0x1800,
1168  0x1C00,
1169  0x2000,
1170  0x2400,
1171  0x2800,
1172  0x2C00,
1173  0x3000,
1174  0x3400,
1175  0x3800,
1176  0x3C00,
1177  0x4000,
1178  0x4400,
1179  0x4800,
1180  0x4C00,
1181  0x5000,
1182  0x5400,
1183  0x5800,
1184  0x5C00,
1185  0x6000,
1186  0x6400,
1187  0x6800,
1188  0x6C00,
1189  0x7000,
1190  0x7400,
1191  0x7800,
1192  0x7BFF,
1193  0x7BFF,
1194  0x7BFF,
1195  0x7BFF,
1196  0x7BFF,
1197  0x7BFF,
1198  0x7BFF,
1199  0x7BFF,
1200  0x7BFF,
1201  0x7BFF,
1202  0x7BFF,
1203  0x7BFF,
1204  0x7BFF,
1205  0x7BFF,
1206  0x7BFF,
1207  0x7BFF,
1208  0x7BFF,
1209  0x7BFF,
1210  0x7BFF,
1211  0x7BFF,
1212  0x7BFF,
1213  0x7BFF,
1214  0x7BFF,
1215  0x7BFF,
1216  0x7BFF,
1217  0x7BFF,
1218  0x7BFF,
1219  0x7BFF,
1220  0x7BFF,
1221  0x7BFF,
1222  0x7BFF,
1223  0x7BFF,
1224  0x7BFF,
1225  0x7BFF,
1226  0x7BFF,
1227  0x7BFF,
1228  0x7BFF,
1229  0x7BFF,
1230  0x7BFF,
1231  0x7BFF,
1232  0x7BFF,
1233  0x7BFF,
1234  0x7BFF,
1235  0x7BFF,
1236  0x7BFF,
1237  0x7BFF,
1238  0x7BFF,
1239  0x7BFF,
1240  0x7BFF,
1241  0x7BFF,
1242  0x7BFF,
1243  0x7BFF,
1244  0x7BFF,
1245  0x7BFF,
1246  0x7BFF,
1247  0x7BFF,
1248  0x7BFF,
1249  0x7BFF,
1250  0x7BFF,
1251  0x7BFF,
1252  0x7BFF,
1253  0x7BFF,
1254  0x7BFF,
1255  0x7BFF,
1256  0x7BFF,
1257  0x7BFF,
1258  0x7BFF,
1259  0x7BFF,
1260  0x7BFF,
1261  0x7BFF,
1262  0x7BFF,
1263  0x7BFF,
1264  0x7BFF,
1265  0x7BFF,
1266  0x7BFF,
1267  0x7BFF,
1268  0x7BFF,
1269  0x7BFF,
1270  0x7BFF,
1271  0x7BFF,
1272  0x7BFF,
1273  0x7BFF,
1274  0x7BFF,
1275  0x7BFF,
1276  0x7BFF,
1277  0x7BFF,
1278  0x7BFF,
1279  0x7BFF,
1280  0x7BFF,
1281  0x7BFF,
1282  0x7BFF,
1283  0x7BFF,
1284  0x7BFF,
1285  0x7BFF,
1286  0x7BFF,
1287  0x7BFF,
1288  0x7BFF,
1289  0x7BFF,
1290  0x7BFF,
1291  0x7BFF,
1292  0x7BFF,
1293  0x7BFF,
1294  0x7BFF,
1295  0x7BFF,
1296  0x7BFF,
1297  0x7BFF,
1298  0x7BFF,
1299  0x7BFF,
1300  0x7BFF,
1301  0x7BFF,
1302  0x7BFF,
1303  0x7BFF,
1304  0x7C00,
1305  0x8000,
1306  0x8000,
1307  0x8000,
1308  0x8000,
1309  0x8000,
1310  0x8000,
1311  0x8000,
1312  0x8000,
1313  0x8000,
1314  0x8000,
1315  0x8000,
1316  0x8000,
1317  0x8000,
1318  0x8000,
1319  0x8000,
1320  0x8000,
1321  0x8000,
1322  0x8000,
1323  0x8000,
1324  0x8000,
1325  0x8000,
1326  0x8000,
1327  0x8000,
1328  0x8000,
1329  0x8000,
1330  0x8000,
1331  0x8000,
1332  0x8000,
1333  0x8000,
1334  0x8000,
1335  0x8000,
1336  0x8000,
1337  0x8000,
1338  0x8000,
1339  0x8000,
1340  0x8000,
1341  0x8000,
1342  0x8000,
1343  0x8000,
1344  0x8000,
1345  0x8000,
1346  0x8000,
1347  0x8000,
1348  0x8000,
1349  0x8000,
1350  0x8000,
1351  0x8000,
1352  0x8000,
1353  0x8000,
1354  0x8000,
1355  0x8000,
1356  0x8000,
1357  0x8000,
1358  0x8000,
1359  0x8000,
1360  0x8000,
1361  0x8000,
1362  0x8000,
1363  0x8000,
1364  0x8000,
1365  0x8000,
1366  0x8000,
1367  0x8000,
1368  0x8000,
1369  0x8000,
1370  0x8000,
1371  0x8000,
1372  0x8000,
1373  0x8000,
1374  0x8000,
1375  0x8000,
1376  0x8000,
1377  0x8000,
1378  0x8000,
1379  0x8000,
1380  0x8000,
1381  0x8000,
1382  0x8000,
1383  0x8000,
1384  0x8000,
1385  0x8000,
1386  0x8000,
1387  0x8000,
1388  0x8000,
1389  0x8000,
1390  0x8000,
1391  0x8000,
1392  0x8000,
1393  0x8000,
1394  0x8000,
1395  0x8000,
1396  0x8000,
1397  0x8000,
1398  0x8000,
1399  0x8000,
1400  0x8000,
1401  0x8000,
1402  0x8000,
1403  0x8000,
1404  0x8000,
1405  0x8000,
1406  0x8000,
1407  0x8000,
1408  0x8001,
1409  0x8002,
1410  0x8004,
1411  0x8008,
1412  0x8010,
1413  0x8020,
1414  0x8040,
1415  0x8080,
1416  0x8100,
1417  0x8200,
1418  0x8400,
1419  0x8800,
1420  0x8C00,
1421  0x9000,
1422  0x9400,
1423  0x9800,
1424  0x9C00,
1425  0xA000,
1426  0xA400,
1427  0xA800,
1428  0xAC00,
1429  0xB000,
1430  0xB400,
1431  0xB800,
1432  0xBC00,
1433  0xC000,
1434  0xC400,
1435  0xC800,
1436  0xCC00,
1437  0xD000,
1438  0xD400,
1439  0xD800,
1440  0xDC00,
1441  0xE000,
1442  0xE400,
1443  0xE800,
1444  0xEC00,
1445  0xF000,
1446  0xF400,
1447  0xF800,
1448  0xFBFF,
1449  0xFBFF,
1450  0xFBFF,
1451  0xFBFF,
1452  0xFBFF,
1453  0xFBFF,
1454  0xFBFF,
1455  0xFBFF,
1456  0xFBFF,
1457  0xFBFF,
1458  0xFBFF,
1459  0xFBFF,
1460  0xFBFF,
1461  0xFBFF,
1462  0xFBFF,
1463  0xFBFF,
1464  0xFBFF,
1465  0xFBFF,
1466  0xFBFF,
1467  0xFBFF,
1468  0xFBFF,
1469  0xFBFF,
1470  0xFBFF,
1471  0xFBFF,
1472  0xFBFF,
1473  0xFBFF,
1474  0xFBFF,
1475  0xFBFF,
1476  0xFBFF,
1477  0xFBFF,
1478  0xFBFF,
1479  0xFBFF,
1480  0xFBFF,
1481  0xFBFF,
1482  0xFBFF,
1483  0xFBFF,
1484  0xFBFF,
1485  0xFBFF,
1486  0xFBFF,
1487  0xFBFF,
1488  0xFBFF,
1489  0xFBFF,
1490  0xFBFF,
1491  0xFBFF,
1492  0xFBFF,
1493  0xFBFF,
1494  0xFBFF,
1495  0xFBFF,
1496  0xFBFF,
1497  0xFBFF,
1498  0xFBFF,
1499  0xFBFF,
1500  0xFBFF,
1501  0xFBFF,
1502  0xFBFF,
1503  0xFBFF,
1504  0xFBFF,
1505  0xFBFF,
1506  0xFBFF,
1507  0xFBFF,
1508  0xFBFF,
1509  0xFBFF,
1510  0xFBFF,
1511  0xFBFF,
1512  0xFBFF,
1513  0xFBFF,
1514  0xFBFF,
1515  0xFBFF,
1516  0xFBFF,
1517  0xFBFF,
1518  0xFBFF,
1519  0xFBFF,
1520  0xFBFF,
1521  0xFBFF,
1522  0xFBFF,
1523  0xFBFF,
1524  0xFBFF,
1525  0xFBFF,
1526  0xFBFF,
1527  0xFBFF,
1528  0xFBFF,
1529  0xFBFF,
1530  0xFBFF,
1531  0xFBFF,
1532  0xFBFF,
1533  0xFBFF,
1534  0xFBFF,
1535  0xFBFF,
1536  0xFBFF,
1537  0xFBFF,
1538  0xFBFF,
1539  0xFBFF,
1540  0xFBFF,
1541  0xFBFF,
1542  0xFBFF,
1543  0xFBFF,
1544  0xFBFF,
1545  0xFBFF,
1546  0xFBFF,
1547  0xFBFF,
1548  0xFBFF,
1549  0xFBFF,
1550  0xFBFF,
1551  0xFBFF,
1552  0xFBFF,
1553  0xFBFF,
1554  0xFBFF,
1555  0xFBFF,
1556  0xFBFF,
1557  0xFBFF,
1558  0xFBFF,
1559  0xFBFF,
1560  0xFC00};
1561  static const unsigned char shift_table[256] = {
1562  24,
1563  25,
1564  25,
1565  25,
1566  25,
1567  25,
1568  25,
1569  25,
1570  25,
1571  25,
1572  25,
1573  25,
1574  25,
1575  25,
1576  25,
1577  25,
1578  25,
1579  25,
1580  25,
1581  25,
1582  25,
1583  25,
1584  25,
1585  25,
1586  25,
1587  25,
1588  25,
1589  25,
1590  25,
1591  25,
1592  25,
1593  25,
1594  25,
1595  25,
1596  25,
1597  25,
1598  25,
1599  25,
1600  25,
1601  25,
1602  25,
1603  25,
1604  25,
1605  25,
1606  25,
1607  25,
1608  25,
1609  25,
1610  25,
1611  25,
1612  25,
1613  25,
1614  25,
1615  25,
1616  25,
1617  25,
1618  25,
1619  25,
1620  25,
1621  25,
1622  25,
1623  25,
1624  25,
1625  25,
1626  25,
1627  25,
1628  25,
1629  25,
1630  25,
1631  25,
1632  25,
1633  25,
1634  25,
1635  25,
1636  25,
1637  25,
1638  25,
1639  25,
1640  25,
1641  25,
1642  25,
1643  25,
1644  25,
1645  25,
1646  25,
1647  25,
1648  25,
1649  25,
1650  25,
1651  25,
1652  25,
1653  25,
1654  25,
1655  25,
1656  25,
1657  25,
1658  25,
1659  25,
1660  25,
1661  25,
1662  25,
1663  25,
1664  24,
1665  23,
1666  22,
1667  21,
1668  20,
1669  19,
1670  18,
1671  17,
1672  16,
1673  15,
1674  14,
1675  13,
1676  13,
1677  13,
1678  13,
1679  13,
1680  13,
1681  13,
1682  13,
1683  13,
1684  13,
1685  13,
1686  13,
1687  13,
1688  13,
1689  13,
1690  13,
1691  13,
1692  13,
1693  13,
1694  13,
1695  13,
1696  13,
1697  13,
1698  13,
1699  13,
1700  13,
1701  13,
1702  13,
1703  13,
1704  13,
1705  24,
1706  24,
1707  24,
1708  24,
1709  24,
1710  24,
1711  24,
1712  24,
1713  24,
1714  24,
1715  24,
1716  24,
1717  24,
1718  24,
1719  24,
1720  24,
1721  24,
1722  24,
1723  24,
1724  24,
1725  24,
1726  24,
1727  24,
1728  24,
1729  24,
1730  24,
1731  24,
1732  24,
1733  24,
1734  24,
1735  24,
1736  24,
1737  24,
1738  24,
1739  24,
1740  24,
1741  24,
1742  24,
1743  24,
1744  24,
1745  24,
1746  24,
1747  24,
1748  24,
1749  24,
1750  24,
1751  24,
1752  24,
1753  24,
1754  24,
1755  24,
1756  24,
1757  24,
1758  24,
1759  24,
1760  24,
1761  24,
1762  24,
1763  24,
1764  24,
1765  24,
1766  24,
1767  24,
1768  24,
1769  24,
1770  24,
1771  24,
1772  24,
1773  24,
1774  24,
1775  24,
1776  24,
1777  24,
1778  24,
1779  24,
1780  24,
1781  24,
1782  24,
1783  24,
1784  24,
1785  24,
1786  24,
1787  24,
1788  24,
1789  24,
1790  24,
1791  24,
1792  24,
1793  24,
1794  24,
1795  24,
1796  24,
1797  24,
1798  24,
1799  24,
1800  24,
1801  24,
1802  24,
1803  24,
1804  24,
1805  24,
1806  24,
1807  24,
1808  24,
1809  24,
1810  24,
1811  24,
1812  24,
1813  24,
1814  24,
1815  24,
1816  24,
1817  13};
1818  int sexp = fbits >> 23, exp = sexp & 0xFF, i = shift_table[exp];
1819  fbits &= 0x7FFFFF;
1820  uint32 m = (fbits | ((exp != 0) << 23)) & -static_cast<uint32>(exp != 0xFF);
1821  return rounded<R, false>(base_table[sexp] + (fbits >> i), (m >> (i - 1)) & 1, (((static_cast<uint32>(1) << (i - 1)) - 1) & m) != 0);
1822 #endif
1823 #endif
1824 }
1825 
1833 template <std::float_round_style R>
1834 unsigned int float2half_impl(double value, true_type)
1836 #if HALF_ENABLE_F16C_INTRINSICS
1837  if (R == std::round_indeterminate)
1838  return _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_cvtpd_ps(_mm_set_sd(value)), _MM_FROUND_CUR_DIRECTION));
1839 #endif
1840  bits<double>::type dbits;
1841  std::memcpy(&dbits, &value, sizeof(double));
1842  uint32 hi = dbits >> 32, lo = dbits & 0xFFFFFFFF;
1843  unsigned int sign = (hi >> 16) & 0x8000;
1844  hi &= 0x7FFFFFFF;
1845  if (hi >= 0x7FF00000)
1846  return sign | 0x7C00 | ((dbits & 0xFFFFFFFFFFFFF) ? (0x200 | ((hi >> 10) & 0x3FF)) : 0);
1847  if (hi >= 0x40F00000)
1848  return overflow<R>(sign);
1849  if (hi >= 0x3F100000)
1850  return rounded<R, false>(sign | (((hi >> 20) - 1008) << 10) | ((hi >> 10) & 0x3FF), (hi >> 9) & 1, ((hi & 0x1FF) | lo) != 0);
1851  if (hi >= 0x3E600000)
1852  {
1853  int i = 1018 - (hi >> 20);
1854  hi = (hi & 0xFFFFF) | 0x100000;
1855  return rounded<R, false>(sign | (hi >> (i + 1)), (hi >> i) & 1, ((hi & ((static_cast<uint32>(1) << i) - 1)) | lo) != 0);
1856  }
1857  if ((hi | lo) != 0)
1858  return underflow<R>(sign);
1859  return sign;
1860 }
1861 
1870 template <std::float_round_style R, typename T>
1871 unsigned int float2half_impl(T value, ...)
1873  unsigned int hbits = static_cast<unsigned>(builtin_signbit(value)) << 15;
1874  if (value == T())
1875  return hbits;
1876  if (builtin_isnan(value))
1877  return hbits | 0x7FFF;
1878  if (builtin_isinf(value))
1879  return hbits | 0x7C00;
1880  int exp;
1881  frexp(value, &exp);
1882  if (exp > 16)
1883  return overflow<R>(hbits);
1884  if (exp < -13)
1885  value = std::ldexp(value, 25);
1886  else
1887  {
1888  value = std::ldexp(value, 12 - exp);
1889  hbits |= ((exp + 13) << 10);
1890  }
1891  T ival, frac = std::modf(value, &ival);
1892  int m = std::abs(static_cast<int>(ival));
1893  return rounded<R, false>(hbits + (m >> 1), m & 1, frac != T());
1894 }
1895 
1904 template <std::float_round_style R, typename T>
1905 unsigned int float2half(T value)
1907  return float2half_impl<R>(value, bool_type<std::numeric_limits<T>::is_iec559 && sizeof(typename bits<T>::type) == sizeof(T)>());
1908 }
1909 
1917 template <std::float_round_style R, typename T>
1918 unsigned int int2half(T value)
1920  unsigned int bits = static_cast<unsigned>(value < 0) << 15;
1921  if (!value)
1922  return bits;
1923  if (bits)
1924  value = -value;
1925  if (value > 0xFFFF)
1926  return overflow<R>(bits);
1927  unsigned int m = static_cast<unsigned int>(value), exp = 24;
1928  for (; m < 0x400; m <<= 1, --exp)
1929  ;
1930  for (; m > 0x7FF; m >>= 1, ++exp)
1931  ;
1932  bits |= (exp << 10) + m;
1933  return (exp > 24) ? rounded<R, false>(bits, (value >> (exp - 25)) & 1, (((1 << (exp - 25)) - 1) & value) != 0) : bits;
1934 }
1935 
1940 inline float half2float_impl(unsigned int value, float, true_type)
1942 #if HALF_ENABLE_F16C_INTRINSICS
1943  return _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128(value)));
1944 #else
1945 #if 1
1946  bits<float>::type fbits = static_cast<bits<float>::type>(value & 0x8000) << 16;
1947  int abs = value & 0x7FFF;
1948  if (abs)
1949  {
1950  fbits |= 0x38000000 << static_cast<unsigned>(abs >= 0x7C00);
1951  for (; abs < 0x400; abs <<= 1, fbits -= 0x800000)
1952  ;
1953  fbits += static_cast<bits<float>::type>(abs) << 13;
1954  }
1955 #else
1956  static const bits<float>::type mantissa_table[2048] = {
1957  0x00000000,
1958  0x33800000,
1959  0x34000000,
1960  0x34400000,
1961  0x34800000,
1962  0x34A00000,
1963  0x34C00000,
1964  0x34E00000,
1965  0x35000000,
1966  0x35100000,
1967  0x35200000,
1968  0x35300000,
1969  0x35400000,
1970  0x35500000,
1971  0x35600000,
1972  0x35700000,
1973  0x35800000,
1974  0x35880000,
1975  0x35900000,
1976  0x35980000,
1977  0x35A00000,
1978  0x35A80000,
1979  0x35B00000,
1980  0x35B80000,
1981  0x35C00000,
1982  0x35C80000,
1983  0x35D00000,
1984  0x35D80000,
1985  0x35E00000,
1986  0x35E80000,
1987  0x35F00000,
1988  0x35F80000,
1989  0x36000000,
1990  0x36040000,
1991  0x36080000,
1992  0x360C0000,
1993  0x36100000,
1994  0x36140000,
1995  0x36180000,
1996  0x361C0000,
1997  0x36200000,
1998  0x36240000,
1999  0x36280000,
2000  0x362C0000,
2001  0x36300000,
2002  0x36340000,
2003  0x36380000,
2004  0x363C0000,
2005  0x36400000,
2006  0x36440000,
2007  0x36480000,
2008  0x364C0000,
2009  0x36500000,
2010  0x36540000,
2011  0x36580000,
2012  0x365C0000,
2013  0x36600000,
2014  0x36640000,
2015  0x36680000,
2016  0x366C0000,
2017  0x36700000,
2018  0x36740000,
2019  0x36780000,
2020  0x367C0000,
2021  0x36800000,
2022  0x36820000,
2023  0x36840000,
2024  0x36860000,
2025  0x36880000,
2026  0x368A0000,
2027  0x368C0000,
2028  0x368E0000,
2029  0x36900000,
2030  0x36920000,
2031  0x36940000,
2032  0x36960000,
2033  0x36980000,
2034  0x369A0000,
2035  0x369C0000,
2036  0x369E0000,
2037  0x36A00000,
2038  0x36A20000,
2039  0x36A40000,
2040  0x36A60000,
2041  0x36A80000,
2042  0x36AA0000,
2043  0x36AC0000,
2044  0x36AE0000,
2045  0x36B00000,
2046  0x36B20000,
2047  0x36B40000,
2048  0x36B60000,
2049  0x36B80000,
2050  0x36BA0000,
2051  0x36BC0000,
2052  0x36BE0000,
2053  0x36C00000,
2054  0x36C20000,
2055  0x36C40000,
2056  0x36C60000,
2057  0x36C80000,
2058  0x36CA0000,
2059  0x36CC0000,
2060  0x36CE0000,
2061  0x36D00000,
2062  0x36D20000,
2063  0x36D40000,
2064  0x36D60000,
2065  0x36D80000,
2066  0x36DA0000,
2067  0x36DC0000,
2068  0x36DE0000,
2069  0x36E00000,
2070  0x36E20000,
2071  0x36E40000,
2072  0x36E60000,
2073  0x36E80000,
2074  0x36EA0000,
2075  0x36EC0000,
2076  0x36EE0000,
2077  0x36F00000,
2078  0x36F20000,
2079  0x36F40000,
2080  0x36F60000,
2081  0x36F80000,
2082  0x36FA0000,
2083  0x36FC0000,
2084  0x36FE0000,
2085  0x37000000,
2086  0x37010000,
2087  0x37020000,
2088  0x37030000,
2089  0x37040000,
2090  0x37050000,
2091  0x37060000,
2092  0x37070000,
2093  0x37080000,
2094  0x37090000,
2095  0x370A0000,
2096  0x370B0000,
2097  0x370C0000,
2098  0x370D0000,
2099  0x370E0000,
2100  0x370F0000,
2101  0x37100000,
2102  0x37110000,
2103  0x37120000,
2104  0x37130000,
2105  0x37140000,
2106  0x37150000,
2107  0x37160000,
2108  0x37170000,
2109  0x37180000,
2110  0x37190000,
2111  0x371A0000,
2112  0x371B0000,
2113  0x371C0000,
2114  0x371D0000,
2115  0x371E0000,
2116  0x371F0000,
2117  0x37200000,
2118  0x37210000,
2119  0x37220000,
2120  0x37230000,
2121  0x37240000,
2122  0x37250000,
2123  0x37260000,
2124  0x37270000,
2125  0x37280000,
2126  0x37290000,
2127  0x372A0000,
2128  0x372B0000,
2129  0x372C0000,
2130  0x372D0000,
2131  0x372E0000,
2132  0x372F0000,
2133  0x37300000,
2134  0x37310000,
2135  0x37320000,
2136  0x37330000,
2137  0x37340000,
2138  0x37350000,
2139  0x37360000,
2140  0x37370000,
2141  0x37380000,
2142  0x37390000,
2143  0x373A0000,
2144  0x373B0000,
2145  0x373C0000,
2146  0x373D0000,
2147  0x373E0000,
2148  0x373F0000,
2149  0x37400000,
2150  0x37410000,
2151  0x37420000,
2152  0x37430000,
2153  0x37440000,
2154  0x37450000,
2155  0x37460000,
2156  0x37470000,
2157  0x37480000,
2158  0x37490000,
2159  0x374A0000,
2160  0x374B0000,
2161  0x374C0000,
2162  0x374D0000,
2163  0x374E0000,
2164  0x374F0000,
2165  0x37500000,
2166  0x37510000,
2167  0x37520000,
2168  0x37530000,
2169  0x37540000,
2170  0x37550000,
2171  0x37560000,
2172  0x37570000,
2173  0x37580000,
2174  0x37590000,
2175  0x375A0000,
2176  0x375B0000,
2177  0x375C0000,
2178  0x375D0000,
2179  0x375E0000,
2180  0x375F0000,
2181  0x37600000,
2182  0x37610000,
2183  0x37620000,
2184  0x37630000,
2185  0x37640000,
2186  0x37650000,
2187  0x37660000,
2188  0x37670000,
2189  0x37680000,
2190  0x37690000,
2191  0x376A0000,
2192  0x376B0000,
2193  0x376C0000,
2194  0x376D0000,
2195  0x376E0000,
2196  0x376F0000,
2197  0x37700000,
2198  0x37710000,
2199  0x37720000,
2200  0x37730000,
2201  0x37740000,
2202  0x37750000,
2203  0x37760000,
2204  0x37770000,
2205  0x37780000,
2206  0x37790000,
2207  0x377A0000,
2208  0x377B0000,
2209  0x377C0000,
2210  0x377D0000,
2211  0x377E0000,
2212  0x377F0000,
2213  0x37800000,
2214  0x37808000,
2215  0x37810000,
2216  0x37818000,
2217  0x37820000,
2218  0x37828000,
2219  0x37830000,
2220  0x37838000,
2221  0x37840000,
2222  0x37848000,
2223  0x37850000,
2224  0x37858000,
2225  0x37860000,
2226  0x37868000,
2227  0x37870000,
2228  0x37878000,
2229  0x37880000,
2230  0x37888000,
2231  0x37890000,
2232  0x37898000,
2233  0x378A0000,
2234  0x378A8000,
2235  0x378B0000,
2236  0x378B8000,
2237  0x378C0000,
2238  0x378C8000,
2239  0x378D0000,
2240  0x378D8000,
2241  0x378E0000,
2242  0x378E8000,
2243  0x378F0000,
2244  0x378F8000,
2245  0x37900000,
2246  0x37908000,
2247  0x37910000,
2248  0x37918000,
2249  0x37920000,
2250  0x37928000,
2251  0x37930000,
2252  0x37938000,
2253  0x37940000,
2254  0x37948000,
2255  0x37950000,
2256  0x37958000,
2257  0x37960000,
2258  0x37968000,
2259  0x37970000,
2260  0x37978000,
2261  0x37980000,
2262  0x37988000,
2263  0x37990000,
2264  0x37998000,
2265  0x379A0000,
2266  0x379A8000,
2267  0x379B0000,
2268  0x379B8000,
2269  0x379C0000,
2270  0x379C8000,
2271  0x379D0000,
2272  0x379D8000,
2273  0x379E0000,
2274  0x379E8000,
2275  0x379F0000,
2276  0x379F8000,
2277  0x37A00000,
2278  0x37A08000,
2279  0x37A10000,
2280  0x37A18000,
2281  0x37A20000,
2282  0x37A28000,
2283  0x37A30000,
2284  0x37A38000,
2285  0x37A40000,
2286  0x37A48000,
2287  0x37A50000,
2288  0x37A58000,
2289  0x37A60000,
2290  0x37A68000,
2291  0x37A70000,
2292  0x37A78000,
2293  0x37A80000,
2294  0x37A88000,
2295  0x37A90000,
2296  0x37A98000,
2297  0x37AA0000,
2298  0x37AA8000,
2299  0x37AB0000,
2300  0x37AB8000,
2301  0x37AC0000,
2302  0x37AC8000,
2303  0x37AD0000,
2304  0x37AD8000,
2305  0x37AE0000,
2306  0x37AE8000,
2307  0x37AF0000,
2308  0x37AF8000,
2309  0x37B00000,
2310  0x37B08000,
2311  0x37B10000,
2312  0x37B18000,
2313  0x37B20000,
2314  0x37B28000,
2315  0x37B30000,
2316  0x37B38000,
2317  0x37B40000,
2318  0x37B48000,
2319  0x37B50000,
2320  0x37B58000,
2321  0x37B60000,
2322  0x37B68000,
2323  0x37B70000,
2324  0x37B78000,
2325  0x37B80000,
2326  0x37B88000,
2327  0x37B90000,
2328  0x37B98000,
2329  0x37BA0000,
2330  0x37BA8000,
2331  0x37BB0000,
2332  0x37BB8000,
2333  0x37BC0000,
2334  0x37BC8000,
2335  0x37BD0000,
2336  0x37BD8000,
2337  0x37BE0000,
2338  0x37BE8000,
2339  0x37BF0000,
2340  0x37BF8000,
2341  0x37C00000,
2342  0x37C08000,
2343  0x37C10000,
2344  0x37C18000,
2345  0x37C20000,
2346  0x37C28000,
2347  0x37C30000,
2348  0x37C38000,
2349  0x37C40000,
2350  0x37C48000,
2351  0x37C50000,
2352  0x37C58000,
2353  0x37C60000,
2354  0x37C68000,
2355  0x37C70000,
2356  0x37C78000,
2357  0x37C80000,
2358  0x37C88000,
2359  0x37C90000,
2360  0x37C98000,
2361  0x37CA0000,
2362  0x37CA8000,
2363  0x37CB0000,
2364  0x37CB8000,
2365  0x37CC0000,
2366  0x37CC8000,
2367  0x37CD0000,
2368  0x37CD8000,
2369  0x37CE0000,
2370  0x37CE8000,
2371  0x37CF0000,
2372  0x37CF8000,
2373  0x37D00000,
2374  0x37D08000,
2375  0x37D10000,
2376  0x37D18000,
2377  0x37D20000,
2378  0x37D28000,
2379  0x37D30000,
2380  0x37D38000,
2381  0x37D40000,
2382  0x37D48000,
2383  0x37D50000,
2384  0x37D58000,
2385  0x37D60000,
2386  0x37D68000,
2387  0x37D70000,
2388  0x37D78000,
2389  0x37D80000,
2390  0x37D88000,
2391  0x37D90000,
2392  0x37D98000,
2393  0x37DA0000,
2394  0x37DA8000,
2395  0x37DB0000,
2396  0x37DB8000,
2397  0x37DC0000,
2398  0x37DC8000,
2399  0x37DD0000,
2400  0x37DD8000,
2401  0x37DE0000,
2402  0x37DE8000,
2403  0x37DF0000,
2404  0x37DF8000,
2405  0x37E00000,
2406  0x37E08000,
2407  0x37E10000,
2408  0x37E18000,
2409  0x37E20000,
2410  0x37E28000,
2411  0x37E30000,
2412  0x37E38000,
2413  0x37E40000,
2414  0x37E48000,
2415  0x37E50000,
2416  0x37E58000,
2417  0x37E60000,
2418  0x37E68000,
2419  0x37E70000,
2420  0x37E78000,
2421  0x37E80000,
2422  0x37E88000,
2423  0x37E90000,
2424  0x37E98000,
2425  0x37EA0000,
2426  0x37EA8000,
2427  0x37EB0000,
2428  0x37EB8000,
2429  0x37EC0000,
2430  0x37EC8000,
2431  0x37ED0000,
2432  0x37ED8000,
2433  0x37EE0000,
2434  0x37EE8000,
2435  0x37EF0000,
2436  0x37EF8000,
2437  0x37F00000,
2438  0x37F08000,
2439  0x37F10000,
2440  0x37F18000,
2441  0x37F20000,
2442  0x37F28000,
2443  0x37F30000,
2444  0x37F38000,
2445  0x37F40000,
2446  0x37F48000,
2447  0x37F50000,
2448  0x37F58000,
2449  0x37F60000,
2450  0x37F68000,
2451  0x37F70000,
2452  0x37F78000,
2453  0x37F80000,
2454  0x37F88000,
2455  0x37F90000,
2456  0x37F98000,
2457  0x37FA0000,
2458  0x37FA8000,
2459  0x37FB0000,
2460  0x37FB8000,
2461  0x37FC0000,
2462  0x37FC8000,
2463  0x37FD0000,
2464  0x37FD8000,
2465  0x37FE0000,
2466  0x37FE8000,
2467  0x37FF0000,
2468  0x37FF8000,
2469  0x38000000,
2470  0x38004000,
2471  0x38008000,
2472  0x3800C000,
2473  0x38010000,
2474  0x38014000,
2475  0x38018000,
2476  0x3801C000,
2477  0x38020000,
2478  0x38024000,
2479  0x38028000,
2480  0x3802C000,
2481  0x38030000,
2482  0x38034000,
2483  0x38038000,
2484  0x3803C000,
2485  0x38040000,
2486  0x38044000,
2487  0x38048000,
2488  0x3804C000,
2489  0x38050000,
2490  0x38054000,
2491  0x38058000,
2492  0x3805C000,
2493  0x38060000,
2494  0x38064000,
2495  0x38068000,
2496  0x3806C000,
2497  0x38070000,
2498  0x38074000,
2499  0x38078000,
2500  0x3807C000,
2501  0x38080000,
2502  0x38084000,
2503  0x38088000,
2504  0x3808C000,
2505  0x38090000,
2506  0x38094000,
2507  0x38098000,
2508  0x3809C000,
2509  0x380A0000,
2510  0x380A4000,
2511  0x380A8000,
2512  0x380AC000,
2513  0x380B0000,
2514  0x380B4000,
2515  0x380B8000,
2516  0x380BC000,
2517  0x380C0000,
2518  0x380C4000,
2519  0x380C8000,
2520  0x380CC000,
2521  0x380D0000,
2522  0x380D4000,
2523  0x380D8000,
2524  0x380DC000,
2525  0x380E0000,
2526  0x380E4000,
2527  0x380E8000,
2528  0x380EC000,
2529  0x380F0000,
2530  0x380F4000,
2531  0x380F8000,
2532  0x380FC000,
2533  0x38100000,
2534  0x38104000,
2535  0x38108000,
2536  0x3810C000,
2537  0x38110000,
2538  0x38114000,
2539  0x38118000,
2540  0x3811C000,
2541  0x38120000,
2542  0x38124000,
2543  0x38128000,
2544  0x3812C000,
2545  0x38130000,
2546  0x38134000,
2547  0x38138000,
2548  0x3813C000,
2549  0x38140000,
2550  0x38144000,
2551  0x38148000,
2552  0x3814C000,
2553  0x38150000,
2554  0x38154000,
2555  0x38158000,
2556  0x3815C000,
2557  0x38160000,
2558  0x38164000,
2559  0x38168000,
2560  0x3816C000,
2561  0x38170000,
2562  0x38174000,
2563  0x38178000,
2564  0x3817C000,
2565  0x38180000,
2566  0x38184000,
2567  0x38188000,
2568  0x3818C000,
2569  0x38190000,
2570  0x38194000,
2571  0x38198000,
2572  0x3819C000,
2573  0x381A0000,
2574  0x381A4000,
2575  0x381A8000,
2576  0x381AC000,
2577  0x381B0000,
2578  0x381B4000,
2579  0x381B8000,
2580  0x381BC000,
2581  0x381C0000,
2582  0x381C4000,
2583  0x381C8000,
2584  0x381CC000,
2585  0x381D0000,
2586  0x381D4000,
2587  0x381D8000,
2588  0x381DC000,
2589  0x381E0000,
2590  0x381E4000,
2591  0x381E8000,
2592  0x381EC000,
2593  0x381F0000,
2594  0x381F4000,
2595  0x381F8000,
2596  0x381FC000,
2597  0x38200000,
2598  0x38204000,
2599  0x38208000,
2600  0x3820C000,
2601  0x38210000,
2602  0x38214000,
2603  0x38218000,
2604  0x3821C000,
2605  0x38220000,
2606  0x38224000,
2607  0x38228000,
2608  0x3822C000,
2609  0x38230000,
2610  0x38234000,
2611  0x38238000,
2612  0x3823C000,
2613  0x38240000,
2614  0x38244000,
2615  0x38248000,
2616  0x3824C000,
2617  0x38250000,
2618  0x38254000,
2619  0x38258000,
2620  0x3825C000,
2621  0x38260000,
2622  0x38264000,
2623  0x38268000,
2624  0x3826C000,
2625  0x38270000,
2626  0x38274000,
2627  0x38278000,
2628  0x3827C000,
2629  0x38280000,
2630  0x38284000,
2631  0x38288000,
2632  0x3828C000,
2633  0x38290000,
2634  0x38294000,
2635  0x38298000,
2636  0x3829C000,
2637  0x382A0000,
2638  0x382A4000,
2639  0x382A8000,
2640  0x382AC000,
2641  0x382B0000,
2642  0x382B4000,
2643  0x382B8000,
2644  0x382BC000,
2645  0x382C0000,
2646  0x382C4000,
2647  0x382C8000,
2648  0x382CC000,
2649  0x382D0000,
2650  0x382D4000,
2651  0x382D8000,
2652  0x382DC000,
2653  0x382E0000,
2654  0x382E4000,
2655  0x382E8000,
2656  0x382EC000,
2657  0x382F0000,
2658  0x382F4000,
2659  0x382F8000,
2660  0x382FC000,
2661  0x38300000,
2662  0x38304000,
2663  0x38308000,
2664  0x3830C000,
2665  0x38310000,
2666  0x38314000,
2667  0x38318000,
2668  0x3831C000,
2669  0x38320000,
2670  0x38324000,
2671  0x38328000,
2672  0x3832C000,
2673  0x38330000,
2674  0x38334000,
2675  0x38338000,
2676  0x3833C000,
2677  0x38340000,
2678  0x38344000,
2679  0x38348000,
2680  0x3834C000,
2681  0x38350000,
2682  0x38354000,
2683  0x38358000,
2684  0x3835C000,
2685  0x38360000,
2686  0x38364000,
2687  0x38368000,
2688  0x3836C000,
2689  0x38370000,
2690  0x38374000,
2691  0x38378000,
2692  0x3837C000,
2693  0x38380000,
2694  0x38384000,
2695  0x38388000,
2696  0x3838C000,
2697  0x38390000,
2698  0x38394000,
2699  0x38398000,
2700  0x3839C000,
2701  0x383A0000,
2702  0x383A4000,
2703  0x383A8000,
2704  0x383AC000,
2705  0x383B0000,
2706  0x383B4000,
2707  0x383B8000,
2708  0x383BC000,
2709  0x383C0000,
2710  0x383C4000,
2711  0x383C8000,
2712  0x383CC000,
2713  0x383D0000,
2714  0x383D4000,
2715  0x383D8000,
2716  0x383DC000,
2717  0x383E0000,
2718  0x383E4000,
2719  0x383E8000,
2720  0x383EC000,
2721  0x383F0000,
2722  0x383F4000,
2723  0x383F8000,
2724  0x383FC000,
2725  0x38400000,
2726  0x38404000,
2727  0x38408000,
2728  0x3840C000,
2729  0x38410000,
2730  0x38414000,
2731  0x38418000,
2732  0x3841C000,
2733  0x38420000,
2734  0x38424000,
2735  0x38428000,
2736  0x3842C000,
2737  0x38430000,
2738  0x38434000,
2739  0x38438000,
2740  0x3843C000,
2741  0x38440000,
2742  0x38444000,
2743  0x38448000,
2744  0x3844C000,
2745  0x38450000,
2746  0x38454000,
2747  0x38458000,
2748  0x3845C000,
2749  0x38460000,
2750  0x38464000,
2751  0x38468000,
2752  0x3846C000,
2753  0x38470000,
2754  0x38474000,
2755  0x38478000,
2756  0x3847C000,
2757  0x38480000,
2758  0x38484000,
2759  0x38488000,
2760  0x3848C000,
2761  0x38490000,
2762  0x38494000,
2763  0x38498000,
2764  0x3849C000,
2765  0x384A0000,
2766  0x384A4000,
2767  0x384A8000,
2768  0x384AC000,
2769  0x384B0000,
2770  0x384B4000,
2771  0x384B8000,
2772  0x384BC000,
2773  0x384C0000,
2774  0x384C4000,
2775  0x384C8000,
2776  0x384CC000,
2777  0x384D0000,
2778  0x384D4000,
2779  0x384D8000,
2780  0x384DC000,
2781  0x384E0000,
2782  0x384E4000,
2783  0x384E8000,
2784  0x384EC000,
2785  0x384F0000,
2786  0x384F4000,
2787  0x384F8000,
2788  0x384FC000,
2789  0x38500000,
2790  0x38504000,
2791  0x38508000,
2792  0x3850C000,
2793  0x38510000,
2794  0x38514000,
2795  0x38518000,
2796  0x3851C000,
2797  0x38520000,
2798  0x38524000,
2799  0x38528000,
2800  0x3852C000,
2801  0x38530000,
2802  0x38534000,
2803  0x38538000,
2804  0x3853C000,
2805  0x38540000,
2806  0x38544000,
2807  0x38548000,
2808  0x3854C000,
2809  0x38550000,
2810  0x38554000,
2811  0x38558000,
2812  0x3855C000,
2813  0x38560000,
2814  0x38564000,
2815  0x38568000,
2816  0x3856C000,
2817  0x38570000,
2818  0x38574000,
2819  0x38578000,
2820  0x3857C000,
2821  0x38580000,
2822  0x38584000,
2823  0x38588000,
2824  0x3858C000,
2825  0x38590000,
2826  0x38594000,
2827  0x38598000,
2828  0x3859C000,
2829  0x385A0000,
2830  0x385A4000,
2831  0x385A8000,
2832  0x385AC000,
2833  0x385B0000,
2834  0x385B4000,
2835  0x385B8000,
2836  0x385BC000,
2837  0x385C0000,
2838  0x385C4000,
2839  0x385C8000,
2840  0x385CC000,
2841  0x385D0000,
2842  0x385D4000,
2843  0x385D8000,
2844  0x385DC000,
2845  0x385E0000,
2846  0x385E4000,
2847  0x385E8000,
2848  0x385EC000,
2849  0x385F0000,
2850  0x385F4000,
2851  0x385F8000,
2852  0x385FC000,
2853  0x38600000,
2854  0x38604000,
2855  0x38608000,
2856  0x3860C000,
2857  0x38610000,
2858  0x38614000,
2859  0x38618000,
2860  0x3861C000,
2861  0x38620000,
2862  0x38624000,
2863  0x38628000,
2864  0x3862C000,
2865  0x38630000,
2866  0x38634000,
2867  0x38638000,
2868  0x3863C000,
2869  0x38640000,
2870  0x38644000,
2871  0x38648000,
2872  0x3864C000,
2873  0x38650000,
2874  0x38654000,
2875  0x38658000,
2876  0x3865C000,
2877  0x38660000,
2878  0x38664000,
2879  0x38668000,
2880  0x3866C000,
2881  0x38670000,
2882  0x38674000,
2883  0x38678000,
2884  0x3867C000,
2885  0x38680000,
2886  0x38684000,
2887  0x38688000,
2888  0x3868C000,
2889  0x38690000,
2890  0x38694000,
2891  0x38698000,
2892  0x3869C000,
2893  0x386A0000,
2894  0x386A4000,
2895  0x386A8000,
2896  0x386AC000,
2897  0x386B0000,
2898  0x386B4000,
2899  0x386B8000,
2900  0x386BC000,
2901  0x386C0000,
2902  0x386C4000,
2903  0x386C8000,
2904  0x386CC000,
2905  0x386D0000,
2906  0x386D4000,
2907  0x386D8000,
2908  0x386DC000,
2909  0x386E0000,
2910  0x386E4000,
2911  0x386E8000,
2912  0x386EC000,
2913  0x386F0000,
2914  0x386F4000,
2915  0x386F8000,
2916  0x386FC000,
2917  0x38700000,
2918  0x38704000,
2919  0x38708000,
2920  0x3870C000,
2921  0x38710000,
2922  0x38714000,
2923  0x38718000,
2924  0x3871C000,
2925  0x38720000,
2926  0x38724000,
2927  0x38728000,
2928  0x3872C000,
2929  0x38730000,
2930  0x38734000,
2931  0x38738000,
2932  0x3873C000,
2933  0x38740000,
2934  0x38744000,
2935  0x38748000,
2936  0x3874C000,
2937  0x38750000,
2938  0x38754000,
2939  0x38758000,
2940  0x3875C000,
2941  0x38760000,
2942  0x38764000,
2943  0x38768000,
2944  0x3876C000,
2945  0x38770000,
2946  0x38774000,
2947  0x38778000,
2948  0x3877C000,
2949  0x38780000,
2950  0x38784000,
2951  0x38788000,
2952  0x3878C000,
2953  0x38790000,
2954  0x38794000,
2955  0x38798000,
2956  0x3879C000,
2957  0x387A0000,
2958  0x387A4000,
2959  0x387A8000,
2960  0x387AC000,
2961  0x387B0000,
2962  0x387B4000,
2963  0x387B8000,
2964  0x387BC000,
2965  0x387C0000,
2966  0x387C4000,
2967  0x387C8000,
2968  0x387CC000,
2969  0x387D0000,
2970  0x387D4000,
2971  0x387D8000,
2972  0x387DC000,
2973  0x387E0000,
2974  0x387E4000,
2975  0x387E8000,
2976  0x387EC000,
2977  0x387F0000,
2978  0x387F4000,
2979  0x387F8000,
2980  0x387FC000,
2981  0x38000000,
2982  0x38002000,
2983  0x38004000,
2984  0x38006000,
2985  0x38008000,
2986  0x3800A000,
2987  0x3800C000,
2988  0x3800E000,
2989  0x38010000,
2990  0x38012000,
2991  0x38014000,
2992  0x38016000,
2993  0x38018000,
2994  0x3801A000,
2995  0x3801C000,
2996  0x3801E000,
2997  0x38020000,
2998  0x38022000,
2999  0x38024000,
3000  0x38026000,
3001  0x38028000,
3002  0x3802A000,
3003  0x3802C000,
3004  0x3802E000,
3005  0x38030000,
3006  0x38032000,
3007  0x38034000,
3008  0x38036000,
3009  0x38038000,
3010  0x3803A000,
3011  0x3803C000,
3012  0x3803E000,
3013  0x38040000,
3014  0x38042000,
3015  0x38044000,
3016  0x38046000,
3017  0x38048000,
3018  0x3804A000,
3019  0x3804C000,
3020  0x3804E000,
3021  0x38050000,
3022  0x38052000,
3023  0x38054000,
3024  0x38056000,
3025  0x38058000,
3026  0x3805A000,
3027  0x3805C000,
3028  0x3805E000,
3029  0x38060000,
3030  0x38062000,
3031  0x38064000,
3032  0x38066000,
3033  0x38068000,
3034  0x3806A000,
3035  0x3806C000,
3036  0x3806E000,
3037  0x38070000,
3038  0x38072000,
3039  0x38074000,
3040  0x38076000,
3041  0x38078000,
3042  0x3807A000,
3043  0x3807C000,
3044  0x3807E000,
3045  0x38080000,
3046  0x38082000,
3047  0x38084000,
3048  0x38086000,
3049  0x38088000,
3050  0x3808A000,
3051  0x3808C000,
3052  0x3808E000,
3053  0x38090000,
3054  0x38092000,
3055  0x38094000,
3056  0x38096000,
3057  0x38098000,
3058  0x3809A000,
3059  0x3809C000,
3060  0x3809E000,
3061  0x380A0000,
3062  0x380A2000,
3063  0x380A4000,
3064  0x380A6000,
3065  0x380A8000,
3066  0x380AA000,
3067  0x380AC000,
3068  0x380AE000,
3069  0x380B0000,
3070  0x380B2000,
3071  0x380B4000,
3072  0x380B6000,
3073  0x380B8000,
3074  0x380BA000,
3075  0x380BC000,
3076  0x380BE000,
3077  0x380C0000,
3078  0x380C2000,
3079  0x380C4000,
3080  0x380C6000,
3081  0x380C8000,
3082  0x380CA000,
3083  0x380CC000,
3084  0x380CE000,
3085  0x380D0000,
3086  0x380D2000,
3087  0x380D4000,
3088  0x380D6000,
3089  0x380D8000,
3090  0x380DA000,
3091  0x380DC000,
3092  0x380DE000,
3093  0x380E0000,
3094  0x380E2000,
3095  0x380E4000,
3096  0x380E6000,
3097  0x380E8000,
3098  0x380EA000,
3099  0x380EC000,
3100  0x380EE000,
3101  0x380F0000,
3102  0x380F2000,
3103  0x380F4000,
3104  0x380F6000,
3105  0x380F8000,
3106  0x380FA000,
3107  0x380FC000,
3108  0x380FE000,
3109  0x38100000,
3110  0x38102000,
3111  0x38104000,
3112  0x38106000,
3113  0x38108000,
3114  0x3810A000,
3115  0x3810C000,
3116  0x3810E000,
3117  0x38110000,
3118  0x38112000,
3119  0x38114000,
3120  0x38116000,
3121  0x38118000,
3122  0x3811A000,
3123  0x3811C000,
3124  0x3811E000,
3125  0x38120000,
3126  0x38122000,
3127  0x38124000,
3128  0x38126000,
3129  0x38128000,
3130  0x3812A000,
3131  0x3812C000,
3132  0x3812E000,
3133  0x38130000,
3134  0x38132000,
3135  0x38134000,
3136  0x38136000,
3137  0x38138000,
3138  0x3813A000,
3139  0x3813C000,
3140  0x3813E000,
3141  0x38140000,
3142  0x38142000,
3143  0x38144000,
3144  0x38146000,
3145  0x38148000,
3146  0x3814A000,
3147  0x3814C000,
3148  0x3814E000,
3149  0x38150000,
3150  0x38152000,
3151  0x38154000,
3152  0x38156000,
3153  0x38158000,
3154  0x3815A000,
3155  0x3815C000,
3156  0x3815E000,
3157  0x38160000,
3158  0x38162000,
3159  0x38164000,
3160  0x38166000,
3161  0x38168000,
3162  0x3816A000,
3163  0x3816C000,
3164  0x3816E000,
3165  0x38170000,
3166  0x38172000,
3167  0x38174000,
3168  0x38176000,
3169  0x38178000,
3170  0x3817A000,
3171  0x3817C000,
3172  0x3817E000,
3173  0x38180000,
3174  0x38182000,
3175  0x38184000,
3176  0x38186000,
3177  0x38188000,
3178  0x3818A000,
3179  0x3818C000,
3180  0x3818E000,
3181  0x38190000,
3182  0x38192000,
3183  0x38194000,
3184  0x38196000,
3185  0x38198000,
3186  0x3819A000,
3187  0x3819C000,
3188  0x3819E000,
3189  0x381A0000,
3190  0x381A2000,
3191  0x381A4000,
3192  0x381A6000,
3193  0x381A8000,
3194  0x381AA000,
3195  0x381AC000,
3196  0x381AE000,
3197  0x381B0000,
3198  0x381B2000,
3199  0x381B4000,
3200  0x381B6000,
3201  0x381B8000,
3202  0x381BA000,
3203  0x381BC000,
3204  0x381BE000,
3205  0x381C0000,
3206  0x381C2000,
3207  0x381C4000,
3208  0x381C6000,
3209  0x381C8000,
3210  0x381CA000,
3211  0x381CC000,
3212  0x381CE000,
3213  0x381D0000,
3214  0x381D2000,
3215  0x381D4000,
3216  0x381D6000,
3217  0x381D8000,
3218  0x381DA000,
3219  0x381DC000,
3220  0x381DE000,
3221  0x381E0000,
3222  0x381E2000,
3223  0x381E4000,
3224  0x381E6000,
3225  0x381E8000,
3226  0x381EA000,
3227  0x381EC000,
3228  0x381EE000,
3229  0x381F0000,
3230  0x381F2000,
3231  0x381F4000,
3232  0x381F6000,
3233  0x381F8000,
3234  0x381FA000,
3235  0x381FC000,
3236  0x381FE000,
3237  0x38200000,
3238  0x38202000,
3239  0x38204000,
3240  0x38206000,
3241  0x38208000,
3242  0x3820A000,
3243  0x3820C000,
3244  0x3820E000,
3245  0x38210000,
3246  0x38212000,
3247  0x38214000,
3248  0x38216000,
3249  0x38218000,
3250  0x3821A000,
3251  0x3821C000,
3252  0x3821E000,
3253  0x38220000,
3254  0x38222000,
3255  0x38224000,
3256  0x38226000,
3257  0x38228000,
3258  0x3822A000,
3259  0x3822C000,
3260  0x3822E000,
3261  0x38230000,
3262  0x38232000,
3263  0x38234000,
3264  0x38236000,
3265  0x38238000,
3266  0x3823A000,
3267  0x3823C000,
3268  0x3823E000,
3269  0x38240000,
3270  0x38242000,
3271  0x38244000,
3272  0x38246000,
3273  0x38248000,
3274  0x3824A000,
3275  0x3824C000,
3276  0x3824E000,
3277  0x38250000,
3278  0x38252000,
3279  0x38254000,
3280  0x38256000,
3281  0x38258000,
3282  0x3825A000,
3283  0x3825C000,
3284  0x3825E000,
3285  0x38260000,
3286  0x38262000,
3287  0x38264000,
3288  0x38266000,
3289  0x38268000,
3290  0x3826A000,
3291  0x3826C000,
3292  0x3826E000,
3293  0x38270000,
3294  0x38272000,
3295  0x38274000,
3296  0x38276000,
3297  0x38278000,
3298  0x3827A000,
3299  0x3827C000,
3300  0x3827E000,
3301  0x38280000,
3302  0x38282000,
3303  0x38284000,
3304  0x38286000,
3305  0x38288000,
3306  0x3828A000,
3307  0x3828C000,
3308  0x3828E000,
3309  0x38290000,
3310  0x38292000,
3311  0x38294000,
3312  0x38296000,
3313  0x38298000,
3314  0x3829A000,
3315  0x3829C000,
3316  0x3829E000,
3317  0x382A0000,
3318  0x382A2000,
3319  0x382A4000,
3320  0x382A6000,
3321  0x382A8000,
3322  0x382AA000,
3323  0x382AC000,
3324  0x382AE000,
3325  0x382B0000,
3326  0x382B2000,
3327  0x382B4000,
3328  0x382B6000,
3329  0x382B8000,
3330  0x382BA000,
3331  0x382BC000,
3332  0x382BE000,
3333  0x382C0000,
3334  0x382C2000,
3335  0x382C4000,
3336  0x382C6000,
3337  0x382C8000,
3338  0x382CA000,
3339  0x382CC000,
3340  0x382CE000,
3341  0x382D0000,
3342  0x382D2000,
3343  0x382D4000,
3344  0x382D6000,
3345  0x382D8000,
3346  0x382DA000,
3347  0x382DC000,
3348  0x382DE000,
3349  0x382E0000,
3350  0x382E2000,
3351  0x382E4000,
3352  0x382E6000,
3353  0x382E8000,
3354  0x382EA000,
3355  0x382EC000,
3356  0x382EE000,
3357  0x382F0000,
3358  0x382F2000,
3359  0x382F4000,
3360  0x382F6000,
3361  0x382F8000,
3362  0x382FA000,
3363  0x382FC000,
3364  0x382FE000,
3365  0x38300000,
3366  0x38302000,
3367  0x38304000,
3368  0x38306000,
3369  0x38308000,
3370  0x3830A000,
3371  0x3830C000,
3372  0x3830E000,
3373  0x38310000,
3374  0x38312000,
3375  0x38314000,
3376  0x38316000,
3377  0x38318000,
3378  0x3831A000,
3379  0x3831C000,
3380  0x3831E000,
3381  0x38320000,
3382  0x38322000,
3383  0x38324000,
3384  0x38326000,
3385  0x38328000,
3386  0x3832A000,
3387  0x3832C000,
3388  0x3832E000,
3389  0x38330000,
3390  0x38332000,
3391  0x38334000,
3392  0x38336000,
3393  0x38338000,
3394  0x3833A000,
3395  0x3833C000,
3396  0x3833E000,
3397  0x38340000,
3398  0x38342000,
3399  0x38344000,
3400  0x38346000,
3401  0x38348000,
3402  0x3834A000,
3403  0x3834C000,
3404  0x3834E000,
3405  0x38350000,
3406  0x38352000,
3407  0x38354000,
3408  0x38356000,
3409  0x38358000,
3410  0x3835A000,
3411  0x3835C000,
3412  0x3835E000,
3413  0x38360000,
3414  0x38362000,
3415  0x38364000,
3416  0x38366000,
3417  0x38368000,
3418  0x3836A000,
3419  0x3836C000,
3420  0x3836E000,
3421  0x38370000,
3422  0x38372000,
3423  0x38374000,
3424  0x38376000,
3425  0x38378000,
3426  0x3837A000,
3427  0x3837C000,
3428  0x3837E000,
3429  0x38380000,
3430  0x38382000,
3431  0x38384000,
3432  0x38386000,
3433  0x38388000,
3434  0x3838A000,
3435  0x3838C000,
3436  0x3838E000,
3437  0x38390000,
3438  0x38392000,
3439  0x38394000,
3440  0x38396000,
3441  0x38398000,
3442  0x3839A000,
3443  0x3839C000,
3444  0x3839E000,
3445  0x383A0000,
3446  0x383A2000,
3447  0x383A4000,
3448  0x383A6000,
3449  0x383A8000,
3450  0x383AA000,
3451  0x383AC000,
3452  0x383AE000,
3453  0x383B0000,
3454  0x383B2000,
3455  0x383B4000,
3456  0x383B6000,
3457  0x383B8000,
3458  0x383BA000,
3459  0x383BC000,
3460  0x383BE000,
3461  0x383C0000,
3462  0x383C2000,
3463  0x383C4000,
3464  0x383C6000,
3465  0x383C8000,
3466  0x383CA000,
3467  0x383CC000,
3468  0x383CE000,
3469  0x383D0000,
3470  0x383D2000,
3471  0x383D4000,
3472  0x383D6000,
3473  0x383D8000,
3474  0x383DA000,
3475  0x383DC000,
3476  0x383DE000,
3477  0x383E0000,
3478  0x383E2000,
3479  0x383E4000,
3480  0x383E6000,
3481  0x383E8000,
3482  0x383EA000,
3483  0x383EC000,
3484  0x383EE000,
3485  0x383F0000,
3486  0x383F2000,
3487  0x383F4000,
3488  0x383F6000,
3489  0x383F8000,
3490  0x383FA000,
3491  0x383FC000,
3492  0x383FE000,
3493  0x38400000,
3494  0x38402000,
3495  0x38404000,
3496  0x38406000,
3497  0x38408000,
3498  0x3840A000,
3499  0x3840C000,
3500  0x3840E000,
3501  0x38410000,
3502  0x38412000,
3503  0x38414000,
3504  0x38416000,
3505  0x38418000,
3506  0x3841A000,
3507  0x3841C000,
3508  0x3841E000,
3509  0x38420000,
3510  0x38422000,
3511  0x38424000,
3512  0x38426000,
3513  0x38428000,
3514  0x3842A000,
3515  0x3842C000,
3516  0x3842E000,
3517  0x38430000,
3518  0x38432000,
3519  0x38434000,
3520  0x38436000,
3521  0x38438000,
3522  0x3843A000,
3523  0x3843C000,
3524  0x3843E000,
3525  0x38440000,
3526  0x38442000,
3527  0x38444000,
3528  0x38446000,
3529  0x38448000,
3530  0x3844A000,
3531  0x3844C000,
3532  0x3844E000,
3533  0x38450000,
3534  0x38452000,
3535  0x38454000,
3536  0x38456000,
3537  0x38458000,
3538  0x3845A000,
3539  0x3845C000,
3540  0x3845E000,
3541  0x38460000,
3542  0x38462000,
3543  0x38464000,
3544  0x38466000,
3545  0x38468000,
3546  0x3846A000,
3547  0x3846C000,
3548  0x3846E000,
3549  0x38470000,
3550  0x38472000,
3551  0x38474000,
3552  0x38476000,
3553  0x38478000,
3554  0x3847A000,
3555  0x3847C000,
3556  0x3847E000,
3557  0x38480000,
3558  0x38482000,
3559  0x38484000,
3560  0x38486000,
3561  0x38488000,
3562  0x3848A000,
3563  0x3848C000,
3564  0x3848E000,
3565  0x38490000,
3566  0x38492000,
3567  0x38494000,
3568  0x38496000,
3569  0x38498000,
3570  0x3849A000,
3571  0x3849C000,
3572  0x3849E000,
3573  0x384A0000,
3574  0x384A2000,
3575  0x384A4000,
3576  0x384A6000,
3577  0x384A8000,
3578  0x384AA000,
3579  0x384AC000,
3580  0x384AE000,
3581  0x384B0000,
3582  0x384B2000,
3583  0x384B4000,
3584  0x384B6000,
3585  0x384B8000,
3586  0x384BA000,
3587  0x384BC000,
3588  0x384BE000,
3589  0x384C0000,
3590  0x384C2000,
3591  0x384C4000,
3592  0x384C6000,
3593  0x384C8000,
3594  0x384CA000,
3595  0x384CC000,
3596  0x384CE000,
3597  0x384D0000,
3598  0x384D2000,
3599  0x384D4000,
3600  0x384D6000,
3601  0x384D8000,
3602  0x384DA000,
3603  0x384DC000,
3604  0x384DE000,
3605  0x384E0000,
3606  0x384E2000,
3607  0x384E4000,
3608  0x384E6000,
3609  0x384E8000,
3610  0x384EA000,
3611  0x384EC000,
3612  0x384EE000,
3613  0x384F0000,
3614  0x384F2000,
3615  0x384F4000,
3616  0x384F6000,
3617  0x384F8000,
3618  0x384FA000,
3619  0x384FC000,
3620  0x384FE000,
3621  0x38500000,
3622  0x38502000,
3623  0x38504000,
3624  0x38506000,
3625  0x38508000,
3626  0x3850A000,
3627  0x3850C000,
3628  0x3850E000,
3629  0x38510000,
3630  0x38512000,
3631  0x38514000,
3632  0x38516000,
3633  0x38518000,
3634  0x3851A000,
3635  0x3851C000,
3636  0x3851E000,
3637  0x38520000,
3638  0x38522000,
3639  0x38524000,
3640  0x38526000,
3641  0x38528000,
3642  0x3852A000,
3643  0x3852C000,
3644  0x3852E000,
3645  0x38530000,
3646  0x38532000,
3647  0x38534000,
3648  0x38536000,
3649  0x38538000,
3650  0x3853A000,
3651  0x3853C000,
3652  0x3853E000,
3653  0x38540000,
3654  0x38542000,
3655  0x38544000,
3656  0x38546000,
3657  0x38548000,
3658  0x3854A000,
3659  0x3854C000,
3660  0x3854E000,
3661  0x38550000,
3662  0x38552000,
3663  0x38554000,
3664  0x38556000,
3665  0x38558000,
3666  0x3855A000,
3667  0x3855C000,
3668  0x3855E000,
3669  0x38560000,
3670  0x38562000,
3671  0x38564000,
3672  0x38566000,
3673  0x38568000,
3674  0x3856A000,
3675  0x3856C000,
3676  0x3856E000,
3677  0x38570000,
3678  0x38572000,
3679  0x38574000,
3680  0x38576000,
3681  0x38578000,
3682  0x3857A000,
3683  0x3857C000,
3684  0x3857E000,
3685  0x38580000,
3686  0x38582000,
3687  0x38584000,
3688  0x38586000,
3689  0x38588000,
3690  0x3858A000,
3691  0x3858C000,
3692  0x3858E000,
3693  0x38590000,
3694  0x38592000,
3695  0x38594000,
3696  0x38596000,
3697  0x38598000,
3698  0x3859A000,
3699  0x3859C000,
3700  0x3859E000,
3701  0x385A0000,
3702  0x385A2000,
3703  0x385A4000,
3704  0x385A6000,
3705  0x385A8000,
3706  0x385AA000,
3707  0x385AC000,
3708  0x385AE000,
3709  0x385B0000,
3710  0x385B2000,
3711  0x385B4000,
3712  0x385B6000,
3713  0x385B8000,
3714  0x385BA000,
3715  0x385BC000,
3716  0x385BE000,
3717  0x385C0000,
3718  0x385C2000,
3719  0x385C4000,
3720  0x385C6000,
3721  0x385C8000,
3722  0x385CA000,
3723  0x385CC000,
3724  0x385CE000,
3725  0x385D0000,
3726  0x385D2000,
3727  0x385D4000,
3728  0x385D6000,
3729  0x385D8000,
3730  0x385DA000,
3731  0x385DC000,
3732  0x385DE000,
3733  0x385E0000,
3734  0x385E2000,
3735  0x385E4000,
3736  0x385E6000,
3737  0x385E8000,
3738  0x385EA000,
3739  0x385EC000,
3740  0x385EE000,
3741  0x385F0000,
3742  0x385F2000,
3743  0x385F4000,
3744  0x385F6000,
3745  0x385F8000,
3746  0x385FA000,
3747  0x385FC000,
3748  0x385FE000,
3749  0x38600000,
3750  0x38602000,
3751  0x38604000,
3752  0x38606000,
3753  0x38608000,
3754  0x3860A000,
3755  0x3860C000,
3756  0x3860E000,
3757  0x38610000,
3758  0x38612000,
3759  0x38614000,
3760  0x38616000,
3761  0x38618000,
3762  0x3861A000,
3763  0x3861C000,
3764  0x3861E000,
3765  0x38620000,
3766  0x38622000,
3767  0x38624000,
3768  0x38626000,
3769  0x38628000,
3770  0x3862A000,
3771  0x3862C000,
3772  0x3862E000,
3773  0x38630000,
3774  0x38632000,
3775  0x38634000,
3776  0x38636000,
3777  0x38638000,
3778  0x3863A000,
3779  0x3863C000,
3780  0x3863E000,
3781  0x38640000,
3782  0x38642000,
3783  0x38644000,
3784  0x38646000,
3785  0x38648000,
3786  0x3864A000,
3787  0x3864C000,
3788  0x3864E000,
3789  0x38650000,
3790  0x38652000,
3791  0x38654000,
3792  0x38656000,
3793  0x38658000,
3794  0x3865A000,
3795  0x3865C000,
3796  0x3865E000,
3797  0x38660000,
3798  0x38662000,
3799  0x38664000,
3800  0x38666000,
3801  0x38668000,
3802  0x3866A000,
3803  0x3866C000,
3804  0x3866E000,
3805  0x38670000,
3806  0x38672000,
3807  0x38674000,
3808  0x38676000,
3809  0x38678000,
3810  0x3867A000,
3811  0x3867C000,
3812  0x3867E000,
3813  0x38680000,
3814  0x38682000,
3815  0x38684000,
3816  0x38686000,
3817  0x38688000,
3818  0x3868A000,
3819  0x3868C000,
3820  0x3868E000,
3821  0x38690000,
3822  0x38692000,
3823  0x38694000,
3824  0x38696000,
3825  0x38698000,
3826  0x3869A000,
3827  0x3869C000,
3828  0x3869E000,
3829  0x386A0000,
3830  0x386A2000,
3831  0x386A4000,
3832  0x386A6000,
3833  0x386A8000,
3834  0x386AA000,
3835  0x386AC000,
3836  0x386AE000,
3837  0x386B0000,
3838  0x386B2000,
3839  0x386B4000,
3840  0x386B6000,
3841  0x386B8000,
3842  0x386BA000,
3843  0x386BC000,
3844  0x386BE000,
3845  0x386C0000,
3846  0x386C2000,
3847  0x386C4000,
3848  0x386C6000,
3849  0x386C8000,
3850  0x386CA000,
3851  0x386CC000,
3852  0x386CE000,
3853  0x386D0000,
3854  0x386D2000,
3855  0x386D4000,
3856  0x386D6000,
3857  0x386D8000,
3858  0x386DA000,
3859  0x386DC000,
3860  0x386DE000,
3861  0x386E0000,
3862  0x386E2000,
3863  0x386E4000,
3864  0x386E6000,
3865  0x386E8000,
3866  0x386EA000,
3867  0x386EC000,
3868  0x386EE000,
3869  0x386F0000,
3870  0x386F2000,
3871  0x386F4000,
3872  0x386F6000,
3873  0x386F8000,
3874  0x386FA000,
3875  0x386FC000,
3876  0x386FE000,
3877  0x38700000,
3878  0x38702000,
3879  0x38704000,
3880  0x38706000,
3881  0x38708000,
3882  0x3870A000,
3883  0x3870C000,
3884  0x3870E000,
3885  0x38710000,
3886  0x38712000,
3887  0x38714000,
3888  0x38716000,
3889  0x38718000,
3890  0x3871A000,
3891  0x3871C000,
3892  0x3871E000,
3893  0x38720000,
3894  0x38722000,
3895  0x38724000,
3896  0x38726000,
3897  0x38728000,
3898  0x3872A000,
3899  0x3872C000,
3900  0x3872E000,
3901  0x38730000,
3902  0x38732000,
3903  0x38734000,
3904  0x38736000,
3905  0x38738000,
3906  0x3873A000,
3907  0x3873C000,
3908  0x3873E000,
3909  0x38740000,
3910  0x38742000,
3911  0x38744000,
3912  0x38746000,
3913  0x38748000,
3914  0x3874A000,
3915  0x3874C000,
3916  0x3874E000,
3917  0x38750000,
3918  0x38752000,
3919  0x38754000,
3920  0x38756000,
3921  0x38758000,
3922  0x3875A000,
3923  0x3875C000,
3924  0x3875E000,
3925  0x38760000,
3926  0x38762000,
3927  0x38764000,
3928  0x38766000,
3929  0x38768000,
3930  0x3876A000,
3931  0x3876C000,
3932  0x3876E000,
3933  0x38770000,
3934  0x38772000,
3935  0x38774000,
3936  0x38776000,
3937  0x38778000,
3938  0x3877A000,
3939  0x3877C000,
3940  0x3877E000,
3941  0x38780000,
3942  0x38782000,
3943  0x38784000,
3944  0x38786000,
3945  0x38788000,
3946  0x3878A000,
3947  0x3878C000,
3948  0x3878E000,
3949  0x38790000,
3950  0x38792000,
3951  0x38794000,
3952  0x38796000,
3953  0x38798000,
3954  0x3879A000,
3955  0x3879C000,
3956  0x3879E000,
3957  0x387A0000,
3958  0x387A2000,
3959  0x387A4000,
3960  0x387A6000,
3961  0x387A8000,
3962  0x387AA000,
3963  0x387AC000,
3964  0x387AE000,
3965  0x387B0000,
3966  0x387B2000,
3967  0x387B4000,
3968  0x387B6000,
3969  0x387B8000,
3970  0x387BA000,
3971  0x387BC000,
3972  0x387BE000,
3973  0x387C0000,
3974  0x387C2000,
3975  0x387C4000,
3976  0x387C6000,
3977  0x387C8000,
3978  0x387CA000,
3979  0x387CC000,
3980  0x387CE000,
3981  0x387D0000,
3982  0x387D2000,
3983  0x387D4000,
3984  0x387D6000,
3985  0x387D8000,
3986  0x387DA000,
3987  0x387DC000,
3988  0x387DE000,
3989  0x387E0000,
3990  0x387E2000,
3991  0x387E4000,
3992  0x387E6000,
3993  0x387E8000,
3994  0x387EA000,
3995  0x387EC000,
3996  0x387EE000,
3997  0x387F0000,
3998  0x387F2000,
3999  0x387F4000,
4000  0x387F6000,
4001  0x387F8000,
4002  0x387FA000,
4003  0x387FC000,
4004  0x387FE000};
4005  static const bits<float>::type exponent_table[64] = {
4006  0x00000000,
4007  0x00800000,
4008  0x01000000,
4009  0x01800000,
4010  0x02000000,
4011  0x02800000,
4012  0x03000000,
4013  0x03800000,
4014  0x04000000,
4015  0x04800000,
4016  0x05000000,
4017  0x05800000,
4018  0x06000000,
4019  0x06800000,
4020  0x07000000,
4021  0x07800000,
4022  0x08000000,
4023  0x08800000,
4024  0x09000000,
4025  0x09800000,
4026  0x0A000000,
4027  0x0A800000,
4028  0x0B000000,
4029  0x0B800000,
4030  0x0C000000,
4031  0x0C800000,
4032  0x0D000000,
4033  0x0D800000,
4034  0x0E000000,
4035  0x0E800000,
4036  0x0F000000,
4037  0x47800000,
4038  0x80000000,
4039  0x80800000,
4040  0x81000000,
4041  0x81800000,
4042  0x82000000,
4043  0x82800000,
4044  0x83000000,
4045  0x83800000,
4046  0x84000000,
4047  0x84800000,
4048  0x85000000,
4049  0x85800000,
4050  0x86000000,
4051  0x86800000,
4052  0x87000000,
4053  0x87800000,
4054  0x88000000,
4055  0x88800000,
4056  0x89000000,
4057  0x89800000,
4058  0x8A000000,
4059  0x8A800000,
4060  0x8B000000,
4061  0x8B800000,
4062  0x8C000000,
4063  0x8C800000,
4064  0x8D000000,
4065  0x8D800000,
4066  0x8E000000,
4067  0x8E800000,
4068  0x8F000000,
4069  0xC7800000};
4070  static const unsigned short offset_table[64] = {
4071  0,
4072  1024,
4073  1024,
4074  1024,
4075  1024,
4076  1024,
4077  1024,
4078  1024,
4079  1024,
4080  1024,
4081  1024,
4082  1024,
4083  1024,
4084  1024,
4085  1024,
4086  1024,
4087  1024,
4088  1024,
4089  1024,
4090  1024,
4091  1024,
4092  1024,
4093  1024,
4094  1024,
4095  1024,
4096  1024,
4097  1024,
4098  1024,
4099  1024,
4100  1024,
4101  1024,
4102  1024,
4103  0,
4104  1024,
4105  1024,
4106  1024,
4107  1024,
4108  1024,
4109  1024,
4110  1024,
4111  1024,
4112  1024,
4113  1024,
4114  1024,
4115  1024,
4116  1024,
4117  1024,
4118  1024,
4119  1024,
4120  1024,
4121  1024,
4122  1024,
4123  1024,
4124  1024,
4125  1024,
4126  1024,
4127  1024,
4128  1024,
4129  1024,
4130  1024,
4131  1024,
4132  1024,
4133  1024,
4134  1024};
4135  bits<float>::type fbits = mantissa_table[offset_table[value >> 10] + (value & 0x3FF)] + exponent_table[value >> 10];
4136 #endif
4137  float out;
4138  std::memcpy(&out, &fbits, sizeof(float));
4139  return out;
4140 #endif
4141 }
4142 
4146 inline double half2float_impl(unsigned int value, double, true_type)
4148 #if HALF_ENABLE_F16C_INTRINSICS
4149  return _mm_cvtsd_f64(_mm_cvtps_pd(_mm_cvtph_ps(_mm_cvtsi32_si128(value))));
4150 #else
4151  uint32 hi = static_cast<uint32>(value & 0x8000) << 16;
4152  unsigned int abs = value & 0x7FFF;
4153  if (abs)
4154  {
4155  hi |= 0x3F000000 << static_cast<unsigned>(abs >= 0x7C00);
4156  for (; abs < 0x400; abs <<= 1, hi -= 0x100000)
4157  ;
4158  hi += static_cast<uint32>(abs) << 10;
4159  }
4160  bits<double>::type dbits = static_cast<bits<double>::type>(hi) << 32;
4161  double out;
4162  std::memcpy(&out, &dbits, sizeof(double));
4163  return out;
4164 #endif
4165 }
4166 
4171 template <typename T>
4172 T half2float_impl(unsigned int value, T, ...)
4174  T out;
4175  unsigned int abs = value & 0x7FFF;
4176  if (abs > 0x7C00)
4177  out = (std::numeric_limits<T>::has_signaling_NaN && !(abs & 0x200)) ? std::numeric_limits<T>::signaling_NaN() : std::numeric_limits<T>::has_quiet_NaN ? std::numeric_limits<T>::quiet_NaN()
4178  : T();
4179  else if (abs == 0x7C00)
4180  out = std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : std::numeric_limits<T>::max();
4181  else if (abs > 0x3FF)
4182  out = ldexp(static_cast<T>((abs & 0x3FF) | 0x400), (abs >> 10) - 25);
4183  else
4184  out = ldexp(static_cast<T>(abs), -24);
4185  return (value & 0x8000) ? -out : out;
4186 }
4187 
4192 template <typename T>
4193 T half2float(unsigned int value)
4195  return half2float_impl(value, T(), bool_type<std::numeric_limits<T>::is_iec559 && sizeof(typename bits<T>::type) == sizeof(T)>());
4196 }
4197 
4207 template <std::float_round_style R, bool E, bool I, typename T>
4208 T half2int(unsigned int value)
4210  unsigned int abs = value & 0x7FFF;
4211  if (abs >= 0x7C00)
4212  {
4213  raise(MU_HALF_FE_INVALID);
4214  return (value & 0x8000) ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max();
4215  }
4216  if (abs < 0x3800)
4217  {
4218  raise(MU_HALF_FE_INEXACT, I);
4219  return (R == std::round_toward_infinity) ? T(~(value >> 15) & (abs != 0)) : (R == std::round_toward_neg_infinity) ? -T(value > 0x8000)
4220  : T();
4221  }
4222  int exp = 25 - (abs >> 10);
4223  unsigned int m = (value & 0x3FF) | 0x400;
4224  int32 i = static_cast<int32>((exp <= 0) ? (m << -exp) : ((m + ((R == std::round_to_nearest) ? ((1 << (exp - 1)) - (~(m >> exp) & E)) : (R == std::round_toward_infinity) ? (((1 << exp) - 1) & ((value >> 15) - 1))
4225  : (R == std::round_toward_neg_infinity) ? (((1 << exp) - 1) & -(value >> 15))
4226  : 0)) >>
4227  exp));
4228  if ((!std::numeric_limits<T>::is_signed && (value & 0x8000)) || (std::numeric_limits<T>::digits < 16 &&
4229  ((value & 0x8000) ? (-i < std::numeric_limits<T>::min()) : (i > std::numeric_limits<T>::max()))))
4230  raise(MU_HALF_FE_INVALID);
4231  else if (I && exp > 0 && (m & ((1 << exp) - 1)))
4232  raise(MU_HALF_FE_INEXACT);
4233  return static_cast<T>((value & 0x8000) ? -i : i);
4234 }
4235 
4239 
4245 template <std::float_round_style R>
4246 uint32 mulhi(uint32 x, uint32 y)
4248  uint32 xy = (x >> 16) * (y & 0xFFFF), yx = (x & 0xFFFF) * (y >> 16), c = (xy & 0xFFFF) + (yx & 0xFFFF) + (((x & 0xFFFF) * (y & 0xFFFF)) >> 16);
4249  return (x >> 16) * (y >> 16) + (xy >> 16) + (yx >> 16) + (c >> 16) +
4250  ((R == std::round_to_nearest) ? ((c >> 15) & 1) : (R == std::round_toward_infinity) ? ((c & 0xFFFF) != 0)
4251  : 0);
4252 }
4253 
4258 inline uint32 multiply64(uint32 x, uint32 y)
4260 #if HALF_ENABLE_CPP11_LONG_LONG
4261  return static_cast<uint32>((static_cast<unsigned long long>(x) * static_cast<unsigned long long>(y) + 0x80000000) >> 32);
4262 #else
4263  return mulhi<std::round_to_nearest>(x, y);
4264 #endif
4265 }
4266 
4272 inline uint32 divide64(uint32 x, uint32 y, int& s)
4274 #if HALF_ENABLE_CPP11_LONG_LONG
4275  unsigned long long xx = static_cast<unsigned long long>(x) << 32;
4276  return s = (xx % y != 0), static_cast<uint32>(xx / y);
4277 #else
4278  y >>= 1;
4279  uint32 rem = x, div = 0;
4280  for (unsigned int i = 0; i < 32; ++i)
4281  {
4282  div <<= 1;
4283  if (rem >= y)
4284  {
4285  rem -= y;
4286  div |= 1;
4287  }
4288  rem <<= 1;
4289  }
4290  return s = rem > 1, div;
4291 #endif
4292 }
4293 
4301 template <bool Q, bool R>
4302 unsigned int mod(unsigned int x, unsigned int y, int* quo = NULL)
4304  unsigned int q = 0;
4305  if (x > y)
4306  {
4307  int absx = x, absy = y, expx = 0, expy = 0;
4308  for (; absx < 0x400; absx <<= 1, --expx)
4309  ;
4310  for (; absy < 0x400; absy <<= 1, --expy)
4311  ;
4312  expx += absx >> 10;
4313  expy += absy >> 10;
4314  int mx = (absx & 0x3FF) | 0x400, my = (absy & 0x3FF) | 0x400;
4315  for (int d = expx - expy; d; --d)
4316  {
4317  if (!Q && mx == my)
4318  return 0;
4319  if (mx >= my)
4320  {
4321  mx -= my;
4322  q += Q;
4323  }
4324  mx <<= 1;
4325  q <<= static_cast<int>(Q);
4326  }
4327  if (!Q && mx == my)
4328  return 0;
4329  if (mx >= my)
4330  {
4331  mx -= my;
4332  ++q;
4333  }
4334  if (Q)
4335  {
4336  q &= (1 << (std::numeric_limits<int>::digits - 1)) - 1;
4337  if (!mx)
4338  return *quo = q, 0;
4339  }
4340  for (; mx < 0x400; mx <<= 1, --expy)
4341  ;
4342  x = (expy > 0) ? ((expy << 10) | (mx & 0x3FF)) : (mx >> (1 - expy));
4343  }
4344  if (R)
4345  {
4346  unsigned int a, b;
4347  if (y < 0x800)
4348  {
4349  a = (x < 0x400) ? (x << 1) : (x + 0x400);
4350  b = y;
4351  }
4352  else
4353  {
4354  a = x;
4355  b = y - 0x400;
4356  }
4357  if (a > b || (a == b && (q & 1)))
4358  {
4359  int exp = (y >> 10) + (y <= 0x3FF), d = exp - (x >> 10) - (x <= 0x3FF);
4360  int m = (((y & 0x3FF) | ((y > 0x3FF) << 10)) << 1) - (((x & 0x3FF) | ((x > 0x3FF) << 10)) << (1 - d));
4361  for (; m < 0x800 && exp > 1; m <<= 1, --exp)
4362  ;
4363  x = 0x8000 + ((exp - 1) << 10) + (m >> 1);
4364  q += Q;
4365  }
4366  }
4367  if (Q)
4368  *quo = q;
4369  return x;
4370 }
4371 
4377 template <unsigned int F>
4378 uint32 sqrt(uint32& r, int& exp)
4380  int i = exp & 1;
4381  r <<= i;
4382  exp = (exp - i) / 2;
4383  uint32 m = 0;
4384  for (uint32 bit = static_cast<uint32>(1) << F; bit; bit >>= 2)
4385  {
4386  if (r < m + bit)
4387  m >>= 1;
4388  else
4389  {
4390  r -= m + bit;
4391  m = (m >> 1) + bit;
4392  }
4393  }
4394  return m;
4395 }
4396 
4402 inline uint32 exp2(uint32 m, unsigned int n = 32)
4404  static const uint32 logs[] = {
4405  0x80000000,
4406  0x4AE00D1D,
4407  0x2934F098,
4408  0x15C01A3A,
4409  0x0B31FB7D,
4410  0x05AEB4DD,
4411  0x02DCF2D1,
4412  0x016FE50B,
4413  0x00B84E23,
4414  0x005C3E10,
4415  0x002E24CA,
4416  0x001713D6,
4417  0x000B8A47,
4418  0x0005C53B,
4419  0x0002E2A3,
4420  0x00017153,
4421  0x0000B8AA,
4422  0x00005C55,
4423  0x00002E2B,
4424  0x00001715,
4425  0x00000B8B,
4426  0x000005C5,
4427  0x000002E3,
4428  0x00000171,
4429  0x000000B9,
4430  0x0000005C,
4431  0x0000002E,
4432  0x00000017,
4433  0x0000000C,
4434  0x00000006,
4435  0x00000003,
4436  0x00000001};
4437  if (!m)
4438  return 0x80000000;
4439  uint32 mx = 0x80000000, my = 0;
4440  for (unsigned int i = 1; i < n; ++i)
4441  {
4442  uint32 mz = my + logs[i];
4443  if (mz <= m)
4444  {
4445  my = mz;
4446  mx += mx >> i;
4447  }
4448  }
4449  return mx;
4450 }
4451 
4457 inline uint32 log2(uint32 m, unsigned int n = 32)
4459  static const uint32 logs[] = {
4460  0x80000000,
4461  0x4AE00D1D,
4462  0x2934F098,
4463  0x15C01A3A,
4464  0x0B31FB7D,
4465  0x05AEB4DD,
4466  0x02DCF2D1,
4467  0x016FE50B,
4468  0x00B84E23,
4469  0x005C3E10,
4470  0x002E24CA,
4471  0x001713D6,
4472  0x000B8A47,
4473  0x0005C53B,
4474  0x0002E2A3,
4475  0x00017153,
4476  0x0000B8AA,
4477  0x00005C55,
4478  0x00002E2B,
4479  0x00001715,
4480  0x00000B8B,
4481  0x000005C5,
4482  0x000002E3,
4483  0x00000171,
4484  0x000000B9,
4485  0x0000005C,
4486  0x0000002E,
4487  0x00000017,
4488  0x0000000C,
4489  0x00000006,
4490  0x00000003,
4491  0x00000001};
4492  if (m == 0x40000000)
4493  return 0;
4494  uint32 mx = 0x40000000, my = 0;
4495  for (unsigned int i = 1; i < n; ++i)
4496  {
4497  uint32 mz = mx + (mx >> i);
4498  if (mz <= m)
4499  {
4500  mx = mz;
4501  my += logs[i];
4502  }
4503  }
4504  return my;
4505 }
4506 
4512 inline std::pair<uint32, uint32> sincos(uint32 mz, unsigned int n = 31)
4514  static const uint32 angles[] = {
4515  0x3243F6A9,
4516  0x1DAC6705,
4517  0x0FADBAFD,
4518  0x07F56EA7,
4519  0x03FEAB77,
4520  0x01FFD55C,
4521  0x00FFFAAB,
4522  0x007FFF55,
4523  0x003FFFEB,
4524  0x001FFFFD,
4525  0x00100000,
4526  0x00080000,
4527  0x00040000,
4528  0x00020000,
4529  0x00010000,
4530  0x00008000,
4531  0x00004000,
4532  0x00002000,
4533  0x00001000,
4534  0x00000800,
4535  0x00000400,
4536  0x00000200,
4537  0x00000100,
4538  0x00000080,
4539  0x00000040,
4540  0x00000020,
4541  0x00000010,
4542  0x00000008,
4543  0x00000004,
4544  0x00000002,
4545  0x00000001};
4546  uint32 mx = 0x26DD3B6A, my = 0;
4547  for (unsigned int i = 0; i < n; ++i)
4548  {
4549  uint32 sign = sign_mask(mz);
4550  uint32 tx = mx - (arithmetic_shift(my, i) ^ sign) + sign;
4551  uint32 ty = my + (arithmetic_shift(mx, i) ^ sign) - sign;
4552  mx = tx;
4553  my = ty;
4554  mz -= (angles[i] ^ sign) - sign;
4555  }
4556  return std::make_pair(my, mx);
4557 }
4558 
4565 inline uint32 atan2(uint32 my, uint32 mx, unsigned int n = 31)
4567  static const uint32 angles[] = {
4568  0x3243F6A9,
4569  0x1DAC6705,
4570  0x0FADBAFD,
4571  0x07F56EA7,
4572  0x03FEAB77,
4573  0x01FFD55C,
4574  0x00FFFAAB,
4575  0x007FFF55,
4576  0x003FFFEB,
4577  0x001FFFFD,
4578  0x00100000,
4579  0x00080000,
4580  0x00040000,
4581  0x00020000,
4582  0x00010000,
4583  0x00008000,
4584  0x00004000,
4585  0x00002000,
4586  0x00001000,
4587  0x00000800,
4588  0x00000400,
4589  0x00000200,
4590  0x00000100,
4591  0x00000080,
4592  0x00000040,
4593  0x00000020,
4594  0x00000010,
4595  0x00000008,
4596  0x00000004,
4597  0x00000002,
4598  0x00000001};
4599  uint32 mz = 0;
4600  for (unsigned int i = 0; i < n; ++i)
4601  {
4602  uint32 sign = sign_mask(my);
4603  uint32 tx = mx + (arithmetic_shift(my, i) ^ sign) - sign;
4604  uint32 ty = my - (arithmetic_shift(mx, i) ^ sign) + sign;
4605  mx = tx;
4606  my = ty;
4607  mz += (angles[i] ^ sign) - sign;
4608  }
4609  return mz;
4610 }
4611 
4616 inline uint32 angle_arg(unsigned int abs, int& k)
4618  uint32 m = (abs & 0x3FF) | ((abs > 0x3FF) << 10);
4619  int exp = (abs >> 10) + (abs <= 0x3FF) - 15;
4620  if (abs < 0x3A48)
4621  return k = 0, m << (exp + 20);
4622 #if HALF_ENABLE_CPP11_LONG_LONG
4623  unsigned long long y = m * 0xA2F9836E4E442, mask = (1ULL << (62 - exp)) - 1, yi = (y + (mask >> 1)) & ~mask, f = y - yi;
4624  uint32 sign = -static_cast<uint32>(f >> 63);
4625  k = static_cast<int>(yi >> (62 - exp));
4626  return (multiply64(static_cast<uint32>((sign ? -f : f) >> (31 - exp)), 0xC90FDAA2) ^ sign) - sign;
4627 #else
4628  uint32 yh = m * 0xA2F98 + mulhi<std::round_toward_zero>(m, 0x36E4E442), yl = (m * 0x36E4E442) & 0xFFFFFFFF;
4629  uint32 mask = (static_cast<uint32>(1) << (30 - exp)) - 1, yi = (yh + (mask >> 1)) & ~mask, sign = -static_cast<uint32>(yi > yh);
4630  k = static_cast<int>(yi >> (30 - exp));
4631  uint32 fh = (yh ^ sign) + (yi ^ ~sign) - ~sign, fl = (yl ^ sign) - sign;
4632  return (multiply64((exp > -1) ? (((fh << (1 + exp)) & 0xFFFFFFFF) | ((fl & 0xFFFFFFFF) >> (31 - exp))) : fh, 0xC90FDAA2) ^ sign) - sign;
4633 #endif
4634 }
4635 
4639 inline std::pair<uint32, uint32> atan2_args(unsigned int abs)
4641  int exp = -15;
4642  for (; abs < 0x400; abs <<= 1, --exp)
4643  ;
4644  exp += abs >> 10;
4645  uint32 my = ((abs & 0x3FF) | 0x400) << 5, r = my * my;
4646  int rexp = 2 * exp;
4647  r = 0x40000000 - ((rexp > -31) ? ((r >> -rexp) | ((r & ((static_cast<uint32>(1) << -rexp) - 1)) != 0)) : 1);
4648  for (rexp = 0; r < 0x40000000; r <<= 1, --rexp)
4649  ;
4650  uint32 mx = sqrt<30>(r, rexp);
4651  int d = exp - rexp;
4652  if (d < 0)
4653  return std::make_pair((d < -14) ? ((my >> (-d - 14)) + ((my >> (-d - 15)) & 1)) : (my << (14 + d)), (mx << 14) + (r << 13) / mx);
4654  if (d > 0)
4655  return std::make_pair(my << 14, (d > 14) ? ((mx >> (d - 14)) + ((mx >> (d - 15)) & 1)) : ((d == 14) ? mx : ((mx << (14 - d)) + (r << (13 - d)) / mx)));
4656  return std::make_pair(my << 13, (mx << 13) + (r << 12) / mx);
4657 }
4658 
4664 inline std::pair<uint32, uint32> hyperbolic_args(unsigned int abs, int& exp, unsigned int n = 32)
4666  uint32 mx = detail::multiply64(static_cast<uint32>((abs & 0x3FF) + ((abs > 0x3FF) << 10)) << 21, 0xB8AA3B29), my;
4667  int e = (abs >> 10) + (abs <= 0x3FF);
4668  if (e < 14)
4669  {
4670  exp = 0;
4671  mx >>= 14 - e;
4672  }
4673  else
4674  {
4675  exp = mx >> (45 - e);
4676  mx = (mx << (e - 14)) & 0x7FFFFFFF;
4677  }
4678  mx = exp2(mx, n);
4679  int d = exp << 1, s;
4680  if (mx > 0x80000000)
4681  {
4682  my = divide64(0x80000000, mx, s);
4683  my |= s;
4684  ++d;
4685  }
4686  else
4687  my = mx;
4688  return std::make_pair(mx, (d < 31) ? ((my >> d) | ((my & ((static_cast<uint32>(1) << d) - 1)) != 0)) : 1);
4689 }
4690 
4702 template <std::float_round_style R>
4703 unsigned int exp2_post(uint32 m, int exp, bool esign, unsigned int sign = 0, unsigned int n = 32)
4705  if (esign)
4706  {
4707  exp = -exp - (m != 0);
4708  if (exp < -25)
4709  return underflow<R>(sign);
4710  else if (exp == -25)
4711  return rounded<R, false>(sign, 1, m != 0);
4712  }
4713  else if (exp > 15)
4714  return overflow<R>(sign);
4715  if (!m)
4716  return sign | (((exp += 15) > 0) ? (exp << 10) : check_underflow(0x200 >> -exp));
4717  m = exp2(m, n);
4718  int s = 0;
4719  if (esign)
4720  m = divide64(0x80000000, m, s);
4721  return fixed2half<R, 31, false, false, true>(m, exp + 14, sign, s);
4722 }
4723 
4735 template <std::float_round_style R, uint32 L>
4736 unsigned int log2_post(uint32 m, int ilog, int exp, unsigned int sign = 0)
4738  uint32 msign = sign_mask(ilog);
4739  m = (((static_cast<uint32>(ilog) << 27) + (m >> 4)) ^ msign) - msign;
4740  if (!m)
4741  return 0;
4742  for (; m < 0x80000000; m <<= 1, --exp)
4743  ;
4744  int i = m >= L, s;
4745  exp += i;
4746  m >>= 1 + i;
4747  sign ^= msign & 0x8000;
4748  if (exp < -11)
4749  return underflow<R>(sign);
4750  m = divide64(m, L, s);
4751  return fixed2half<R, 30, false, false, true>(m, exp, sign, 1);
4752 }
4753 
4762 template <std::float_round_style R>
4763 unsigned int hypot_post(uint32 r, int exp)
4765  int i = r >> 31;
4766  if ((exp += i) > 46)
4767  return overflow<R>();
4768  if (exp < -34)
4769  return underflow<R>();
4770  r = (r >> i) | (r & i);
4771  uint32 m = sqrt<30>(r, exp += 15);
4772  return fixed2half<R, 15, false, false, false>(m, exp - 1, 0, r != 0);
4773 }
4774 
4785 template <std::float_round_style R>
4786 unsigned int tangent_post(uint32 my, uint32 mx, int exp, unsigned int sign = 0)
4788  int i = my >= mx, s;
4789  exp += i;
4790  if (exp > 29)
4791  return overflow<R>(sign);
4792  if (exp < -11)
4793  return underflow<R>(sign);
4794  uint32 m = divide64(my >> (i + 1), mx, s);
4795  return fixed2half<R, 30, false, false, true>(m, exp, sign, s);
4796 }
4797 
4807 template <std::float_round_style R, bool S>
4808 unsigned int area(unsigned int arg)
4810  int abs = arg & 0x7FFF, expx = (abs >> 10) + (abs <= 0x3FF) - 15, expy = -15, ilog, i;
4811  uint32 mx = static_cast<uint32>((abs & 0x3FF) | ((abs > 0x3FF) << 10)) << 20, my, r;
4812  for (; abs < 0x400; abs <<= 1, --expy)
4813  ;
4814  expy += abs >> 10;
4815  r = ((abs & 0x3FF) | 0x400) << 5;
4816  r *= r;
4817  i = r >> 31;
4818  expy = 2 * expy + i;
4819  r >>= i;
4820  if (S)
4821  {
4822  if (expy < 0)
4823  {
4824  r = 0x40000000 + ((expy > -30) ? ((r >> -expy) | ((r & ((static_cast<uint32>(1) << -expy) - 1)) != 0)) : 1);
4825  expy = 0;
4826  }
4827  else
4828  {
4829  r += 0x40000000 >> expy;
4830  i = r >> 31;
4831  r = (r >> i) | (r & i);
4832  expy += i;
4833  }
4834  }
4835  else
4836  {
4837  r -= 0x40000000 >> expy;
4838  for (; r < 0x40000000; r <<= 1, --expy)
4839  ;
4840  }
4841  my = sqrt<30>(r, expy);
4842  my = (my << 15) + (r << 14) / my;
4843  if (S)
4844  {
4845  mx >>= expy - expx;
4846  ilog = expy;
4847  }
4848  else
4849  {
4850  my >>= expx - expy;
4851  ilog = expx;
4852  }
4853  my += mx;
4854  i = my >> 31;
4855  static const int G = S && (R == std::round_to_nearest);
4856  return log2_post<R, 0xB8AA3B2A>(log2(my >> i, 26 + S + G) + (G << 3), ilog + i, 17, arg & (static_cast<unsigned>(S) << 15));
4857 }
4858 
4860 struct f31
4865  HALF_CONSTEXPR f31(uint32 mant, int e)
4866  : m(mant),
4867  exp(e)
4868  {
4869  }
4870 
4873  f31(unsigned int abs)
4874  : exp(-15)
4875  {
4876  for (; abs < 0x400; abs <<= 1, --exp)
4877  ;
4878  m = static_cast<uint32>((abs & 0x3FF) | 0x400) << 21;
4879  exp += (abs >> 10);
4880  }
4881 
4886  friend f31 operator+(f31 a, f31 b)
4887  {
4888  if (b.exp > a.exp)
4889  std::swap(a, b);
4890  int d = a.exp - b.exp;
4891  uint32 m = a.m + ((d < 32) ? (b.m >> d) : 0);
4892  int i = (m & 0xFFFFFFFF) < a.m;
4893  return f31(((m + i) >> i) | 0x80000000, a.exp + i);
4894  }
4895 
4900  friend f31 operator-(f31 a, f31 b)
4901  {
4902  int d = a.exp - b.exp, exp = a.exp;
4903  uint32 m = a.m - ((d < 32) ? (b.m >> d) : 0);
4904  if (!m)
4905  return f31(0, -32);
4906  for (; m < 0x80000000; m <<= 1, --exp)
4907  ;
4908  return f31(m, exp);
4909  }
4910 
4915  friend f31 operator*(f31 a, f31 b)
4916  {
4917  uint32 m = multiply64(a.m, b.m);
4918  int i = m >> 31;
4919  return f31(m << (1 - i), a.exp + b.exp + i);
4920  }
4921 
4926  friend f31 operator/(f31 a, f31 b)
4927  {
4928  int i = a.m >= b.m, s;
4929  uint32 m = divide64((a.m + i) >> i, b.m, s);
4930  return f31(m, a.exp - b.exp + i - 1);
4931  }
4932 
4933  uint32 m;
4934  int exp;
4935 };
4936 
4947 template <std::float_round_style R, bool C>
4948 unsigned int erf(unsigned int arg)
4950  unsigned int abs = arg & 0x7FFF, sign = arg & 0x8000;
4951  f31 x(abs), x2 = x * x * f31(0xB8AA3B29, 0), t = f31(0x80000000, 0) / (f31(0x80000000, 0) + f31(0xA7BA054A, -2) * x), t2 = t * t;
4952  f31 e = ((f31(0x87DC2213, 0) * t2 + f31(0xB5F0E2AE, 0)) * t2 + f31(0x82790637, -2) - (f31(0xBA00E2B8, 0) * t2 + f31(0x91A98E62, -2)) * t) * t /
4953  ((x2.exp < 0) ? f31(exp2((x2.exp > -32) ? (x2.m >> -x2.exp) : 0, 30), 0) : f31(exp2((x2.m << x2.exp) & 0x7FFFFFFF, 22), x2.m >> (31 - x2.exp)));
4954  return (!C || sign) ? fixed2half<R, 31, false, true, true>(0x80000000 - (e.m >> (C - e.exp)), 14 + C, sign & (C - 1U)) : (e.exp < -25) ? underflow<R>()
4955  : fixed2half<R, 30, false, false, true>(e.m >> 1, e.exp + 14, 0, e.m & 1);
4956 }
4957 
4967 template <std::float_round_style R, bool L>
4968 unsigned int gamma(unsigned int arg)
4970  /* static const double p[] ={ 2.50662827563479526904, 225.525584619175212544, -268.295973841304927459, 80.9030806934622512966, -5.00757863970517583837, 0.0114684895434781459556 };
4971  double t = arg + 4.65, s = p[0];
4972  for(unsigned int i=0; i<5; ++i)
4973  s += p[i+1] / (arg+i);
4974  return std::log(s) + (arg-0.5)*std::log(t) - t;
4975  */
4976  static const f31 pi(0xC90FDAA2, 1), lbe(0xB8AA3B29, 0);
4977  unsigned int abs = arg & 0x7FFF, sign = arg & 0x8000;
4978  bool bsign = sign != 0;
4979  f31 z(abs), x = sign ? (z + f31(0x80000000, 0)) : z, t = x + f31(0x94CCCCCD, 2), s = f31(0xA06C9901, 1) + f31(0xBBE654E2, -7) / (x + f31(0x80000000, 2)) + f31(0xA1CE6098, 6) / (x + f31(0x80000000, 1)) + f31(0xE1868CB7, 7) / x - f31(0x8625E279, 8) / (x + f31(0x80000000, 0)) - f31(0xA03E158F, 2) / (x + f31(0xC0000000, 1));
4980  int i = (s.exp >= 2) + (s.exp >= 4) + (s.exp >= 8) + (s.exp >= 16);
4981  s = f31((static_cast<uint32>(s.exp) << (31 - i)) + (log2(s.m >> 1, 28) >> i), i) / lbe;
4982  if (x.exp != -1 || x.m != 0x80000000)
4983  {
4984  i = (t.exp >= 2) + (t.exp >= 4) + (t.exp >= 8);
4985  f31 l = f31((static_cast<uint32>(t.exp) << (31 - i)) + (log2(t.m >> 1, 30) >> i), i) / lbe;
4986  s = (x.exp < -1) ? (s - (f31(0x80000000, -1) - x) * l) : (s + (x - f31(0x80000000, -1)) * l);
4987  }
4988  s = x.exp ? (s - t) : (t - s);
4989  if (bsign)
4990  {
4991  if (z.exp >= 0)
4992  {
4993  sign &= (L | ((z.m >> (31 - z.exp)) & 1)) - 1;
4994  for (z = f31((z.m << (1 + z.exp)) & 0xFFFFFFFF, -1); z.m < 0x80000000; z.m <<= 1, --z.exp)
4995  ;
4996  }
4997  if (z.exp == -1)
4998  z = f31(0x80000000, 0) - z;
4999  if (z.exp < -1)
5000  {
5001  z = z * pi;
5002  z.m = sincos(z.m >> (1 - z.exp), 30).first;
5003  for (z.exp = 1; z.m < 0x80000000; z.m <<= 1, --z.exp)
5004  ;
5005  }
5006  else
5007  z = f31(0x80000000, 0);
5008  }
5009  if (L)
5010  {
5011  if (bsign)
5012  {
5013  f31 l(0x92868247, 0);
5014  if (z.exp < 0)
5015  {
5016  uint32 m = log2((z.m + 1) >> 1, 27);
5017  z = f31(-((static_cast<uint32>(z.exp) << 26) + (m >> 5)), 5);
5018  for (; z.m < 0x80000000; z.m <<= 1, --z.exp)
5019  ;
5020  l = l + z / lbe;
5021  }
5022  sign = static_cast<unsigned>(x.exp && (l.exp < s.exp || (l.exp == s.exp && l.m < s.m))) << 15;
5023  s = sign ? (s - l) : x.exp ? (l - s)
5024  : (l + s);
5025  }
5026  else
5027  {
5028  sign = static_cast<unsigned>(x.exp == 0) << 15;
5029  if (s.exp < -24)
5030  return underflow<R>(sign);
5031  if (s.exp > 15)
5032  return overflow<R>(sign);
5033  }
5034  }
5035  else
5036  {
5037  s = s * lbe;
5038  uint32 m;
5039  if (s.exp < 0)
5040  {
5041  m = s.m >> -s.exp;
5042  s.exp = 0;
5043  }
5044  else
5045  {
5046  m = (s.m << s.exp) & 0x7FFFFFFF;
5047  s.exp = (s.m >> (31 - s.exp));
5048  }
5049  s.m = exp2(m, 27);
5050  if (!x.exp)
5051  s = f31(0x80000000, 0) / s;
5052  if (bsign)
5053  {
5054  if (z.exp < 0)
5055  s = s * z;
5056  s = pi / s;
5057  if (s.exp < -24)
5058  return underflow<R>(sign);
5059  }
5060  else if (z.exp > 0 && !(z.m & ((1 << (31 - z.exp)) - 1)))
5061  return ((s.exp + 14) << 10) + (s.m >> 21);
5062  if (s.exp > 15)
5063  return overflow<R>(sign);
5064  }
5065  return fixed2half<R, 31, false, false, true>(s.m, s.exp + 14, sign);
5066 }
5068 
5069 template <typename, typename, std::float_round_style>
5070 struct half_caster;
5071 } // namespace detail
5072 
5090 class half
5091 {
5092 public:
5095 
5100  {
5101  }
5102 
5106  explicit half(float rhs)
5107  : data_(static_cast<detail::uint16>(detail::float2half<round_style>(rhs)))
5108  {
5109  }
5110 
5113  operator float() const
5114  {
5115  return detail::half2float<float>(data_);
5116  }
5117 
5122  half& operator=(float rhs)
5123  {
5124  data_ = static_cast<detail::uint16>(detail::float2half<round_style>(rhs));
5125  return *this;
5126  }
5127 
5131 
5138  {
5139  return *this = *this + rhs;
5140  }
5141 
5148  {
5149  return *this = *this - rhs;
5150  }
5151 
5158  {
5159  return *this = *this * rhs;
5160  }
5161 
5168  {
5169  return *this = *this / rhs;
5170  }
5171 
5176  half& operator+=(float rhs)
5177  {
5178  return *this = *this + rhs;
5179  }
5180 
5185  half& operator-=(float rhs)
5186  {
5187  return *this = *this - rhs;
5188  }
5189 
5194  half& operator*=(float rhs)
5195  {
5196  return *this = *this * rhs;
5197  }
5198 
5203  half& operator/=(float rhs)
5204  {
5205  return *this = *this / rhs;
5206  }
5207 
5211 
5216  {
5217  return *this = *this + half(detail::binary, 0x3C00);
5218  }
5219 
5224  {
5225  return *this = *this + half(detail::binary, 0xBC00);
5226  }
5227 
5232  {
5233  half out(*this);
5234  ++*this;
5235  return out;
5236  }
5237 
5242  {
5243  half out(*this);
5244  --*this;
5245  return out;
5246  }
5248 
5249 private:
5251  static const std::float_round_style round_style = (std::float_round_style)(HALF_ROUND_STYLE);
5252 
5255  HALF_CONSTEXPR half(detail::binary_t, unsigned int bits) HALF_NOEXCEPT : data_(static_cast<detail::uint16>(bits))
5256  {
5257  }
5258 
5260  detail::uint16 data_;
5261 
5262 #ifndef HALF_DOXYGEN_ONLY
5263  friend HALF_CONSTEXPR_NOERR bool operator==(half, half);
5264  friend HALF_CONSTEXPR_NOERR bool operator!=(half, half);
5265  friend HALF_CONSTEXPR_NOERR bool operator<(half, half);
5266  friend HALF_CONSTEXPR_NOERR bool operator>(half, half);
5267  friend HALF_CONSTEXPR_NOERR bool operator<=(half, half);
5268  friend HALF_CONSTEXPR_NOERR bool operator>=(half, half);
5270  friend half operator+(half, half);
5271  friend half operator-(half, half);
5272  friend half operator*(half, half);
5273  friend half operator/(half, half);
5274 
5275  // ERASED
5276  // template<typename charT,typename traits> friend std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT,traits>&, half);
5277  // template<typename charT,typename traits> friend std::basic_istream<charT,traits>& operator>>(std::basic_istream<charT,traits>&, half&);
5278  friend HALF_CONSTEXPR half fabs(half);
5279  friend half fmod(half, half);
5280  friend half remainder(half, half);
5281  friend half remquo(half, half, int*);
5282  friend half fma(half, half, half);
5285  friend half fdim(half, half);
5286  friend half nanh(const char*);
5287  friend half exp(half);
5288  friend half exp2(half);
5289  friend half expm1(half);
5290  friend half log(half);
5291  friend half log10(half);
5292  friend half log2(half);
5293  friend half log1p(half);
5294  friend half sqrt(half);
5295  friend half rsqrt(half);
5296  friend half cbrt(half);
5297  friend half hypot(half, half);
5298  friend half hypot(half, half, half);
5299  friend half pow(half, half);
5300  friend void sincos(half, half*, half*);
5301  friend half sin(half);
5302  friend half cos(half);
5303  friend half tan(half);
5304  friend half asin(half);
5305  friend half acos(half);
5306  friend half atan(half);
5307  friend half atan2(half, half);
5308  friend half sinh(half);
5309  friend half cosh(half);
5310  friend half tanh(half);
5311  friend half asinh(half);
5312  friend half acosh(half);
5313  friend half atanh(half);
5314  friend half erf(half);
5315  friend half erfc(half);
5316  friend half lgamma(half);
5317  friend half tgamma(half);
5318  friend half ceil(half);
5319  friend half floor(half);
5320  friend half trunc(half);
5321  friend half round(half);
5322  friend long lround(half);
5323  friend half rint(half);
5324  friend long lrint(half);
5325  friend half nearbyint(half);
5326 #ifdef HALF_ENABLE_CPP11_LONG_LONG
5327  friend long long llround(half);
5328  friend long long llrint(half);
5329 #endif
5330  friend half frexp(half, int*);
5331  friend half scalbln(half, long);
5332  friend half modf(half, half*);
5333  friend int ilogb(half);
5334  friend half logb(half);
5335  friend half nextafter(half, half);
5336  friend half nexttoward(half, long double);
5338  friend HALF_CONSTEXPR int fpclassify(half);
5339  friend HALF_CONSTEXPR bool isfinite(half);
5340  friend HALF_CONSTEXPR bool isinf(half);
5341  friend HALF_CONSTEXPR bool isnan(half);
5342  friend HALF_CONSTEXPR bool isnormal(half);
5343  friend HALF_CONSTEXPR bool signbit(half);
5344  friend HALF_CONSTEXPR bool isgreater(half, half);
5345  friend HALF_CONSTEXPR bool isgreaterequal(half, half);
5346  friend HALF_CONSTEXPR bool isless(half, half);
5347  friend HALF_CONSTEXPR bool islessequal(half, half);
5348  friend HALF_CONSTEXPR bool islessgreater(half, half);
5349  template <typename, typename, std::float_round_style>
5350  friend struct detail::half_caster;
5351  friend class std::numeric_limits<half>;
5352 #if HALF_ENABLE_CPP11_HASH
5353  friend struct std::hash<half>;
5354 #endif
5355 #if HALF_ENABLE_CPP11_USER_LITERALS
5356  friend half literal::operator"" _h(long double);
5357 #endif
5358 #endif
5359 };
5360 
5361 #if HALF_ENABLE_CPP11_USER_LITERALS
5362 namespace literal
5363 {
5371 inline half operator"" _h(long double value)
5372 {
5373  return half(detail::binary, detail::float2half<half::round_style>(value));
5374 }
5375 } // namespace literal
5376 #endif
5377 
5378 namespace detail
5379 {
5386 template <typename T, typename U, std::float_round_style R = (std::float_round_style)(HALF_ROUND_STYLE)>
5388 {
5389 };
5390 template <typename U, std::float_round_style R>
5391 struct half_caster<half, U, R>
5392 {
5393 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
5394  static_assert(std::is_arithmetic<U>::value, "half_cast from non-arithmetic type unsupported");
5395 #endif
5396 
5397  static half cast(U arg)
5398  {
5399  return cast_impl(arg, is_float<U>());
5400  };
5401 
5402 private:
5403  static half cast_impl(U arg, true_type)
5404  {
5405  return half(binary, float2half<R>(arg));
5406  }
5407  static half cast_impl(U arg, false_type)
5408  {
5409  return half(binary, int2half<R>(arg));
5410  }
5411 };
5412 template <typename T, std::float_round_style R>
5413 struct half_caster<T, half, R>
5414 {
5415 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
5416  static_assert(std::is_arithmetic<T>::value, "half_cast to non-arithmetic type unsupported");
5417 #endif
5418 
5419  static T cast(half arg)
5420  {
5421  return cast_impl(arg, is_float<T>());
5422  }
5423 
5424 private:
5425  static T cast_impl(half arg, true_type)
5426  {
5427  return half2float<T>(arg.data_);
5428  }
5429  static T cast_impl(half arg, false_type)
5430  {
5431  return half2int<R, true, true, T>(arg.data_);
5432  }
5433 };
5434 template <std::float_round_style R>
5435 struct half_caster<half, half, R>
5436 {
5437  static half cast(half arg)
5438  {
5439  return arg;
5440  }
5441 };
5442 } // namespace detail
5443 } // namespace half_float
5444 
5446 namespace std
5447 {
5450 template <>
5451 class numeric_limits<half_float::half>
5452 {
5453 public:
5455  static HALF_CONSTEXPR_CONST bool is_specialized = true;
5456 
5458  static HALF_CONSTEXPR_CONST bool is_signed = true;
5459 
5461  static HALF_CONSTEXPR_CONST bool is_integer = false;
5462 
5464  static HALF_CONSTEXPR_CONST bool is_exact = false;
5465 
5467  static HALF_CONSTEXPR_CONST bool is_modulo = false;
5468 
5470  static HALF_CONSTEXPR_CONST bool is_bounded = true;
5471 
5473  static HALF_CONSTEXPR_CONST bool is_iec559 = true;
5474 
5476  static HALF_CONSTEXPR_CONST bool has_infinity = true;
5477 
5479  static HALF_CONSTEXPR_CONST bool has_quiet_NaN = true;
5480 
5482  static HALF_CONSTEXPR_CONST bool has_signaling_NaN = true;
5483 
5485  static HALF_CONSTEXPR_CONST float_denorm_style has_denorm = denorm_present;
5486 
5488  static HALF_CONSTEXPR_CONST bool has_denorm_loss = false;
5489 
5490 #if HALF_ERRHANDLING_THROWS
5491  static HALF_CONSTEXPR_CONST bool traps = true;
5492 #else
5494  static HALF_CONSTEXPR_CONST bool traps = false;
5495 #endif
5496 
5498  static HALF_CONSTEXPR_CONST bool tinyness_before = false;
5499 
5501  static HALF_CONSTEXPR_CONST float_round_style round_style = half_float::half::round_style;
5502 
5504  static HALF_CONSTEXPR_CONST int digits = 11;
5505 
5507  static HALF_CONSTEXPR_CONST int digits10 = 3;
5508 
5510  static HALF_CONSTEXPR_CONST int max_digits10 = 5;
5511 
5513  static HALF_CONSTEXPR_CONST int radix = 2;
5514 
5516  static HALF_CONSTEXPR_CONST int min_exponent = -13;
5517 
5519  static HALF_CONSTEXPR_CONST int min_exponent10 = -4;
5520 
5522  static HALF_CONSTEXPR_CONST int max_exponent = 16;
5523 
5525  static HALF_CONSTEXPR_CONST int max_exponent10 = 4;
5526 
5529  {
5531  }
5532 
5535  {
5537  }
5538 
5541  {
5543  }
5544 
5547  {
5549  }
5550 
5553  {
5554  return half_float::half(half_float::detail::binary, (round_style == std::round_to_nearest) ? 0x3800 : 0x3C00);
5555  }
5556 
5559  {
5561  }
5562 
5565  {
5567  }
5568 
5571  {
5573  }
5574 
5577  {
5579  }
5580 };
5581 
5582 #if HALF_ENABLE_CPP11_HASH
5587 template <>
5588 struct hash<half_float::half>
5589 {
5591  typedef half_float::half argument_type;
5592 
5594  typedef size_t result_type;
5595 
5599  result_type operator()(argument_type arg) const
5600  {
5601  return hash<half_float::detail::uint16>()(arg.data_ & -static_cast<unsigned>(arg.data_ != 0x8000));
5602  }
5603 };
5604 #endif
5605 } // namespace std
5606 
5607 namespace half_float
5608 {
5612 
5620 {
5621  return !detail::compsignal(x.data_, y.data_) && (x.data_ == y.data_ || !((x.data_ | y.data_) & 0x7FFF));
5622 }
5623 
5631 {
5632  return detail::compsignal(x.data_, y.data_) || (x.data_ != y.data_ && ((x.data_ | y.data_) & 0x7FFF));
5633 }
5634 
5642 {
5643  return !detail::compsignal(x.data_, y.data_) &&
5644  ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) < ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15));
5645 }
5646 
5654 {
5655  return !detail::compsignal(x.data_, y.data_) &&
5656  ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) > ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15));
5657 }
5658 
5666 {
5667  return !detail::compsignal(x.data_, y.data_) &&
5668  ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) <= ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15));
5669 }
5670 
5678 {
5679  return !detail::compsignal(x.data_, y.data_) &&
5680  ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) >= ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15));
5681 }
5682 
5687 
5692 {
5693  return arg;
5694 }
5695 
5700 {
5701  return half(detail::binary, arg.data_ ^ 0x8000);
5702 }
5703 
5711 inline half operator+(half x, half y)
5712 {
5713 #ifdef HALF_ARITHMETIC_TYPE
5714  return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_) + detail::half2float<detail::internal_t>(y.data_)));
5715 #else
5716  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF;
5717  bool sub = ((x.data_ ^ y.data_) & 0x8000) != 0;
5718  if (absx >= 0x7C00 || absy >= 0x7C00)
5719  return half(detail::binary, (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_) : (absy != 0x7C00) ? x.data_
5720  : (sub && absx == 0x7C00) ? detail::invalid()
5721  : y.data_);
5722  if (!absx)
5723  return absy ? y : half(detail::binary, (half::round_style == std::round_toward_neg_infinity) ? (x.data_ | y.data_) : (x.data_ & y.data_));
5724  if (!absy)
5725  return x;
5726  unsigned int sign = ((sub && absy > absx) ? y.data_ : x.data_) & 0x8000;
5727  if (absy > absx)
5728  std::swap(absx, absy);
5729  int exp = (absx >> 10) + (absx <= 0x3FF), d = exp - (absy >> 10) - (absy <= 0x3FF), mx = ((absx & 0x3FF) | ((absx > 0x3FF) << 10)) << 3, my;
5730  if (d < 13)
5731  {
5732  my = ((absy & 0x3FF) | ((absy > 0x3FF) << 10)) << 3;
5733  my = (my >> d) | ((my & ((1 << d) - 1)) != 0);
5734  }
5735  else
5736  my = 1;
5737  if (sub)
5738  {
5739  if (!(mx -= my))
5740  return half(detail::binary, static_cast<unsigned>(half::round_style == std::round_toward_neg_infinity) << 15);
5741  for (; mx < 0x2000 && exp > 1; mx <<= 1, --exp)
5742  ;
5743  }
5744  else
5745  {
5746  mx += my;
5747  int i = mx >> 14;
5748  if ((exp += i) > 30)
5749  return half(detail::binary, detail::overflow<half::round_style>(sign));
5750  mx = (mx >> i) | (mx & i);
5751  }
5752  return half(detail::binary, detail::rounded<half::round_style, false>(sign + ((exp - 1) << 10) + (mx >> 3), (mx >> 2) & 1, (mx & 0x3) != 0));
5753 #endif
5754 }
5755 
5763 inline half operator-(half x, half y)
5764 {
5765 #ifdef HALF_ARITHMETIC_TYPE
5766  return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_) - detail::half2float<detail::internal_t>(y.data_)));
5767 #else
5768  return x + -y;
5769 #endif
5770 }
5771 
5779 inline half operator*(half x, half y)
5780 {
5781 #ifdef HALF_ARITHMETIC_TYPE
5782  return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_) * detail::half2float<detail::internal_t>(y.data_)));
5783 #else
5784  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -16;
5785  unsigned int sign = (x.data_ ^ y.data_) & 0x8000;
5786  if (absx >= 0x7C00 || absy >= 0x7C00)
5787  return half(detail::binary, (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_) : ((absx == 0x7C00 && !absy) || (absy == 0x7C00 && !absx)) ? detail::invalid()
5788  : (sign | 0x7C00));
5789  if (!absx || !absy)
5790  return half(detail::binary, sign);
5791  for (; absx < 0x400; absx <<= 1, --exp)
5792  ;
5793  for (; absy < 0x400; absy <<= 1, --exp)
5794  ;
5795  detail::uint32 m = static_cast<detail::uint32>((absx & 0x3FF) | 0x400) * static_cast<detail::uint32>((absy & 0x3FF) | 0x400);
5796  int i = m >> 21, s = m & i;
5797  exp += (absx >> 10) + (absy >> 10) + i;
5798  if (exp > 29)
5799  return half(detail::binary, detail::overflow<half::round_style>(sign));
5800  else if (exp < -11)
5801  return half(detail::binary, detail::underflow<half::round_style>(sign));
5802  return half(detail::binary, detail::fixed2half<half::round_style, 20, false, false, false>(m >> i, exp, sign, s));
5803 #endif
5804 }
5805 
5814 inline half operator/(half x, half y)
5815 {
5816 #ifdef HALF_ARITHMETIC_TYPE
5817  return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_) / detail::half2float<detail::internal_t>(y.data_)));
5818 #else
5819  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = 14;
5820  unsigned int sign = (x.data_ ^ y.data_) & 0x8000;
5821  if (absx >= 0x7C00 || absy >= 0x7C00)
5822  return half(detail::binary, (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_) : (absx == absy) ? detail::invalid()
5823  : (sign | ((absx == 0x7C00) ? 0x7C00 : 0)));
5824  if (!absx)
5825  return half(detail::binary, absy ? sign : detail::invalid());
5826  if (!absy)
5827  return half(detail::binary, detail::pole(sign));
5828  for (; absx < 0x400; absx <<= 1, --exp)
5829  ;
5830  for (; absy < 0x400; absy <<= 1, ++exp)
5831  ;
5832  detail::uint32 mx = (absx & 0x3FF) | 0x400, my = (absy & 0x3FF) | 0x400;
5833  int i = mx < my;
5834  exp += (absx >> 10) - (absy >> 10) - i;
5835  if (exp > 29)
5836  return half(detail::binary, detail::overflow<half::round_style>(sign));
5837  else if (exp < -11)
5838  return half(detail::binary, detail::underflow<half::round_style>(sign));
5839  mx <<= 12 + i;
5840  my <<= 1;
5841  return half(detail::binary, detail::fixed2half<half::round_style, 11, false, false, false>(mx / my, exp, sign, mx % my != 0));
5842 #endif
5843 }
5844 
5849 
5850 // ERASED
5856 // template<typename charT,typename traits> std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT,traits> &out, half arg)
5857 //{
5858 // #ifdef HALF_ARITHMETIC_TYPE
5859 // return out << detail::half2float<detail::internal_t>(arg.data_);
5860 // #else
5861 // return out << detail::half2float<float>(arg.data_);
5862 // #endif
5863 // }
5864 
5865 // ERASED
5875 // template<typename charT,typename traits> std::basic_istream<charT,traits>& operator>>(std::basic_istream<charT,traits> &in, half &arg)
5876 //{
5877 // #ifdef HALF_ARITHMETIC_TYPE
5878 // detail::internal_t f;
5879 // #else
5880 // double f;
5881 // #endif
5882 // if(in >> f)
5883 // arg.data_ = detail::float2half<half::round_style>(f);
5884 // return in;
5885 // }
5886 
5891 
5897 {
5898  return half(detail::binary, arg.data_ & 0x7FFF);
5899 }
5900 
5906 {
5907  return fabs(arg);
5908 }
5909 
5916 inline half fmod(half x, half y)
5917 {
5918  unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000;
5919  if (absx >= 0x7C00 || absy >= 0x7C00)
5920  return half(detail::binary, (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_) : (absx == 0x7C00) ? detail::invalid()
5921  : x.data_);
5922  if (!absy)
5923  return half(detail::binary, detail::invalid());
5924  if (!absx)
5925  return x;
5926  if (absx == absy)
5927  return half(detail::binary, sign);
5928  return half(detail::binary, sign | detail::mod<false, false>(absx, absy));
5929 }
5930 
5937 inline half remainder(half x, half y)
5938 {
5939  unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000;
5940  if (absx >= 0x7C00 || absy >= 0x7C00)
5941  return half(detail::binary, (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_) : (absx == 0x7C00) ? detail::invalid()
5942  : x.data_);
5943  if (!absy)
5944  return half(detail::binary, detail::invalid());
5945  if (absx == absy)
5946  return half(detail::binary, sign);
5947  return half(detail::binary, sign ^ detail::mod<false, true>(absx, absy));
5948 }
5949 
5957 inline half remquo(half x, half y, int* quo)
5958 {
5959  unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, value = x.data_ & 0x8000;
5960  if (absx >= 0x7C00 || absy >= 0x7C00)
5961  return half(detail::binary, (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_) : (absx == 0x7C00) ? detail::invalid()
5962  : (*quo = 0, x.data_));
5963  if (!absy)
5964  return half(detail::binary, detail::invalid());
5965  bool qsign = ((value ^ y.data_) & 0x8000) != 0;
5966  int q = 1;
5967  if (absx != absy)
5968  value ^= detail::mod<true, true>(absx, absy, &q);
5969  return *quo = qsign ? -q : q, half(detail::binary, value);
5970 }
5971 
5982 inline half fma(half x, half y, half z)
5983 {
5984 #ifdef HALF_ARITHMETIC_TYPE
5985  detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_), fz = detail::half2float<detail::internal_t>(z.data_);
5986 #if HALF_ENABLE_CPP11_CMATH && FP_FAST_FMA
5987  return half(detail::binary, detail::float2half<half::round_style>(std::fma(fx, fy, fz)));
5988 #else
5989  return half(detail::binary, detail::float2half<half::round_style>(fx * fy + fz));
5990 #endif
5991 #else
5992  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, exp = -15;
5993  unsigned int sign = (x.data_ ^ y.data_) & 0x8000;
5994  bool sub = ((sign ^ z.data_) & 0x8000) != 0;
5995  if (absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
5996  return (absx > 0x7C00 || absy > 0x7C00 || absz > 0x7C00) ? half(detail::binary, detail::signal(x.data_, y.data_, z.data_)) : (absx == 0x7C00) ? half(detail::binary, (!absy || (sub && absz == 0x7C00)) ? detail::invalid() : (sign | 0x7C00))
5997  : (absy == 0x7C00) ? half(detail::binary, (!absx || (sub && absz == 0x7C00)) ? detail::invalid() : (sign | 0x7C00))
5998  : z;
5999  if (!absx || !absy)
6000  return absz ? z : half(detail::binary, (half::round_style == std::round_toward_neg_infinity) ? (z.data_ | sign) : (z.data_ & sign));
6001  for (; absx < 0x400; absx <<= 1, --exp)
6002  ;
6003  for (; absy < 0x400; absy <<= 1, --exp)
6004  ;
6005  detail::uint32 m = static_cast<detail::uint32>((absx & 0x3FF) | 0x400) * static_cast<detail::uint32>((absy & 0x3FF) | 0x400);
6006  int i = m >> 21;
6007  exp += (absx >> 10) + (absy >> 10) + i;
6008  m <<= 3 - i;
6009  if (absz)
6010  {
6011  int expz = 0;
6012  for (; absz < 0x400; absz <<= 1, --expz)
6013  ;
6014  expz += absz >> 10;
6015  detail::uint32 mz = static_cast<detail::uint32>((absz & 0x3FF) | 0x400) << 13;
6016  if (expz > exp || (expz == exp && mz > m))
6017  {
6018  std::swap(m, mz);
6019  std::swap(exp, expz);
6020  if (sub)
6021  sign = z.data_ & 0x8000;
6022  }
6023  int d = exp - expz;
6024  mz = (d < 23) ? ((mz >> d) | ((mz & ((static_cast<detail::uint32>(1) << d) - 1)) != 0)) : 1;
6025  if (sub)
6026  {
6027  m = m - mz;
6028  if (!m)
6029  return half(detail::binary, static_cast<unsigned>(half::round_style == std::round_toward_neg_infinity) << 15);
6030  for (; m < 0x800000; m <<= 1, --exp)
6031  ;
6032  }
6033  else
6034  {
6035  m += mz;
6036  i = m >> 24;
6037  m = (m >> i) | (m & i);
6038  exp += i;
6039  }
6040  }
6041  if (exp > 30)
6042  return half(detail::binary, detail::overflow<half::round_style>(sign));
6043  else if (exp < -10)
6044  return half(detail::binary, detail::underflow<half::round_style>(sign));
6045  return half(detail::binary, detail::fixed2half<half::round_style, 23, false, false, false>(m, exp - 1, sign));
6046 #endif
6047 }
6048 
6056 {
6057  return half(detail::binary, (!isnan(y) && (isnan(x) || (x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) < (y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))))) ? detail::select(y.data_, x.data_) : detail::select(x.data_, y.data_));
6058 }
6059 
6067 {
6068  return half(detail::binary, (!isnan(y) && (isnan(x) || (x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) > (y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))))) ? detail::select(y.data_, x.data_) : detail::select(x.data_, y.data_));
6069 }
6070 
6079 inline half fdim(half x, half y)
6080 {
6081  if (isnan(x) || isnan(y))
6082  return half(detail::binary, detail::signal(x.data_, y.data_));
6083  return (x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) <= (y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) ? half(detail::binary, 0) : (x - y);
6084 }
6085 
6090 inline half nanh(const char* arg)
6091 {
6092  unsigned int value = 0x7FFF;
6093  while (*arg)
6094  value ^= static_cast<unsigned>(*arg++) & 0xFF;
6095  return half(detail::binary, value);
6096 }
6097 
6102 
6111 inline half exp(half arg)
6112 {
6113 #ifdef HALF_ARITHMETIC_TYPE
6114  return half(detail::binary, detail::float2half<half::round_style>(std::exp(detail::half2float<detail::internal_t>(arg.data_))));
6115 #else
6116  int abs = arg.data_ & 0x7FFF, e = (abs >> 10) + (abs <= 0x3FF), exp;
6117  if (!abs)
6118  return half(detail::binary, 0x3C00);
6119  if (abs >= 0x7C00)
6120  return half(detail::binary, (abs == 0x7C00) ? (0x7C00 & ((arg.data_ >> 15) - 1U)) : detail::signal(arg.data_));
6121  if (abs >= 0x4C80)
6122  return half(detail::binary, (arg.data_ & 0x8000) ? detail::underflow<half::round_style>() : detail::overflow<half::round_style>());
6123  detail::uint32 m = detail::multiply64(static_cast<detail::uint32>((abs & 0x3FF) + ((abs > 0x3FF) << 10)) << 21, 0xB8AA3B29);
6124  if (e < 14)
6125  {
6126  exp = 0;
6127  m >>= 14 - e;
6128  }
6129  else
6130  {
6131  exp = m >> (45 - e);
6132  m = (m << (e - 14)) & 0x7FFFFFFF;
6133  }
6134  return half(detail::binary, detail::exp2_post<half::round_style>(m, exp, (arg.data_ & 0x8000) != 0, 0, 26));
6135 #endif
6136 }
6137 
6146 inline half exp2(half arg)
6147 {
6148 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
6149  return half(detail::binary, detail::float2half<half::round_style>(std::exp2(detail::half2float<detail::internal_t>(arg.data_))));
6150 #else
6151  int abs = arg.data_ & 0x7FFF, e = (abs >> 10) + (abs <= 0x3FF), exp = (abs & 0x3FF) + ((abs > 0x3FF) << 10);
6152  if (!abs)
6153  return half(detail::binary, 0x3C00);
6154  if (abs >= 0x7C00)
6155  return half(detail::binary, (abs == 0x7C00) ? (0x7C00 & ((arg.data_ >> 15) - 1U)) : detail::signal(arg.data_));
6156  if (abs >= 0x4E40)
6157  return half(detail::binary, (arg.data_ & 0x8000) ? detail::underflow<half::round_style>() : detail::overflow<half::round_style>());
6158  return half(detail::binary, detail::exp2_post<half::round_style>((static_cast<detail::uint32>(exp) << (6 + e)) & 0x7FFFFFFF, exp >> (25 - e), (arg.data_ & 0x8000) != 0, 0, 28));
6159 #endif
6160 }
6161 
6171 inline half expm1(half arg)
6172 {
6173 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
6174  return half(detail::binary, detail::float2half<half::round_style>(std::expm1(detail::half2float<detail::internal_t>(arg.data_))));
6175 #else
6176  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000, e = (abs >> 10) + (abs <= 0x3FF), exp;
6177  if (!abs)
6178  return arg;
6179  if (abs >= 0x7C00)
6180  return half(detail::binary, (abs == 0x7C00) ? (0x7C00 + (sign >> 1)) : detail::signal(arg.data_));
6181  if (abs >= 0x4A00)
6182  return half(detail::binary, (arg.data_ & 0x8000) ? detail::rounded<half::round_style, true>(0xBBFF, 1, 1) : detail::overflow<half::round_style>());
6183  detail::uint32 m = detail::multiply64(static_cast<detail::uint32>((abs & 0x3FF) + ((abs > 0x3FF) << 10)) << 21, 0xB8AA3B29);
6184  if (e < 14)
6185  {
6186  exp = 0;
6187  m >>= 14 - e;
6188  }
6189  else
6190  {
6191  exp = m >> (45 - e);
6192  m = (m << (e - 14)) & 0x7FFFFFFF;
6193  }
6194  m = detail::exp2(m);
6195  if (sign)
6196  {
6197  int s = 0;
6198  if (m > 0x80000000)
6199  {
6200  ++exp;
6201  m = detail::divide64(0x80000000, m, s);
6202  }
6203  m = 0x80000000 - ((m >> exp) | ((m & ((static_cast<detail::uint32>(1) << exp) - 1)) != 0) | s);
6204  exp = 0;
6205  }
6206  else
6207  m -= (exp < 31) ? (0x80000000 >> exp) : 1;
6208  for (exp += 14; m < 0x80000000 && exp; m <<= 1, --exp)
6209  ;
6210  if (exp > 29)
6211  return half(detail::binary, detail::overflow<half::round_style>());
6212  return half(detail::binary, detail::rounded<half::round_style, true>(sign + (exp << 10) + (m >> 21), (m >> 20) & 1, (m & 0xFFFFF) != 0));
6213 #endif
6214 }
6215 
6225 inline half log(half arg)
6226 {
6227 #ifdef HALF_ARITHMETIC_TYPE
6228  return half(detail::binary, detail::float2half<half::round_style>(std::log(detail::half2float<detail::internal_t>(arg.data_))));
6229 #else
6230  int abs = arg.data_ & 0x7FFF, exp = -15;
6231  if (!abs)
6232  return half(detail::binary, detail::pole(0x8000));
6233  if (arg.data_ & 0x8000)
6234  return half(detail::binary, (arg.data_ <= 0xFC00) ? detail::invalid() : detail::signal(arg.data_));
6235  if (abs >= 0x7C00)
6236  return (abs == 0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
6237  for (; abs < 0x400; abs <<= 1, --exp)
6238  ;
6239  exp += abs >> 10;
6240  return half(detail::binary, detail::log2_post<half::round_style, 0xB8AA3B2A>(detail::log2(static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 20, 27) + 8, exp, 17));
6241 #endif
6242 }
6243 
6253 inline half log10(half arg)
6254 {
6255 #ifdef HALF_ARITHMETIC_TYPE
6256  return half(detail::binary, detail::float2half<half::round_style>(std::log10(detail::half2float<detail::internal_t>(arg.data_))));
6257 #else
6258  int abs = arg.data_ & 0x7FFF, exp = -15;
6259  if (!abs)
6260  return half(detail::binary, detail::pole(0x8000));
6261  if (arg.data_ & 0x8000)
6262  return half(detail::binary, (arg.data_ <= 0xFC00) ? detail::invalid() : detail::signal(arg.data_));
6263  if (abs >= 0x7C00)
6264  return (abs == 0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
6265  switch (abs)
6266  {
6267  case 0x4900:
6268  return half(detail::binary, 0x3C00);
6269  case 0x5640:
6270  return half(detail::binary, 0x4000);
6271  case 0x63D0:
6272  return half(detail::binary, 0x4200);
6273  case 0x70E2:
6274  return half(detail::binary, 0x4400);
6275  }
6276  for (; abs < 0x400; abs <<= 1, --exp)
6277  ;
6278  exp += abs >> 10;
6279  return half(detail::binary, detail::log2_post<half::round_style, 0xD49A784C>(detail::log2(static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 20, 27) + 8, exp, 16));
6280 #endif
6281 }
6282 
6292 inline half log2(half arg)
6293 {
6294 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
6295  return half(detail::binary, detail::float2half<half::round_style>(std::log2(detail::half2float<detail::internal_t>(arg.data_))));
6296 #else
6297  int abs = arg.data_ & 0x7FFF, exp = -15, s = 0;
6298  if (!abs)
6299  return half(detail::binary, detail::pole(0x8000));
6300  if (arg.data_ & 0x8000)
6301  return half(detail::binary, (arg.data_ <= 0xFC00) ? detail::invalid() : detail::signal(arg.data_));
6302  if (abs >= 0x7C00)
6303  return (abs == 0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
6304  if (abs == 0x3C00)
6305  return half(detail::binary, 0);
6306  for (; abs < 0x400; abs <<= 1, --exp)
6307  ;
6308  exp += (abs >> 10);
6309  if (!(abs & 0x3FF))
6310  {
6311  unsigned int value = static_cast<unsigned>(exp < 0) << 15, m = std::abs(exp) << 6;
6312  for (exp = 18; m < 0x400; m <<= 1, --exp)
6313  ;
6314  return half(detail::binary, value + (exp << 10) + m);
6315  }
6316  detail::uint32 ilog = exp, sign = detail::sign_mask(ilog), m = (((ilog << 27) + (detail::log2(static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 20, 28) >> 4)) ^ sign) - sign;
6317  if (!m)
6318  return half(detail::binary, 0);
6319  for (exp = 14; m < 0x8000000 && exp; m <<= 1, --exp)
6320  ;
6321  for (; m > 0xFFFFFFF; m >>= 1, ++exp)
6322  s |= m & 1;
6323  return half(detail::binary, detail::fixed2half<half::round_style, 27, false, false, true>(m, exp, sign & 0x8000, s));
6324 #endif
6325 }
6326 
6337 inline half log1p(half arg)
6338 {
6339 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
6340  return half(detail::binary, detail::float2half<half::round_style>(std::log1p(detail::half2float<detail::internal_t>(arg.data_))));
6341 #else
6342  if (arg.data_ >= 0xBC00)
6343  return half(detail::binary, (arg.data_ == 0xBC00) ? detail::pole(0x8000) : (arg.data_ <= 0xFC00) ? detail::invalid()
6344  : detail::signal(arg.data_));
6345  int abs = arg.data_ & 0x7FFF, exp = -15;
6346  if (!abs || abs >= 0x7C00)
6347  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
6348  for (; abs < 0x400; abs <<= 1, --exp)
6349  ;
6350  exp += abs >> 10;
6351  detail::uint32 m = static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 20;
6352  if (arg.data_ & 0x8000)
6353  {
6354  m = 0x40000000 - (m >> -exp);
6355  for (exp = 0; m < 0x40000000; m <<= 1, --exp)
6356  ;
6357  }
6358  else
6359  {
6360  if (exp < 0)
6361  {
6362  m = 0x40000000 + (m >> -exp);
6363  exp = 0;
6364  }
6365  else
6366  {
6367  m += 0x40000000 >> exp;
6368  int i = m >> 31;
6369  m >>= i;
6370  exp += i;
6371  }
6372  }
6373  return half(detail::binary, detail::log2_post<half::round_style, 0xB8AA3B2A>(detail::log2(m), exp, 17));
6374 #endif
6375 }
6376 
6381 
6390 inline half sqrt(half arg)
6391 {
6392 #ifdef HALF_ARITHMETIC_TYPE
6393  return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(detail::half2float<detail::internal_t>(arg.data_))));
6394 #else
6395  int abs = arg.data_ & 0x7FFF, exp = 15;
6396  if (!abs || arg.data_ >= 0x7C00)
6397  return half(detail::binary, (abs > 0x7C00) ? detail::signal(arg.data_) : (arg.data_ > 0x8000) ? detail::invalid()
6398  : arg.data_);
6399  for (; abs < 0x400; abs <<= 1, --exp)
6400  ;
6401  detail::uint32 r = static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 10, m = detail::sqrt<20>(r, exp += abs >> 10);
6402  return half(detail::binary, detail::rounded<half::round_style, false>((exp << 10) + (m & 0x3FF), r > m, r != 0));
6403 #endif
6404 }
6405 
6413 inline half rsqrt(half arg)
6414 {
6415 #ifdef HALF_ARITHMETIC_TYPE
6416  return half(detail::binary, detail::float2half<half::round_style>(detail::internal_t(1) / std::sqrt(detail::half2float<detail::internal_t>(arg.data_))));
6417 #else
6418  unsigned int abs = arg.data_ & 0x7FFF, bias = 0x4000;
6419  if (!abs || arg.data_ >= 0x7C00)
6420  return half(detail::binary, (abs > 0x7C00) ? detail::signal(arg.data_) : (arg.data_ > 0x8000) ? detail::invalid()
6421  : !abs ? detail::pole(arg.data_ & 0x8000)
6422  : 0);
6423  for (; abs < 0x400; abs <<= 1, bias -= 0x400)
6424  ;
6425  unsigned int frac = (abs += bias) & 0x7FF;
6426  if (frac == 0x400)
6427  return half(detail::binary, 0x7A00 - (abs >> 1));
6428  if ((half::round_style == std::round_to_nearest && (frac == 0x3FE || frac == 0x76C)) ||
6429  (half::round_style != std::round_to_nearest && (frac == 0x15A || frac == 0x3FC || frac == 0x401 || frac == 0x402 || frac == 0x67B)))
6430  return pow(arg, half(detail::binary, 0xB800));
6431  detail::uint32 f = 0x17376 - abs, mx = (abs & 0x3FF) | 0x400, my = ((f >> 1) & 0x3FF) | 0x400, mz = my * my;
6432  int expy = (f >> 11) - 31, expx = 32 - (abs >> 10), i = mz >> 21;
6433  for (mz = 0x60000000 - (((mz >> i) * mx) >> (expx - 2 * expy - i)); mz < 0x40000000; mz <<= 1, --expy)
6434  ;
6435  i = (my *= mz >> 10) >> 31;
6436  expy += i;
6437  my = (my >> (20 + i)) + 1;
6438  i = (mz = my * my) >> 21;
6439  for (mz = 0x60000000 - (((mz >> i) * mx) >> (expx - 2 * expy - i)); mz < 0x40000000; mz <<= 1, --expy)
6440  ;
6441  i = (my *= (mz >> 10) + 1) >> 31;
6442  return half(detail::binary, detail::fixed2half<half::round_style, 30, false, false, true>(my >> i, expy + i + 14));
6443 #endif
6444 }
6445 
6454 inline half cbrt(half arg)
6455 {
6456 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
6457  return half(detail::binary, detail::float2half<half::round_style>(std::cbrt(detail::half2float<detail::internal_t>(arg.data_))));
6458 #else
6459  int abs = arg.data_ & 0x7FFF, exp = -15;
6460  if (!abs || abs == 0x3C00 || abs >= 0x7C00)
6461  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
6462  for (; abs < 0x400; abs <<= 1, --exp)
6463  ;
6464  detail::uint32 ilog = exp + (abs >> 10), sign = detail::sign_mask(ilog), f, m = (((ilog << 27) + (detail::log2(static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 20, 24) >> 4)) ^ sign) - sign;
6465  for (exp = 2; m < 0x80000000; m <<= 1, --exp)
6466  ;
6467  m = detail::multiply64(m, 0xAAAAAAAB);
6468  int i = m >> 31, s;
6469  exp += i;
6470  m <<= 1 - i;
6471  if (exp < 0)
6472  {
6473  f = m >> -exp;
6474  exp = 0;
6475  }
6476  else
6477  {
6478  f = (m << exp) & 0x7FFFFFFF;
6479  exp = m >> (31 - exp);
6480  }
6481  m = detail::exp2(f, (half::round_style == std::round_to_nearest) ? 29 : 26);
6482  if (sign)
6483  {
6484  if (m > 0x80000000)
6485  {
6486  m = detail::divide64(0x80000000, m, s);
6487  ++exp;
6488  }
6489  exp = -exp;
6490  }
6491  return half(detail::binary, (half::round_style == std::round_to_nearest) ? detail::fixed2half<half::round_style, 31, false, false, false>(m, exp + 14, arg.data_ & 0x8000) : detail::fixed2half<half::round_style, 23, false, false, false>((m + 0x80) >> 8, exp + 14, arg.data_ & 0x8000));
6492 #endif
6493 }
6494 
6504 inline half hypot(half x, half y)
6505 {
6506 #ifdef HALF_ARITHMETIC_TYPE
6507  detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_);
6508 #if HALF_ENABLE_CPP11_CMATH
6509  return half(detail::binary, detail::float2half<half::round_style>(std::hypot(fx, fy)));
6510 #else
6511  return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(fx * fx + fy * fy)));
6512 #endif
6513 #else
6514  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, expx = 0, expy = 0;
6515  if (absx >= 0x7C00 || absy >= 0x7C00)
6516  return half(detail::binary, (absx == 0x7C00) ? detail::select(0x7C00, y.data_) : (absy == 0x7C00) ? detail::select(0x7C00, x.data_)
6517  : detail::signal(x.data_, y.data_));
6518  if (!absx)
6519  return half(detail::binary, absy ? detail::check_underflow(absy) : 0);
6520  if (!absy)
6522  if (absy > absx)
6523  std::swap(absx, absy);
6524  for (; absx < 0x400; absx <<= 1, --expx)
6525  ;
6526  for (; absy < 0x400; absy <<= 1, --expy)
6527  ;
6528  detail::uint32 mx = (absx & 0x3FF) | 0x400, my = (absy & 0x3FF) | 0x400;
6529  mx *= mx;
6530  my *= my;
6531  int ix = mx >> 21, iy = my >> 21;
6532  expx = 2 * (expx + (absx >> 10)) - 15 + ix;
6533  expy = 2 * (expy + (absy >> 10)) - 15 + iy;
6534  mx <<= 10 - ix;
6535  my <<= 10 - iy;
6536  int d = expx - expy;
6537  my = (d < 30) ? ((my >> d) | ((my & ((static_cast<detail::uint32>(1) << d) - 1)) != 0)) : 1;
6538  return half(detail::binary, detail::hypot_post<half::round_style>(mx + my, expx));
6539 #endif
6540 }
6541 
6552 inline half hypot(half x, half y, half z)
6553 {
6554 #ifdef HALF_ARITHMETIC_TYPE
6555  detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_), fz = detail::half2float<detail::internal_t>(z.data_);
6556  return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(fx * fx + fy * fy + fz * fz)));
6557 #else
6558  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, expx = 0, expy = 0, expz = 0;
6559  if (!absx)
6560  return hypot(y, z);
6561  if (!absy)
6562  return hypot(x, z);
6563  if (!absz)
6564  return hypot(x, y);
6565  if (absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
6566  return half(detail::binary, (absx == 0x7C00) ? detail::select(0x7C00, detail::select(y.data_, z.data_)) : (absy == 0x7C00) ? detail::select(0x7C00, detail::select(x.data_, z.data_))
6567  : (absz == 0x7C00) ? detail::select(0x7C00, detail::select(x.data_, y.data_))
6568  : detail::signal(x.data_, y.data_, z.data_));
6569  if (absz > absy)
6570  std::swap(absy, absz);
6571  if (absy > absx)
6572  std::swap(absx, absy);
6573  if (absz > absy)
6574  std::swap(absy, absz);
6575  for (; absx < 0x400; absx <<= 1, --expx)
6576  ;
6577  for (; absy < 0x400; absy <<= 1, --expy)
6578  ;
6579  for (; absz < 0x400; absz <<= 1, --expz)
6580  ;
6581  detail::uint32 mx = (absx & 0x3FF) | 0x400, my = (absy & 0x3FF) | 0x400, mz = (absz & 0x3FF) | 0x400;
6582  mx *= mx;
6583  my *= my;
6584  mz *= mz;
6585  int ix = mx >> 21, iy = my >> 21, iz = mz >> 21;
6586  expx = 2 * (expx + (absx >> 10)) - 15 + ix;
6587  expy = 2 * (expy + (absy >> 10)) - 15 + iy;
6588  expz = 2 * (expz + (absz >> 10)) - 15 + iz;
6589  mx <<= 10 - ix;
6590  my <<= 10 - iy;
6591  mz <<= 10 - iz;
6592  int d = expy - expz;
6593  mz = (d < 30) ? ((mz >> d) | ((mz & ((static_cast<detail::uint32>(1) << d) - 1)) != 0)) : 1;
6594  my += mz;
6595  if (my & 0x80000000)
6596  {
6597  my = (my >> 1) | (my & 1);
6598  if (++expy > expx)
6599  {
6600  std::swap(mx, my);
6601  std::swap(expx, expy);
6602  }
6603  }
6604  d = expx - expy;
6605  my = (d < 30) ? ((my >> d) | ((my & ((static_cast<detail::uint32>(1) << d) - 1)) != 0)) : 1;
6606  return half(detail::binary, detail::hypot_post<half::round_style>(mx + my, expx));
6607 #endif
6608 }
6609 
6620 inline half pow(half x, half y)
6621 {
6622 #ifdef HALF_ARITHMETIC_TYPE
6623  return half(detail::binary, detail::float2half<half::round_style>(std::pow(detail::half2float<detail::internal_t>(x.data_), detail::half2float<detail::internal_t>(y.data_))));
6624 #else
6625  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -15;
6626  if (!absy || x.data_ == 0x3C00)
6627  return half(detail::binary, detail::select(0x3C00, (x.data_ == 0x3C00) ? y.data_ : x.data_));
6628  bool is_int = absy >= 0x6400 || (absy >= 0x3C00 && !(absy & ((1 << (25 - (absy >> 10))) - 1)));
6629  unsigned int sign = x.data_ & (static_cast<unsigned>((absy < 0x6800) && is_int && ((absy >> (25 - (absy >> 10))) & 1)) << 15);
6630  if (absx >= 0x7C00 || absy >= 0x7C00)
6631  return half(detail::binary, (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_) : (absy == 0x7C00) ? ((absx == 0x3C00) ? 0x3C00 : (!absx && y.data_ == 0xFC00) ? detail::pole()
6632  : (0x7C00 & -((y.data_ >> 15) ^ (absx > 0x3C00))))
6633  : (sign | (0x7C00 & ((y.data_ >> 15) - 1U))));
6634  if (!absx)
6635  return half(detail::binary, (y.data_ & 0x8000) ? detail::pole(sign) : sign);
6636  if ((x.data_ & 0x8000) && !is_int)
6637  return half(detail::binary, detail::invalid());
6638  if (x.data_ == 0xBC00)
6639  return half(detail::binary, sign | 0x3C00);
6640  switch (y.data_)
6641  {
6642  case 0x3800:
6643  return sqrt(x);
6644  case 0x3C00:
6645  return half(detail::binary, detail::check_underflow(x.data_));
6646  case 0x4000:
6647  return x * x;
6648  case 0xBC00:
6649  return half(detail::binary, 0x3C00) / x;
6650  }
6651  for (; absx < 0x400; absx <<= 1, --exp)
6652  ;
6653  detail::uint32 ilog = exp + (absx >> 10), msign = detail::sign_mask(ilog), f, m = (((ilog << 27) + ((detail::log2(static_cast<detail::uint32>((absx & 0x3FF) | 0x400) << 20) + 8) >> 4)) ^ msign) - msign;
6654  for (exp = -11; m < 0x80000000; m <<= 1, --exp)
6655  ;
6656  for (; absy < 0x400; absy <<= 1, --exp)
6657  ;
6658  m = detail::multiply64(m, static_cast<detail::uint32>((absy & 0x3FF) | 0x400) << 21);
6659  int i = m >> 31;
6660  exp += (absy >> 10) + i;
6661  m <<= 1 - i;
6662  if (exp < 0)
6663  {
6664  f = m >> -exp;
6665  exp = 0;
6666  }
6667  else
6668  {
6669  f = (m << exp) & 0x7FFFFFFF;
6670  exp = m >> (31 - exp);
6671  }
6672  return half(detail::binary, detail::exp2_post<half::round_style>(f, exp, ((msign & 1) ^ (y.data_ >> 15)) != 0, sign));
6673 #endif
6674 }
6675 
6680 
6690 inline void sincos(half arg, half* sin, half* cos)
6691 {
6692 #ifdef HALF_ARITHMETIC_TYPE
6693  detail::internal_t f = detail::half2float<detail::internal_t>(arg.data_);
6694  *sin = half(detail::binary, detail::float2half<half::round_style>(std::sin(f)));
6695  *cos = half(detail::binary, detail::float2half<half::round_style>(std::cos(f)));
6696 #else
6697  int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15, k;
6698  if (abs >= 0x7C00)
6699  *sin = *cos = half(detail::binary, (abs == 0x7C00) ? detail::invalid() : detail::signal(arg.data_));
6700  else if (!abs)
6701  {
6702  *sin = arg;
6703  *cos = half(detail::binary, 0x3C00);
6704  }
6705  else if (abs < 0x2500)
6706  {
6707  *sin = half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
6708  *cos = half(detail::binary, detail::rounded<half::round_style, true>(0x3BFF, 1, 1));
6709  }
6710  else
6711  {
6712  if (half::round_style != std::round_to_nearest)
6713  {
6714  switch (abs)
6715  {
6716  case 0x48B7:
6717  *sin = half(detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x1D07, 1, 1));
6718  *cos = half(detail::binary, detail::rounded<half::round_style, true>(0xBBFF, 1, 1));
6719  return;
6720  case 0x598C:
6721  *sin = half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x3BFF, 1, 1));
6722  *cos = half(detail::binary, detail::rounded<half::round_style, true>(0x80FC, 1, 1));
6723  return;
6724  case 0x6A64:
6725  *sin = half(detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x3BFE, 1, 1));
6726  *cos = half(detail::binary, detail::rounded<half::round_style, true>(0x27FF, 1, 1));
6727  return;
6728  case 0x6D8C:
6729  *sin = half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x0FE6, 1, 1));
6730  *cos = half(detail::binary, detail::rounded<half::round_style, true>(0x3BFF, 1, 1));
6731  return;
6732  }
6733  }
6734  std::pair<detail::uint32, detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
6735  switch (k & 3)
6736  {
6737  case 1:
6738  sc = std::make_pair(sc.second, -sc.first);
6739  break;
6740  case 2:
6741  sc = std::make_pair(-sc.first, -sc.second);
6742  break;
6743  case 3:
6744  sc = std::make_pair(-sc.second, sc.first);
6745  break;
6746  }
6747  *sin = half(detail::binary, detail::fixed2half<half::round_style, 30, true, true, true>((sc.first ^ -static_cast<detail::uint32>(sign)) + sign));
6748  *cos = half(detail::binary, detail::fixed2half<half::round_style, 30, true, true, true>(sc.second));
6749  }
6750 #endif
6751 }
6752 
6761 inline half sin(half arg)
6762 {
6763 #ifdef HALF_ARITHMETIC_TYPE
6764  return half(detail::binary, detail::float2half<half::round_style>(std::sin(detail::half2float<detail::internal_t>(arg.data_))));
6765 #else
6766  int abs = arg.data_ & 0x7FFF, k;
6767  if (!abs)
6768  return arg;
6769  if (abs >= 0x7C00)
6770  return half(detail::binary, (abs == 0x7C00) ? detail::invalid() : detail::signal(arg.data_));
6771  if (abs < 0x2900)
6772  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
6773  if (half::round_style != std::round_to_nearest)
6774  switch (abs)
6775  {
6776  case 0x48B7:
6777  return half(detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x1D07, 1, 1));
6778  case 0x6A64:
6779  return half(detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x3BFE, 1, 1));
6780  case 0x6D8C:
6781  return half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x0FE6, 1, 1));
6782  }
6783  std::pair<detail::uint32, detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
6784  detail::uint32 sign = -static_cast<detail::uint32>(((k >> 1) & 1) ^ (arg.data_ >> 15));
6785  return half(detail::binary, detail::fixed2half<half::round_style, 30, true, true, true>((((k & 1) ? sc.second : sc.first) ^ sign) - sign));
6786 #endif
6787 }
6788 
6797 inline half cos(half arg)
6798 {
6799 #ifdef HALF_ARITHMETIC_TYPE
6800  return half(detail::binary, detail::float2half<half::round_style>(std::cos(detail::half2float<detail::internal_t>(arg.data_))));
6801 #else
6802  int abs = arg.data_ & 0x7FFF, k;
6803  if (!abs)
6804  return half(detail::binary, 0x3C00);
6805  if (abs >= 0x7C00)
6806  return half(detail::binary, (abs == 0x7C00) ? detail::invalid() : detail::signal(arg.data_));
6807  if (abs < 0x2500)
6808  return half(detail::binary, detail::rounded<half::round_style, true>(0x3BFF, 1, 1));
6809  if (half::round_style != std::round_to_nearest && abs == 0x598C)
6810  return half(detail::binary, detail::rounded<half::round_style, true>(0x80FC, 1, 1));
6811  std::pair<detail::uint32, detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
6812  detail::uint32 sign = -static_cast<detail::uint32>(((k >> 1) ^ k) & 1);
6813  return half(detail::binary, detail::fixed2half<half::round_style, 30, true, true, true>((((k & 1) ? sc.first : sc.second) ^ sign) - sign));
6814 #endif
6815 }
6816 
6825 inline half tan(half arg)
6826 {
6827 #ifdef HALF_ARITHMETIC_TYPE
6828  return half(detail::binary, detail::float2half<half::round_style>(std::tan(detail::half2float<detail::internal_t>(arg.data_))));
6829 #else
6830  int abs = arg.data_ & 0x7FFF, exp = 13, k;
6831  if (!abs)
6832  return arg;
6833  if (abs >= 0x7C00)
6834  return half(detail::binary, (abs == 0x7C00) ? detail::invalid() : detail::signal(arg.data_));
6835  if (abs < 0x2700)
6836  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_, 0, 1));
6837  if (half::round_style != std::round_to_nearest)
6838  switch (abs)
6839  {
6840  case 0x658C:
6841  return half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x07E6, 1, 1));
6842  case 0x7330:
6843  return half(detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x4B62, 1, 1));
6844  }
6845  std::pair<detail::uint32, detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 30);
6846  if (k & 1)
6847  sc = std::make_pair(-sc.second, sc.first);
6848  detail::uint32 signy = detail::sign_mask(sc.first), signx = detail::sign_mask(sc.second);
6849  detail::uint32 my = (sc.first ^ signy) - signy, mx = (sc.second ^ signx) - signx;
6850  for (; my < 0x80000000; my <<= 1, --exp)
6851  ;
6852  for (; mx < 0x80000000; mx <<= 1, ++exp)
6853  ;
6854  return half(detail::binary, detail::tangent_post<half::round_style>(my, mx, exp, (signy ^ signx ^ arg.data_) & 0x8000));
6855 #endif
6856 }
6857 
6866 inline half asin(half arg)
6867 {
6868 #ifdef HALF_ARITHMETIC_TYPE
6869  return half(detail::binary, detail::float2half<half::round_style>(std::asin(detail::half2float<detail::internal_t>(arg.data_))));
6870 #else
6871  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
6872  if (!abs)
6873  return arg;
6874  if (abs >= 0x3C00)
6875  return half(detail::binary, (abs > 0x7C00) ? detail::signal(arg.data_) : (abs > 0x3C00) ? detail::invalid()
6876  : detail::rounded<half::round_style, true>(sign | 0x3E48, 0, 1));
6877  if (abs < 0x2900)
6878  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_, 0, 1));
6879  if (half::round_style != std::round_to_nearest && (abs == 0x2B44 || abs == 0x2DC3))
6880  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ + 1, 1, 1));
6881  std::pair<detail::uint32, detail::uint32> sc = detail::atan2_args(abs);
6882  detail::uint32 m = detail::atan2(sc.first, sc.second, (half::round_style == std::round_to_nearest) ? 27 : 26);
6883  return half(detail::binary, detail::fixed2half<half::round_style, 30, false, true, true>(m, 14, sign));
6884 #endif
6885 }
6886 
6895 inline half acos(half arg)
6896 {
6897 #ifdef HALF_ARITHMETIC_TYPE
6898  return half(detail::binary, detail::float2half<half::round_style>(std::acos(detail::half2float<detail::internal_t>(arg.data_))));
6899 #else
6900  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15;
6901  if (!abs)
6902  return half(detail::binary, detail::rounded<half::round_style, true>(0x3E48, 0, 1));
6903  if (abs >= 0x3C00)
6904  return half(detail::binary, (abs > 0x7C00) ? detail::signal(arg.data_) : (abs > 0x3C00) ? detail::invalid()
6905  : sign ? detail::rounded<half::round_style, true>(0x4248, 0, 1)
6906  : 0);
6907  std::pair<detail::uint32, detail::uint32> cs = detail::atan2_args(abs);
6908  detail::uint32 m = detail::atan2(cs.second, cs.first, 28);
6909  return half(detail::binary, detail::fixed2half<half::round_style, 31, false, true, true>(sign ? (0xC90FDAA2 - m) : m, 15, 0, sign));
6910 #endif
6911 }
6912 
6921 inline half atan(half arg)
6922 {
6923 #ifdef HALF_ARITHMETIC_TYPE
6924  return half(detail::binary, detail::float2half<half::round_style>(std::atan(detail::half2float<detail::internal_t>(arg.data_))));
6925 #else
6926  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
6927  if (!abs)
6928  return arg;
6929  if (abs >= 0x7C00)
6930  return half(detail::binary, (abs == 0x7C00) ? detail::rounded<half::round_style, true>(sign | 0x3E48, 0, 1) : detail::signal(arg.data_));
6931  if (abs <= 0x2700)
6932  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
6933  int exp = (abs >> 10) + (abs <= 0x3FF);
6934  detail::uint32 my = (abs & 0x3FF) | ((abs > 0x3FF) << 10);
6935  detail::uint32 m = (exp > 15) ? detail::atan2(my << 19, 0x20000000 >> (exp - 15), (half::round_style == std::round_to_nearest) ? 26 : 24) : detail::atan2(my << (exp + 4), 0x20000000, (half::round_style == std::round_to_nearest) ? 30 : 28);
6936  return half(detail::binary, detail::fixed2half<half::round_style, 30, false, true, true>(m, 14, sign));
6937 #endif
6938 }
6939 
6950 inline half atan2(half y, half x)
6951 {
6952 #ifdef HALF_ARITHMETIC_TYPE
6953  return half(detail::binary, detail::float2half<half::round_style>(std::atan2(detail::half2float<detail::internal_t>(y.data_), detail::half2float<detail::internal_t>(x.data_))));
6954 #else
6955  unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, signx = x.data_ >> 15, signy = y.data_ & 0x8000;
6956  if (absx >= 0x7C00 || absy >= 0x7C00)
6957  {
6958  if (absx > 0x7C00 || absy > 0x7C00)
6959  return half(detail::binary, detail::signal(x.data_, y.data_));
6960  if (absy == 0x7C00)
6961  return half(detail::binary, (absx < 0x7C00) ? detail::rounded<half::round_style, true>(signy | 0x3E48, 0, 1) : signx ? detail::rounded<half::round_style, true>(signy | 0x40B6, 0, 1)
6962  : detail::rounded<half::round_style, true>(signy | 0x3A48, 0, 1));
6963  return (x.data_ == 0x7C00) ? half(detail::binary, signy) : half(detail::binary, detail::rounded<half::round_style, true>(signy | 0x4248, 0, 1));
6964  }
6965  if (!absy)
6966  return signx ? half(detail::binary, detail::rounded<half::round_style, true>(signy | 0x4248, 0, 1)) : y;
6967  if (!absx)
6968  return half(detail::binary, detail::rounded<half::round_style, true>(signy | 0x3E48, 0, 1));
6969  int d = (absy >> 10) + (absy <= 0x3FF) - (absx >> 10) - (absx <= 0x3FF);
6970  if (d > (signx ? 18 : 12))
6971  return half(detail::binary, detail::rounded<half::round_style, true>(signy | 0x3E48, 0, 1));
6972  if (signx && d < -11)
6973  return half(detail::binary, detail::rounded<half::round_style, true>(signy | 0x4248, 0, 1));
6974  if (!signx && d < ((half::round_style == std::round_toward_zero) ? -15 : -9))
6975  {
6976  for (; absy < 0x400; absy <<= 1, --d)
6977  ;
6978  detail::uint32 mx = ((absx << 1) & 0x7FF) | 0x800, my = ((absy << 1) & 0x7FF) | 0x800;
6979  int i = my < mx;
6980  d -= i;
6981  if (d < -25)
6982  return half(detail::binary, detail::underflow<half::round_style>(signy));
6983  my <<= 11 + i;
6984  return half(detail::binary, detail::fixed2half<half::round_style, 11, false, false, true>(my / mx, d + 14, signy, my % mx != 0));
6985  }
6986  detail::uint32 m = detail::atan2(((absy & 0x3FF) | ((absy > 0x3FF) << 10)) << (19 + ((d < 0) ? d : (d > 0) ? 0
6987  : -1)),
6988  ((absx & 0x3FF) | ((absx > 0x3FF) << 10)) << (19 - ((d > 0) ? d : (d < 0) ? 0
6989  : 1)));
6990  return half(detail::binary, detail::fixed2half<half::round_style, 31, false, true, true>(signx ? (0xC90FDAA2 - m) : m, 15, signy, signx));
6991 #endif
6992 }
6993 
6998 
7007 inline half sinh(half arg)
7008 {
7009 #ifdef HALF_ARITHMETIC_TYPE
7010  return half(detail::binary, detail::float2half<half::round_style>(std::sinh(detail::half2float<detail::internal_t>(arg.data_))));
7011 #else
7012  int abs = arg.data_ & 0x7FFF, exp;
7013  if (!abs || abs >= 0x7C00)
7014  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
7015  if (abs <= 0x2900)
7016  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_, 0, 1));
7017  std::pair<detail::uint32, detail::uint32> mm = detail::hyperbolic_args(abs, exp, (half::round_style == std::round_to_nearest) ? 29 : 27);
7018  detail::uint32 m = mm.first - mm.second;
7019  for (exp += 13; m < 0x80000000 && exp; m <<= 1, --exp)
7020  ;
7021  unsigned int sign = arg.data_ & 0x8000;
7022  if (exp > 29)
7023  return half(detail::binary, detail::overflow<half::round_style>(sign));
7024  return half(detail::binary, detail::fixed2half<half::round_style, 31, false, false, true>(m, exp, sign));
7025 #endif
7026 }
7027 
7036 inline half cosh(half arg)
7037 {
7038 #ifdef HALF_ARITHMETIC_TYPE
7039  return half(detail::binary, detail::float2half<half::round_style>(std::cosh(detail::half2float<detail::internal_t>(arg.data_))));
7040 #else
7041  int abs = arg.data_ & 0x7FFF, exp;
7042  if (!abs)
7043  return half(detail::binary, 0x3C00);
7044  if (abs >= 0x7C00)
7045  return half(detail::binary, (abs > 0x7C00) ? detail::signal(arg.data_) : 0x7C00);
7046  std::pair<detail::uint32, detail::uint32> mm = detail::hyperbolic_args(abs, exp, (half::round_style == std::round_to_nearest) ? 23 : 26);
7047  detail::uint32 m = mm.first + mm.second, i = (~m & 0xFFFFFFFF) >> 31;
7048  m = (m >> i) | (m & i) | 0x80000000;
7049  if ((exp += 13 + i) > 29)
7050  return half(detail::binary, detail::overflow<half::round_style>());
7051  return half(detail::binary, detail::fixed2half<half::round_style, 31, false, false, true>(m, exp));
7052 #endif
7053 }
7054 
7063 inline half tanh(half arg)
7064 {
7065 #ifdef HALF_ARITHMETIC_TYPE
7066  return half(detail::binary, detail::float2half<half::round_style>(std::tanh(detail::half2float<detail::internal_t>(arg.data_))));
7067 #else
7068  int abs = arg.data_ & 0x7FFF, exp;
7069  if (!abs)
7070  return arg;
7071  if (abs >= 0x7C00)
7072  return half(detail::binary, (abs > 0x7C00) ? detail::signal(arg.data_) : (arg.data_ - 0x4000));
7073  if (abs >= 0x4500)
7074  return half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x3BFF, 1, 1));
7075  if (abs < 0x2700)
7076  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
7077  if (half::round_style != std::round_to_nearest && abs == 0x2D3F)
7078  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 3, 0, 1));
7079  std::pair<detail::uint32, detail::uint32> mm = detail::hyperbolic_args(abs, exp, 27);
7080  detail::uint32 my = mm.first - mm.second - (half::round_style != std::round_to_nearest), mx = mm.first + mm.second, i = (~mx & 0xFFFFFFFF) >> 31;
7081  for (exp = 13; my < 0x80000000; my <<= 1, --exp)
7082  ;
7083  mx = (mx >> i) | 0x80000000;
7084  return half(detail::binary, detail::tangent_post<half::round_style>(my, mx, exp - i, arg.data_ & 0x8000));
7085 #endif
7086 }
7087 
7096 inline half asinh(half arg)
7097 {
7098 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7099  return half(detail::binary, detail::float2half<half::round_style>(std::asinh(detail::half2float<detail::internal_t>(arg.data_))));
7100 #else
7101  int abs = arg.data_ & 0x7FFF;
7102  if (!abs || abs >= 0x7C00)
7103  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
7104  if (abs <= 0x2900)
7105  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
7106  if (half::round_style != std::round_to_nearest)
7107  switch (abs)
7108  {
7109  case 0x32D4:
7110  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 13, 1, 1));
7111  case 0x3B5B:
7112  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 197, 1, 1));
7113  }
7114  return half(detail::binary, detail::area<half::round_style, true>(arg.data_));
7115 #endif
7116 }
7117 
7126 inline half acosh(half arg)
7127 {
7128 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7129  return half(detail::binary, detail::float2half<half::round_style>(std::acosh(detail::half2float<detail::internal_t>(arg.data_))));
7130 #else
7131  int abs = arg.data_ & 0x7FFF;
7132  if ((arg.data_ & 0x8000) || abs < 0x3C00)
7133  return half(detail::binary, (abs <= 0x7C00) ? detail::invalid() : detail::signal(arg.data_));
7134  if (abs == 0x3C00)
7135  return half(detail::binary, 0);
7136  if (arg.data_ >= 0x7C00)
7137  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
7138  return half(detail::binary, detail::area<half::round_style, false>(arg.data_));
7139 #endif
7140 }
7141 
7151 inline half atanh(half arg)
7152 {
7153 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7154  return half(detail::binary, detail::float2half<half::round_style>(std::atanh(detail::half2float<detail::internal_t>(arg.data_))));
7155 #else
7156  int abs = arg.data_ & 0x7FFF, exp = 0;
7157  if (!abs)
7158  return arg;
7159  if (abs >= 0x3C00)
7160  return half(detail::binary, (abs == 0x3C00) ? detail::pole(arg.data_ & 0x8000) : (abs <= 0x7C00) ? detail::invalid()
7161  : detail::signal(arg.data_));
7162  if (abs < 0x2700)
7163  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_, 0, 1));
7164  detail::uint32 m = static_cast<detail::uint32>((abs & 0x3FF) | ((abs > 0x3FF) << 10)) << ((abs >> 10) + (abs <= 0x3FF) + 6), my = 0x80000000 + m, mx = 0x80000000 - m;
7165  for (; mx < 0x80000000; mx <<= 1, ++exp)
7166  ;
7167  int i = my >= mx, s;
7168  return half(detail::binary, detail::log2_post<half::round_style, 0xB8AA3B2A>(detail::log2((detail::divide64(my >> i, mx, s) + 1) >> 1, 27) + 0x10, exp + i - 1, 16, arg.data_ & 0x8000));
7169 #endif
7170 }
7171 
7176 
7185 inline half erf(half arg)
7186 {
7187 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7188  return half(detail::binary, detail::float2half<half::round_style>(std::erf(detail::half2float<detail::internal_t>(arg.data_))));
7189 #else
7190  unsigned int abs = arg.data_ & 0x7FFF;
7191  if (!abs || abs >= 0x7C00)
7192  return (abs >= 0x7C00) ? half(detail::binary, (abs == 0x7C00) ? (arg.data_ - 0x4000) : detail::signal(arg.data_)) : arg;
7193  if (abs >= 0x4200)
7194  return half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x3BFF, 1, 1));
7195  return half(detail::binary, detail::erf<half::round_style, false>(arg.data_));
7196 #endif
7197 }
7198 
7207 inline half erfc(half arg)
7208 {
7209 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7210  return half(detail::binary, detail::float2half<half::round_style>(std::erfc(detail::half2float<detail::internal_t>(arg.data_))));
7211 #else
7212  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
7213  if (abs >= 0x7C00)
7214  return (abs >= 0x7C00) ? half(detail::binary, (abs == 0x7C00) ? (sign >> 1) : detail::signal(arg.data_)) : arg;
7215  if (!abs)
7216  return half(detail::binary, 0x3C00);
7217  if (abs >= 0x4400)
7218  return half(detail::binary, detail::rounded<half::round_style, true>((sign >> 1) - (sign >> 15), sign >> 15, 1));
7219  return half(detail::binary, detail::erf<half::round_style, true>(arg.data_));
7220 #endif
7221 }
7222 
7232 inline half lgamma(half arg)
7233 {
7234 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7235  return half(detail::binary, detail::float2half<half::round_style>(std::lgamma(detail::half2float<detail::internal_t>(arg.data_))));
7236 #else
7237  int abs = arg.data_ & 0x7FFF;
7238  if (abs >= 0x7C00)
7239  return half(detail::binary, (abs == 0x7C00) ? 0x7C00 : detail::signal(arg.data_));
7240  if (!abs || arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(abs & ((1 << (25 - (abs >> 10))) - 1))))
7241  return half(detail::binary, detail::pole());
7242  if (arg.data_ == 0x3C00 || arg.data_ == 0x4000)
7243  return half(detail::binary, 0);
7244  return half(detail::binary, detail::gamma<half::round_style, true>(arg.data_));
7245 #endif
7246 }
7247 
7257 inline half tgamma(half arg)
7258 {
7259 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7260  return half(detail::binary, detail::float2half<half::round_style>(std::tgamma(detail::half2float<detail::internal_t>(arg.data_))));
7261 #else
7262  unsigned int abs = arg.data_ & 0x7FFF;
7263  if (!abs)
7264  return half(detail::binary, detail::pole(arg.data_));
7265  if (abs >= 0x7C00)
7266  return (arg.data_ == 0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
7267  if (arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(abs & ((1 << (25 - (abs >> 10))) - 1))))
7268  return half(detail::binary, detail::invalid());
7269  if (arg.data_ >= 0xCA80)
7270  return half(detail::binary, detail::underflow<half::round_style>((1 - ((abs >> (25 - (abs >> 10))) & 1)) << 15));
7271  if (arg.data_ <= 0x100 || (arg.data_ >= 0x4900 && arg.data_ < 0x8000))
7272  return half(detail::binary, detail::overflow<half::round_style>());
7273  if (arg.data_ == 0x3C00)
7274  return arg;
7275  return half(detail::binary, detail::gamma<half::round_style, false>(arg.data_));
7276 #endif
7277 }
7278 
7283 
7290 inline half ceil(half arg)
7291 {
7292  return half(detail::binary, detail::integral<std::round_toward_infinity, true, true>(arg.data_));
7293 }
7294 
7301 inline half floor(half arg)
7302 {
7303  return half(detail::binary, detail::integral<std::round_toward_neg_infinity, true, true>(arg.data_));
7304 }
7305 
7312 inline half trunc(half arg)
7313 {
7314  return half(detail::binary, detail::integral<std::round_toward_zero, true, true>(arg.data_));
7315 }
7316 
7323 inline half round(half arg)
7324 {
7325  return half(detail::binary, detail::integral<std::round_to_nearest, false, true>(arg.data_));
7326 }
7327 
7333 inline long lround(half arg)
7334 {
7335  return detail::half2int<std::round_to_nearest, false, false, long>(arg.data_);
7336 }
7337 
7344 inline half rint(half arg)
7345 {
7346  return half(detail::binary, detail::integral<half::round_style, true, true>(arg.data_));
7347 }
7348 
7355 inline long lrint(half arg)
7356 {
7357  return detail::half2int<half::round_style, true, true, long>(arg.data_);
7358 }
7359 
7365 inline half nearbyint(half arg)
7366 {
7367  return half(detail::binary, detail::integral<half::round_style, true, false>(arg.data_));
7368 }
7369 #if HALF_ENABLE_CPP11_LONG_LONG
7375 inline long long llround(half arg)
7376 {
7377  return detail::half2int<std::round_to_nearest, false, false, long long>(arg.data_);
7378 }
7379 
7386 inline long long llrint(half arg)
7387 {
7388  return detail::half2int<half::round_style, true, true, long long>(arg.data_);
7389 }
7390 #endif
7391 
7396 
7403 inline half frexp(half arg, int* exp)
7404 {
7405  *exp = 0;
7406  unsigned int abs = arg.data_ & 0x7FFF;
7407  if (abs >= 0x7C00 || !abs)
7408  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
7409  for (; abs < 0x400; abs <<= 1, --*exp)
7410  ;
7411  *exp += (abs >> 10) - 14;
7412  return half(detail::binary, (arg.data_ & 0x8000) | 0x3800 | (abs & 0x3FF));
7413 }
7414 
7424 inline half scalbln(half arg, long exp)
7425 {
7426  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
7427  if (abs >= 0x7C00 || !abs)
7428  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
7429  for (; abs < 0x400; abs <<= 1, --exp)
7430  ;
7431  exp += abs >> 10;
7432  if (exp > 30)
7433  return half(detail::binary, detail::overflow<half::round_style>(sign));
7434  else if (exp < -10)
7435  return half(detail::binary, detail::underflow<half::round_style>(sign));
7436  else if (exp > 0)
7437  return half(detail::binary, sign | (exp << 10) | (abs & 0x3FF));
7438  unsigned int m = (abs & 0x3FF) | 0x400;
7439  return half(detail::binary, detail::rounded<half::round_style, false>(sign | (m >> (1 - exp)), (m >> -exp) & 1, (m & ((1 << -exp) - 1)) != 0));
7440 }
7441 
7451 inline half scalbn(half arg, int exp)
7452 {
7453  return scalbln(arg, exp);
7454 }
7455 
7465 inline half ldexp(half arg, int exp)
7466 {
7467  return scalbln(arg, exp);
7468 }
7469 
7476 inline half modf(half arg, half* iptr)
7477 {
7478  unsigned int abs = arg.data_ & 0x7FFF;
7479  if (abs > 0x7C00)
7480  {
7481  arg = half(detail::binary, detail::signal(arg.data_));
7482  return *iptr = arg, arg;
7483  }
7484  if (abs >= 0x6400)
7485  return *iptr = arg, half(detail::binary, arg.data_ & 0x8000);
7486  if (abs < 0x3C00)
7487  return iptr->data_ = arg.data_ & 0x8000, arg;
7488  unsigned int exp = abs >> 10, mask = (1 << (25 - exp)) - 1, m = arg.data_ & mask;
7489  iptr->data_ = arg.data_ & ~mask;
7490  if (!m)
7491  return half(detail::binary, arg.data_ & 0x8000);
7492  for (; m < 0x400; m <<= 1, --exp)
7493  ;
7494  return half(detail::binary, (arg.data_ & 0x8000) | (exp << 10) | (m & 0x3FF));
7495 }
7496 
7505 inline int ilogb(half arg)
7506 {
7507  int abs = arg.data_ & 0x7FFF, exp;
7508  if (!abs || abs >= 0x7C00)
7509  {
7511  return !abs ? FP_ILOGB0 : (abs == 0x7C00) ? INT_MAX
7512  : FP_ILOGBNAN;
7513  }
7514  for (exp = (abs >> 10) - 15; abs < 0x200; abs <<= 1, --exp)
7515  ;
7516  return exp;
7517 }
7518 
7525 inline half logb(half arg)
7526 {
7527  int abs = arg.data_ & 0x7FFF, exp;
7528  if (!abs)
7529  return half(detail::binary, detail::pole(0x8000));
7530  if (abs >= 0x7C00)
7531  return half(detail::binary, (abs == 0x7C00) ? 0x7C00 : detail::signal(arg.data_));
7532  for (exp = (abs >> 10) - 15; abs < 0x200; abs <<= 1, --exp)
7533  ;
7534  unsigned int value = static_cast<unsigned>(exp < 0) << 15;
7535  if (exp)
7536  {
7537  unsigned int m = std::abs(exp) << 6;
7538  for (exp = 18; m < 0x400; m <<= 1, --exp)
7539  ;
7540  value |= (exp << 10) + m;
7541  }
7542  return half(detail::binary, value);
7543 }
7544 
7553 inline half nextafter(half from, half to)
7554 {
7555  int fabs = from.data_ & 0x7FFF, tabs = to.data_ & 0x7FFF;
7556  if (fabs > 0x7C00 || tabs > 0x7C00)
7557  return half(detail::binary, detail::signal(from.data_, to.data_));
7558  if (from.data_ == to.data_ || !(fabs | tabs))
7559  return to;
7560  if (!fabs)
7561  {
7563  return half(detail::binary, (to.data_ & 0x8000) + 1);
7564  }
7565  unsigned int out = from.data_ + (((from.data_ >> 15) ^ static_cast<unsigned>((from.data_ ^ (0x8000 | (0x8000 - (from.data_ >> 15)))) < (to.data_ ^ (0x8000 | (0x8000 - (to.data_ >> 15)))))) << 1) - 1;
7566  detail::raise(MU_HALF_FE_OVERFLOW, fabs < 0x7C00 && (out & 0x7C00) == 0x7C00);
7568  return half(detail::binary, out);
7569 }
7570 
7579 inline half nexttoward(half from, long double to)
7580 {
7581  int fabs = from.data_ & 0x7FFF;
7582  if (fabs > 0x7C00)
7583  return half(detail::binary, detail::signal(from.data_));
7584  long double lfrom = static_cast<long double>(from);
7585  if (detail::builtin_isnan(to) || lfrom == to)
7586  return half(static_cast<float>(to));
7587  if (!fabs)
7588  {
7590  return half(detail::binary, (static_cast<unsigned>(detail::builtin_signbit(to)) << 15) + 1);
7591  }
7592  unsigned int out = from.data_ + (((from.data_ >> 15) ^ static_cast<unsigned>(lfrom < to)) << 1) - 1;
7593  detail::raise(MU_HALF_FE_OVERFLOW, (out & 0x7FFF) == 0x7C00);
7595  return half(detail::binary, out);
7596 }
7597 
7604 {
7605  return half(detail::binary, x.data_ ^ ((x.data_ ^ y.data_) & 0x8000));
7606 }
7607 
7612 
7622 {
7623  return !(arg.data_ & 0x7FFF) ? FP_ZERO : ((arg.data_ & 0x7FFF) < 0x400) ? FP_SUBNORMAL
7624  : ((arg.data_ & 0x7FFF) < 0x7C00) ? FP_NORMAL
7625  : ((arg.data_ & 0x7FFF) == 0x7C00) ? FP_INFINITE
7626  : FP_NAN;
7627 }
7628 
7634 inline HALF_CONSTEXPR bool isfinite(half arg)
7635 {
7636  return (arg.data_ & 0x7C00) != 0x7C00;
7637 }
7638 
7644 inline HALF_CONSTEXPR bool isinf(half arg)
7645 {
7646  return (arg.data_ & 0x7FFF) == 0x7C00;
7647 }
7648 
7654 inline HALF_CONSTEXPR bool isnan(half arg)
7655 {
7656  return (arg.data_ & 0x7FFF) > 0x7C00;
7657 }
7658 
7664 inline HALF_CONSTEXPR bool isnormal(half arg)
7665 {
7666  return ((arg.data_ & 0x7C00) != 0) && ((arg.data_ & 0x7C00) != 0x7C00);
7667 }
7668 
7674 inline HALF_CONSTEXPR bool signbit(half arg)
7675 {
7676  return (arg.data_ & 0x8000) != 0;
7677 }
7678 
7683 
7691 {
7692  return ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) > ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15)) && !isnan(x) && !isnan(y);
7693 }
7694 
7702 {
7703  return ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) >= ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15)) && !isnan(x) && !isnan(y);
7704 }
7705 
7712 inline HALF_CONSTEXPR bool isless(half x, half y)
7713 {
7714  return ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) < ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15)) && !isnan(x) && !isnan(y);
7715 }
7716 
7724 {
7725  return ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) <= ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15)) && !isnan(x) && !isnan(y);
7726 }
7727 
7735 {
7736  return x.data_ != y.data_ && ((x.data_ | y.data_) & 0x7FFF) && !isnan(x) && !isnan(y);
7737 }
7738 
7746 {
7747  return isnan(x) || isnan(y);
7748 }
7749 
7754 
7768 template <typename T, typename U>
7769 T half_cast(U arg)
7770 {
7771  return detail::half_caster<T, U>::cast(arg);
7772 }
7773 
7788 template <typename T, std::float_round_style R, typename U>
7789 T half_cast(U arg)
7790 {
7792 }
7794 
7799 
7807 inline int feclearexcept(int excepts)
7808 {
7809  detail::errflags() &= ~excepts;
7810  return 0;
7811 }
7812 
7820 inline int fetestexcept(int excepts)
7821 {
7822  return detail::errflags() & excepts;
7823 }
7824 
7834 inline int feraiseexcept(int excepts)
7835 {
7836  detail::errflags() |= excepts;
7837  detail::raise(excepts);
7838  return 0;
7839 }
7840 
7849 inline int fegetexceptflag(int* flagp, int excepts)
7850 {
7851  *flagp = detail::errflags() & excepts;
7852  return 0;
7853 }
7854 
7864 inline int fesetexceptflag(const int* flagp, int excepts)
7865 {
7866  detail::errflags() = (detail::errflags() | (*flagp & excepts)) & (*flagp | ~excepts);
7867  return 0;
7868 }
7869 
7881 inline void fethrowexcept([[maybe_unused]] int excepts, [[maybe_unused]] const char* msg = "")
7882 {
7883  // ERASED
7884  // excepts &= detail::errflags();
7885  // if(excepts & (MU_HALF_FE_INVALID|MU_HALF_FE_DIVBYZERO))
7886  // throw std::domain_error(msg);
7887  // if(excepts & MU_HALF_FE_OVERFLOW)
7888  // throw std::overflow_error(msg);
7889  // if(excepts & MU_HALF_FE_UNDERFLOW)
7890  // throw std::underflow_error(msg);
7891  // if(excepts & MU_HALF_FE_INEXACT)
7892  // throw std::range_error(msg);
7893 }
7895 } // namespace half_float
7896 
7897 #undef HALF_UNUSED_NOERR
7898 #undef HALF_CONSTEXPR
7899 #undef HALF_CONSTEXPR_CONST
7900 #undef HALF_CONSTEXPR_NOERR
7901 #undef HALF_NOEXCEPT
7902 #undef HALF_NOTHROW
7903 #undef HALF_THREAD_LOCAL
7904 #undef HALF_TWOS_COMPLEMENT_INT
7905 #ifdef HALF_POP_WARNINGS
7906 #pragma warning(pop)
7907 #undef HALF_POP_WARNINGS
7908 #endif
7909 
7910 #endif
friend half asinh(half)
Definition: half.hpp:7096
friend void sincos(half, half *, half *)
Definition: half.hpp:6690
friend half exp2(half)
Definition: half.hpp:6146
half operator++(int)
Definition: half.hpp:5231
friend half tanh(half)
Definition: half.hpp:7063
friend long lrint(half)
Definition: half.hpp:7355
friend half nanh(const char *)
Definition: half.hpp:6090
friend half atanh(half)
Definition: half.hpp:7151
friend half atan(half)
Definition: half.hpp:6921
friend half tan(half)
Definition: half.hpp:6825
friend half nearbyint(half)
Definition: half.hpp:7365
friend half log1p(half)
Definition: half.hpp:6337
friend half pow(half, half)
Definition: half.hpp:6620
half & operator-=(float rhs)
Definition: half.hpp:5185
half & operator=(float rhs)
Definition: half.hpp:5122
friend half remquo(half, half, int *)
Definition: half.hpp:5957
HALF_CONSTEXPR half() HALF_NOEXCEPT
Definition: half.hpp:5099
half & operator--()
Definition: half.hpp:5223
friend half sqrt(half)
Definition: half.hpp:6390
friend half ceil(half)
Definition: half.hpp:7290
friend half erf(half)
Definition: half.hpp:7185
friend half atan2(half, half)
Definition: half.hpp:6950
half & operator/=(float rhs)
Definition: half.hpp:5203
friend half modf(half, half *)
Definition: half.hpp:7476
friend half operator*(half, half)
Definition: half.hpp:5779
friend half sin(half)
Definition: half.hpp:6761
friend half trunc(half)
Definition: half.hpp:7312
friend half nexttoward(half, long double)
Definition: half.hpp:7579
friend half lgamma(half)
Definition: half.hpp:7232
friend HALF_CONSTEXPR bool isgreaterequal(half, half)
Definition: half.hpp:7701
friend half nextafter(half, half)
Definition: half.hpp:7553
friend HALF_CONSTEXPR half copysign(half, half)
Definition: half.hpp:7603
friend half operator/(half, half)
Definition: half.hpp:5814
friend half tgamma(half)
Definition: half.hpp:7257
half & operator/=(half rhs)
Definition: half.hpp:5167
friend half exp(half)
Definition: half.hpp:6111
friend HALF_CONSTEXPR half operator-(half)
Definition: half.hpp:5699
friend half log10(half)
Definition: half.hpp:6253
friend HALF_CONSTEXPR bool isnan(half)
Definition: half.hpp:7654
friend half scalbln(half, long)
Definition: half.hpp:7424
friend half frexp(half, int *)
Definition: half.hpp:7403
friend half cbrt(half)
Definition: half.hpp:6454
friend half log(half)
Definition: half.hpp:6225
friend HALF_CONSTEXPR half fabs(half)
Definition: half.hpp:5896
friend HALF_CONSTEXPR bool islessgreater(half, half)
Definition: half.hpp:7734
friend HALF_CONSTEXPR bool isnormal(half)
Definition: half.hpp:7664
friend half fdim(half, half)
Definition: half.hpp:6079
friend HALF_CONSTEXPR int fpclassify(half)
Definition: half.hpp:7621
half & operator*=(half rhs)
Definition: half.hpp:5157
friend HALF_CONSTEXPR_NOERR bool operator==(half, half)
Definition: half.hpp:5619
friend half cos(half)
Definition: half.hpp:6797
half & operator+=(float rhs)
Definition: half.hpp:5176
half & operator+=(half rhs)
Definition: half.hpp:5137
friend HALF_CONSTEXPR bool isfinite(half)
Definition: half.hpp:7634
friend half rsqrt(half)
Definition: half.hpp:6413
friend HALF_CONSTEXPR bool isgreater(half, half)
Definition: half.hpp:7690
friend half fmod(half, half)
Definition: half.hpp:5916
half(float rhs)
Definition: half.hpp:5106
friend HALF_CONSTEXPR bool signbit(half)
Definition: half.hpp:7674
friend half acos(half)
Definition: half.hpp:6895
half & operator*=(float rhs)
Definition: half.hpp:5194
friend half remainder(half, half)
Definition: half.hpp:5937
friend half cosh(half)
Definition: half.hpp:7036
friend HALF_CONSTEXPR_NOERR half fmax(half, half)
Definition: half.hpp:6055
friend long lround(half)
Definition: half.hpp:7333
friend HALF_CONSTEXPR_NOERR bool operator<=(half, half)
Definition: half.hpp:5665
friend half acosh(half)
Definition: half.hpp:7126
friend half log2(half)
Definition: half.hpp:6292
friend half round(half)
Definition: half.hpp:7323
friend HALF_CONSTEXPR bool isless(half, half)
Definition: half.hpp:7712
friend half expm1(half)
Definition: half.hpp:6171
friend HALF_CONSTEXPR_NOERR bool operator>=(half, half)
Definition: half.hpp:5677
friend half hypot(half, half)
Definition: half.hpp:6504
half & operator-=(half rhs)
Definition: half.hpp:5147
friend HALF_CONSTEXPR_NOERR bool operator!=(half, half)
Definition: half.hpp:5630
half & operator++()
Definition: half.hpp:5215
friend HALF_CONSTEXPR_NOERR bool operator<(half, half)
Definition: half.hpp:5641
friend half erfc(half)
Definition: half.hpp:7207
friend half operator+(half, half)
Definition: half.hpp:5711
friend half floor(half)
Definition: half.hpp:7301
friend HALF_CONSTEXPR_NOERR half fmin(half, half)
Definition: half.hpp:6066
half operator--(int)
Definition: half.hpp:5241
friend HALF_CONSTEXPR bool isinf(half)
Definition: half.hpp:7644
friend int ilogb(half)
Definition: half.hpp:7505
friend half fma(half, half, half)
Definition: half.hpp:5982
friend half sinh(half)
Definition: half.hpp:7007
friend half rint(half)
Definition: half.hpp:7344
friend HALF_CONSTEXPR bool islessequal(half, half)
Definition: half.hpp:7723
friend half asin(half)
Definition: half.hpp:6866
friend half logb(half)
Definition: half.hpp:7525
friend HALF_CONSTEXPR_NOERR bool operator>(half, half)
Definition: half.hpp:5653
static HALF_CONSTEXPR half_float::half max() HALF_NOTHROW
Largest finite value.
Definition: half.hpp:5540
static HALF_CONSTEXPR half_float::half quiet_NaN() HALF_NOTHROW
Quiet NaN.
Definition: half.hpp:5564
static HALF_CONSTEXPR half_float::half min() HALF_NOTHROW
Smallest positive normal value.
Definition: half.hpp:5528
static HALF_CONSTEXPR half_float::half round_error() HALF_NOTHROW
Maximum rounding error in ULP (units in the last place).
Definition: half.hpp:5552
static HALF_CONSTEXPR half_float::half infinity() HALF_NOTHROW
Positive infinity.
Definition: half.hpp:5558
static HALF_CONSTEXPR half_float::half epsilon() HALF_NOTHROW
Difference between 1 and next representable value.
Definition: half.hpp:5546
static HALF_CONSTEXPR half_float::half lowest() HALF_NOTHROW
Smallest finite value.
Definition: half.hpp:5534
static HALF_CONSTEXPR half_float::half signaling_NaN() HALF_NOTHROW
Signaling NaN.
Definition: half.hpp:5570
static HALF_CONSTEXPR half_float::half denorm_min() HALF_NOTHROW
Smallest positive subnormal value.
Definition: half.hpp:5576
#define FP_ILOGBNAN
Definition: half.hpp:427
#define HALF_NOEXCEPT
Definition: half.hpp:244
#define FP_NAN
Definition: half.hpp:436
#define HALF_CONSTEXPR_NOERR
Definition: half.hpp:236
#define FP_ZERO
Definition: half.hpp:433
#define MU_HALF_FE_UNDERFLOW
Definition: half.hpp:44
#define FP_INFINITE
Definition: half.hpp:439
#define HALF_CONSTEXPR_CONST
Definition: half.hpp:235
#define HALF_THREAD_LOCAL
Definition: half.hpp:252
#define HALF_NOTHROW
Definition: half.hpp:245
#define MU_HALF_FE_DIVBYZERO
Definition: half.hpp:42
#define MU_HALF_FE_OVERFLOW
Definition: half.hpp:43
#define FP_ILOGB0
Definition: half.hpp:424
#define MU_HALF_FE_INVALID
Definition: half.hpp:41
#define HALF_UNUSED_NOERR(name)
Definition: half.hpp:221
#define FP_NORMAL
Definition: half.hpp:442
#define HALF_CONSTEXPR
Definition: half.hpp:234
#define MU_HALF_FE_INEXACT
Definition: half.hpp:45
#define FP_SUBNORMAL
Definition: half.hpp:430
#define HALF_ROUND_STYLE
Definition: half.hpp:399
#define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
Definition: half.hpp:377
bool_type< false > false_type
Definition: half.hpp:516
HALF_CONSTEXPR_CONST binary_t binary
Tag for binary construction.
Definition: half.hpp:635
std::pair< uint32, uint32 > hyperbolic_args(unsigned int abs, int &exp, unsigned int n=32)
Definition: half.hpp:4665
unsigned int integral(unsigned int value)
Definition: half.hpp:957
uint32 exp2(uint32 m, unsigned int n=32)
Definition: half.hpp:4403
bool builtin_signbit(T arg)
Definition: half.hpp:680
unsigned int hypot_post(uint32 r, int exp)
Definition: half.hpp:4764
int & errflags()
Definition: half.hpp:722
bool builtin_isnan(T arg)
Definition: half.hpp:663
unsigned short uint16
Unsigned integer of (at least) 16 bits width.
Definition: half.hpp:593
std::pair< uint32, uint32 > atan2_args(unsigned int abs)
Definition: half.hpp:4640
HALF_CONSTEXPR_NOERR unsigned int check_underflow(unsigned int arg)
Definition: half.hpp:874
unsigned int fixed2half(uint32 m, int exp=14, unsigned int sign=0, int s=0)
Definition: half.hpp:994
unsigned int mod(unsigned int x, unsigned int y, int *quo=NULL)
Definition: half.hpp:4303
uint32 sqrt(uint32 &r, int &exp)
Definition: half.hpp:4379
HALF_CONSTEXPR_NOERR unsigned int select(unsigned int x, unsigned int HALF_UNUSED_NOERR(y))
Definition: half.hpp:838
float half2float_impl(unsigned int value, float, true_type)
Definition: half.hpp:1941
HALF_CONSTEXPR_NOERR unsigned int overflow(unsigned int sign=0)
Definition: half.hpp:892
uint32 multiply64(uint32 x, uint32 y)
Definition: half.hpp:4259
T half2int(unsigned int value)
Definition: half.hpp:4209
uint32 mulhi(uint32 x, uint32 y)
Definition: half.hpp:4247
bool_type< true > true_type
Definition: half.hpp:515
HALF_CONSTEXPR_NOERR bool compsignal(unsigned int x, unsigned int y)
Definition: half.hpp:785
uint32 atan2(uint32 my, uint32 mx, unsigned int n=31)
Definition: half.hpp:4566
long int32
Fastest unsigned integer of (at least) 32 bits width.
Definition: half.hpp:599
unsigned int float2half(T value)
Definition: half.hpp:1906
HALF_CONSTEXPR_NOERR unsigned int underflow(unsigned int sign=0)
Definition: half.hpp:908
HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int nan)
Definition: half.hpp:797
HALF_CONSTEXPR_NOERR unsigned int invalid()
Definition: half.hpp:850
unsigned int gamma(unsigned int arg)
Definition: half.hpp:4969
std::pair< uint32, uint32 > sincos(uint32 mz, unsigned int n=31)
Definition: half.hpp:4513
uint32 arithmetic_shift(uint32 arg, int i)
Definition: half.hpp:707
uint32 log2(uint32 m, unsigned int n=32)
Definition: half.hpp:4458
T half2float(unsigned int value)
Definition: half.hpp:4194
uint32 divide64(uint32 x, uint32 y, int &s)
Definition: half.hpp:4273
void raise(int HALF_UNUSED_NOERR(flags), bool HALF_UNUSED_NOERR(cond)=true)
Definition: half.hpp:731
uint32 angle_arg(unsigned int abs, int &k)
Definition: half.hpp:4617
unsigned int log2_post(uint32 m, int ilog, int exp, unsigned int sign=0)
Definition: half.hpp:4737
unsigned int area(unsigned int arg)
Definition: half.hpp:4809
HALF_CONSTEXPR_NOERR unsigned int rounded(unsigned int value, int g, int s)
Definition: half.hpp:928
unsigned long uint32
Fastest unsigned integer of (at least) 32 bits width.
Definition: half.hpp:596
unsigned int float2half_impl(float value, true_type)
Definition: half.hpp:1019
uint32 sign_mask(uint32 arg)
Definition: half.hpp:693
bool builtin_isinf(T arg)
Definition: half.hpp:646
unsigned int erf(unsigned int arg)
Definition: half.hpp:4949
unsigned int int2half(T value)
Definition: half.hpp:1919
unsigned int tangent_post(uint32 my, uint32 mx, int exp, unsigned int sign=0)
Definition: half.hpp:4787
unsigned int exp2_post(uint32 m, int exp, bool esign, unsigned int sign=0, unsigned int n=32)
Definition: half.hpp:4704
HALF_CONSTEXPR_NOERR unsigned int pole(unsigned int sign=0)
Definition: half.hpp:862
half asinh(half arg)
Definition: half.hpp:7096
half sinh(half arg)
Definition: half.hpp:7007
int feclearexcept(int excepts)
Definition: half.hpp:7807
HALF_CONSTEXPR half fabs(half arg)
Definition: half.hpp:5896
half nextafter(half from, half to)
Definition: half.hpp:7553
half atan(half arg)
Definition: half.hpp:6921
half hypot(half x, half y)
Definition: half.hpp:6504
HALF_CONSTEXPR bool isunordered(half x, half y)
Definition: half.hpp:7745
half fdim(half x, half y)
Definition: half.hpp:6079
half remquo(half x, half y, int *quo)
Definition: half.hpp:5957
int fegetexceptflag(int *flagp, int excepts)
Definition: half.hpp:7849
int ilogb(half arg)
Definition: half.hpp:7505
half lgamma(half arg)
Definition: half.hpp:7232
HALF_CONSTEXPR half copysign(half x, half y)
Definition: half.hpp:7603
HALF_CONSTEXPR bool isfinite(half arg)
Definition: half.hpp:7634
int fesetexceptflag(const int *flagp, int excepts)
Definition: half.hpp:7864
HALF_CONSTEXPR half abs(half arg)
Definition: half.hpp:5905
half fma(half x, half y, half z)
Definition: half.hpp:5982
HALF_CONSTEXPR_NOERR half fmin(half x, half y)
Definition: half.hpp:6066
half nearbyint(half arg)
Definition: half.hpp:7365
half expm1(half arg)
Definition: half.hpp:6171
half ldexp(half arg, int exp)
Definition: half.hpp:7465
half sin(half arg)
Definition: half.hpp:6761
half tanh(half arg)
Definition: half.hpp:7063
half rint(half arg)
Definition: half.hpp:7344
HALF_CONSTEXPR_NOERR bool operator!=(half x, half y)
Definition: half.hpp:5630
HALF_CONSTEXPR_NOERR half fmax(half x, half y)
Definition: half.hpp:6055
HALF_CONSTEXPR_NOERR bool operator<(half x, half y)
Definition: half.hpp:5641
HALF_CONSTEXPR half operator-(half arg)
Definition: half.hpp:5699
T half_cast(U arg)
Definition: half.hpp:7769
half fmod(half x, half y)
Definition: half.hpp:5916
half log(half arg)
Definition: half.hpp:6225
half cos(half arg)
Definition: half.hpp:6797
half scalbn(half arg, int exp)
Definition: half.hpp:7451
half exp2(half arg)
Definition: half.hpp:6146
HALF_CONSTEXPR int fpclassify(half arg)
Definition: half.hpp:7621
HALF_CONSTEXPR_NOERR bool operator>=(half x, half y)
Definition: half.hpp:5677
half atanh(half arg)
Definition: half.hpp:7151
half nexttoward(half from, long double to)
Definition: half.hpp:7579
half round(half arg)
Definition: half.hpp:7323
half log2(half arg)
Definition: half.hpp:6292
HALF_CONSTEXPR bool isgreater(half x, half y)
Definition: half.hpp:7690
half asin(half arg)
Definition: half.hpp:6866
half sqrt(half arg)
Definition: half.hpp:6390
half trunc(half arg)
Definition: half.hpp:7312
half erfc(half arg)
Definition: half.hpp:7207
half tan(half arg)
Definition: half.hpp:6825
HALF_CONSTEXPR half operator+(half arg)
Definition: half.hpp:5691
half log10(half arg)
Definition: half.hpp:6253
half rsqrt(half arg)
Definition: half.hpp:6413
HALF_CONSTEXPR bool signbit(half arg)
Definition: half.hpp:7674
half floor(half arg)
Definition: half.hpp:7301
half acosh(half arg)
Definition: half.hpp:7126
void fethrowexcept([[maybe_unused]] int excepts, [[maybe_unused]] const char *msg="")
Definition: half.hpp:7881
HALF_CONSTEXPR bool isnan(half arg)
Definition: half.hpp:7654
HALF_CONSTEXPR_NOERR bool operator<=(half x, half y)
Definition: half.hpp:5665
half operator*(half x, half y)
Definition: half.hpp:5779
HALF_CONSTEXPR bool isnormal(half arg)
Definition: half.hpp:7664
half atan2(half y, half x)
Definition: half.hpp:6950
int feraiseexcept(int excepts)
Definition: half.hpp:7834
HALF_CONSTEXPR bool isless(half x, half y)
Definition: half.hpp:7712
half scalbln(half arg, long exp)
Definition: half.hpp:7424
half tgamma(half arg)
Definition: half.hpp:7257
HALF_CONSTEXPR_NOERR bool operator==(half x, half y)
Definition: half.hpp:5619
long lrint(half arg)
Definition: half.hpp:7355
HALF_CONSTEXPR bool isinf(half arg)
Definition: half.hpp:7644
HALF_CONSTEXPR_NOERR bool operator>(half x, half y)
Definition: half.hpp:5653
half cosh(half arg)
Definition: half.hpp:7036
half logb(half arg)
Definition: half.hpp:7525
half erf(half arg)
Definition: half.hpp:7185
void sincos(half arg, half *sin, half *cos)
Definition: half.hpp:6690
half ceil(half arg)
Definition: half.hpp:7290
half frexp(half arg, int *exp)
Definition: half.hpp:7403
half log1p(half arg)
Definition: half.hpp:6337
HALF_CONSTEXPR bool islessgreater(half x, half y)
Definition: half.hpp:7734
half hypot(half x, half y, half z)
Definition: half.hpp:6552
long lround(half arg)
Definition: half.hpp:7333
half acos(half arg)
Definition: half.hpp:6895
HALF_CONSTEXPR bool islessequal(half x, half y)
Definition: half.hpp:7723
half pow(half x, half y)
Definition: half.hpp:6620
half nanh(const char *arg)
Definition: half.hpp:6090
half modf(half arg, half *iptr)
Definition: half.hpp:7476
half cbrt(half arg)
Definition: half.hpp:6454
HALF_CONSTEXPR bool isgreaterequal(half x, half y)
Definition: half.hpp:7701
int fetestexcept(int excepts)
Definition: half.hpp:7820
half exp(half arg)
Definition: half.hpp:6111
half remainder(half x, half y)
Definition: half.hpp:5937
half operator/(half x, half y)
Definition: half.hpp:5814
Extensions to the C++ standard library.
Definition: half.hpp:5447
Tag type for binary construction.
Definition: half.hpp:631
Type traits for floating-point bits.
Definition: half.hpp:552
unsigned char type
Definition: half.hpp:553
Helper for tag dispatching.
Definition: half.hpp:513
Conditional type.
Definition: half.hpp:501
Class for 1.31 unsigned floating-point computation.
Definition: half.hpp:4862
friend f31 operator-(f31 a, f31 b)
Definition: half.hpp:4901
int exp
exponent.
Definition: half.hpp:4935
friend f31 operator*(f31 a, f31 b)
Definition: half.hpp:4916
friend f31 operator/(f31 a, f31 b)
Definition: half.hpp:4927
friend f31 operator+(f31 a, f31 b)
Definition: half.hpp:4887
HALF_CONSTEXPR f31(uint32 mant, int e)
Definition: half.hpp:4866
uint32 m
mantissa as 1.31.
Definition: half.hpp:4934
Type traits for floating-point types.
Definition: half.hpp:521