Qrack  10.0
General classical-emulating-quantum development framework
half.hpp
Go to the documentation of this file.
1 // half - IEEE 754-based half-precision floating-point library.
2 //
3 // Copyright (c) 2012-2021 Christian Rau <rauy@users.sourceforge.net>
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6 // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
7 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
8 // permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
11 // Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
14 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
15 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17 
18 // Version 2.2.0
19 
22 
23 #ifndef HALF_HALF_HPP
24 #define HALF_HALF_HPP
25 
26 #define HALF_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
27 
28 #if defined(__INTEL_COMPILER)
29 #define HALF_ICC_VERSION __INTEL_COMPILER
30 #elif defined(__ICC)
31 #define HALF_ICC_VERSION __ICC
32 #elif defined(__ICL)
33 #define HALF_ICC_VERSION __ICL
34 #else
35 #define HALF_ICC_VERSION 0
36 #endif
37 
38 // check C++11 language features
39 #if defined(__clang__) // clang
40 #if __has_feature(cxx_static_assert) && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
41 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
42 #endif
43 #if __has_feature(cxx_constexpr) && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
44 #define HALF_ENABLE_CPP11_CONSTEXPR 1
45 #endif
46 #if __has_feature(cxx_noexcept) && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
47 #define HALF_ENABLE_CPP11_NOEXCEPT 1
48 #endif
49 #if __has_feature(cxx_user_literals) && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
50 #define HALF_ENABLE_CPP11_USER_LITERALS 1
51 #endif
52 #if __has_feature(cxx_thread_local) && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
53 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
54 #endif
55 #if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) && !defined(HALF_ENABLE_CPP11_LONG_LONG)
56 #define HALF_ENABLE_CPP11_LONG_LONG 1
57 #endif
58 #elif HALF_ICC_VERSION && defined(__INTEL_CXX11_MODE__) // Intel C++
59 #if HALF_ICC_VERSION >= 1500 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
60 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
61 #endif
62 #if HALF_ICC_VERSION >= 1500 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
63 #define HALF_ENABLE_CPP11_USER_LITERALS 1
64 #endif
65 #if HALF_ICC_VERSION >= 1400 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
66 #define HALF_ENABLE_CPP11_CONSTEXPR 1
67 #endif
68 #if HALF_ICC_VERSION >= 1400 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
69 #define HALF_ENABLE_CPP11_NOEXCEPT 1
70 #endif
71 #if HALF_ICC_VERSION >= 1110 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
72 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
73 #endif
74 #if HALF_ICC_VERSION >= 1110 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
75 #define HALF_ENABLE_CPP11_LONG_LONG 1
76 #endif
77 #elif defined(__GNUC__) // gcc
78 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
79 #if HALF_GCC_VERSION >= 408 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
80 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
81 #endif
82 #if HALF_GCC_VERSION >= 407 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
83 #define HALF_ENABLE_CPP11_USER_LITERALS 1
84 #endif
85 #if HALF_GCC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
86 #define HALF_ENABLE_CPP11_CONSTEXPR 1
87 #endif
88 #if HALF_GCC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
89 #define HALF_ENABLE_CPP11_NOEXCEPT 1
90 #endif
91 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
92 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
93 #endif
94 #if !defined(HALF_ENABLE_CPP11_LONG_LONG)
95 #define HALF_ENABLE_CPP11_LONG_LONG 1
96 #endif
97 #endif
98 #define HALF_TWOS_COMPLEMENT_INT 1
99 #elif defined(_MSC_VER) // Visual C++
100 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
101 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
102 #endif
103 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
104 #define HALF_ENABLE_CPP11_USER_LITERALS 1
105 #endif
106 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
107 #define HALF_ENABLE_CPP11_CONSTEXPR 1
108 #endif
109 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
110 #define HALF_ENABLE_CPP11_NOEXCEPT 1
111 #endif
112 #if _MSC_VER >= 1600 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
113 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
114 #endif
115 #if _MSC_VER >= 1310 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
116 #define HALF_ENABLE_CPP11_LONG_LONG 1
117 #endif
118 #define HALF_TWOS_COMPLEMENT_INT 1
119 #define HALF_POP_WARNINGS 1
120 #pragma warning(push)
121 #pragma warning(disable : 4099 4127 4146) // struct vs class, constant in if, negative unsigned
122 #endif
123 
124 // check C++11 library features
125 #include <utility>
126 #if defined(_LIBCPP_VERSION) // libc++
127 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
128 #ifndef HALF_ENABLE_CPP11_TYPE_TRAITS
129 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
130 #endif
131 #ifndef HALF_ENABLE_CPP11_CSTDINT
132 #define HALF_ENABLE_CPP11_CSTDINT 1
133 #endif
134 #ifndef HALF_ENABLE_CPP11_CMATH
135 #define HALF_ENABLE_CPP11_CMATH 1
136 #endif
137 #ifndef HALF_ENABLE_CPP11_HASH
138 #define HALF_ENABLE_CPP11_HASH 1
139 #endif
140 #ifndef HALF_ENABLE_CPP11_CFENV
141 #define HALF_ENABLE_CPP11_CFENV 1
142 #endif
143 #endif
144 #elif defined(__GLIBCXX__) // libstdc++
145 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
146 #ifdef __clang__
147 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
148 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
149 #endif
150 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CSTDINT)
151 #define HALF_ENABLE_CPP11_CSTDINT 1
152 #endif
153 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CMATH)
154 #define HALF_ENABLE_CPP11_CMATH 1
155 #endif
156 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_HASH)
157 #define HALF_ENABLE_CPP11_HASH 1
158 #endif
159 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CFENV)
160 #define HALF_ENABLE_CPP11_CFENV 1
161 #endif
162 #else
163 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
164 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
165 #endif
166 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CSTDINT)
167 #define HALF_ENABLE_CPP11_CSTDINT 1
168 #endif
169 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CMATH)
170 #define HALF_ENABLE_CPP11_CMATH 1
171 #endif
172 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_HASH)
173 #define HALF_ENABLE_CPP11_HASH 1
174 #endif
175 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CFENV)
176 #define HALF_ENABLE_CPP11_CFENV 1
177 #endif
178 #endif
179 #endif
180 #elif defined(_CPPLIB_VER) // Dinkumware/Visual C++
181 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
182 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
183 #endif
184 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_CSTDINT)
185 #define HALF_ENABLE_CPP11_CSTDINT 1
186 #endif
187 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_HASH)
188 #define HALF_ENABLE_CPP11_HASH 1
189 #endif
190 #if _CPPLIB_VER >= 610 && !defined(HALF_ENABLE_CPP11_CMATH)
191 #define HALF_ENABLE_CPP11_CMATH 1
192 #endif
193 #if _CPPLIB_VER >= 610 && !defined(HALF_ENABLE_CPP11_CFENV)
194 #define HALF_ENABLE_CPP11_CFENV 1
195 #endif
196 #endif
197 #undef HALF_GCC_VERSION
198 #undef HALF_ICC_VERSION
199 
200 // any error throwing C++ exceptions?
201 #if defined(HALF_ERRHANDLING_THROW_INVALID) || defined(HALF_ERRHANDLING_THROW_DIVBYZERO) || \
202  defined(HALF_ERRHANDLING_THROW_OVERFLOW) || defined(HALF_ERRHANDLING_THROW_UNDERFLOW) || \
203  defined(HALF_ERRHANDLING_THROW_INEXACT)
204 #define HALF_ERRHANDLING_THROWS 1
205 #endif
206 
207 // any error handling enabled?
208 #define HALF_ERRHANDLING \
209  (HALF_ERRHANDLING_FLAGS || HALF_ERRHANDLING_ERRNO || HALF_ERRHANDLING_FENV || HALF_ERRHANDLING_THROWS)
210 
211 #if HALF_ERRHANDLING
212 #define HALF_UNUSED_NOERR(name) name
213 #else
214 #define HALF_UNUSED_NOERR(name)
215 #endif
216 
217 // support constexpr
218 #if HALF_ENABLE_CPP11_CONSTEXPR
219 #define HALF_CONSTEXPR constexpr
220 #define HALF_CONSTEXPR_CONST constexpr
221 #if HALF_ERRHANDLING
222 #define HALF_CONSTEXPR_NOERR
223 #else
224 #define HALF_CONSTEXPR_NOERR constexpr
225 #endif
226 #else
227 #define HALF_CONSTEXPR
228 #define HALF_CONSTEXPR_CONST const
229 #define HALF_CONSTEXPR_NOERR
230 #endif
231 
232 // support noexcept
233 #if HALF_ENABLE_CPP11_NOEXCEPT
234 #define HALF_NOEXCEPT noexcept
235 #define HALF_NOTHROW noexcept
236 #else
237 #define HALF_NOEXCEPT
238 #define HALF_NOTHROW throw()
239 #endif
240 
241 // support thread storage
242 #if HALF_ENABLE_CPP11_THREAD_LOCAL
243 #define HALF_THREAD_LOCAL thread_local
244 #else
245 #define HALF_THREAD_LOCAL static
246 #endif
247 
248 #include <algorithm>
249 #include <climits>
250 #include <cmath>
251 #include <cstdlib>
252 #include <cstring>
253 #include <istream>
254 #include <limits>
255 #include <ostream>
256 #include <stdexcept>
257 #include <utility>
258 #if HALF_ENABLE_CPP11_TYPE_TRAITS
259 #include <type_traits>
260 #endif
261 #if HALF_ENABLE_CPP11_CSTDINT
262 #include <cstdint>
263 #endif
264 #if HALF_ERRHANDLING_ERRNO
265 #include <cerrno>
266 #endif
267 #if HALF_ENABLE_CPP11_CFENV
268 #include <cfenv>
269 #endif
270 #if HALF_ENABLE_CPP11_HASH
271 #include <functional>
272 #endif
273 
274 #ifndef HALF_ENABLE_F16C_INTRINSICS
283 #define HALF_ENABLE_F16C_INTRINSICS __F16C__
284 #endif
285 #if HALF_ENABLE_F16C_INTRINSICS
286 #include <immintrin.h>
287 #endif
288 
289 #ifdef HALF_DOXYGEN_ONLY
296 #define HALF_ARITHMETIC_TYPE (undefined)
297 
301 #define HALF_ERRHANDLING_FLAGS 0
302 
308 #define HALF_ERRHANDLING_ERRNO 0
309 
316 #define HALF_ERRHANDLING_FENV 0
317 
322 #define HALF_ERRHANDLING_THROW_INVALID (undefined)
323 
327 #define HALF_ERRHANDLING_THROW_DIVBYZERO (undefined)
328 
333 #define HALF_ERRHANDLING_THROW_OVERFLOW (undefined)
334 
339 #define HALF_ERRHANDLING_THROW_UNDERFLOW (undefined)
340 
345 #define HALF_ERRHANDLING_THROW_INEXACT (undefined)
346 #endif
347 
348 #ifndef HALF_ERRHANDLING_OVERFLOW_TO_INEXACT
352 #define HALF_ERRHANDLING_OVERFLOW_TO_INEXACT 1
353 #endif
354 
355 #ifndef HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
363 #define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT 1
364 #endif
365 
386 #ifndef HALF_ROUND_STYLE
387 #define HALF_ROUND_STYLE 1 // = std::round_to_nearest
388 #endif
389 
395 #define HUGE_VALH std::numeric_limits<half_float::half>::infinity()
396 
402 #define FP_FAST_FMAH 1
403 
409 #define HLF_ROUNDS HALF_ROUND_STYLE
410 
411 #ifndef FP_ILOGB0
412 #define FP_ILOGB0 INT_MIN
413 #endif
414 #ifndef FP_ILOGBNAN
415 #define FP_ILOGBNAN INT_MAX
416 #endif
417 #ifndef FP_SUBNORMAL
418 #define FP_SUBNORMAL 0
419 #endif
420 #ifndef FP_ZERO
421 #define FP_ZERO 1
422 #endif
423 #ifndef FP_NAN
424 #define FP_NAN 2
425 #endif
426 #ifndef FP_INFINITE
427 #define FP_INFINITE 3
428 #endif
429 #ifndef FP_NORMAL
430 #define FP_NORMAL 4
431 #endif
432 
433 #if !HALF_ENABLE_CPP11_CFENV && !defined(FE_ALL_EXCEPT)
434 #define FE_INVALID 0x10
435 #define FE_DIVBYZERO 0x08
436 #define FE_OVERFLOW 0x04
437 #define FE_UNDERFLOW 0x02
438 #define FE_INEXACT 0x01
439 #define FE_ALL_EXCEPT (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
440 #endif
441 
444 namespace half_float {
445 class half;
446 
447 #if HALF_ENABLE_CPP11_USER_LITERALS
454 namespace literal {
455  half operator"" _h(long double);
456 }
457 #endif
458 
461 namespace detail {
462 #if HALF_ENABLE_CPP11_TYPE_TRAITS
464  template <bool B, typename T, typename F> struct conditional : std::conditional<B, T, F> {};
465 
467  template <bool B> struct bool_type : std::integral_constant<bool, B> {};
468  using std::false_type;
469  using std::true_type;
470 
472  template <typename T> struct is_float : std::is_floating_point<T> {};
473 #else
475  template <bool, typename T, typename> struct conditional {
476  typedef T type;
477  };
478  template <typename T, typename F> struct conditional<false, T, F> {
479  typedef F type;
480  };
481 
483  template <bool> struct bool_type {};
486 
488  template <typename> struct is_float : false_type {};
489  template <typename T> struct is_float<const T> : is_float<T> {};
490  template <typename T> struct is_float<volatile T> : is_float<T> {};
491  template <typename T> struct is_float<const volatile T> : is_float<T> {};
492  template <> struct is_float<float> : true_type {};
493  template <> struct is_float<double> : true_type {};
494  template <> struct is_float<long double> : true_type {};
495 #endif
496 
498  template <typename T> struct bits {
499  typedef unsigned char type;
500  };
501  template <typename T> struct bits<const T> : bits<T> {};
502  template <typename T> struct bits<volatile T> : bits<T> {};
503  template <typename T> struct bits<const volatile T> : bits<T> {};
504 
505 #if HALF_ENABLE_CPP11_CSTDINT
507  typedef std::uint_least16_t uint16;
508 
510  typedef std::uint_fast32_t uint32;
511 
513  typedef std::int_fast32_t int32;
514 
516  template <> struct bits<float> {
517  typedef std::uint_least32_t type;
518  };
519 
521  template <> struct bits<double> {
522  typedef std::uint_least64_t type;
523  };
524 #else
526  typedef unsigned short uint16;
527 
529  typedef unsigned long uint32;
530 
532  typedef long int32;
533 
535  template <>
536  struct bits<float> : conditional<std::numeric_limits<unsigned int>::digits >= 32, unsigned int, unsigned long> {};
537 
538 #if HALF_ENABLE_CPP11_LONG_LONG
540  template <>
541  struct bits<double>
542  : conditional<std::numeric_limits<unsigned long>::digits >= 64, unsigned long, unsigned long long> {};
543 #else
545  template <> struct bits<double> {
546  typedef unsigned long type;
547  };
548 #endif
549 #endif
550 
551 #ifdef HALF_ARITHMETIC_TYPE
553  typedef HALF_ARITHMETIC_TYPE internal_t;
554 #endif
555 
557  struct binary_t {};
558 
561 
564 
570  template <typename T> bool builtin_isinf(T arg)
571  {
572 #if HALF_ENABLE_CPP11_CMATH
573  return std::isinf(arg);
574 #elif defined(_MSC_VER)
575  return !::_finite(static_cast<double>(arg)) && !::_isnan(static_cast<double>(arg));
576 #else
577  return arg == std::numeric_limits<T>::infinity() || arg == -std::numeric_limits<T>::infinity();
578 #endif
579  }
580 
586  template <typename T> bool builtin_isnan(T arg)
587  {
588 #if HALF_ENABLE_CPP11_CMATH
589  return std::isnan(arg);
590 #elif defined(_MSC_VER)
591  return ::_isnan(static_cast<double>(arg)) != 0;
592 #else
593  return arg != arg;
594 #endif
595  }
596 
602  template <typename T> bool builtin_signbit(T arg)
603  {
604 #if HALF_ENABLE_CPP11_CMATH
605  return std::signbit(arg);
606 #else
607  return arg < T() || (arg == T() && T(1) / arg < T());
608 #endif
609  }
610 
615  inline uint32 sign_mask(uint32 arg)
616  {
617  static const int N = std::numeric_limits<uint32>::digits - 1;
618 #if HALF_TWOS_COMPLEMENT_INT
619  return static_cast<int32>(arg) >> N;
620 #else
621  return -((arg >> N) & 1);
622 #endif
623  }
624 
629  inline uint32 arithmetic_shift(uint32 arg, int i)
630  {
631 #if HALF_TWOS_COMPLEMENT_INT
632  return static_cast<int32>(arg) >> i;
633 #else
634  return static_cast<int32>(arg) / (static_cast<int32>(1) << i) -
635  ((arg >> (std::numeric_limits<uint32>::digits - 1)) & 1);
636 #endif
637  }
638 
642 
645  inline int& errflags()
646  {
647  HALF_THREAD_LOCAL int flags = 0;
648  return flags;
649  }
650 
654  inline void raise(int HALF_UNUSED_NOERR(flags), bool HALF_UNUSED_NOERR(cond) = true)
655  {
656 #if HALF_ERRHANDLING
657  if (!cond)
658  return;
659 #if HALF_ERRHANDLING_FLAGS
660  errflags() |= flags;
661 #endif
662 #if HALF_ERRHANDLING_ERRNO
663  if (flags & FE_INVALID)
664  errno = EDOM;
665  else if (flags & (FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW))
666  errno = ERANGE;
667 #endif
668 #if HALF_ERRHANDLING_FENV && HALF_ENABLE_CPP11_CFENV
669  std::feraiseexcept(flags);
670 #endif
671 #ifdef HALF_ERRHANDLING_THROW_INVALID
672  if (flags & FE_INVALID)
673  throw std::domain_error(HALF_ERRHANDLING_THROW_INVALID);
674 #endif
675 #ifdef HALF_ERRHANDLING_THROW_DIVBYZERO
676  if (flags & FE_DIVBYZERO)
677  throw std::domain_error(HALF_ERRHANDLING_THROW_DIVBYZERO);
678 #endif
679 #ifdef HALF_ERRHANDLING_THROW_OVERFLOW
680  if (flags & FE_OVERFLOW)
681  throw std::overflow_error(HALF_ERRHANDLING_THROW_OVERFLOW);
682 #endif
683 #ifdef HALF_ERRHANDLING_THROW_UNDERFLOW
684  if (flags & FE_UNDERFLOW)
685  throw std::underflow_error(HALF_ERRHANDLING_THROW_UNDERFLOW);
686 #endif
687 #ifdef HALF_ERRHANDLING_THROW_INEXACT
688  if (flags & FE_INEXACT)
689  throw std::range_error(HALF_ERRHANDLING_THROW_INEXACT);
690 #endif
691 #if HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
692  if ((flags & FE_UNDERFLOW) && !(flags & FE_INEXACT))
693  raise(FE_INEXACT);
694 #endif
695 #if HALF_ERRHANDLING_OVERFLOW_TO_INEXACT
696  if ((flags & FE_OVERFLOW) && !(flags & FE_INEXACT))
697  raise(FE_INEXACT);
698 #endif
699 #endif
700  }
701 
708  inline HALF_CONSTEXPR_NOERR bool compsignal(unsigned int x, unsigned int y)
709  {
710 #if HALF_ERRHANDLING
711  raise(FE_INVALID, (x & 0x7FFF) > 0x7C00 || (y & 0x7FFF) > 0x7C00);
712 #endif
713  return (x & 0x7FFF) > 0x7C00 || (y & 0x7FFF) > 0x7C00;
714  }
715 
720  inline HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int nan)
721  {
722 #if HALF_ERRHANDLING
723  raise(FE_INVALID, !(nan & 0x200));
724 #endif
725  return nan | 0x200;
726  }
727 
733  inline HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int x, unsigned int y)
734  {
735 #if HALF_ERRHANDLING
736  raise(FE_INVALID, ((x & 0x7FFF) > 0x7C00 && !(x & 0x200)) || ((y & 0x7FFF) > 0x7C00 && !(y & 0x200)));
737 #endif
738  return ((x & 0x7FFF) > 0x7C00) ? (x | 0x200) : (y | 0x200);
739  }
740 
747  inline HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int x, unsigned int y, unsigned int z)
748  {
749 #if HALF_ERRHANDLING
750  raise(FE_INVALID,
751  ((x & 0x7FFF) > 0x7C00 && !(x & 0x200)) || ((y & 0x7FFF) > 0x7C00 && !(y & 0x200)) ||
752  ((z & 0x7FFF) > 0x7C00 && !(z & 0x200)));
753 #endif
754  return ((x & 0x7FFF) > 0x7C00) ? (x | 0x200) : ((y & 0x7FFF) > 0x7C00) ? (y | 0x200) : (z | 0x200);
755  }
756 
762  inline HALF_CONSTEXPR_NOERR unsigned int select(unsigned int x, unsigned int HALF_UNUSED_NOERR(y))
763  {
764 #if HALF_ERRHANDLING
765  return (((y & 0x7FFF) > 0x7C00) && !(y & 0x200)) ? signal(y) : x;
766 #else
767  return x;
768 #endif
769  }
770 
774  inline HALF_CONSTEXPR_NOERR unsigned int invalid()
775  {
776 #if HALF_ERRHANDLING
777  raise(FE_INVALID);
778 #endif
779  return 0x7FFF;
780  }
781 
786  inline HALF_CONSTEXPR_NOERR unsigned int pole(unsigned int sign = 0)
787  {
788 #if HALF_ERRHANDLING
789  raise(FE_DIVBYZERO);
790 #endif
791  return sign | 0x7C00;
792  }
793 
798  inline HALF_CONSTEXPR_NOERR unsigned int check_underflow(unsigned int arg)
799  {
800 #if HALF_ERRHANDLING && !HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
801  raise(FE_UNDERFLOW, !(arg & 0x7C00));
802 #endif
803  return arg;
804  }
805 
809 
815  template <std::float_round_style R> HALF_CONSTEXPR_NOERR unsigned int overflow(unsigned int sign = 0)
816  {
817 #if HALF_ERRHANDLING
818  raise(FE_OVERFLOW);
819 #endif
820  return (R == std::round_toward_infinity) ? (sign + 0x7C00 - (sign >> 15))
821  : (R == std::round_toward_neg_infinity) ? (sign + 0x7BFF + (sign >> 15))
822  : (R == std::round_toward_zero) ? (sign | 0x7BFF)
823  : (sign | 0x7C00);
824  }
825 
831  template <std::float_round_style R> HALF_CONSTEXPR_NOERR unsigned int underflow(unsigned int sign = 0)
832  {
833 #if HALF_ERRHANDLING
834  raise(FE_UNDERFLOW);
835 #endif
836  return (R == std::round_toward_infinity) ? (sign + 1 - (sign >> 15))
837  : (R == std::round_toward_neg_infinity) ? (sign + (sign >> 15))
838  : sign;
839  }
840 
851  template <std::float_round_style R, bool I>
852  HALF_CONSTEXPR_NOERR unsigned int rounded(unsigned int value, int g, int s)
853  {
854 #if HALF_ERRHANDLING
855  value += (R == std::round_to_nearest) ? (g & (s | value))
856  : (R == std::round_toward_infinity) ? (~(value >> 15) & (g | s))
857  : (R == std::round_toward_neg_infinity) ? ((value >> 15) & (g | s))
858  : 0;
859  if ((value & 0x7C00) == 0x7C00)
860  raise(FE_OVERFLOW);
861  else if (value & 0x7C00)
862  raise(FE_INEXACT, I || (g | s) != 0);
863  else
864  raise(FE_UNDERFLOW, !(HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT) || I || (g | s) != 0);
865  return value;
866 #else
867  return (R == std::round_to_nearest) ? (value + (g & (s | value)))
868  : (R == std::round_toward_infinity) ? (value + (~(value >> 15) & (g | s)))
869  : (R == std::round_toward_neg_infinity) ? (value + ((value >> 15) & (g | s)))
870  : value;
871 #endif
872  }
873 
882  template <std::float_round_style R, bool E, bool I> unsigned int integral(unsigned int value)
883  {
884  unsigned int abs = value & 0x7FFF;
885  if (abs < 0x3C00) {
886  raise(FE_INEXACT, I);
887  return ((R == std::round_to_nearest) ? (0x3C00 & -static_cast<unsigned>(abs >= (0x3800 + E)))
888  : (R == std::round_toward_infinity) ? (0x3C00 & -(~(value >> 15) & (abs != 0)))
889  : (R == std::round_toward_neg_infinity) ? (0x3C00 & -static_cast<unsigned>(value > 0x8000))
890  : 0) |
891  (value & 0x8000);
892  }
893  if (abs >= 0x6400)
894  return (abs > 0x7C00) ? signal(value) : value;
895  unsigned int exp = 25 - (abs >> 10), mask = (1 << exp) - 1;
896  raise(FE_INEXACT, I && (value & mask));
897  return (((R == std::round_to_nearest) ? ((1 << (exp - 1)) - (~(value >> exp) & E))
898  : (R == std::round_toward_infinity) ? (mask & ((value >> 15) - 1))
899  : (R == std::round_toward_neg_infinity) ? (mask & -(value >> 15))
900  : 0) +
901  value) &
902  ~mask;
903  }
904 
919  template <std::float_round_style R, unsigned int F, bool S, bool N, bool I>
920  unsigned int fixed2half(uint32 m, int exp = 14, unsigned int sign = 0, int s = 0)
921  {
922  if (S) {
923  uint32 msign = sign_mask(m);
924  m = (m ^ msign) - msign;
925  sign = msign & 0x8000;
926  }
927  if (N)
928  for (; m < (static_cast<uint32>(1) << F) && exp; m <<= 1, --exp)
929  ;
930  else if (exp < 0)
931  return rounded<R, I>(sign + (m >> (F - 10 - exp)), (m >> (F - 11 - exp)) & 1,
932  s | ((m & ((static_cast<uint32>(1) << (F - 11 - exp)) - 1)) != 0));
933  return rounded<R, I>(sign + (exp << 10) + (m >> (F - 10)), (m >> (F - 11)) & 1,
934  s | ((m & ((static_cast<uint32>(1) << (F - 11)) - 1)) != 0));
935  }
936 
945  template <std::float_round_style R> unsigned int float2half_impl(float value, true_type)
946  {
947 #if HALF_ENABLE_F16C_INTRINSICS
948  return _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_set_ss(value),
949  (R == std::round_to_nearest) ? _MM_FROUND_TO_NEAREST_INT
950  : (R == std::round_toward_zero) ? _MM_FROUND_TO_ZERO
951  : (R == std::round_toward_infinity) ? _MM_FROUND_TO_POS_INF
952  : (R == std::round_toward_neg_infinity) ? _MM_FROUND_TO_NEG_INF
953  : _MM_FROUND_CUR_DIRECTION));
954 #else
955  bits<float>::type fbits;
956  std::memcpy(&fbits, &value, sizeof(float));
957 #if 1
958  unsigned int sign = (fbits >> 16) & 0x8000;
959  fbits &= 0x7FFFFFFF;
960  if (fbits >= 0x7F800000)
961  return sign | 0x7C00 | ((fbits > 0x7F800000) ? (0x200 | ((fbits >> 13) & 0x3FF)) : 0);
962  if (fbits >= 0x47800000)
963  return overflow<R>(sign);
964  if (fbits >= 0x38800000)
965  return rounded<R, false>(sign | (((fbits >> 23) - 112) << 10) | ((fbits >> 13) & 0x3FF), (fbits >> 12) & 1,
966  (fbits & 0xFFF) != 0);
967  if (fbits >= 0x33000000) {
968  int i = 125 - (fbits >> 23);
969  fbits = (fbits & 0x7FFFFF) | 0x800000;
970  return rounded<R, false>(
971  sign | (fbits >> (i + 1)), (fbits >> i) & 1, (fbits & ((static_cast<uint32>(1) << i) - 1)) != 0);
972  }
973  if (fbits != 0)
974  return underflow<R>(sign);
975  return sign;
976 #else
977  static const uint16 base_table[512] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
978  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
979  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
980  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
981  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
982  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
983  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
984  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
985  0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200,
986  0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, 0x2C00, 0x3000, 0x3400,
987  0x3800, 0x3C00, 0x4000, 0x4400, 0x4800, 0x4C00, 0x5000, 0x5400, 0x5800, 0x5C00, 0x6000, 0x6400, 0x6800,
988  0x6C00, 0x7000, 0x7400, 0x7800, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
989  0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
990  0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
991  0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
992  0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
993  0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
994  0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
995  0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
996  0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7C00,
997  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
998  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
999  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
1000  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
1001  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
1002  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
1003  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
1004  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001,
1005  0x8002, 0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100, 0x8200, 0x8400, 0x8800, 0x8C00, 0x9000,
1006  0x9400, 0x9800, 0x9C00, 0xA000, 0xA400, 0xA800, 0xAC00, 0xB000, 0xB400, 0xB800, 0xBC00, 0xC000, 0xC400,
1007  0xC800, 0xCC00, 0xD000, 0xD400, 0xD800, 0xDC00, 0xE000, 0xE400, 0xE800, 0xEC00, 0xF000, 0xF400, 0xF800,
1008  0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
1009  0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
1010  0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
1011  0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
1012  0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
1013  0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
1014  0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
1015  0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
1016  0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFC00 };
1017  static const unsigned char shift_table[256] = { 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
1018  25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
1019  25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
1020  25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
1021  25, 25, 25, 25, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
1022  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 24, 24, 24, 24, 24, 24, 24, 24,
1023  24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
1024  24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
1025  24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
1026  24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 13 };
1027  int sexp = fbits >> 23, exp = sexp & 0xFF, i = shift_table[exp];
1028  fbits &= 0x7FFFFF;
1029  uint32 m = (fbits | ((exp != 0) << 23)) & -static_cast<uint32>(exp != 0xFF);
1030  return rounded<R, false>(
1031  base_table[sexp] + (fbits >> i), (m >> (i - 1)) & 1, (((static_cast<uint32>(1) << (i - 1)) - 1) & m) != 0);
1032 #endif
1033 #endif
1034  }
1035 
1043  template <std::float_round_style R> unsigned int float2half_impl(double value, true_type)
1044  {
1045 #if HALF_ENABLE_F16C_INTRINSICS
1046  if (R == std::round_indeterminate)
1047  return _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_cvtpd_ps(_mm_set_sd(value)), _MM_FROUND_CUR_DIRECTION));
1048 #endif
1049  bits<double>::type dbits;
1050  std::memcpy(&dbits, &value, sizeof(double));
1051  uint32 hi = dbits >> 32, lo = dbits & 0xFFFFFFFF;
1052  unsigned int sign = (hi >> 16) & 0x8000;
1053  hi &= 0x7FFFFFFF;
1054  if (hi >= 0x7FF00000)
1055  return sign | 0x7C00 | ((dbits & 0xFFFFFFFFFFFFF) ? (0x200 | ((hi >> 10) & 0x3FF)) : 0);
1056  if (hi >= 0x40F00000)
1057  return overflow<R>(sign);
1058  if (hi >= 0x3F100000)
1059  return rounded<R, false>(
1060  sign | (((hi >> 20) - 1008) << 10) | ((hi >> 10) & 0x3FF), (hi >> 9) & 1, ((hi & 0x1FF) | lo) != 0);
1061  if (hi >= 0x3E600000) {
1062  int i = 1018 - (hi >> 20);
1063  hi = (hi & 0xFFFFF) | 0x100000;
1064  return rounded<R, false>(
1065  sign | (hi >> (i + 1)), (hi >> i) & 1, ((hi & ((static_cast<uint32>(1) << i) - 1)) | lo) != 0);
1066  }
1067  if ((hi | lo) != 0)
1068  return underflow<R>(sign);
1069  return sign;
1070  }
1071 
1080  template <std::float_round_style R, typename T> unsigned int float2half_impl(T value, ...)
1081  {
1082  unsigned int hbits = static_cast<unsigned>(builtin_signbit(value)) << 15;
1083  if (value == T())
1084  return hbits;
1085  if (builtin_isnan(value))
1086  return hbits | 0x7FFF;
1087  if (builtin_isinf(value))
1088  return hbits | 0x7C00;
1089  int exp;
1090  std::frexp(value, &exp);
1091  if (exp > 16)
1092  return overflow<R>(hbits);
1093  if (exp < -13)
1094  value = std::ldexp(value, 25);
1095  else {
1096  value = std::ldexp(value, 12 - exp);
1097  hbits |= ((exp + 13) << 10);
1098  }
1099  T ival, frac = std::modf(value, &ival);
1100  int m = std::abs(static_cast<int>(ival));
1101  return rounded<R, false>(hbits + (m >> 1), m & 1, frac != T());
1102  }
1103 
1112  template <std::float_round_style R, typename T> unsigned int float2half(T value)
1113  {
1114  return float2half_impl<R>(
1115  value, bool_type<std::numeric_limits<T>::is_iec559 && sizeof(typename bits<T>::type) == sizeof(T)>());
1116  }
1117 
1125  template <std::float_round_style R, typename T> unsigned int int2half(T value)
1126  {
1127  unsigned int bits = static_cast<unsigned>(value < 0) << 15;
1128  if (!value)
1129  return bits;
1130  if (bits)
1131  value = -value;
1132  if (value > 0xFFFF)
1133  return overflow<R>(bits);
1134  unsigned int m = static_cast<unsigned int>(value), exp = 24;
1135  for (; m < 0x400; m <<= 1, --exp)
1136  ;
1137  for (; m > 0x7FF; m >>= 1, ++exp)
1138  ;
1139  bits |= (exp << 10) + m;
1140  return (exp > 24) ? rounded<R, false>(bits, (value >> (exp - 25)) & 1, (((1 << (exp - 25)) - 1) & value) != 0)
1141  : bits;
1142  }
1143 
1148  inline float half2float_impl(unsigned int value, float, true_type)
1149  {
1150 #if HALF_ENABLE_F16C_INTRINSICS
1151  return _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128(value)));
1152 #else
1153 #if 0
1154  bits<float>::type fbits = static_cast<bits<float>::type>(value&0x8000) << 16;
1155  int abs = value & 0x7FFF;
1156  if(abs)
1157  {
1158  fbits |= 0x38000000 << static_cast<unsigned>(abs>=0x7C00);
1159  for(; abs<0x400; abs<<=1,fbits-=0x800000) ;
1160  fbits += static_cast<bits<float>::type>(abs) << 13;
1161  }
1162 #else
1163  static const bits<float>::type mantissa_table[2048] = { 0x00000000, 0x33800000, 0x34000000, 0x34400000,
1164  0x34800000, 0x34A00000, 0x34C00000, 0x34E00000, 0x35000000, 0x35100000, 0x35200000, 0x35300000, 0x35400000,
1165  0x35500000, 0x35600000, 0x35700000, 0x35800000, 0x35880000, 0x35900000, 0x35980000, 0x35A00000, 0x35A80000,
1166  0x35B00000, 0x35B80000, 0x35C00000, 0x35C80000, 0x35D00000, 0x35D80000, 0x35E00000, 0x35E80000, 0x35F00000,
1167  0x35F80000, 0x36000000, 0x36040000, 0x36080000, 0x360C0000, 0x36100000, 0x36140000, 0x36180000, 0x361C0000,
1168  0x36200000, 0x36240000, 0x36280000, 0x362C0000, 0x36300000, 0x36340000, 0x36380000, 0x363C0000, 0x36400000,
1169  0x36440000, 0x36480000, 0x364C0000, 0x36500000, 0x36540000, 0x36580000, 0x365C0000, 0x36600000, 0x36640000,
1170  0x36680000, 0x366C0000, 0x36700000, 0x36740000, 0x36780000, 0x367C0000, 0x36800000, 0x36820000, 0x36840000,
1171  0x36860000, 0x36880000, 0x368A0000, 0x368C0000, 0x368E0000, 0x36900000, 0x36920000, 0x36940000, 0x36960000,
1172  0x36980000, 0x369A0000, 0x369C0000, 0x369E0000, 0x36A00000, 0x36A20000, 0x36A40000, 0x36A60000, 0x36A80000,
1173  0x36AA0000, 0x36AC0000, 0x36AE0000, 0x36B00000, 0x36B20000, 0x36B40000, 0x36B60000, 0x36B80000, 0x36BA0000,
1174  0x36BC0000, 0x36BE0000, 0x36C00000, 0x36C20000, 0x36C40000, 0x36C60000, 0x36C80000, 0x36CA0000, 0x36CC0000,
1175  0x36CE0000, 0x36D00000, 0x36D20000, 0x36D40000, 0x36D60000, 0x36D80000, 0x36DA0000, 0x36DC0000, 0x36DE0000,
1176  0x36E00000, 0x36E20000, 0x36E40000, 0x36E60000, 0x36E80000, 0x36EA0000, 0x36EC0000, 0x36EE0000, 0x36F00000,
1177  0x36F20000, 0x36F40000, 0x36F60000, 0x36F80000, 0x36FA0000, 0x36FC0000, 0x36FE0000, 0x37000000, 0x37010000,
1178  0x37020000, 0x37030000, 0x37040000, 0x37050000, 0x37060000, 0x37070000, 0x37080000, 0x37090000, 0x370A0000,
1179  0x370B0000, 0x370C0000, 0x370D0000, 0x370E0000, 0x370F0000, 0x37100000, 0x37110000, 0x37120000, 0x37130000,
1180  0x37140000, 0x37150000, 0x37160000, 0x37170000, 0x37180000, 0x37190000, 0x371A0000, 0x371B0000, 0x371C0000,
1181  0x371D0000, 0x371E0000, 0x371F0000, 0x37200000, 0x37210000, 0x37220000, 0x37230000, 0x37240000, 0x37250000,
1182  0x37260000, 0x37270000, 0x37280000, 0x37290000, 0x372A0000, 0x372B0000, 0x372C0000, 0x372D0000, 0x372E0000,
1183  0x372F0000, 0x37300000, 0x37310000, 0x37320000, 0x37330000, 0x37340000, 0x37350000, 0x37360000, 0x37370000,
1184  0x37380000, 0x37390000, 0x373A0000, 0x373B0000, 0x373C0000, 0x373D0000, 0x373E0000, 0x373F0000, 0x37400000,
1185  0x37410000, 0x37420000, 0x37430000, 0x37440000, 0x37450000, 0x37460000, 0x37470000, 0x37480000, 0x37490000,
1186  0x374A0000, 0x374B0000, 0x374C0000, 0x374D0000, 0x374E0000, 0x374F0000, 0x37500000, 0x37510000, 0x37520000,
1187  0x37530000, 0x37540000, 0x37550000, 0x37560000, 0x37570000, 0x37580000, 0x37590000, 0x375A0000, 0x375B0000,
1188  0x375C0000, 0x375D0000, 0x375E0000, 0x375F0000, 0x37600000, 0x37610000, 0x37620000, 0x37630000, 0x37640000,
1189  0x37650000, 0x37660000, 0x37670000, 0x37680000, 0x37690000, 0x376A0000, 0x376B0000, 0x376C0000, 0x376D0000,
1190  0x376E0000, 0x376F0000, 0x37700000, 0x37710000, 0x37720000, 0x37730000, 0x37740000, 0x37750000, 0x37760000,
1191  0x37770000, 0x37780000, 0x37790000, 0x377A0000, 0x377B0000, 0x377C0000, 0x377D0000, 0x377E0000, 0x377F0000,
1192  0x37800000, 0x37808000, 0x37810000, 0x37818000, 0x37820000, 0x37828000, 0x37830000, 0x37838000, 0x37840000,
1193  0x37848000, 0x37850000, 0x37858000, 0x37860000, 0x37868000, 0x37870000, 0x37878000, 0x37880000, 0x37888000,
1194  0x37890000, 0x37898000, 0x378A0000, 0x378A8000, 0x378B0000, 0x378B8000, 0x378C0000, 0x378C8000, 0x378D0000,
1195  0x378D8000, 0x378E0000, 0x378E8000, 0x378F0000, 0x378F8000, 0x37900000, 0x37908000, 0x37910000, 0x37918000,
1196  0x37920000, 0x37928000, 0x37930000, 0x37938000, 0x37940000, 0x37948000, 0x37950000, 0x37958000, 0x37960000,
1197  0x37968000, 0x37970000, 0x37978000, 0x37980000, 0x37988000, 0x37990000, 0x37998000, 0x379A0000, 0x379A8000,
1198  0x379B0000, 0x379B8000, 0x379C0000, 0x379C8000, 0x379D0000, 0x379D8000, 0x379E0000, 0x379E8000, 0x379F0000,
1199  0x379F8000, 0x37A00000, 0x37A08000, 0x37A10000, 0x37A18000, 0x37A20000, 0x37A28000, 0x37A30000, 0x37A38000,
1200  0x37A40000, 0x37A48000, 0x37A50000, 0x37A58000, 0x37A60000, 0x37A68000, 0x37A70000, 0x37A78000, 0x37A80000,
1201  0x37A88000, 0x37A90000, 0x37A98000, 0x37AA0000, 0x37AA8000, 0x37AB0000, 0x37AB8000, 0x37AC0000, 0x37AC8000,
1202  0x37AD0000, 0x37AD8000, 0x37AE0000, 0x37AE8000, 0x37AF0000, 0x37AF8000, 0x37B00000, 0x37B08000, 0x37B10000,
1203  0x37B18000, 0x37B20000, 0x37B28000, 0x37B30000, 0x37B38000, 0x37B40000, 0x37B48000, 0x37B50000, 0x37B58000,
1204  0x37B60000, 0x37B68000, 0x37B70000, 0x37B78000, 0x37B80000, 0x37B88000, 0x37B90000, 0x37B98000, 0x37BA0000,
1205  0x37BA8000, 0x37BB0000, 0x37BB8000, 0x37BC0000, 0x37BC8000, 0x37BD0000, 0x37BD8000, 0x37BE0000, 0x37BE8000,
1206  0x37BF0000, 0x37BF8000, 0x37C00000, 0x37C08000, 0x37C10000, 0x37C18000, 0x37C20000, 0x37C28000, 0x37C30000,
1207  0x37C38000, 0x37C40000, 0x37C48000, 0x37C50000, 0x37C58000, 0x37C60000, 0x37C68000, 0x37C70000, 0x37C78000,
1208  0x37C80000, 0x37C88000, 0x37C90000, 0x37C98000, 0x37CA0000, 0x37CA8000, 0x37CB0000, 0x37CB8000, 0x37CC0000,
1209  0x37CC8000, 0x37CD0000, 0x37CD8000, 0x37CE0000, 0x37CE8000, 0x37CF0000, 0x37CF8000, 0x37D00000, 0x37D08000,
1210  0x37D10000, 0x37D18000, 0x37D20000, 0x37D28000, 0x37D30000, 0x37D38000, 0x37D40000, 0x37D48000, 0x37D50000,
1211  0x37D58000, 0x37D60000, 0x37D68000, 0x37D70000, 0x37D78000, 0x37D80000, 0x37D88000, 0x37D90000, 0x37D98000,
1212  0x37DA0000, 0x37DA8000, 0x37DB0000, 0x37DB8000, 0x37DC0000, 0x37DC8000, 0x37DD0000, 0x37DD8000, 0x37DE0000,
1213  0x37DE8000, 0x37DF0000, 0x37DF8000, 0x37E00000, 0x37E08000, 0x37E10000, 0x37E18000, 0x37E20000, 0x37E28000,
1214  0x37E30000, 0x37E38000, 0x37E40000, 0x37E48000, 0x37E50000, 0x37E58000, 0x37E60000, 0x37E68000, 0x37E70000,
1215  0x37E78000, 0x37E80000, 0x37E88000, 0x37E90000, 0x37E98000, 0x37EA0000, 0x37EA8000, 0x37EB0000, 0x37EB8000,
1216  0x37EC0000, 0x37EC8000, 0x37ED0000, 0x37ED8000, 0x37EE0000, 0x37EE8000, 0x37EF0000, 0x37EF8000, 0x37F00000,
1217  0x37F08000, 0x37F10000, 0x37F18000, 0x37F20000, 0x37F28000, 0x37F30000, 0x37F38000, 0x37F40000, 0x37F48000,
1218  0x37F50000, 0x37F58000, 0x37F60000, 0x37F68000, 0x37F70000, 0x37F78000, 0x37F80000, 0x37F88000, 0x37F90000,
1219  0x37F98000, 0x37FA0000, 0x37FA8000, 0x37FB0000, 0x37FB8000, 0x37FC0000, 0x37FC8000, 0x37FD0000, 0x37FD8000,
1220  0x37FE0000, 0x37FE8000, 0x37FF0000, 0x37FF8000, 0x38000000, 0x38004000, 0x38008000, 0x3800C000, 0x38010000,
1221  0x38014000, 0x38018000, 0x3801C000, 0x38020000, 0x38024000, 0x38028000, 0x3802C000, 0x38030000, 0x38034000,
1222  0x38038000, 0x3803C000, 0x38040000, 0x38044000, 0x38048000, 0x3804C000, 0x38050000, 0x38054000, 0x38058000,
1223  0x3805C000, 0x38060000, 0x38064000, 0x38068000, 0x3806C000, 0x38070000, 0x38074000, 0x38078000, 0x3807C000,
1224  0x38080000, 0x38084000, 0x38088000, 0x3808C000, 0x38090000, 0x38094000, 0x38098000, 0x3809C000, 0x380A0000,
1225  0x380A4000, 0x380A8000, 0x380AC000, 0x380B0000, 0x380B4000, 0x380B8000, 0x380BC000, 0x380C0000, 0x380C4000,
1226  0x380C8000, 0x380CC000, 0x380D0000, 0x380D4000, 0x380D8000, 0x380DC000, 0x380E0000, 0x380E4000, 0x380E8000,
1227  0x380EC000, 0x380F0000, 0x380F4000, 0x380F8000, 0x380FC000, 0x38100000, 0x38104000, 0x38108000, 0x3810C000,
1228  0x38110000, 0x38114000, 0x38118000, 0x3811C000, 0x38120000, 0x38124000, 0x38128000, 0x3812C000, 0x38130000,
1229  0x38134000, 0x38138000, 0x3813C000, 0x38140000, 0x38144000, 0x38148000, 0x3814C000, 0x38150000, 0x38154000,
1230  0x38158000, 0x3815C000, 0x38160000, 0x38164000, 0x38168000, 0x3816C000, 0x38170000, 0x38174000, 0x38178000,
1231  0x3817C000, 0x38180000, 0x38184000, 0x38188000, 0x3818C000, 0x38190000, 0x38194000, 0x38198000, 0x3819C000,
1232  0x381A0000, 0x381A4000, 0x381A8000, 0x381AC000, 0x381B0000, 0x381B4000, 0x381B8000, 0x381BC000, 0x381C0000,
1233  0x381C4000, 0x381C8000, 0x381CC000, 0x381D0000, 0x381D4000, 0x381D8000, 0x381DC000, 0x381E0000, 0x381E4000,
1234  0x381E8000, 0x381EC000, 0x381F0000, 0x381F4000, 0x381F8000, 0x381FC000, 0x38200000, 0x38204000, 0x38208000,
1235  0x3820C000, 0x38210000, 0x38214000, 0x38218000, 0x3821C000, 0x38220000, 0x38224000, 0x38228000, 0x3822C000,
1236  0x38230000, 0x38234000, 0x38238000, 0x3823C000, 0x38240000, 0x38244000, 0x38248000, 0x3824C000, 0x38250000,
1237  0x38254000, 0x38258000, 0x3825C000, 0x38260000, 0x38264000, 0x38268000, 0x3826C000, 0x38270000, 0x38274000,
1238  0x38278000, 0x3827C000, 0x38280000, 0x38284000, 0x38288000, 0x3828C000, 0x38290000, 0x38294000, 0x38298000,
1239  0x3829C000, 0x382A0000, 0x382A4000, 0x382A8000, 0x382AC000, 0x382B0000, 0x382B4000, 0x382B8000, 0x382BC000,
1240  0x382C0000, 0x382C4000, 0x382C8000, 0x382CC000, 0x382D0000, 0x382D4000, 0x382D8000, 0x382DC000, 0x382E0000,
1241  0x382E4000, 0x382E8000, 0x382EC000, 0x382F0000, 0x382F4000, 0x382F8000, 0x382FC000, 0x38300000, 0x38304000,
1242  0x38308000, 0x3830C000, 0x38310000, 0x38314000, 0x38318000, 0x3831C000, 0x38320000, 0x38324000, 0x38328000,
1243  0x3832C000, 0x38330000, 0x38334000, 0x38338000, 0x3833C000, 0x38340000, 0x38344000, 0x38348000, 0x3834C000,
1244  0x38350000, 0x38354000, 0x38358000, 0x3835C000, 0x38360000, 0x38364000, 0x38368000, 0x3836C000, 0x38370000,
1245  0x38374000, 0x38378000, 0x3837C000, 0x38380000, 0x38384000, 0x38388000, 0x3838C000, 0x38390000, 0x38394000,
1246  0x38398000, 0x3839C000, 0x383A0000, 0x383A4000, 0x383A8000, 0x383AC000, 0x383B0000, 0x383B4000, 0x383B8000,
1247  0x383BC000, 0x383C0000, 0x383C4000, 0x383C8000, 0x383CC000, 0x383D0000, 0x383D4000, 0x383D8000, 0x383DC000,
1248  0x383E0000, 0x383E4000, 0x383E8000, 0x383EC000, 0x383F0000, 0x383F4000, 0x383F8000, 0x383FC000, 0x38400000,
1249  0x38404000, 0x38408000, 0x3840C000, 0x38410000, 0x38414000, 0x38418000, 0x3841C000, 0x38420000, 0x38424000,
1250  0x38428000, 0x3842C000, 0x38430000, 0x38434000, 0x38438000, 0x3843C000, 0x38440000, 0x38444000, 0x38448000,
1251  0x3844C000, 0x38450000, 0x38454000, 0x38458000, 0x3845C000, 0x38460000, 0x38464000, 0x38468000, 0x3846C000,
1252  0x38470000, 0x38474000, 0x38478000, 0x3847C000, 0x38480000, 0x38484000, 0x38488000, 0x3848C000, 0x38490000,
1253  0x38494000, 0x38498000, 0x3849C000, 0x384A0000, 0x384A4000, 0x384A8000, 0x384AC000, 0x384B0000, 0x384B4000,
1254  0x384B8000, 0x384BC000, 0x384C0000, 0x384C4000, 0x384C8000, 0x384CC000, 0x384D0000, 0x384D4000, 0x384D8000,
1255  0x384DC000, 0x384E0000, 0x384E4000, 0x384E8000, 0x384EC000, 0x384F0000, 0x384F4000, 0x384F8000, 0x384FC000,
1256  0x38500000, 0x38504000, 0x38508000, 0x3850C000, 0x38510000, 0x38514000, 0x38518000, 0x3851C000, 0x38520000,
1257  0x38524000, 0x38528000, 0x3852C000, 0x38530000, 0x38534000, 0x38538000, 0x3853C000, 0x38540000, 0x38544000,
1258  0x38548000, 0x3854C000, 0x38550000, 0x38554000, 0x38558000, 0x3855C000, 0x38560000, 0x38564000, 0x38568000,
1259  0x3856C000, 0x38570000, 0x38574000, 0x38578000, 0x3857C000, 0x38580000, 0x38584000, 0x38588000, 0x3858C000,
1260  0x38590000, 0x38594000, 0x38598000, 0x3859C000, 0x385A0000, 0x385A4000, 0x385A8000, 0x385AC000, 0x385B0000,
1261  0x385B4000, 0x385B8000, 0x385BC000, 0x385C0000, 0x385C4000, 0x385C8000, 0x385CC000, 0x385D0000, 0x385D4000,
1262  0x385D8000, 0x385DC000, 0x385E0000, 0x385E4000, 0x385E8000, 0x385EC000, 0x385F0000, 0x385F4000, 0x385F8000,
1263  0x385FC000, 0x38600000, 0x38604000, 0x38608000, 0x3860C000, 0x38610000, 0x38614000, 0x38618000, 0x3861C000,
1264  0x38620000, 0x38624000, 0x38628000, 0x3862C000, 0x38630000, 0x38634000, 0x38638000, 0x3863C000, 0x38640000,
1265  0x38644000, 0x38648000, 0x3864C000, 0x38650000, 0x38654000, 0x38658000, 0x3865C000, 0x38660000, 0x38664000,
1266  0x38668000, 0x3866C000, 0x38670000, 0x38674000, 0x38678000, 0x3867C000, 0x38680000, 0x38684000, 0x38688000,
1267  0x3868C000, 0x38690000, 0x38694000, 0x38698000, 0x3869C000, 0x386A0000, 0x386A4000, 0x386A8000, 0x386AC000,
1268  0x386B0000, 0x386B4000, 0x386B8000, 0x386BC000, 0x386C0000, 0x386C4000, 0x386C8000, 0x386CC000, 0x386D0000,
1269  0x386D4000, 0x386D8000, 0x386DC000, 0x386E0000, 0x386E4000, 0x386E8000, 0x386EC000, 0x386F0000, 0x386F4000,
1270  0x386F8000, 0x386FC000, 0x38700000, 0x38704000, 0x38708000, 0x3870C000, 0x38710000, 0x38714000, 0x38718000,
1271  0x3871C000, 0x38720000, 0x38724000, 0x38728000, 0x3872C000, 0x38730000, 0x38734000, 0x38738000, 0x3873C000,
1272  0x38740000, 0x38744000, 0x38748000, 0x3874C000, 0x38750000, 0x38754000, 0x38758000, 0x3875C000, 0x38760000,
1273  0x38764000, 0x38768000, 0x3876C000, 0x38770000, 0x38774000, 0x38778000, 0x3877C000, 0x38780000, 0x38784000,
1274  0x38788000, 0x3878C000, 0x38790000, 0x38794000, 0x38798000, 0x3879C000, 0x387A0000, 0x387A4000, 0x387A8000,
1275  0x387AC000, 0x387B0000, 0x387B4000, 0x387B8000, 0x387BC000, 0x387C0000, 0x387C4000, 0x387C8000, 0x387CC000,
1276  0x387D0000, 0x387D4000, 0x387D8000, 0x387DC000, 0x387E0000, 0x387E4000, 0x387E8000, 0x387EC000, 0x387F0000,
1277  0x387F4000, 0x387F8000, 0x387FC000, 0x38000000, 0x38002000, 0x38004000, 0x38006000, 0x38008000, 0x3800A000,
1278  0x3800C000, 0x3800E000, 0x38010000, 0x38012000, 0x38014000, 0x38016000, 0x38018000, 0x3801A000, 0x3801C000,
1279  0x3801E000, 0x38020000, 0x38022000, 0x38024000, 0x38026000, 0x38028000, 0x3802A000, 0x3802C000, 0x3802E000,
1280  0x38030000, 0x38032000, 0x38034000, 0x38036000, 0x38038000, 0x3803A000, 0x3803C000, 0x3803E000, 0x38040000,
1281  0x38042000, 0x38044000, 0x38046000, 0x38048000, 0x3804A000, 0x3804C000, 0x3804E000, 0x38050000, 0x38052000,
1282  0x38054000, 0x38056000, 0x38058000, 0x3805A000, 0x3805C000, 0x3805E000, 0x38060000, 0x38062000, 0x38064000,
1283  0x38066000, 0x38068000, 0x3806A000, 0x3806C000, 0x3806E000, 0x38070000, 0x38072000, 0x38074000, 0x38076000,
1284  0x38078000, 0x3807A000, 0x3807C000, 0x3807E000, 0x38080000, 0x38082000, 0x38084000, 0x38086000, 0x38088000,
1285  0x3808A000, 0x3808C000, 0x3808E000, 0x38090000, 0x38092000, 0x38094000, 0x38096000, 0x38098000, 0x3809A000,
1286  0x3809C000, 0x3809E000, 0x380A0000, 0x380A2000, 0x380A4000, 0x380A6000, 0x380A8000, 0x380AA000, 0x380AC000,
1287  0x380AE000, 0x380B0000, 0x380B2000, 0x380B4000, 0x380B6000, 0x380B8000, 0x380BA000, 0x380BC000, 0x380BE000,
1288  0x380C0000, 0x380C2000, 0x380C4000, 0x380C6000, 0x380C8000, 0x380CA000, 0x380CC000, 0x380CE000, 0x380D0000,
1289  0x380D2000, 0x380D4000, 0x380D6000, 0x380D8000, 0x380DA000, 0x380DC000, 0x380DE000, 0x380E0000, 0x380E2000,
1290  0x380E4000, 0x380E6000, 0x380E8000, 0x380EA000, 0x380EC000, 0x380EE000, 0x380F0000, 0x380F2000, 0x380F4000,
1291  0x380F6000, 0x380F8000, 0x380FA000, 0x380FC000, 0x380FE000, 0x38100000, 0x38102000, 0x38104000, 0x38106000,
1292  0x38108000, 0x3810A000, 0x3810C000, 0x3810E000, 0x38110000, 0x38112000, 0x38114000, 0x38116000, 0x38118000,
1293  0x3811A000, 0x3811C000, 0x3811E000, 0x38120000, 0x38122000, 0x38124000, 0x38126000, 0x38128000, 0x3812A000,
1294  0x3812C000, 0x3812E000, 0x38130000, 0x38132000, 0x38134000, 0x38136000, 0x38138000, 0x3813A000, 0x3813C000,
1295  0x3813E000, 0x38140000, 0x38142000, 0x38144000, 0x38146000, 0x38148000, 0x3814A000, 0x3814C000, 0x3814E000,
1296  0x38150000, 0x38152000, 0x38154000, 0x38156000, 0x38158000, 0x3815A000, 0x3815C000, 0x3815E000, 0x38160000,
1297  0x38162000, 0x38164000, 0x38166000, 0x38168000, 0x3816A000, 0x3816C000, 0x3816E000, 0x38170000, 0x38172000,
1298  0x38174000, 0x38176000, 0x38178000, 0x3817A000, 0x3817C000, 0x3817E000, 0x38180000, 0x38182000, 0x38184000,
1299  0x38186000, 0x38188000, 0x3818A000, 0x3818C000, 0x3818E000, 0x38190000, 0x38192000, 0x38194000, 0x38196000,
1300  0x38198000, 0x3819A000, 0x3819C000, 0x3819E000, 0x381A0000, 0x381A2000, 0x381A4000, 0x381A6000, 0x381A8000,
1301  0x381AA000, 0x381AC000, 0x381AE000, 0x381B0000, 0x381B2000, 0x381B4000, 0x381B6000, 0x381B8000, 0x381BA000,
1302  0x381BC000, 0x381BE000, 0x381C0000, 0x381C2000, 0x381C4000, 0x381C6000, 0x381C8000, 0x381CA000, 0x381CC000,
1303  0x381CE000, 0x381D0000, 0x381D2000, 0x381D4000, 0x381D6000, 0x381D8000, 0x381DA000, 0x381DC000, 0x381DE000,
1304  0x381E0000, 0x381E2000, 0x381E4000, 0x381E6000, 0x381E8000, 0x381EA000, 0x381EC000, 0x381EE000, 0x381F0000,
1305  0x381F2000, 0x381F4000, 0x381F6000, 0x381F8000, 0x381FA000, 0x381FC000, 0x381FE000, 0x38200000, 0x38202000,
1306  0x38204000, 0x38206000, 0x38208000, 0x3820A000, 0x3820C000, 0x3820E000, 0x38210000, 0x38212000, 0x38214000,
1307  0x38216000, 0x38218000, 0x3821A000, 0x3821C000, 0x3821E000, 0x38220000, 0x38222000, 0x38224000, 0x38226000,
1308  0x38228000, 0x3822A000, 0x3822C000, 0x3822E000, 0x38230000, 0x38232000, 0x38234000, 0x38236000, 0x38238000,
1309  0x3823A000, 0x3823C000, 0x3823E000, 0x38240000, 0x38242000, 0x38244000, 0x38246000, 0x38248000, 0x3824A000,
1310  0x3824C000, 0x3824E000, 0x38250000, 0x38252000, 0x38254000, 0x38256000, 0x38258000, 0x3825A000, 0x3825C000,
1311  0x3825E000, 0x38260000, 0x38262000, 0x38264000, 0x38266000, 0x38268000, 0x3826A000, 0x3826C000, 0x3826E000,
1312  0x38270000, 0x38272000, 0x38274000, 0x38276000, 0x38278000, 0x3827A000, 0x3827C000, 0x3827E000, 0x38280000,
1313  0x38282000, 0x38284000, 0x38286000, 0x38288000, 0x3828A000, 0x3828C000, 0x3828E000, 0x38290000, 0x38292000,
1314  0x38294000, 0x38296000, 0x38298000, 0x3829A000, 0x3829C000, 0x3829E000, 0x382A0000, 0x382A2000, 0x382A4000,
1315  0x382A6000, 0x382A8000, 0x382AA000, 0x382AC000, 0x382AE000, 0x382B0000, 0x382B2000, 0x382B4000, 0x382B6000,
1316  0x382B8000, 0x382BA000, 0x382BC000, 0x382BE000, 0x382C0000, 0x382C2000, 0x382C4000, 0x382C6000, 0x382C8000,
1317  0x382CA000, 0x382CC000, 0x382CE000, 0x382D0000, 0x382D2000, 0x382D4000, 0x382D6000, 0x382D8000, 0x382DA000,
1318  0x382DC000, 0x382DE000, 0x382E0000, 0x382E2000, 0x382E4000, 0x382E6000, 0x382E8000, 0x382EA000, 0x382EC000,
1319  0x382EE000, 0x382F0000, 0x382F2000, 0x382F4000, 0x382F6000, 0x382F8000, 0x382FA000, 0x382FC000, 0x382FE000,
1320  0x38300000, 0x38302000, 0x38304000, 0x38306000, 0x38308000, 0x3830A000, 0x3830C000, 0x3830E000, 0x38310000,
1321  0x38312000, 0x38314000, 0x38316000, 0x38318000, 0x3831A000, 0x3831C000, 0x3831E000, 0x38320000, 0x38322000,
1322  0x38324000, 0x38326000, 0x38328000, 0x3832A000, 0x3832C000, 0x3832E000, 0x38330000, 0x38332000, 0x38334000,
1323  0x38336000, 0x38338000, 0x3833A000, 0x3833C000, 0x3833E000, 0x38340000, 0x38342000, 0x38344000, 0x38346000,
1324  0x38348000, 0x3834A000, 0x3834C000, 0x3834E000, 0x38350000, 0x38352000, 0x38354000, 0x38356000, 0x38358000,
1325  0x3835A000, 0x3835C000, 0x3835E000, 0x38360000, 0x38362000, 0x38364000, 0x38366000, 0x38368000, 0x3836A000,
1326  0x3836C000, 0x3836E000, 0x38370000, 0x38372000, 0x38374000, 0x38376000, 0x38378000, 0x3837A000, 0x3837C000,
1327  0x3837E000, 0x38380000, 0x38382000, 0x38384000, 0x38386000, 0x38388000, 0x3838A000, 0x3838C000, 0x3838E000,
1328  0x38390000, 0x38392000, 0x38394000, 0x38396000, 0x38398000, 0x3839A000, 0x3839C000, 0x3839E000, 0x383A0000,
1329  0x383A2000, 0x383A4000, 0x383A6000, 0x383A8000, 0x383AA000, 0x383AC000, 0x383AE000, 0x383B0000, 0x383B2000,
1330  0x383B4000, 0x383B6000, 0x383B8000, 0x383BA000, 0x383BC000, 0x383BE000, 0x383C0000, 0x383C2000, 0x383C4000,
1331  0x383C6000, 0x383C8000, 0x383CA000, 0x383CC000, 0x383CE000, 0x383D0000, 0x383D2000, 0x383D4000, 0x383D6000,
1332  0x383D8000, 0x383DA000, 0x383DC000, 0x383DE000, 0x383E0000, 0x383E2000, 0x383E4000, 0x383E6000, 0x383E8000,
1333  0x383EA000, 0x383EC000, 0x383EE000, 0x383F0000, 0x383F2000, 0x383F4000, 0x383F6000, 0x383F8000, 0x383FA000,
1334  0x383FC000, 0x383FE000, 0x38400000, 0x38402000, 0x38404000, 0x38406000, 0x38408000, 0x3840A000, 0x3840C000,
1335  0x3840E000, 0x38410000, 0x38412000, 0x38414000, 0x38416000, 0x38418000, 0x3841A000, 0x3841C000, 0x3841E000,
1336  0x38420000, 0x38422000, 0x38424000, 0x38426000, 0x38428000, 0x3842A000, 0x3842C000, 0x3842E000, 0x38430000,
1337  0x38432000, 0x38434000, 0x38436000, 0x38438000, 0x3843A000, 0x3843C000, 0x3843E000, 0x38440000, 0x38442000,
1338  0x38444000, 0x38446000, 0x38448000, 0x3844A000, 0x3844C000, 0x3844E000, 0x38450000, 0x38452000, 0x38454000,
1339  0x38456000, 0x38458000, 0x3845A000, 0x3845C000, 0x3845E000, 0x38460000, 0x38462000, 0x38464000, 0x38466000,
1340  0x38468000, 0x3846A000, 0x3846C000, 0x3846E000, 0x38470000, 0x38472000, 0x38474000, 0x38476000, 0x38478000,
1341  0x3847A000, 0x3847C000, 0x3847E000, 0x38480000, 0x38482000, 0x38484000, 0x38486000, 0x38488000, 0x3848A000,
1342  0x3848C000, 0x3848E000, 0x38490000, 0x38492000, 0x38494000, 0x38496000, 0x38498000, 0x3849A000, 0x3849C000,
1343  0x3849E000, 0x384A0000, 0x384A2000, 0x384A4000, 0x384A6000, 0x384A8000, 0x384AA000, 0x384AC000, 0x384AE000,
1344  0x384B0000, 0x384B2000, 0x384B4000, 0x384B6000, 0x384B8000, 0x384BA000, 0x384BC000, 0x384BE000, 0x384C0000,
1345  0x384C2000, 0x384C4000, 0x384C6000, 0x384C8000, 0x384CA000, 0x384CC000, 0x384CE000, 0x384D0000, 0x384D2000,
1346  0x384D4000, 0x384D6000, 0x384D8000, 0x384DA000, 0x384DC000, 0x384DE000, 0x384E0000, 0x384E2000, 0x384E4000,
1347  0x384E6000, 0x384E8000, 0x384EA000, 0x384EC000, 0x384EE000, 0x384F0000, 0x384F2000, 0x384F4000, 0x384F6000,
1348  0x384F8000, 0x384FA000, 0x384FC000, 0x384FE000, 0x38500000, 0x38502000, 0x38504000, 0x38506000, 0x38508000,
1349  0x3850A000, 0x3850C000, 0x3850E000, 0x38510000, 0x38512000, 0x38514000, 0x38516000, 0x38518000, 0x3851A000,
1350  0x3851C000, 0x3851E000, 0x38520000, 0x38522000, 0x38524000, 0x38526000, 0x38528000, 0x3852A000, 0x3852C000,
1351  0x3852E000, 0x38530000, 0x38532000, 0x38534000, 0x38536000, 0x38538000, 0x3853A000, 0x3853C000, 0x3853E000,
1352  0x38540000, 0x38542000, 0x38544000, 0x38546000, 0x38548000, 0x3854A000, 0x3854C000, 0x3854E000, 0x38550000,
1353  0x38552000, 0x38554000, 0x38556000, 0x38558000, 0x3855A000, 0x3855C000, 0x3855E000, 0x38560000, 0x38562000,
1354  0x38564000, 0x38566000, 0x38568000, 0x3856A000, 0x3856C000, 0x3856E000, 0x38570000, 0x38572000, 0x38574000,
1355  0x38576000, 0x38578000, 0x3857A000, 0x3857C000, 0x3857E000, 0x38580000, 0x38582000, 0x38584000, 0x38586000,
1356  0x38588000, 0x3858A000, 0x3858C000, 0x3858E000, 0x38590000, 0x38592000, 0x38594000, 0x38596000, 0x38598000,
1357  0x3859A000, 0x3859C000, 0x3859E000, 0x385A0000, 0x385A2000, 0x385A4000, 0x385A6000, 0x385A8000, 0x385AA000,
1358  0x385AC000, 0x385AE000, 0x385B0000, 0x385B2000, 0x385B4000, 0x385B6000, 0x385B8000, 0x385BA000, 0x385BC000,
1359  0x385BE000, 0x385C0000, 0x385C2000, 0x385C4000, 0x385C6000, 0x385C8000, 0x385CA000, 0x385CC000, 0x385CE000,
1360  0x385D0000, 0x385D2000, 0x385D4000, 0x385D6000, 0x385D8000, 0x385DA000, 0x385DC000, 0x385DE000, 0x385E0000,
1361  0x385E2000, 0x385E4000, 0x385E6000, 0x385E8000, 0x385EA000, 0x385EC000, 0x385EE000, 0x385F0000, 0x385F2000,
1362  0x385F4000, 0x385F6000, 0x385F8000, 0x385FA000, 0x385FC000, 0x385FE000, 0x38600000, 0x38602000, 0x38604000,
1363  0x38606000, 0x38608000, 0x3860A000, 0x3860C000, 0x3860E000, 0x38610000, 0x38612000, 0x38614000, 0x38616000,
1364  0x38618000, 0x3861A000, 0x3861C000, 0x3861E000, 0x38620000, 0x38622000, 0x38624000, 0x38626000, 0x38628000,
1365  0x3862A000, 0x3862C000, 0x3862E000, 0x38630000, 0x38632000, 0x38634000, 0x38636000, 0x38638000, 0x3863A000,
1366  0x3863C000, 0x3863E000, 0x38640000, 0x38642000, 0x38644000, 0x38646000, 0x38648000, 0x3864A000, 0x3864C000,
1367  0x3864E000, 0x38650000, 0x38652000, 0x38654000, 0x38656000, 0x38658000, 0x3865A000, 0x3865C000, 0x3865E000,
1368  0x38660000, 0x38662000, 0x38664000, 0x38666000, 0x38668000, 0x3866A000, 0x3866C000, 0x3866E000, 0x38670000,
1369  0x38672000, 0x38674000, 0x38676000, 0x38678000, 0x3867A000, 0x3867C000, 0x3867E000, 0x38680000, 0x38682000,
1370  0x38684000, 0x38686000, 0x38688000, 0x3868A000, 0x3868C000, 0x3868E000, 0x38690000, 0x38692000, 0x38694000,
1371  0x38696000, 0x38698000, 0x3869A000, 0x3869C000, 0x3869E000, 0x386A0000, 0x386A2000, 0x386A4000, 0x386A6000,
1372  0x386A8000, 0x386AA000, 0x386AC000, 0x386AE000, 0x386B0000, 0x386B2000, 0x386B4000, 0x386B6000, 0x386B8000,
1373  0x386BA000, 0x386BC000, 0x386BE000, 0x386C0000, 0x386C2000, 0x386C4000, 0x386C6000, 0x386C8000, 0x386CA000,
1374  0x386CC000, 0x386CE000, 0x386D0000, 0x386D2000, 0x386D4000, 0x386D6000, 0x386D8000, 0x386DA000, 0x386DC000,
1375  0x386DE000, 0x386E0000, 0x386E2000, 0x386E4000, 0x386E6000, 0x386E8000, 0x386EA000, 0x386EC000, 0x386EE000,
1376  0x386F0000, 0x386F2000, 0x386F4000, 0x386F6000, 0x386F8000, 0x386FA000, 0x386FC000, 0x386FE000, 0x38700000,
1377  0x38702000, 0x38704000, 0x38706000, 0x38708000, 0x3870A000, 0x3870C000, 0x3870E000, 0x38710000, 0x38712000,
1378  0x38714000, 0x38716000, 0x38718000, 0x3871A000, 0x3871C000, 0x3871E000, 0x38720000, 0x38722000, 0x38724000,
1379  0x38726000, 0x38728000, 0x3872A000, 0x3872C000, 0x3872E000, 0x38730000, 0x38732000, 0x38734000, 0x38736000,
1380  0x38738000, 0x3873A000, 0x3873C000, 0x3873E000, 0x38740000, 0x38742000, 0x38744000, 0x38746000, 0x38748000,
1381  0x3874A000, 0x3874C000, 0x3874E000, 0x38750000, 0x38752000, 0x38754000, 0x38756000, 0x38758000, 0x3875A000,
1382  0x3875C000, 0x3875E000, 0x38760000, 0x38762000, 0x38764000, 0x38766000, 0x38768000, 0x3876A000, 0x3876C000,
1383  0x3876E000, 0x38770000, 0x38772000, 0x38774000, 0x38776000, 0x38778000, 0x3877A000, 0x3877C000, 0x3877E000,
1384  0x38780000, 0x38782000, 0x38784000, 0x38786000, 0x38788000, 0x3878A000, 0x3878C000, 0x3878E000, 0x38790000,
1385  0x38792000, 0x38794000, 0x38796000, 0x38798000, 0x3879A000, 0x3879C000, 0x3879E000, 0x387A0000, 0x387A2000,
1386  0x387A4000, 0x387A6000, 0x387A8000, 0x387AA000, 0x387AC000, 0x387AE000, 0x387B0000, 0x387B2000, 0x387B4000,
1387  0x387B6000, 0x387B8000, 0x387BA000, 0x387BC000, 0x387BE000, 0x387C0000, 0x387C2000, 0x387C4000, 0x387C6000,
1388  0x387C8000, 0x387CA000, 0x387CC000, 0x387CE000, 0x387D0000, 0x387D2000, 0x387D4000, 0x387D6000, 0x387D8000,
1389  0x387DA000, 0x387DC000, 0x387DE000, 0x387E0000, 0x387E2000, 0x387E4000, 0x387E6000, 0x387E8000, 0x387EA000,
1390  0x387EC000, 0x387EE000, 0x387F0000, 0x387F2000, 0x387F4000, 0x387F6000, 0x387F8000, 0x387FA000, 0x387FC000,
1391  0x387FE000 };
1392  static const bits<float>::type exponent_table[64] = { 0x00000000, 0x00800000, 0x01000000, 0x01800000,
1393  0x02000000, 0x02800000, 0x03000000, 0x03800000, 0x04000000, 0x04800000, 0x05000000, 0x05800000, 0x06000000,
1394  0x06800000, 0x07000000, 0x07800000, 0x08000000, 0x08800000, 0x09000000, 0x09800000, 0x0A000000, 0x0A800000,
1395  0x0B000000, 0x0B800000, 0x0C000000, 0x0C800000, 0x0D000000, 0x0D800000, 0x0E000000, 0x0E800000, 0x0F000000,
1396  0x47800000, 0x80000000, 0x80800000, 0x81000000, 0x81800000, 0x82000000, 0x82800000, 0x83000000, 0x83800000,
1397  0x84000000, 0x84800000, 0x85000000, 0x85800000, 0x86000000, 0x86800000, 0x87000000, 0x87800000, 0x88000000,
1398  0x88800000, 0x89000000, 0x89800000, 0x8A000000, 0x8A800000, 0x8B000000, 0x8B800000, 0x8C000000, 0x8C800000,
1399  0x8D000000, 0x8D800000, 0x8E000000, 0x8E800000, 0x8F000000, 0xC7800000 };
1400  static const unsigned short offset_table[64] = { 0, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1401  1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1402  1024, 1024, 1024, 0, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1403  1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024 };
1404  bits<float>::type fbits =
1405  mantissa_table[offset_table[value >> 10] + (value & 0x3FF)] + exponent_table[value >> 10];
1406 #endif
1407  float out;
1408  std::memcpy(&out, &fbits, sizeof(float));
1409  return out;
1410 #endif
1411  }
1412 
1416  inline double half2float_impl(unsigned int value, double, true_type)
1417  {
1418 #if HALF_ENABLE_F16C_INTRINSICS
1419  return _mm_cvtsd_f64(_mm_cvtps_pd(_mm_cvtph_ps(_mm_cvtsi32_si128(value))));
1420 #else
1421  uint32 hi = static_cast<uint32>(value & 0x8000) << 16;
1422  unsigned int abs = value & 0x7FFF;
1423  if (abs) {
1424  hi |= 0x3F000000 << static_cast<unsigned>(abs >= 0x7C00);
1425  for (; abs < 0x400; abs <<= 1, hi -= 0x100000)
1426  ;
1427  hi += static_cast<uint32>(abs) << 10;
1428  }
1429  bits<double>::type dbits = static_cast<bits<double>::type>(hi) << 32;
1430  double out;
1431  std::memcpy(&out, &dbits, sizeof(double));
1432  return out;
1433 #endif
1434  }
1435 
1440  template <typename T> T half2float_impl(unsigned int value, T, ...)
1441  {
1442  T out;
1443  unsigned int abs = value & 0x7FFF;
1444  if (abs > 0x7C00)
1445  out = (std::numeric_limits<T>::has_signaling_NaN && !(abs & 0x200))
1446  ? std::numeric_limits<T>::signaling_NaN()
1447  : std::numeric_limits<T>::has_quiet_NaN ? std::numeric_limits<T>::quiet_NaN()
1448  : T();
1449  else if (abs == 0x7C00)
1450  out = std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity()
1451  : std::numeric_limits<T>::max();
1452  else if (abs > 0x3FF)
1453  out = std::ldexp(static_cast<T>((abs & 0x3FF) | 0x400), (abs >> 10) - 25);
1454  else
1455  out = std::ldexp(static_cast<T>(abs), -24);
1456  return (value & 0x8000) ? -out : out;
1457  }
1458 
1463  template <typename T> T half2float(unsigned int value)
1464  {
1465  return half2float_impl(
1466  value, T(), bool_type<std::numeric_limits<T>::is_iec559 && sizeof(typename bits<T>::type) == sizeof(T)>());
1467  }
1468 
1476  template <std::float_round_style R, bool E, bool I, typename T> T half2int(unsigned int value)
1477  {
1478  unsigned int abs = value & 0x7FFF;
1479  if (abs >= 0x7C00) {
1480  raise(FE_INVALID);
1481  return (value & 0x8000) ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max();
1482  }
1483  if (abs < 0x3800) {
1484  raise(FE_INEXACT, I);
1485  return (R == std::round_toward_infinity) ? T(~(value >> 15) & (abs != 0))
1486  : (R == std::round_toward_neg_infinity) ? -T(value > 0x8000)
1487  : T();
1488  }
1489  int exp = 25 - (abs >> 10);
1490  unsigned int m = (value & 0x3FF) | 0x400;
1491  int32 i = static_cast<int32>((exp <= 0)
1492  ? (m << -exp)
1493  : ((m +
1494  ((R == std::round_to_nearest) ? ((1 << (exp - 1)) - (~(m >> exp) & E))
1495  : (R == std::round_toward_infinity) ? (((1 << exp) - 1) & ((value >> 15) - 1))
1496  : (R == std::round_toward_neg_infinity) ? (((1 << exp) - 1) & -(value >> 15))
1497  : 0)) >>
1498  exp));
1499  if ((!std::numeric_limits<T>::is_signed && (value & 0x8000)) ||
1500  (std::numeric_limits<T>::digits < 16 &&
1501  ((value & 0x8000) ? (-i < std::numeric_limits<T>::min()) : (i > std::numeric_limits<T>::max()))))
1502  raise(FE_INVALID);
1503  else if (I && exp > 0 && (m & ((1 << exp) - 1)))
1504  raise(FE_INEXACT);
1505  return static_cast<T>((value & 0x8000) ? -i : i);
1506  }
1507 
1511 
1517  template <std::float_round_style R> uint32 mulhi(uint32 x, uint32 y)
1518  {
1519  uint32 xy = (x >> 16) * (y & 0xFFFF), yx = (x & 0xFFFF) * (y >> 16),
1520  c = (xy & 0xFFFF) + (yx & 0xFFFF) + (((x & 0xFFFF) * (y & 0xFFFF)) >> 16);
1521  return (x >> 16) * (y >> 16) + (xy >> 16) + (yx >> 16) + (c >> 16) +
1522  ((R == std::round_to_nearest) ? ((c >> 15) & 1)
1523  : (R == std::round_toward_infinity) ? ((c & 0xFFFF) != 0)
1524  : 0);
1525  }
1526 
1532  {
1533 #if HALF_ENABLE_CPP11_LONG_LONG
1534  return static_cast<uint32>(
1535  (static_cast<unsigned long long>(x) * static_cast<unsigned long long>(y) + 0x80000000) >> 32);
1536 #else
1537  return mulhi<std::round_to_nearest>(x, y);
1538 #endif
1539  }
1540 
1546  inline uint32 divide64(uint32 x, uint32 y, int& s)
1547  {
1548 #if HALF_ENABLE_CPP11_LONG_LONG
1549  unsigned long long xx = static_cast<unsigned long long>(x) << 32;
1550  return s = (xx % y != 0), static_cast<uint32>(xx / y);
1551 #else
1552  y >>= 1;
1553  uint32 rem = x, div = 0;
1554  for (unsigned int i = 0; i < 32; ++i) {
1555  div <<= 1;
1556  if (rem >= y) {
1557  rem -= y;
1558  div |= 1;
1559  }
1560  rem <<= 1;
1561  }
1562  return s = rem > 1, div;
1563 #endif
1564  }
1565 
1573  template <bool Q, bool R> unsigned int mod(unsigned int x, unsigned int y, int* quo = NULL)
1574  {
1575  unsigned int q = 0;
1576  if (x > y) {
1577  int absx = x, absy = y, expx = 0, expy = 0;
1578  for (; absx < 0x400; absx <<= 1, --expx)
1579  ;
1580  for (; absy < 0x400; absy <<= 1, --expy)
1581  ;
1582  expx += absx >> 10;
1583  expy += absy >> 10;
1584  int mx = (absx & 0x3FF) | 0x400, my = (absy & 0x3FF) | 0x400;
1585  for (int d = expx - expy; d; --d) {
1586  if (!Q && mx == my)
1587  return 0;
1588  if (mx >= my) {
1589  mx -= my;
1590  q += Q;
1591  }
1592  mx <<= 1;
1593  q <<= static_cast<int>(Q);
1594  }
1595  if (!Q && mx == my)
1596  return 0;
1597  if (mx >= my) {
1598  mx -= my;
1599  ++q;
1600  }
1601  if (Q) {
1602  q &= (1 << (std::numeric_limits<int>::digits - 1)) - 1;
1603  if (!mx)
1604  return *quo = q, 0;
1605  }
1606  for (; mx < 0x400; mx <<= 1, --expy)
1607  ;
1608  x = (expy > 0) ? ((expy << 10) | (mx & 0x3FF)) : (mx >> (1 - expy));
1609  }
1610  if (R) {
1611  unsigned int a, b;
1612  if (y < 0x800) {
1613  a = (x < 0x400) ? (x << 1) : (x + 0x400);
1614  b = y;
1615  } else {
1616  a = x;
1617  b = y - 0x400;
1618  }
1619  if (a > b || (a == b && (q & 1))) {
1620  int exp = (y >> 10) + (y <= 0x3FF), d = exp - (x >> 10) - (x <= 0x3FF);
1621  int m = (((y & 0x3FF) | ((y > 0x3FF) << 10)) << 1) - (((x & 0x3FF) | ((x > 0x3FF) << 10)) << (1 - d));
1622  for (; m < 0x800 && exp > 1; m <<= 1, --exp)
1623  ;
1624  x = 0x8000 + ((exp - 1) << 10) + (m >> 1);
1625  q += Q;
1626  }
1627  }
1628  if (Q)
1629  *quo = q;
1630  return x;
1631  }
1632 
1638  template <unsigned int F> uint32 sqrt(uint32& r, int& exp)
1639  {
1640  int i = exp & 1;
1641  r <<= i;
1642  exp = (exp - i) / 2;
1643  uint32 m = 0;
1644  for (uint32 bit = static_cast<uint32>(1) << F; bit; bit >>= 2) {
1645  if (r < m + bit)
1646  m >>= 1;
1647  else {
1648  r -= m + bit;
1649  m = (m >> 1) + bit;
1650  }
1651  }
1652  return m;
1653  }
1654 
1660  inline uint32 exp2(uint32 m, unsigned int n = 32)
1661  {
1662  static const uint32 logs[] = { 0x80000000, 0x4AE00D1D, 0x2934F098, 0x15C01A3A, 0x0B31FB7D, 0x05AEB4DD,
1663  0x02DCF2D1, 0x016FE50B, 0x00B84E23, 0x005C3E10, 0x002E24CA, 0x001713D6, 0x000B8A47, 0x0005C53B, 0x0002E2A3,
1664  0x00017153, 0x0000B8AA, 0x00005C55, 0x00002E2B, 0x00001715, 0x00000B8B, 0x000005C5, 0x000002E3, 0x00000171,
1665  0x000000B9, 0x0000005C, 0x0000002E, 0x00000017, 0x0000000C, 0x00000006, 0x00000003, 0x00000001 };
1666  if (!m)
1667  return 0x80000000;
1668  uint32 mx = 0x80000000, my = 0;
1669  for (unsigned int i = 1; i < n; ++i) {
1670  uint32 mz = my + logs[i];
1671  if (mz <= m) {
1672  my = mz;
1673  mx += mx >> i;
1674  }
1675  }
1676  return mx;
1677  }
1678 
1684  inline uint32 log2(uint32 m, unsigned int n = 32)
1685  {
1686  static const uint32 logs[] = { 0x80000000, 0x4AE00D1D, 0x2934F098, 0x15C01A3A, 0x0B31FB7D, 0x05AEB4DD,
1687  0x02DCF2D1, 0x016FE50B, 0x00B84E23, 0x005C3E10, 0x002E24CA, 0x001713D6, 0x000B8A47, 0x0005C53B, 0x0002E2A3,
1688  0x00017153, 0x0000B8AA, 0x00005C55, 0x00002E2B, 0x00001715, 0x00000B8B, 0x000005C5, 0x000002E3, 0x00000171,
1689  0x000000B9, 0x0000005C, 0x0000002E, 0x00000017, 0x0000000C, 0x00000006, 0x00000003, 0x00000001 };
1690  if (m == 0x40000000)
1691  return 0;
1692  uint32 mx = 0x40000000, my = 0;
1693  for (unsigned int i = 1; i < n; ++i) {
1694  uint32 mz = mx + (mx >> i);
1695  if (mz <= m) {
1696  mx = mz;
1697  my += logs[i];
1698  }
1699  }
1700  return my;
1701  }
1702 
1708  inline std::pair<uint32, uint32> sincos(uint32 mz, unsigned int n = 31)
1709  {
1710  static const uint32 angles[] = { 0x3243F6A9, 0x1DAC6705, 0x0FADBAFD, 0x07F56EA7, 0x03FEAB77, 0x01FFD55C,
1711  0x00FFFAAB, 0x007FFF55, 0x003FFFEB, 0x001FFFFD, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000,
1712  0x00008000, 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080,
1713  0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 };
1714  uint32 mx = 0x26DD3B6A, my = 0;
1715  for (unsigned int i = 0; i < n; ++i) {
1716  uint32 sign = sign_mask(mz);
1717  uint32 tx = mx - (arithmetic_shift(my, i) ^ sign) + sign;
1718  uint32 ty = my + (arithmetic_shift(mx, i) ^ sign) - sign;
1719  mx = tx;
1720  my = ty;
1721  mz -= (angles[i] ^ sign) - sign;
1722  }
1723  return std::make_pair(my, mx);
1724  }
1725 
1732  inline uint32 atan2(uint32 my, uint32 mx, unsigned int n = 31)
1733  {
1734  static const uint32 angles[] = { 0x3243F6A9, 0x1DAC6705, 0x0FADBAFD, 0x07F56EA7, 0x03FEAB77, 0x01FFD55C,
1735  0x00FFFAAB, 0x007FFF55, 0x003FFFEB, 0x001FFFFD, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000,
1736  0x00008000, 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080,
1737  0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 };
1738  uint32 mz = 0;
1739  for (unsigned int i = 0; i < n; ++i) {
1740  uint32 sign = sign_mask(my);
1741  uint32 tx = mx + (arithmetic_shift(my, i) ^ sign) - sign;
1742  uint32 ty = my - (arithmetic_shift(mx, i) ^ sign) + sign;
1743  mx = tx;
1744  my = ty;
1745  mz += (angles[i] ^ sign) - sign;
1746  }
1747  return mz;
1748  }
1749 
1754  inline uint32 angle_arg(unsigned int abs, int& k)
1755  {
1756  uint32 m = (abs & 0x3FF) | ((abs > 0x3FF) << 10);
1757  int exp = (abs >> 10) + (abs <= 0x3FF) - 15;
1758  if (abs < 0x3A48)
1759  return k = 0, m << (exp + 20);
1760 #if HALF_ENABLE_CPP11_LONG_LONG
1761  unsigned long long y = m * 0xA2F9836E4E442, mask = (1ULL << (62 - exp)) - 1, yi = (y + (mask >> 1)) & ~mask,
1762  f = y - yi;
1763  uint32 sign = -static_cast<uint32>(f >> 63);
1764  k = static_cast<int>(yi >> (62 - exp));
1765  return (multiply64(static_cast<uint32>((sign ? -f : f) >> (31 - exp)), 0xC90FDAA2) ^ sign) - sign;
1766 #else
1767  uint32 yh = m * 0xA2F98 + mulhi<std::round_toward_zero>(m, 0x36E4E442), yl = (m * 0x36E4E442) & 0xFFFFFFFF;
1768  uint32 mask = (static_cast<uint32>(1) << (30 - exp)) - 1, yi = (yh + (mask >> 1)) & ~mask,
1769  sign = -static_cast<uint32>(yi > yh);
1770  k = static_cast<int>(yi >> (30 - exp));
1771  uint32 fh = (yh ^ sign) + (yi ^ ~sign) - ~sign, fl = (yl ^ sign) - sign;
1772  return (multiply64((exp > -1) ? (((fh << (1 + exp)) & 0xFFFFFFFF) | ((fl & 0xFFFFFFFF) >> (31 - exp))) : fh,
1773  0xC90FDAA2) ^
1774  sign) -
1775  sign;
1776 #endif
1777  }
1778 
1782  inline std::pair<uint32, uint32> atan2_args(unsigned int abs)
1783  {
1784  int exp = -15;
1785  for (; abs < 0x400; abs <<= 1, --exp)
1786  ;
1787  exp += abs >> 10;
1788  uint32 my = ((abs & 0x3FF) | 0x400) << 5, r = my * my;
1789  int rexp = 2 * exp;
1790  r = 0x40000000 - ((rexp > -31) ? ((r >> -rexp) | ((r & ((static_cast<uint32>(1) << -rexp) - 1)) != 0)) : 1);
1791  for (rexp = 0; r < 0x40000000; r <<= 1, --rexp)
1792  ;
1793  uint32 mx = sqrt<30>(r, rexp);
1794  int d = exp - rexp;
1795  if (d < 0)
1796  return std::make_pair((d < -14) ? ((my >> (-d - 14)) + ((my >> (-d - 15)) & 1)) : (my << (14 + d)),
1797  (mx << 14) + (r << 13) / mx);
1798  if (d > 0)
1799  return std::make_pair(my << 14,
1800  (d > 14) ? ((mx >> (d - 14)) + ((mx >> (d - 15)) & 1))
1801  : ((d == 14) ? mx : ((mx << (14 - d)) + (r << (13 - d)) / mx)));
1802  return std::make_pair(my << 13, (mx << 13) + (r << 12) / mx);
1803  }
1804 
1810  inline std::pair<uint32, uint32> hyperbolic_args(unsigned int abs, int& exp, unsigned int n = 32)
1811  {
1812  uint32 mx = detail::multiply64(static_cast<uint32>((abs & 0x3FF) + ((abs > 0x3FF) << 10)) << 21, 0xB8AA3B29),
1813  my;
1814  int e = (abs >> 10) + (abs <= 0x3FF);
1815  if (e < 14) {
1816  exp = 0;
1817  mx >>= 14 - e;
1818  } else {
1819  exp = mx >> (45 - e);
1820  mx = (mx << (e - 14)) & 0x7FFFFFFF;
1821  }
1822  mx = exp2(mx, n);
1823  int d = exp << 1, s;
1824  if (mx > 0x80000000) {
1825  my = divide64(0x80000000, mx, s);
1826  my |= s;
1827  ++d;
1828  } else
1829  my = mx;
1830  return std::make_pair(mx, (d < 31) ? ((my >> d) | ((my & ((static_cast<uint32>(1) << d) - 1)) != 0)) : 1);
1831  }
1832 
1844  template <std::float_round_style R>
1845  unsigned int exp2_post(uint32 m, int exp, bool esign, unsigned int sign = 0, unsigned int n = 32)
1846  {
1847  if (esign) {
1848  exp = -exp - (m != 0);
1849  if (exp < -25)
1850  return underflow<R>(sign);
1851  else if (exp == -25)
1852  return rounded<R, false>(sign, 1, m != 0);
1853  } else if (exp > 15)
1854  return overflow<R>(sign);
1855  if (!m)
1856  return sign | (((exp += 15) > 0) ? (exp << 10) : check_underflow(0x200 >> -exp));
1857  m = exp2(m, n);
1858  int s = 0;
1859  if (esign)
1860  m = divide64(0x80000000, m, s);
1861  return fixed2half<R, 31, false, false, true>(m, exp + 14, sign, s);
1862  }
1863 
1875  template <std::float_round_style R, uint32 L>
1876  unsigned int log2_post(uint32 m, int ilog, int exp, unsigned int sign = 0)
1877  {
1878  uint32 msign = sign_mask(ilog);
1879  m = (((static_cast<uint32>(ilog) << 27) + (m >> 4)) ^ msign) - msign;
1880  if (!m)
1881  return 0;
1882  for (; m < 0x80000000; m <<= 1, --exp)
1883  ;
1884  int i = m >= L, s;
1885  exp += i;
1886  m >>= 1 + i;
1887  sign ^= msign & 0x8000;
1888  if (exp < -11)
1889  return underflow<R>(sign);
1890  m = divide64(m, L, s);
1891  return fixed2half<R, 30, false, false, true>(m, exp, sign, 1);
1892  }
1893 
1902  template <std::float_round_style R> unsigned int hypot_post(uint32 r, int exp)
1903  {
1904  int i = r >> 31;
1905  if ((exp += i) > 46)
1906  return overflow<R>();
1907  if (exp < -34)
1908  return underflow<R>();
1909  r = (r >> i) | (r & i);
1910  uint32 m = sqrt<30>(r, exp += 15);
1911  return fixed2half<R, 15, false, false, false>(m, exp - 1, 0, r != 0);
1912  }
1913 
1924  template <std::float_round_style R> unsigned int tangent_post(uint32 my, uint32 mx, int exp, unsigned int sign = 0)
1925  {
1926  int i = my >= mx, s;
1927  exp += i;
1928  if (exp > 29)
1929  return overflow<R>(sign);
1930  if (exp < -11)
1931  return underflow<R>(sign);
1932  uint32 m = divide64(my >> (i + 1), mx, s);
1933  return fixed2half<R, 30, false, false, true>(m, exp, sign, s);
1934  }
1935 
1945  template <std::float_round_style R, bool S> unsigned int area(unsigned int arg)
1946  {
1947  int abs = arg & 0x7FFF, expx = (abs >> 10) + (abs <= 0x3FF) - 15, expy = -15, ilog, i;
1948  uint32 mx = static_cast<uint32>((abs & 0x3FF) | ((abs > 0x3FF) << 10)) << 20, my, r;
1949  for (; abs < 0x400; abs <<= 1, --expy)
1950  ;
1951  expy += abs >> 10;
1952  r = ((abs & 0x3FF) | 0x400) << 5;
1953  r *= r;
1954  i = r >> 31;
1955  expy = 2 * expy + i;
1956  r >>= i;
1957  if (S) {
1958  if (expy < 0) {
1959  r = 0x40000000 +
1960  ((expy > -30) ? ((r >> -expy) | ((r & ((static_cast<uint32>(1) << -expy) - 1)) != 0)) : 1);
1961  expy = 0;
1962  } else {
1963  r += 0x40000000 >> expy;
1964  i = r >> 31;
1965  r = (r >> i) | (r & i);
1966  expy += i;
1967  }
1968  } else {
1969  r -= 0x40000000 >> expy;
1970  for (; r < 0x40000000; r <<= 1, --expy)
1971  ;
1972  }
1973  my = sqrt<30>(r, expy);
1974  my = (my << 15) + (r << 14) / my;
1975  if (S) {
1976  mx >>= expy - expx;
1977  ilog = expy;
1978  } else {
1979  my >>= expx - expy;
1980  ilog = expx;
1981  }
1982  my += mx;
1983  i = my >> 31;
1984  static const int G = S && (R == std::round_to_nearest);
1985  return log2_post<R, 0xB8AA3B2A>(
1986  log2(my >> i, 26 + S + G) + (G << 3), ilog + i, 17, arg & (static_cast<unsigned>(S) << 15));
1987  }
1988 
1990  struct f31 {
1995  : m(mant)
1996  , exp(e)
1997  {
1998  }
1999 
2002  f31(unsigned int abs)
2003  : exp(-15)
2004  {
2005  for (; abs < 0x400; abs <<= 1, --exp)
2006  ;
2007  m = static_cast<uint32>((abs & 0x3FF) | 0x400) << 21;
2008  exp += (abs >> 10);
2009  }
2010 
2015  friend f31 operator+(f31 a, f31 b)
2016  {
2017  if (b.exp > a.exp)
2018  std::swap(a, b);
2019  int d = a.exp - b.exp;
2020  uint32 m = a.m + ((d < 32) ? (b.m >> d) : 0);
2021  int i = (m & 0xFFFFFFFF) < a.m;
2022  return f31(((m + i) >> i) | 0x80000000, a.exp + i);
2023  }
2024 
2029  friend f31 operator-(f31 a, f31 b)
2030  {
2031  int d = a.exp - b.exp, exp = a.exp;
2032  uint32 m = a.m - ((d < 32) ? (b.m >> d) : 0);
2033  if (!m)
2034  return f31(0, -32);
2035  for (; m < 0x80000000; m <<= 1, --exp)
2036  ;
2037  return f31(m, exp);
2038  }
2039 
2044  friend f31 operator*(f31 a, f31 b)
2045  {
2046  uint32 m = multiply64(a.m, b.m);
2047  int i = m >> 31;
2048  return f31(m << (1 - i), a.exp + b.exp + i);
2049  }
2050 
2055  friend f31 operator/(f31 a, f31 b)
2056  {
2057  int i = a.m >= b.m, s;
2058  uint32 m = divide64((a.m + i) >> i, b.m, s);
2059  return f31(m, a.exp - b.exp + i - 1);
2060  }
2061 
2063  int exp;
2064  };
2065 
2076  template <std::float_round_style R, bool C> unsigned int erf(unsigned int arg)
2077  {
2078  unsigned int abs = arg & 0x7FFF, sign = arg & 0x8000;
2079  f31 x(abs), x2 = x * x * f31(0xB8AA3B29, 0),
2080  t = f31(0x80000000, 0) / (f31(0x80000000, 0) + f31(0xA7BA054A, -2) * x), t2 = t * t;
2081  f31 e = ((f31(0x87DC2213, 0) * t2 + f31(0xB5F0E2AE, 0)) * t2 + f31(0x82790637, -2) -
2082  (f31(0xBA00E2B8, 0) * t2 + f31(0x91A98E62, -2)) * t) *
2083  t /
2084  ((x2.exp < 0) ? f31(exp2((x2.exp > -32) ? (x2.m >> -x2.exp) : 0, 30), 0)
2085  : f31(exp2((x2.m << x2.exp) & 0x7FFFFFFF, 22), x2.m >> (31 - x2.exp)));
2086  return (!C || sign)
2087  ? fixed2half<R, 31, false, true, true>(0x80000000 - (e.m >> (C - e.exp)), 14 + C, sign & (C - 1U))
2088  : (e.exp < -25) ? underflow<R>()
2089  : fixed2half<R, 30, false, false, true>(e.m >> 1, e.exp + 14, 0, e.m & 1);
2090  }
2091 
2101  template <std::float_round_style R, bool L> unsigned int gamma(unsigned int arg)
2102  {
2103  /* static const double p[] ={ 2.50662827563479526904, 225.525584619175212544,
2104  -268.295973841304927459, 80.9030806934622512966, -5.00757863970517583837, 0.0114684895434781459556 }; double
2105  t = arg + 4.65, s = p[0]; for(unsigned int i=0; i<5; ++i) s += p[i+1] / (arg+i); return std::log(s) +
2106  (arg-0.5)*std::log(t) - t;
2107  */
2108  static const f31 pi(0xC90FDAA2, 1), lbe(0xB8AA3B29, 0);
2109  unsigned int abs = arg & 0x7FFF, sign = arg & 0x8000;
2110  bool bsign = sign != 0;
2111  f31 z(abs), x = sign ? (z + f31(0x80000000, 0)) : z, t = x + f31(0x94CCCCCD, 2),
2112  s = f31(0xA06C9901, 1) + f31(0xBBE654E2, -7) / (x + f31(0x80000000, 2)) +
2113  f31(0xA1CE6098, 6) / (x + f31(0x80000000, 1)) + f31(0xE1868CB7, 7) / x -
2114  f31(0x8625E279, 8) / (x + f31(0x80000000, 0)) - f31(0xA03E158F, 2) / (x + f31(0xC0000000, 1));
2115  int i = (s.exp >= 2) + (s.exp >= 4) + (s.exp >= 8) + (s.exp >= 16);
2116  s = f31((static_cast<uint32>(s.exp) << (31 - i)) + (log2(s.m >> 1, 28) >> i), i) / lbe;
2117  if (x.exp != -1 || x.m != 0x80000000) {
2118  i = (t.exp >= 2) + (t.exp >= 4) + (t.exp >= 8);
2119  f31 l = f31((static_cast<uint32>(t.exp) << (31 - i)) + (log2(t.m >> 1, 30) >> i), i) / lbe;
2120  s = (x.exp < -1) ? (s - (f31(0x80000000, -1) - x) * l) : (s + (x - f31(0x80000000, -1)) * l);
2121  }
2122  s = x.exp ? (s - t) : (t - s);
2123  if (bsign) {
2124  if (z.exp >= 0) {
2125  sign &= (L | ((z.m >> (31 - z.exp)) & 1)) - 1;
2126  for (z = f31((z.m << (1 + z.exp)) & 0xFFFFFFFF, -1); z.m < 0x80000000; z.m <<= 1, --z.exp)
2127  ;
2128  }
2129  if (z.exp == -1)
2130  z = f31(0x80000000, 0) - z;
2131  if (z.exp < -1) {
2132  z = z * pi;
2133  z.m = sincos(z.m >> (1 - z.exp), 30).first;
2134  for (z.exp = 1; z.m < 0x80000000; z.m <<= 1, --z.exp)
2135  ;
2136  } else
2137  z = f31(0x80000000, 0);
2138  }
2139  if (L) {
2140  if (bsign) {
2141  f31 l(0x92868247, 0);
2142  if (z.exp < 0) {
2143  uint32 m = log2((z.m + 1) >> 1, 27);
2144  z = f31(-((static_cast<uint32>(z.exp) << 26) + (m >> 5)), 5);
2145  for (; z.m < 0x80000000; z.m <<= 1, --z.exp)
2146  ;
2147  l = l + z / lbe;
2148  }
2149  sign = static_cast<unsigned>(x.exp && (l.exp < s.exp || (l.exp == s.exp && l.m < s.m))) << 15;
2150  s = sign ? (s - l) : x.exp ? (l - s) : (l + s);
2151  } else {
2152  sign = static_cast<unsigned>(x.exp == 0) << 15;
2153  if (s.exp < -24)
2154  return underflow<R>(sign);
2155  if (s.exp > 15)
2156  return overflow<R>(sign);
2157  }
2158  } else {
2159  s = s * lbe;
2160  uint32 m;
2161  if (s.exp < 0) {
2162  m = s.m >> -s.exp;
2163  s.exp = 0;
2164  } else {
2165  m = (s.m << s.exp) & 0x7FFFFFFF;
2166  s.exp = (s.m >> (31 - s.exp));
2167  }
2168  s.m = exp2(m, 27);
2169  if (!x.exp)
2170  s = f31(0x80000000, 0) / s;
2171  if (bsign) {
2172  if (z.exp < 0)
2173  s = s * z;
2174  s = pi / s;
2175  if (s.exp < -24)
2176  return underflow<R>(sign);
2177  } else if (z.exp > 0 && !(z.m & ((1 << (31 - z.exp)) - 1)))
2178  return ((s.exp + 14) << 10) + (s.m >> 21);
2179  if (s.exp > 15)
2180  return overflow<R>(sign);
2181  }
2182  return fixed2half<R, 31, false, false, true>(s.m, s.exp + 14, sign);
2183  }
2185 
2186  template <typename, typename, std::float_round_style> struct half_caster;
2187 } // namespace detail
2188 
2206 class half {
2207 public:
2210 
2215 
2219  explicit half(float rhs)
2220  : data_(static_cast<detail::uint16>(detail::float2half<round_style>(rhs)))
2221  {
2222  }
2223 
2226  operator float() const { return detail::half2float<float>(data_); }
2227 
2232  half& operator=(float rhs)
2233  {
2234  data_ = static_cast<detail::uint16>(detail::float2half<round_style>(rhs));
2235  return *this;
2236  }
2237 
2241 
2247  half& operator+=(half rhs) { return *this = *this + rhs; }
2248 
2254  half& operator-=(half rhs) { return *this = *this - rhs; }
2255 
2261  half& operator*=(half rhs) { return *this = *this * rhs; }
2262 
2268  half& operator/=(half rhs) { return *this = *this / rhs; }
2269 
2274  half& operator+=(float rhs) { return *this = *this + rhs; }
2275 
2280  half& operator-=(float rhs) { return *this = *this - rhs; }
2281 
2286  half& operator*=(float rhs) { return *this = *this * rhs; }
2287 
2292  half& operator/=(float rhs) { return *this = *this / rhs; }
2293 
2297 
2301  half& operator++() { return *this = *this + half(detail::binary, 0x3C00); }
2302 
2306  half& operator--() { return *this = *this + half(detail::binary, 0xBC00); }
2307 
2312  {
2313  half out(*this);
2314  ++*this;
2315  return out;
2316  }
2317 
2322  {
2323  half out(*this);
2324  --*this;
2325  return out;
2326  }
2328 
2329 private:
2331  static const std::float_round_style round_style = (std::float_round_style)(HALF_ROUND_STYLE);
2332 
2335  HALF_CONSTEXPR half(detail::binary_t, unsigned int bits) HALF_NOEXCEPT : data_(static_cast<detail::uint16>(bits)) {}
2336 
2339 
2340 #ifndef HALF_DOXYGEN_ONLY
2341  friend HALF_CONSTEXPR_NOERR bool operator==(half, half);
2342  friend HALF_CONSTEXPR_NOERR bool operator!=(half, half);
2343  friend HALF_CONSTEXPR_NOERR bool operator<(half, half);
2344  friend HALF_CONSTEXPR_NOERR bool operator>(half, half);
2345  friend HALF_CONSTEXPR_NOERR bool operator<=(half, half);
2346  friend HALF_CONSTEXPR_NOERR bool operator>=(half, half);
2348  friend half operator+(half, half);
2349  friend half operator-(half, half);
2350  friend half operator*(half, half);
2351  friend half operator/(half, half);
2352  template <typename charT, typename traits>
2353  friend std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>&, half);
2354  template <typename charT, typename traits>
2355  friend std::basic_istream<charT, traits>& operator>>(std::basic_istream<charT, traits>&, half&);
2356  friend HALF_CONSTEXPR half fabs(half);
2357  friend half fmod(half, half);
2358  friend half remainder(half, half);
2359  friend half remquo(half, half, int*);
2360  friend half fma(half, half, half);
2363  friend half fdim(half, half);
2364  friend half nanh(const char*);
2365  friend half exp(half);
2366  friend half exp2(half);
2367  friend half expm1(half);
2368  friend half log(half);
2369  friend half log10(half);
2370  friend half log2(half);
2371  friend half log1p(half);
2372  friend half sqrt(half);
2373  friend half rsqrt(half);
2374  friend half cbrt(half);
2375  friend half hypot(half, half);
2376  friend half hypot(half, half, half);
2377  friend half pow(half, half);
2378  friend void sincos(half, half*, half*);
2379  friend half sin(half);
2380  friend half cos(half);
2381  friend half tan(half);
2382  friend half asin(half);
2383  friend half acos(half);
2384  friend half atan(half);
2385  friend half atan2(half, half);
2386  friend half sinh(half);
2387  friend half cosh(half);
2388  friend half tanh(half);
2389  friend half asinh(half);
2390  friend half acosh(half);
2391  friend half atanh(half);
2392  friend half erf(half);
2393  friend half erfc(half);
2394  friend half lgamma(half);
2395  friend half tgamma(half);
2396  friend half ceil(half);
2397  friend half floor(half);
2398  friend half trunc(half);
2399  friend half round(half);
2400  friend long lround(half);
2401  friend half rint(half);
2402  friend long lrint(half);
2403  friend half nearbyint(half);
2404 #ifdef HALF_ENABLE_CPP11_LONG_LONG
2405  friend long long llround(half);
2406  friend long long llrint(half);
2407 #endif
2408  friend half frexp(half, int*);
2409  friend half scalbln(half, long);
2410  friend half modf(half, half*);
2411  friend int ilogb(half);
2412  friend half logb(half);
2413  friend half nextafter(half, half);
2414  friend half nexttoward(half, long double);
2416  friend HALF_CONSTEXPR int fpclassify(half);
2417  friend HALF_CONSTEXPR bool isfinite(half);
2418  friend HALF_CONSTEXPR bool isinf(half);
2419  friend HALF_CONSTEXPR bool isnan(half);
2420  friend HALF_CONSTEXPR bool isnormal(half);
2421  friend HALF_CONSTEXPR bool signbit(half);
2422  friend HALF_CONSTEXPR bool isgreater(half, half);
2423  friend HALF_CONSTEXPR bool isgreaterequal(half, half);
2424  friend HALF_CONSTEXPR bool isless(half, half);
2425  friend HALF_CONSTEXPR bool islessequal(half, half);
2426  friend HALF_CONSTEXPR bool islessgreater(half, half);
2427  template <typename, typename, std::float_round_style> friend struct detail::half_caster;
2428  friend class std::numeric_limits<half>;
2429 #if HALF_ENABLE_CPP11_HASH
2430  friend struct std::hash<half>;
2431 #endif
2432 #if HALF_ENABLE_CPP11_USER_LITERALS
2433  friend half literal::operator"" _h(long double);
2434 #endif
2435 #endif
2436 };
2437 
2438 #if HALF_ENABLE_CPP11_USER_LITERALS
2439 namespace literal {
2447  inline half operator"" _h(long double value)
2448  {
2449  return half(detail::binary, detail::float2half<half::round_style>(value));
2450  }
2451 } // namespace literal
2452 #endif
2453 
2454 namespace detail {
2461  template <typename T, typename U, std::float_round_style R = (std::float_round_style)(HALF_ROUND_STYLE)>
2462  struct half_caster {};
2463  template <typename U, std::float_round_style R> struct half_caster<half, U, R> {
2464 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
2465  static_assert(std::is_arithmetic<U>::value, "half_cast from non-arithmetic type unsupported");
2466 #endif
2467 
2468  static half cast(U arg) { return cast_impl(arg, is_float<U>()); };
2469 
2470  private:
2471  static half cast_impl(U arg, true_type) { return half(binary, float2half<R>(arg)); }
2472  static half cast_impl(U arg, false_type) { return half(binary, int2half<R>(arg)); }
2473  };
2474  template <typename T, std::float_round_style R> struct half_caster<T, half, R> {
2475 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
2476  static_assert(std::is_arithmetic<T>::value, "half_cast to non-arithmetic type unsupported");
2477 #endif
2478 
2479  static T cast(half arg) { return cast_impl(arg, is_float<T>()); }
2480 
2481  private:
2482  static T cast_impl(half arg, true_type) { return half2float<T>(arg.data_); }
2483  static T cast_impl(half arg, false_type) { return half2int<R, true, true, T>(arg.data_); }
2484  };
2485  template <std::float_round_style R> struct half_caster<half, half, R> {
2486  static half cast(half arg) { return arg; }
2487  };
2488 } // namespace detail
2489 } // namespace half_float
2490 
2492 namespace std {
2495 template <> class numeric_limits<half_float::half> {
2496 public:
2498  static HALF_CONSTEXPR_CONST bool is_specialized = true;
2499 
2501  static HALF_CONSTEXPR_CONST bool is_signed = true;
2502 
2504  static HALF_CONSTEXPR_CONST bool is_integer = false;
2505 
2507  static HALF_CONSTEXPR_CONST bool is_exact = false;
2508 
2510  static HALF_CONSTEXPR_CONST bool is_modulo = false;
2511 
2513  static HALF_CONSTEXPR_CONST bool is_bounded = true;
2514 
2516  static HALF_CONSTEXPR_CONST bool is_iec559 = true;
2517 
2519  static HALF_CONSTEXPR_CONST bool has_infinity = true;
2520 
2522  static HALF_CONSTEXPR_CONST bool has_quiet_NaN = true;
2523 
2525  static HALF_CONSTEXPR_CONST bool has_signaling_NaN = true;
2526 
2528  static HALF_CONSTEXPR_CONST float_denorm_style has_denorm = denorm_present;
2529 
2531  static HALF_CONSTEXPR_CONST bool has_denorm_loss = false;
2532 
2533 #if HALF_ERRHANDLING_THROWS
2534  static HALF_CONSTEXPR_CONST bool traps = true;
2535 #else
2537  static HALF_CONSTEXPR_CONST bool traps = false;
2538 #endif
2539 
2541  static HALF_CONSTEXPR_CONST bool tinyness_before = false;
2542 
2544  static HALF_CONSTEXPR_CONST float_round_style round_style = half_float::half::round_style;
2545 
2547  static HALF_CONSTEXPR_CONST int digits = 11;
2548 
2550  static HALF_CONSTEXPR_CONST int digits10 = 3;
2551 
2553  static HALF_CONSTEXPR_CONST int max_digits10 = 5;
2554 
2556  static HALF_CONSTEXPR_CONST int radix = 2;
2557 
2559  static HALF_CONSTEXPR_CONST int min_exponent = -13;
2560 
2562  static HALF_CONSTEXPR_CONST int min_exponent10 = -4;
2563 
2565  static HALF_CONSTEXPR_CONST int max_exponent = 16;
2566 
2568  static HALF_CONSTEXPR_CONST int max_exponent10 = 4;
2569 
2572  {
2574  }
2575 
2578  {
2580  }
2581 
2584  {
2586  }
2587 
2590  {
2592  }
2593 
2596  {
2597  return half_float::half(half_float::detail::binary, (round_style == std::round_to_nearest) ? 0x3800 : 0x3C00);
2598  }
2599 
2602  {
2604  }
2605 
2608  {
2610  }
2611 
2614  {
2616  }
2617 
2620  {
2622  }
2623 };
2624 
2625 #if HALF_ENABLE_CPP11_HASH
2630 template <> struct hash<half_float::half> {
2632  typedef half_float::half argument_type;
2633 
2635  typedef size_t result_type;
2636 
2640  result_type operator()(argument_type arg) const
2641  {
2642  return hash<half_float::detail::uint16>()(arg.data_ & -static_cast<unsigned>(arg.data_ != 0x8000));
2643  }
2644 };
2645 #endif
2646 } // namespace std
2647 
2648 namespace half_float {
2652 
2660 {
2661  return !detail::compsignal(x.data_, y.data_) && (x.data_ == y.data_ || !((x.data_ | y.data_) & 0x7FFF));
2662 }
2663 
2671 {
2672  return detail::compsignal(x.data_, y.data_) || (x.data_ != y.data_ && ((x.data_ | y.data_) & 0x7FFF));
2673 }
2674 
2682 {
2683  return !detail::compsignal(x.data_, y.data_) &&
2684  ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) <
2685  ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15));
2686 }
2687 
2695 {
2696  return !detail::compsignal(x.data_, y.data_) &&
2697  ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) >
2698  ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15));
2699 }
2700 
2708 {
2709  return !detail::compsignal(x.data_, y.data_) &&
2710  ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) <=
2711  ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15));
2712 }
2713 
2721 {
2722  return !detail::compsignal(x.data_, y.data_) &&
2723  ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) >=
2724  ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15));
2725 }
2726 
2731 
2735 inline HALF_CONSTEXPR half operator+(half arg) { return arg; }
2736 
2740 inline HALF_CONSTEXPR half operator-(half arg) { return half(detail::binary, arg.data_ ^ 0x8000); }
2741 
2749 inline half operator+(half x, half y)
2750 {
2751 #ifdef HALF_ARITHMETIC_TYPE
2752  return half(detail::binary,
2753  detail::float2half<half::round_style>(
2754  detail::half2float<detail::internal_t>(x.data_) + detail::half2float<detail::internal_t>(y.data_)));
2755 #else
2756  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF;
2757  bool sub = ((x.data_ ^ y.data_) & 0x8000) != 0;
2758  if (absx >= 0x7C00 || absy >= 0x7C00)
2759  return half(detail::binary,
2760  (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_)
2761  : (absy != 0x7C00) ? x.data_
2762  : (sub && absx == 0x7C00) ? detail::invalid()
2763  : y.data_);
2764  if (!absx)
2765  return absy
2766  ? y
2767  : half(detail::binary,
2768  (half::round_style == std::round_toward_neg_infinity) ? (x.data_ | y.data_) : (x.data_ & y.data_));
2769  if (!absy)
2770  return x;
2771  unsigned int sign = ((sub && absy > absx) ? y.data_ : x.data_) & 0x8000;
2772  if (absy > absx)
2773  std::swap(absx, absy);
2774  int exp = (absx >> 10) + (absx <= 0x3FF), d = exp - (absy >> 10) - (absy <= 0x3FF),
2775  mx = ((absx & 0x3FF) | ((absx > 0x3FF) << 10)) << 3, my;
2776  if (d < 13) {
2777  my = ((absy & 0x3FF) | ((absy > 0x3FF) << 10)) << 3;
2778  my = (my >> d) | ((my & ((1 << d) - 1)) != 0);
2779  } else
2780  my = 1;
2781  if (sub) {
2782  if (!(mx -= my))
2783  return half(
2784  detail::binary, static_cast<unsigned>(half::round_style == std::round_toward_neg_infinity) << 15);
2785  for (; mx < 0x2000 && exp > 1; mx <<= 1, --exp)
2786  ;
2787  } else {
2788  mx += my;
2789  int i = mx >> 14;
2790  if ((exp += i) > 30)
2791  return half(detail::binary, detail::overflow<half::round_style>(sign));
2792  mx = (mx >> i) | (mx & i);
2793  }
2794  return half(detail::binary,
2795  detail::rounded<half::round_style, false>(
2796  sign + ((exp - 1) << 10) + (mx >> 3), (mx >> 2) & 1, (mx & 0x3) != 0));
2797 #endif
2798 }
2799 
2807 inline half operator-(half x, half y)
2808 {
2809 #ifdef HALF_ARITHMETIC_TYPE
2810  return half(detail::binary,
2811  detail::float2half<half::round_style>(
2812  detail::half2float<detail::internal_t>(x.data_) - detail::half2float<detail::internal_t>(y.data_)));
2813 #else
2814  return x + -y;
2815 #endif
2816 }
2817 
2825 inline half operator*(half x, half y)
2826 {
2827 #ifdef HALF_ARITHMETIC_TYPE
2828  return half(detail::binary,
2829  detail::float2half<half::round_style>(
2830  detail::half2float<detail::internal_t>(x.data_) * detail::half2float<detail::internal_t>(y.data_)));
2831 #else
2832  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -16;
2833  unsigned int sign = (x.data_ ^ y.data_) & 0x8000;
2834  if (absx >= 0x7C00 || absy >= 0x7C00)
2835  return half(detail::binary,
2836  (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_)
2837  : ((absx == 0x7C00 && !absy) || (absy == 0x7C00 && !absx)) ? detail::invalid()
2838  : (sign | 0x7C00));
2839  if (!absx || !absy)
2840  return half(detail::binary, sign);
2841  for (; absx < 0x400; absx <<= 1, --exp)
2842  ;
2843  for (; absy < 0x400; absy <<= 1, --exp)
2844  ;
2845  detail::uint32 m =
2846  static_cast<detail::uint32>((absx & 0x3FF) | 0x400) * static_cast<detail::uint32>((absy & 0x3FF) | 0x400);
2847  int i = m >> 21, s = m & i;
2848  exp += (absx >> 10) + (absy >> 10) + i;
2849  if (exp > 29)
2850  return half(detail::binary, detail::overflow<half::round_style>(sign));
2851  else if (exp < -11)
2852  return half(detail::binary, detail::underflow<half::round_style>(sign));
2853  return half(detail::binary, detail::fixed2half<half::round_style, 20, false, false, false>(m >> i, exp, sign, s));
2854 #endif
2855 }
2856 
2865 inline half operator/(half x, half y)
2866 {
2867 #ifdef HALF_ARITHMETIC_TYPE
2868  return half(detail::binary,
2869  detail::float2half<half::round_style>(
2870  detail::half2float<detail::internal_t>(x.data_) / detail::half2float<detail::internal_t>(y.data_)));
2871 #else
2872  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = 14;
2873  unsigned int sign = (x.data_ ^ y.data_) & 0x8000;
2874  if (absx >= 0x7C00 || absy >= 0x7C00)
2875  return half(detail::binary,
2876  (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_)
2877  : (absx == absy) ? detail::invalid()
2878  : (sign | ((absx == 0x7C00) ? 0x7C00 : 0)));
2879  if (!absx)
2880  return half(detail::binary, absy ? sign : detail::invalid());
2881  if (!absy)
2882  return half(detail::binary, detail::pole(sign));
2883  for (; absx < 0x400; absx <<= 1, --exp)
2884  ;
2885  for (; absy < 0x400; absy <<= 1, ++exp)
2886  ;
2887  detail::uint32 mx = (absx & 0x3FF) | 0x400, my = (absy & 0x3FF) | 0x400;
2888  int i = mx < my;
2889  exp += (absx >> 10) - (absy >> 10) - i;
2890  if (exp > 29)
2891  return half(detail::binary, detail::overflow<half::round_style>(sign));
2892  else if (exp < -11)
2893  return half(detail::binary, detail::underflow<half::round_style>(sign));
2894  mx <<= 12 + i;
2895  my <<= 1;
2896  return half(detail::binary,
2897  detail::fixed2half<half::round_style, 11, false, false, false>(mx / my, exp, sign, mx % my != 0));
2898 #endif
2899 }
2900 
2905 
2911 template <typename charT, typename traits>
2912 std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& out, half arg)
2913 {
2914 #ifdef HALF_ARITHMETIC_TYPE
2915  return out << detail::half2float<detail::internal_t>(arg.data_);
2916 #else
2917  return out << detail::half2float<float>(arg.data_);
2918 #endif
2919 }
2920 
2930 template <typename charT, typename traits>
2931 std::basic_istream<charT, traits>& operator>>(std::basic_istream<charT, traits>& in, half& arg)
2932 {
2933 #ifdef HALF_ARITHMETIC_TYPE
2934  detail::internal_t f;
2935 #else
2936  double f;
2937 #endif
2938  if (in >> f)
2939  arg.data_ = detail::float2half<half::round_style>(f);
2940  return in;
2941 }
2942 
2947 
2952 inline HALF_CONSTEXPR half fabs(half arg) { return half(detail::binary, arg.data_ & 0x7FFF); }
2953 
2958 inline HALF_CONSTEXPR half abs(half arg) { return fabs(arg); }
2959 
2966 inline half fmod(half x, half y)
2967 {
2968  unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000;
2969  if (absx >= 0x7C00 || absy >= 0x7C00)
2970  return half(detail::binary,
2971  (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_)
2972  : (absx == 0x7C00) ? detail::invalid()
2973  : x.data_);
2974  if (!absy)
2975  return half(detail::binary, detail::invalid());
2976  if (!absx)
2977  return x;
2978  if (absx == absy)
2979  return half(detail::binary, sign);
2980  return half(detail::binary, sign | detail::mod<false, false>(absx, absy));
2981 }
2982 
2989 inline half remainder(half x, half y)
2990 {
2991  unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000;
2992  if (absx >= 0x7C00 || absy >= 0x7C00)
2993  return half(detail::binary,
2994  (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_)
2995  : (absx == 0x7C00) ? detail::invalid()
2996  : x.data_);
2997  if (!absy)
2998  return half(detail::binary, detail::invalid());
2999  if (absx == absy)
3000  return half(detail::binary, sign);
3001  return half(detail::binary, sign ^ detail::mod<false, true>(absx, absy));
3002 }
3003 
3011 inline half remquo(half x, half y, int* quo)
3012 {
3013  unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, value = x.data_ & 0x8000;
3014  if (absx >= 0x7C00 || absy >= 0x7C00)
3015  return half(detail::binary,
3016  (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_)
3017  : (absx == 0x7C00) ? detail::invalid()
3018  : (*quo = 0, x.data_));
3019  if (!absy)
3020  return half(detail::binary, detail::invalid());
3021  bool qsign = ((value ^ y.data_) & 0x8000) != 0;
3022  int q = 1;
3023  if (absx != absy)
3024  value ^= detail::mod<true, true>(absx, absy, &q);
3025  return *quo = qsign ? -q : q, half(detail::binary, value);
3026 }
3027 
3038 inline half fma(half x, half y, half z)
3039 {
3040 #ifdef HALF_ARITHMETIC_TYPE
3041  detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_),
3042  fy = detail::half2float<detail::internal_t>(y.data_),
3043  fz = detail::half2float<detail::internal_t>(z.data_);
3044 #if HALF_ENABLE_CPP11_CMATH && FP_FAST_FMA
3045  return half(detail::binary, detail::float2half<half::round_style>(std::fma(fx, fy, fz)));
3046 #else
3047  return half(detail::binary, detail::float2half<half::round_style>(fx * fy + fz));
3048 #endif
3049 #else
3050  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, exp = -15;
3051  unsigned int sign = (x.data_ ^ y.data_) & 0x8000;
3052  bool sub = ((sign ^ z.data_) & 0x8000) != 0;
3053  if (absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
3054  return (absx > 0x7C00 || absy > 0x7C00 || absz > 0x7C00)
3056  : (absx == 0x7C00)
3057  ? half(detail::binary, (!absy || (sub && absz == 0x7C00)) ? detail::invalid() : (sign | 0x7C00))
3058  : (absy == 0x7C00)
3059  ? half(detail::binary, (!absx || (sub && absz == 0x7C00)) ? detail::invalid() : (sign | 0x7C00))
3060  : z;
3061  if (!absx || !absy)
3062  return absz ? z
3063  : half(detail::binary,
3064  (half::round_style == std::round_toward_neg_infinity) ? (z.data_ | sign) : (z.data_ & sign));
3065  for (; absx < 0x400; absx <<= 1, --exp)
3066  ;
3067  for (; absy < 0x400; absy <<= 1, --exp)
3068  ;
3069  detail::uint32 m =
3070  static_cast<detail::uint32>((absx & 0x3FF) | 0x400) * static_cast<detail::uint32>((absy & 0x3FF) | 0x400);
3071  int i = m >> 21;
3072  exp += (absx >> 10) + (absy >> 10) + i;
3073  m <<= 3 - i;
3074  if (absz) {
3075  int expz = 0;
3076  for (; absz < 0x400; absz <<= 1, --expz)
3077  ;
3078  expz += absz >> 10;
3079  detail::uint32 mz = static_cast<detail::uint32>((absz & 0x3FF) | 0x400) << 13;
3080  if (expz > exp || (expz == exp && mz > m)) {
3081  std::swap(m, mz);
3082  std::swap(exp, expz);
3083  if (sub)
3084  sign = z.data_ & 0x8000;
3085  }
3086  int d = exp - expz;
3087  mz = (d < 23) ? ((mz >> d) | ((mz & ((static_cast<detail::uint32>(1) << d) - 1)) != 0)) : 1;
3088  if (sub) {
3089  m = m - mz;
3090  if (!m)
3091  return half(
3092  detail::binary, static_cast<unsigned>(half::round_style == std::round_toward_neg_infinity) << 15);
3093  for (; m < 0x800000; m <<= 1, --exp)
3094  ;
3095  } else {
3096  m += mz;
3097  i = m >> 24;
3098  m = (m >> i) | (m & i);
3099  exp += i;
3100  }
3101  }
3102  if (exp > 30)
3103  return half(detail::binary, detail::overflow<half::round_style>(sign));
3104  else if (exp < -10)
3105  return half(detail::binary, detail::underflow<half::round_style>(sign));
3106  return half(detail::binary, detail::fixed2half<half::round_style, 23, false, false, false>(m, exp - 1, sign));
3107 #endif
3108 }
3109 
3117 {
3118  return half(detail::binary,
3119  (!isnan(y) &&
3120  (isnan(x) ||
3121  (x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) < (y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15))))))
3122  ? detail::select(y.data_, x.data_)
3123  : detail::select(x.data_, y.data_));
3124 }
3125 
3133 {
3134  return half(detail::binary,
3135  (!isnan(y) &&
3136  (isnan(x) ||
3137  (x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) > (y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15))))))
3138  ? detail::select(y.data_, x.data_)
3139  : detail::select(x.data_, y.data_));
3140 }
3141 
3150 inline half fdim(half x, half y)
3151 {
3152  if (isnan(x) || isnan(y))
3153  return half(detail::binary, detail::signal(x.data_, y.data_));
3154  return (x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) <= (y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15))))
3155  ? half(detail::binary, 0)
3156  : (x - y);
3157 }
3158 
3163 inline half nanh(const char* arg)
3164 {
3165  unsigned int value = 0x7FFF;
3166  while (*arg)
3167  value ^= static_cast<unsigned>(*arg++) & 0xFF;
3168  return half(detail::binary, value);
3169 }
3170 
3175 
3184 inline half exp(half arg)
3185 {
3186 #ifdef HALF_ARITHMETIC_TYPE
3187  return half(detail::binary,
3188  detail::float2half<half::round_style>(std::exp(detail::half2float<detail::internal_t>(arg.data_))));
3189 #else
3190  int abs = arg.data_ & 0x7FFF, e = (abs >> 10) + (abs <= 0x3FF), exp;
3191  if (!abs)
3192  return half(detail::binary, 0x3C00);
3193  if (abs >= 0x7C00)
3194  return half(detail::binary, (abs == 0x7C00) ? (0x7C00 & ((arg.data_ >> 15) - 1U)) : detail::signal(arg.data_));
3195  if (abs >= 0x4C80)
3196  return half(detail::binary,
3197  (arg.data_ & 0x8000) ? detail::underflow<half::round_style>() : detail::overflow<half::round_style>());
3198  detail::uint32 m =
3199  detail::multiply64(static_cast<detail::uint32>((abs & 0x3FF) + ((abs > 0x3FF) << 10)) << 21, 0xB8AA3B29);
3200  if (e < 14) {
3201  exp = 0;
3202  m >>= 14 - e;
3203  } else {
3204  exp = m >> (45 - e);
3205  m = (m << (e - 14)) & 0x7FFFFFFF;
3206  }
3207  return half(detail::binary, detail::exp2_post<half::round_style>(m, exp, (arg.data_ & 0x8000) != 0, 0, 26));
3208 #endif
3209 }
3210 
3219 inline half exp2(half arg)
3220 {
3221 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3222  return half(detail::binary,
3223  detail::float2half<half::round_style>(std::exp2(detail::half2float<detail::internal_t>(arg.data_))));
3224 #else
3225  int abs = arg.data_ & 0x7FFF, e = (abs >> 10) + (abs <= 0x3FF), exp = (abs & 0x3FF) + ((abs > 0x3FF) << 10);
3226  if (!abs)
3227  return half(detail::binary, 0x3C00);
3228  if (abs >= 0x7C00)
3229  return half(detail::binary, (abs == 0x7C00) ? (0x7C00 & ((arg.data_ >> 15) - 1U)) : detail::signal(arg.data_));
3230  if (abs >= 0x4E40)
3231  return half(detail::binary,
3232  (arg.data_ & 0x8000) ? detail::underflow<half::round_style>() : detail::overflow<half::round_style>());
3233  return half(detail::binary,
3234  detail::exp2_post<half::round_style>((static_cast<detail::uint32>(exp) << (6 + e)) & 0x7FFFFFFF,
3235  exp >> (25 - e), (arg.data_ & 0x8000) != 0, 0, 28));
3236 #endif
3237 }
3238 
3248 inline half expm1(half arg)
3249 {
3250 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3251  return half(detail::binary,
3252  detail::float2half<half::round_style>(std::expm1(detail::half2float<detail::internal_t>(arg.data_))));
3253 #else
3254  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000, e = (abs >> 10) + (abs <= 0x3FF), exp;
3255  if (!abs)
3256  return arg;
3257  if (abs >= 0x7C00)
3258  return half(detail::binary, (abs == 0x7C00) ? (0x7C00 + (sign >> 1)) : detail::signal(arg.data_));
3259  if (abs >= 0x4A00)
3260  return half(detail::binary,
3261  (arg.data_ & 0x8000) ? detail::rounded<half::round_style, true>(0xBBFF, 1, 1)
3262  : detail::overflow<half::round_style>());
3263  detail::uint32 m =
3264  detail::multiply64(static_cast<detail::uint32>((abs & 0x3FF) + ((abs > 0x3FF) << 10)) << 21, 0xB8AA3B29);
3265  if (e < 14) {
3266  exp = 0;
3267  m >>= 14 - e;
3268  } else {
3269  exp = m >> (45 - e);
3270  m = (m << (e - 14)) & 0x7FFFFFFF;
3271  }
3272  m = detail::exp2(m);
3273  if (sign) {
3274  int s = 0;
3275  if (m > 0x80000000) {
3276  ++exp;
3277  m = detail::divide64(0x80000000, m, s);
3278  }
3279  m = 0x80000000 - ((m >> exp) | ((m & ((static_cast<detail::uint32>(1) << exp) - 1)) != 0) | s);
3280  exp = 0;
3281  } else
3282  m -= (exp < 31) ? (0x80000000 >> exp) : 1;
3283  for (exp += 14; m < 0x80000000 && exp; m <<= 1, --exp)
3284  ;
3285  if (exp > 29)
3286  return half(detail::binary, detail::overflow<half::round_style>());
3287  return half(detail::binary,
3288  detail::rounded<half::round_style, true>(sign + (exp << 10) + (m >> 21), (m >> 20) & 1, (m & 0xFFFFF) != 0));
3289 #endif
3290 }
3291 
3301 inline half log(half arg)
3302 {
3303 #ifdef HALF_ARITHMETIC_TYPE
3304  return half(detail::binary,
3305  detail::float2half<half::round_style>(std::log(detail::half2float<detail::internal_t>(arg.data_))));
3306 #else
3307  int abs = arg.data_ & 0x7FFF, exp = -15;
3308  if (!abs)
3309  return half(detail::binary, detail::pole(0x8000));
3310  if (arg.data_ & 0x8000)
3311  return half(detail::binary, (arg.data_ <= 0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3312  if (abs >= 0x7C00)
3313  return (abs == 0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
3314  for (; abs < 0x400; abs <<= 1, --exp)
3315  ;
3316  exp += abs >> 10;
3317  return half(detail::binary,
3318  detail::log2_post<half::round_style, 0xB8AA3B2A>(
3319  detail::log2(static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 20, 27) + 8, exp, 17));
3320 #endif
3321 }
3322 
3332 inline half log10(half arg)
3333 {
3334 #ifdef HALF_ARITHMETIC_TYPE
3335  return half(detail::binary,
3336  detail::float2half<half::round_style>(std::log10(detail::half2float<detail::internal_t>(arg.data_))));
3337 #else
3338  int abs = arg.data_ & 0x7FFF, exp = -15;
3339  if (!abs)
3340  return half(detail::binary, detail::pole(0x8000));
3341  if (arg.data_ & 0x8000)
3342  return half(detail::binary, (arg.data_ <= 0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3343  if (abs >= 0x7C00)
3344  return (abs == 0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
3345  switch (abs) {
3346  case 0x4900:
3347  return half(detail::binary, 0x3C00);
3348  case 0x5640:
3349  return half(detail::binary, 0x4000);
3350  case 0x63D0:
3351  return half(detail::binary, 0x4200);
3352  case 0x70E2:
3353  return half(detail::binary, 0x4400);
3354  }
3355  for (; abs < 0x400; abs <<= 1, --exp)
3356  ;
3357  exp += abs >> 10;
3358  return half(detail::binary,
3359  detail::log2_post<half::round_style, 0xD49A784C>(
3360  detail::log2(static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 20, 27) + 8, exp, 16));
3361 #endif
3362 }
3363 
3373 inline half log2(half arg)
3374 {
3375 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3376  return half(detail::binary,
3377  detail::float2half<half::round_style>(std::log2(detail::half2float<detail::internal_t>(arg.data_))));
3378 #else
3379  int abs = arg.data_ & 0x7FFF, exp = -15, s = 0;
3380  if (!abs)
3381  return half(detail::binary, detail::pole(0x8000));
3382  if (arg.data_ & 0x8000)
3383  return half(detail::binary, (arg.data_ <= 0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3384  if (abs >= 0x7C00)
3385  return (abs == 0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
3386  if (abs == 0x3C00)
3387  return half(detail::binary, 0);
3388  for (; abs < 0x400; abs <<= 1, --exp)
3389  ;
3390  exp += (abs >> 10);
3391  if (!(abs & 0x3FF)) {
3392  unsigned int value = static_cast<unsigned>(exp < 0) << 15, m = std::abs(exp) << 6;
3393  for (exp = 18; m < 0x400; m <<= 1, --exp)
3394  ;
3395  return half(detail::binary, value + (exp << 10) + m);
3396  }
3397  detail::uint32 ilog = exp, sign = detail::sign_mask(ilog),
3398  m = (((ilog << 27) +
3399  (detail::log2(static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 20, 28) >> 4)) ^
3400  sign) -
3401  sign;
3402  if (!m)
3403  return half(detail::binary, 0);
3404  for (exp = 14; m < 0x8000000 && exp; m <<= 1, --exp)
3405  ;
3406  for (; m > 0xFFFFFFF; m >>= 1, ++exp)
3407  s |= m & 1;
3408  return half(
3409  detail::binary, detail::fixed2half<half::round_style, 27, false, false, true>(m, exp, sign & 0x8000, s));
3410 #endif
3411 }
3412 
3423 inline half log1p(half arg)
3424 {
3425 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3426  return half(detail::binary,
3427  detail::float2half<half::round_style>(std::log1p(detail::half2float<detail::internal_t>(arg.data_))));
3428 #else
3429  if (arg.data_ >= 0xBC00)
3430  return half(detail::binary,
3431  (arg.data_ == 0xBC00) ? detail::pole(0x8000)
3432  : (arg.data_ <= 0xFC00) ? detail::invalid()
3433  : detail::signal(arg.data_));
3434  int abs = arg.data_ & 0x7FFF, exp = -15;
3435  if (!abs || abs >= 0x7C00)
3436  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3437  for (; abs < 0x400; abs <<= 1, --exp)
3438  ;
3439  exp += abs >> 10;
3440  detail::uint32 m = static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 20;
3441  if (arg.data_ & 0x8000) {
3442  m = 0x40000000 - (m >> -exp);
3443  for (exp = 0; m < 0x40000000; m <<= 1, --exp)
3444  ;
3445  } else {
3446  if (exp < 0) {
3447  m = 0x40000000 + (m >> -exp);
3448  exp = 0;
3449  } else {
3450  m += 0x40000000 >> exp;
3451  int i = m >> 31;
3452  m >>= i;
3453  exp += i;
3454  }
3455  }
3456  return half(detail::binary, detail::log2_post<half::round_style, 0xB8AA3B2A>(detail::log2(m), exp, 17));
3457 #endif
3458 }
3459 
3464 
3473 inline half sqrt(half arg)
3474 {
3475 #ifdef HALF_ARITHMETIC_TYPE
3476  return half(detail::binary,
3477  detail::float2half<half::round_style>(std::sqrt(detail::half2float<detail::internal_t>(arg.data_))));
3478 #else
3479  int abs = arg.data_ & 0x7FFF, exp = 15;
3480  if (!abs || arg.data_ >= 0x7C00)
3481  return half(detail::binary,
3482  (abs > 0x7C00) ? detail::signal(arg.data_)
3483  : (arg.data_ > 0x8000) ? detail::invalid()
3484  : arg.data_);
3485  for (; abs < 0x400; abs <<= 1, --exp)
3486  ;
3487  detail::uint32 r = static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 10,
3488  m = detail::sqrt<20>(r, exp += abs >> 10);
3489  return half(detail::binary, detail::rounded<half::round_style, false>((exp << 10) + (m & 0x3FF), r > m, r != 0));
3490 #endif
3491 }
3492 
3500 inline half rsqrt(half arg)
3501 {
3502 #ifdef HALF_ARITHMETIC_TYPE
3503  return half(detail::binary,
3504  detail::float2half<half::round_style>(
3505  detail::internal_t(1) / std::sqrt(detail::half2float<detail::internal_t>(arg.data_))));
3506 #else
3507  unsigned int abs = arg.data_ & 0x7FFF, bias = 0x4000;
3508  if (!abs || arg.data_ >= 0x7C00)
3509  return half(detail::binary,
3510  (abs > 0x7C00) ? detail::signal(arg.data_)
3511  : (arg.data_ > 0x8000) ? detail::invalid()
3512  : !abs ? detail::pole(arg.data_ & 0x8000)
3513  : 0);
3514  for (; abs < 0x400; abs <<= 1, bias -= 0x400)
3515  ;
3516  unsigned int frac = (abs += bias) & 0x7FF;
3517  if (frac == 0x400)
3518  return half(detail::binary, 0x7A00 - (abs >> 1));
3519  if ((half::round_style == std::round_to_nearest && (frac == 0x3FE || frac == 0x76C)) ||
3520  (half::round_style != std::round_to_nearest &&
3521  (frac == 0x15A || frac == 0x3FC || frac == 0x401 || frac == 0x402 || frac == 0x67B)))
3522  return pow(arg, half(detail::binary, 0xB800));
3523  detail::uint32 f = 0x17376 - abs, mx = (abs & 0x3FF) | 0x400, my = ((f >> 1) & 0x3FF) | 0x400, mz = my * my;
3524  int expy = (f >> 11) - 31, expx = 32 - (abs >> 10), i = mz >> 21;
3525  for (mz = 0x60000000 - (((mz >> i) * mx) >> (expx - 2 * expy - i)); mz < 0x40000000; mz <<= 1, --expy)
3526  ;
3527  i = (my *= mz >> 10) >> 31;
3528  expy += i;
3529  my = (my >> (20 + i)) + 1;
3530  i = (mz = my * my) >> 21;
3531  for (mz = 0x60000000 - (((mz >> i) * mx) >> (expx - 2 * expy - i)); mz < 0x40000000; mz <<= 1, --expy)
3532  ;
3533  i = (my *= (mz >> 10) + 1) >> 31;
3534  return half(detail::binary, detail::fixed2half<half::round_style, 30, false, false, true>(my >> i, expy + i + 14));
3535 #endif
3536 }
3537 
3546 inline half cbrt(half arg)
3547 {
3548 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3549  return half(detail::binary,
3550  detail::float2half<half::round_style>(std::cbrt(detail::half2float<detail::internal_t>(arg.data_))));
3551 #else
3552  int abs = arg.data_ & 0x7FFF, exp = -15;
3553  if (!abs || abs == 0x3C00 || abs >= 0x7C00)
3554  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3555  for (; abs < 0x400; abs <<= 1, --exp)
3556  ;
3557  detail::uint32 ilog = exp + (abs >> 10), sign = detail::sign_mask(ilog), f,
3558  m = (((ilog << 27) +
3559  (detail::log2(static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 20, 24) >> 4)) ^
3560  sign) -
3561  sign;
3562  for (exp = 2; m < 0x80000000; m <<= 1, --exp)
3563  ;
3564  m = detail::multiply64(m, 0xAAAAAAAB);
3565  int i = m >> 31, s;
3566  exp += i;
3567  m <<= 1 - i;
3568  if (exp < 0) {
3569  f = m >> -exp;
3570  exp = 0;
3571  } else {
3572  f = (m << exp) & 0x7FFFFFFF;
3573  exp = m >> (31 - exp);
3574  }
3575  m = detail::exp2(f, (half::round_style == std::round_to_nearest) ? 29 : 26);
3576  if (sign) {
3577  if (m > 0x80000000) {
3578  m = detail::divide64(0x80000000, m, s);
3579  ++exp;
3580  }
3581  exp = -exp;
3582  }
3583  return half(detail::binary,
3584  (half::round_style == std::round_to_nearest)
3585  ? detail::fixed2half<half::round_style, 31, false, false, false>(m, exp + 14, arg.data_ & 0x8000)
3586  : detail::fixed2half<half::round_style, 23, false, false, false>(
3587  (m + 0x80) >> 8, exp + 14, arg.data_ & 0x8000));
3588 #endif
3589 }
3590 
3600 inline half hypot(half x, half y)
3601 {
3602 #ifdef HALF_ARITHMETIC_TYPE
3603  detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_),
3604  fy = detail::half2float<detail::internal_t>(y.data_);
3605 #if HALF_ENABLE_CPP11_CMATH
3606  return half(detail::binary, detail::float2half<half::round_style>(std::hypot(fx, fy)));
3607 #else
3608  return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(fx * fx + fy * fy)));
3609 #endif
3610 #else
3611  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, expx = 0, expy = 0;
3612  if (absx >= 0x7C00 || absy >= 0x7C00)
3613  return half(detail::binary,
3614  (absx == 0x7C00) ? detail::select(0x7C00, y.data_)
3615  : (absy == 0x7C00) ? detail::select(0x7C00, x.data_)
3616  : detail::signal(x.data_, y.data_));
3617  if (!absx)
3618  return half(detail::binary, absy ? detail::check_underflow(absy) : 0);
3619  if (!absy)
3621  if (absy > absx)
3622  std::swap(absx, absy);
3623  for (; absx < 0x400; absx <<= 1, --expx)
3624  ;
3625  for (; absy < 0x400; absy <<= 1, --expy)
3626  ;
3627  detail::uint32 mx = (absx & 0x3FF) | 0x400, my = (absy & 0x3FF) | 0x400;
3628  mx *= mx;
3629  my *= my;
3630  int ix = mx >> 21, iy = my >> 21;
3631  expx = 2 * (expx + (absx >> 10)) - 15 + ix;
3632  expy = 2 * (expy + (absy >> 10)) - 15 + iy;
3633  mx <<= 10 - ix;
3634  my <<= 10 - iy;
3635  int d = expx - expy;
3636  my = (d < 30) ? ((my >> d) | ((my & ((static_cast<detail::uint32>(1) << d) - 1)) != 0)) : 1;
3637  return half(detail::binary, detail::hypot_post<half::round_style>(mx + my, expx));
3638 #endif
3639 }
3640 
3651 inline half hypot(half x, half y, half z)
3652 {
3653 #ifdef HALF_ARITHMETIC_TYPE
3654  detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_),
3655  fy = detail::half2float<detail::internal_t>(y.data_),
3656  fz = detail::half2float<detail::internal_t>(z.data_);
3657  return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(fx * fx + fy * fy + fz * fz)));
3658 #else
3659  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, expx = 0, expy = 0, expz = 0;
3660  if (!absx)
3661  return hypot(y, z);
3662  if (!absy)
3663  return hypot(x, z);
3664  if (!absz)
3665  return hypot(x, y);
3666  if (absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
3667  return half(detail::binary,
3668  (absx == 0x7C00) ? detail::select(0x7C00, detail::select(y.data_, z.data_))
3669  : (absy == 0x7C00) ? detail::select(0x7C00, detail::select(x.data_, z.data_))
3670  : (absz == 0x7C00) ? detail::select(0x7C00, detail::select(x.data_, y.data_))
3671  : detail::signal(x.data_, y.data_, z.data_));
3672  if (absz > absy)
3673  std::swap(absy, absz);
3674  if (absy > absx)
3675  std::swap(absx, absy);
3676  if (absz > absy)
3677  std::swap(absy, absz);
3678  for (; absx < 0x400; absx <<= 1, --expx)
3679  ;
3680  for (; absy < 0x400; absy <<= 1, --expy)
3681  ;
3682  for (; absz < 0x400; absz <<= 1, --expz)
3683  ;
3684  detail::uint32 mx = (absx & 0x3FF) | 0x400, my = (absy & 0x3FF) | 0x400, mz = (absz & 0x3FF) | 0x400;
3685  mx *= mx;
3686  my *= my;
3687  mz *= mz;
3688  int ix = mx >> 21, iy = my >> 21, iz = mz >> 21;
3689  expx = 2 * (expx + (absx >> 10)) - 15 + ix;
3690  expy = 2 * (expy + (absy >> 10)) - 15 + iy;
3691  expz = 2 * (expz + (absz >> 10)) - 15 + iz;
3692  mx <<= 10 - ix;
3693  my <<= 10 - iy;
3694  mz <<= 10 - iz;
3695  int d = expy - expz;
3696  mz = (d < 30) ? ((mz >> d) | ((mz & ((static_cast<detail::uint32>(1) << d) - 1)) != 0)) : 1;
3697  my += mz;
3698  if (my & 0x80000000) {
3699  my = (my >> 1) | (my & 1);
3700  if (++expy > expx) {
3701  std::swap(mx, my);
3702  std::swap(expx, expy);
3703  }
3704  }
3705  d = expx - expy;
3706  my = (d < 30) ? ((my >> d) | ((my & ((static_cast<detail::uint32>(1) << d) - 1)) != 0)) : 1;
3707  return half(detail::binary, detail::hypot_post<half::round_style>(mx + my, expx));
3708 #endif
3709 }
3710 
3721 inline half pow(half x, half y)
3722 {
3723 #ifdef HALF_ARITHMETIC_TYPE
3724  return half(detail::binary,
3725  detail::float2half<half::round_style>(std::pow(
3726  detail::half2float<detail::internal_t>(x.data_), detail::half2float<detail::internal_t>(y.data_))));
3727 #else
3728  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -15;
3729  if (!absy || x.data_ == 0x3C00)
3730  return half(detail::binary, detail::select(0x3C00, (x.data_ == 0x3C00) ? y.data_ : x.data_));
3731  bool is_int = absy >= 0x6400 || (absy >= 0x3C00 && !(absy & ((1 << (25 - (absy >> 10))) - 1)));
3732  unsigned int sign =
3733  x.data_ & (static_cast<unsigned>((absy < 0x6800) && is_int && ((absy >> (25 - (absy >> 10))) & 1)) << 15);
3734  if (absx >= 0x7C00 || absy >= 0x7C00)
3735  return half(detail::binary,
3736  (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_)
3737  : (absy == 0x7C00)
3738  ? ((absx == 0x3C00) ? 0x3C00
3739  : (!absx && y.data_ == 0xFC00) ? detail::pole()
3740  : (0x7C00 & -((y.data_ >> 15) ^ (absx > 0x3C00))))
3741  : (sign | (0x7C00 & ((y.data_ >> 15) - 1U))));
3742  if (!absx)
3743  return half(detail::binary, (y.data_ & 0x8000) ? detail::pole(sign) : sign);
3744  if ((x.data_ & 0x8000) && !is_int)
3745  return half(detail::binary, detail::invalid());
3746  if (x.data_ == 0xBC00)
3747  return half(detail::binary, sign | 0x3C00);
3748  switch (y.data_) {
3749  case 0x3800:
3750  return sqrt(x);
3751  case 0x3C00:
3753  case 0x4000:
3754  return x * x;
3755  case 0xBC00:
3756  return half(detail::binary, 0x3C00) / x;
3757  }
3758  for (; absx < 0x400; absx <<= 1, --exp)
3759  ;
3760  detail::uint32 ilog = exp + (absx >> 10), msign = detail::sign_mask(ilog), f,
3761  m = (((ilog << 27) +
3762  ((detail::log2(static_cast<detail::uint32>((absx & 0x3FF) | 0x400) << 20) + 8) >> 4)) ^
3763  msign) -
3764  msign;
3765  for (exp = -11; m < 0x80000000; m <<= 1, --exp)
3766  ;
3767  for (; absy < 0x400; absy <<= 1, --exp)
3768  ;
3769  m = detail::multiply64(m, static_cast<detail::uint32>((absy & 0x3FF) | 0x400) << 21);
3770  int i = m >> 31;
3771  exp += (absy >> 10) + i;
3772  m <<= 1 - i;
3773  if (exp < 0) {
3774  f = m >> -exp;
3775  exp = 0;
3776  } else {
3777  f = (m << exp) & 0x7FFFFFFF;
3778  exp = m >> (31 - exp);
3779  }
3780  return half(
3781  detail::binary, detail::exp2_post<half::round_style>(f, exp, ((msign & 1) ^ (y.data_ >> 15)) != 0, sign));
3782 #endif
3783 }
3784 
3789 
3799 inline void sincos(half arg, half* sin, half* cos)
3800 {
3801 #ifdef HALF_ARITHMETIC_TYPE
3802  detail::internal_t f = detail::half2float<detail::internal_t>(arg.data_);
3803  *sin = half(detail::binary, detail::float2half<half::round_style>(std::sin(f)));
3804  *cos = half(detail::binary, detail::float2half<half::round_style>(std::cos(f)));
3805 #else
3806  int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15, k;
3807  if (abs >= 0x7C00)
3808  *sin = *cos = half(detail::binary, (abs == 0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3809  else if (!abs) {
3810  *sin = arg;
3811  *cos = half(detail::binary, 0x3C00);
3812  } else if (abs < 0x2500) {
3813  *sin = half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
3814  *cos = half(detail::binary, detail::rounded<half::round_style, true>(0x3BFF, 1, 1));
3815  } else {
3816  if (half::round_style != std::round_to_nearest) {
3817  switch (abs) {
3818  case 0x48B7:
3819  *sin = half(
3820  detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x1D07, 1, 1));
3821  *cos = half(detail::binary, detail::rounded<half::round_style, true>(0xBBFF, 1, 1));
3822  return;
3823  case 0x598C:
3824  *sin =
3825  half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x3BFF, 1, 1));
3826  *cos = half(detail::binary, detail::rounded<half::round_style, true>(0x80FC, 1, 1));
3827  return;
3828  case 0x6A64:
3829  *sin = half(
3830  detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x3BFE, 1, 1));
3831  *cos = half(detail::binary, detail::rounded<half::round_style, true>(0x27FF, 1, 1));
3832  return;
3833  case 0x6D8C:
3834  *sin =
3835  half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x0FE6, 1, 1));
3836  *cos = half(detail::binary, detail::rounded<half::round_style, true>(0x3BFF, 1, 1));
3837  return;
3838  }
3839  }
3840  std::pair<detail::uint32, detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
3841  switch (k & 3) {
3842  case 1:
3843  sc = std::make_pair(sc.second, -sc.first);
3844  break;
3845  case 2:
3846  sc = std::make_pair(-sc.first, -sc.second);
3847  break;
3848  case 3:
3849  sc = std::make_pair(-sc.second, sc.first);
3850  break;
3851  }
3852  *sin = half(detail::binary,
3853  detail::fixed2half<half::round_style, 30, true, true, true>(
3854  (sc.first ^ -static_cast<detail::uint32>(sign)) + sign));
3855  *cos = half(detail::binary, detail::fixed2half<half::round_style, 30, true, true, true>(sc.second));
3856  }
3857 #endif
3858 }
3859 
3868 inline half sin(half arg)
3869 {
3870 #ifdef HALF_ARITHMETIC_TYPE
3871  return half(detail::binary,
3872  detail::float2half<half::round_style>(std::sin(detail::half2float<detail::internal_t>(arg.data_))));
3873 #else
3874  int abs = arg.data_ & 0x7FFF, k;
3875  if (!abs)
3876  return arg;
3877  if (abs >= 0x7C00)
3878  return half(detail::binary, (abs == 0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3879  if (abs < 0x2900)
3880  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
3881  if (half::round_style != std::round_to_nearest)
3882  switch (abs) {
3883  case 0x48B7:
3884  return half(detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x1D07, 1, 1));
3885  case 0x6A64:
3886  return half(detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x3BFE, 1, 1));
3887  case 0x6D8C:
3888  return half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x0FE6, 1, 1));
3889  }
3890  std::pair<detail::uint32, detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
3891  detail::uint32 sign = -static_cast<detail::uint32>(((k >> 1) & 1) ^ (arg.data_ >> 15));
3892  return half(detail::binary,
3893  detail::fixed2half<half::round_style, 30, true, true, true>((((k & 1) ? sc.second : sc.first) ^ sign) - sign));
3894 #endif
3895 }
3896 
3905 inline half cos(half arg)
3906 {
3907 #ifdef HALF_ARITHMETIC_TYPE
3908  return half(detail::binary,
3909  detail::float2half<half::round_style>(std::cos(detail::half2float<detail::internal_t>(arg.data_))));
3910 #else
3911  int abs = arg.data_ & 0x7FFF, k;
3912  if (!abs)
3913  return half(detail::binary, 0x3C00);
3914  if (abs >= 0x7C00)
3915  return half(detail::binary, (abs == 0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3916  if (abs < 0x2500)
3917  return half(detail::binary, detail::rounded<half::round_style, true>(0x3BFF, 1, 1));
3918  if (half::round_style != std::round_to_nearest && abs == 0x598C)
3919  return half(detail::binary, detail::rounded<half::round_style, true>(0x80FC, 1, 1));
3920  std::pair<detail::uint32, detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
3921  detail::uint32 sign = -static_cast<detail::uint32>(((k >> 1) ^ k) & 1);
3922  return half(detail::binary,
3923  detail::fixed2half<half::round_style, 30, true, true, true>((((k & 1) ? sc.first : sc.second) ^ sign) - sign));
3924 #endif
3925 }
3926 
3935 inline half tan(half arg)
3936 {
3937 #ifdef HALF_ARITHMETIC_TYPE
3938  return half(detail::binary,
3939  detail::float2half<half::round_style>(std::tan(detail::half2float<detail::internal_t>(arg.data_))));
3940 #else
3941  int abs = arg.data_ & 0x7FFF, exp = 13, k;
3942  if (!abs)
3943  return arg;
3944  if (abs >= 0x7C00)
3945  return half(detail::binary, (abs == 0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3946  if (abs < 0x2700)
3947  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_, 0, 1));
3948  if (half::round_style != std::round_to_nearest)
3949  switch (abs) {
3950  case 0x658C:
3951  return half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x07E6, 1, 1));
3952  case 0x7330:
3953  return half(detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x4B62, 1, 1));
3954  }
3955  std::pair<detail::uint32, detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 30);
3956  if (k & 1)
3957  sc = std::make_pair(-sc.second, sc.first);
3958  detail::uint32 signy = detail::sign_mask(sc.first), signx = detail::sign_mask(sc.second);
3959  detail::uint32 my = (sc.first ^ signy) - signy, mx = (sc.second ^ signx) - signx;
3960  for (; my < 0x80000000; my <<= 1, --exp)
3961  ;
3962  for (; mx < 0x80000000; mx <<= 1, ++exp)
3963  ;
3964  return half(
3965  detail::binary, detail::tangent_post<half::round_style>(my, mx, exp, (signy ^ signx ^ arg.data_) & 0x8000));
3966 #endif
3967 }
3968 
3977 inline half asin(half arg)
3978 {
3979 #ifdef HALF_ARITHMETIC_TYPE
3980  return half(detail::binary,
3981  detail::float2half<half::round_style>(std::asin(detail::half2float<detail::internal_t>(arg.data_))));
3982 #else
3983  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
3984  if (!abs)
3985  return arg;
3986  if (abs >= 0x3C00)
3987  return half(detail::binary,
3988  (abs > 0x7C00) ? detail::signal(arg.data_)
3989  : (abs > 0x3C00) ? detail::invalid()
3990  : detail::rounded<half::round_style, true>(sign | 0x3E48, 0, 1));
3991  if (abs < 0x2900)
3992  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_, 0, 1));
3993  if (half::round_style != std::round_to_nearest && (abs == 0x2B44 || abs == 0x2DC3))
3994  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ + 1, 1, 1));
3995  std::pair<detail::uint32, detail::uint32> sc = detail::atan2_args(abs);
3996  detail::uint32 m = detail::atan2(sc.first, sc.second, (half::round_style == std::round_to_nearest) ? 27 : 26);
3997  return half(detail::binary, detail::fixed2half<half::round_style, 30, false, true, true>(m, 14, sign));
3998 #endif
3999 }
4000 
4009 inline half acos(half arg)
4010 {
4011 #ifdef HALF_ARITHMETIC_TYPE
4012  return half(detail::binary,
4013  detail::float2half<half::round_style>(std::acos(detail::half2float<detail::internal_t>(arg.data_))));
4014 #else
4015  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15;
4016  if (!abs)
4017  return half(detail::binary, detail::rounded<half::round_style, true>(0x3E48, 0, 1));
4018  if (abs >= 0x3C00)
4019  return half(detail::binary,
4020  (abs > 0x7C00) ? detail::signal(arg.data_)
4021  : (abs > 0x3C00) ? detail::invalid()
4022  : sign ? detail::rounded<half::round_style, true>(0x4248, 0, 1)
4023  : 0);
4024  std::pair<detail::uint32, detail::uint32> cs = detail::atan2_args(abs);
4025  detail::uint32 m = detail::atan2(cs.second, cs.first, 28);
4026  return half(detail::binary,
4027  detail::fixed2half<half::round_style, 31, false, true, true>(sign ? (0xC90FDAA2 - m) : m, 15, 0, sign));
4028 #endif
4029 }
4030 
4039 inline half atan(half arg)
4040 {
4041 #ifdef HALF_ARITHMETIC_TYPE
4042  return half(detail::binary,
4043  detail::float2half<half::round_style>(std::atan(detail::half2float<detail::internal_t>(arg.data_))));
4044 #else
4045  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
4046  if (!abs)
4047  return arg;
4048  if (abs >= 0x7C00)
4049  return half(detail::binary,
4050  (abs == 0x7C00) ? detail::rounded<half::round_style, true>(sign | 0x3E48, 0, 1)
4051  : detail::signal(arg.data_));
4052  if (abs <= 0x2700)
4053  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
4054  int exp = (abs >> 10) + (abs <= 0x3FF);
4055  detail::uint32 my = (abs & 0x3FF) | ((abs > 0x3FF) << 10);
4056  detail::uint32 m = (exp > 15)
4057  ? detail::atan2(my << 19, 0x20000000 >> (exp - 15), (half::round_style == std::round_to_nearest) ? 26 : 24)
4058  : detail::atan2(my << (exp + 4), 0x20000000, (half::round_style == std::round_to_nearest) ? 30 : 28);
4059  return half(detail::binary, detail::fixed2half<half::round_style, 30, false, true, true>(m, 14, sign));
4060 #endif
4061 }
4062 
4073 inline half atan2(half y, half x)
4074 {
4075 #ifdef HALF_ARITHMETIC_TYPE
4076  return half(detail::binary,
4077  detail::float2half<half::round_style>(std::atan2(
4078  detail::half2float<detail::internal_t>(y.data_), detail::half2float<detail::internal_t>(x.data_))));
4079 #else
4080  unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, signx = x.data_ >> 15, signy = y.data_ & 0x8000;
4081  if (absx >= 0x7C00 || absy >= 0x7C00) {
4082  if (absx > 0x7C00 || absy > 0x7C00)
4083  return half(detail::binary, detail::signal(x.data_, y.data_));
4084  if (absy == 0x7C00)
4085  return half(detail::binary,
4086  (absx < 0x7C00) ? detail::rounded<half::round_style, true>(signy | 0x3E48, 0, 1)
4087  : signx ? detail::rounded<half::round_style, true>(signy | 0x40B6, 0, 1)
4088  : detail::rounded<half::round_style, true>(signy | 0x3A48, 0, 1));
4089  return (x.data_ == 0x7C00)
4090  ? half(detail::binary, signy)
4091  : half(detail::binary, detail::rounded<half::round_style, true>(signy | 0x4248, 0, 1));
4092  }
4093  if (!absy)
4094  return signx ? half(detail::binary, detail::rounded<half::round_style, true>(signy | 0x4248, 0, 1)) : y;
4095  if (!absx)
4096  return half(detail::binary, detail::rounded<half::round_style, true>(signy | 0x3E48, 0, 1));
4097  int d = (absy >> 10) + (absy <= 0x3FF) - (absx >> 10) - (absx <= 0x3FF);
4098  if (d > (signx ? 18 : 12))
4099  return half(detail::binary, detail::rounded<half::round_style, true>(signy | 0x3E48, 0, 1));
4100  if (signx && d < -11)
4101  return half(detail::binary, detail::rounded<half::round_style, true>(signy | 0x4248, 0, 1));
4102  if (!signx && d < ((half::round_style == std::round_toward_zero) ? -15 : -9)) {
4103  for (; absy < 0x400; absy <<= 1, --d)
4104  ;
4105  detail::uint32 mx = ((absx << 1) & 0x7FF) | 0x800, my = ((absy << 1) & 0x7FF) | 0x800;
4106  int i = my < mx;
4107  d -= i;
4108  if (d < -25)
4109  return half(detail::binary, detail::underflow<half::round_style>(signy));
4110  my <<= 11 + i;
4111  return half(detail::binary,
4112  detail::fixed2half<half::round_style, 11, false, false, true>(my / mx, d + 14, signy, my % mx != 0));
4113  }
4114  detail::uint32 m = detail::atan2(((absy & 0x3FF) | ((absy > 0x3FF) << 10)) << (19 +
4115  ((d < 0) ? d
4116  : (d > 0) ? 0
4117  : -1)),
4118  ((absx & 0x3FF) | ((absx > 0x3FF) << 10)) << (19 -
4119  ((d > 0) ? d
4120  : (d < 0) ? 0
4121  : 1)));
4122  return half(detail::binary,
4123  detail::fixed2half<half::round_style, 31, false, true, true>(signx ? (0xC90FDAA2 - m) : m, 15, signy, signx));
4124 #endif
4125 }
4126 
4131 
4140 inline half sinh(half arg)
4141 {
4142 #ifdef HALF_ARITHMETIC_TYPE
4143  return half(detail::binary,
4144  detail::float2half<half::round_style>(std::sinh(detail::half2float<detail::internal_t>(arg.data_))));
4145 #else
4146  int abs = arg.data_ & 0x7FFF, exp;
4147  if (!abs || abs >= 0x7C00)
4148  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
4149  if (abs <= 0x2900)
4150  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_, 0, 1));
4151  std::pair<detail::uint32, detail::uint32> mm =
4152  detail::hyperbolic_args(abs, exp, (half::round_style == std::round_to_nearest) ? 29 : 27);
4153  detail::uint32 m = mm.first - mm.second;
4154  for (exp += 13; m < 0x80000000 && exp; m <<= 1, --exp)
4155  ;
4156  unsigned int sign = arg.data_ & 0x8000;
4157  if (exp > 29)
4158  return half(detail::binary, detail::overflow<half::round_style>(sign));
4159  return half(detail::binary, detail::fixed2half<half::round_style, 31, false, false, true>(m, exp, sign));
4160 #endif
4161 }
4162 
4171 inline half cosh(half arg)
4172 {
4173 #ifdef HALF_ARITHMETIC_TYPE
4174  return half(detail::binary,
4175  detail::float2half<half::round_style>(std::cosh(detail::half2float<detail::internal_t>(arg.data_))));
4176 #else
4177  int abs = arg.data_ & 0x7FFF, exp;
4178  if (!abs)
4179  return half(detail::binary, 0x3C00);
4180  if (abs >= 0x7C00)
4181  return half(detail::binary, (abs > 0x7C00) ? detail::signal(arg.data_) : 0x7C00);
4182  std::pair<detail::uint32, detail::uint32> mm =
4183  detail::hyperbolic_args(abs, exp, (half::round_style == std::round_to_nearest) ? 23 : 26);
4184  detail::uint32 m = mm.first + mm.second, i = (~m & 0xFFFFFFFF) >> 31;
4185  m = (m >> i) | (m & i) | 0x80000000;
4186  if ((exp += 13 + i) > 29)
4187  return half(detail::binary, detail::overflow<half::round_style>());
4188  return half(detail::binary, detail::fixed2half<half::round_style, 31, false, false, true>(m, exp));
4189 #endif
4190 }
4191 
4200 inline half tanh(half arg)
4201 {
4202 #ifdef HALF_ARITHMETIC_TYPE
4203  return half(detail::binary,
4204  detail::float2half<half::round_style>(std::tanh(detail::half2float<detail::internal_t>(arg.data_))));
4205 #else
4206  int abs = arg.data_ & 0x7FFF, exp;
4207  if (!abs)
4208  return arg;
4209  if (abs >= 0x7C00)
4210  return half(detail::binary, (abs > 0x7C00) ? detail::signal(arg.data_) : (arg.data_ - 0x4000));
4211  if (abs >= 0x4500)
4212  return half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x3BFF, 1, 1));
4213  if (abs < 0x2700)
4214  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
4215  if (half::round_style != std::round_to_nearest && abs == 0x2D3F)
4216  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 3, 0, 1));
4217  std::pair<detail::uint32, detail::uint32> mm = detail::hyperbolic_args(abs, exp, 27);
4218  detail::uint32 my = mm.first - mm.second - (half::round_style != std::round_to_nearest), mx = mm.first + mm.second,
4219  i = (~mx & 0xFFFFFFFF) >> 31;
4220  for (exp = 13; my < 0x80000000; my <<= 1, --exp)
4221  ;
4222  mx = (mx >> i) | 0x80000000;
4223  return half(detail::binary, detail::tangent_post<half::round_style>(my, mx, exp - i, arg.data_ & 0x8000));
4224 #endif
4225 }
4226 
4235 inline half asinh(half arg)
4236 {
4237 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
4238  return half(detail::binary,
4239  detail::float2half<half::round_style>(std::asinh(detail::half2float<detail::internal_t>(arg.data_))));
4240 #else
4241  int abs = arg.data_ & 0x7FFF;
4242  if (!abs || abs >= 0x7C00)
4243  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
4244  if (abs <= 0x2900)
4245  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
4246  if (half::round_style != std::round_to_nearest)
4247  switch (abs) {
4248  case 0x32D4:
4249  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 13, 1, 1));
4250  case 0x3B5B:
4251  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 197, 1, 1));
4252  }
4253  return half(detail::binary, detail::area<half::round_style, true>(arg.data_));
4254 #endif
4255 }
4256 
4265 inline half acosh(half arg)
4266 {
4267 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
4268  return half(detail::binary,
4269  detail::float2half<half::round_style>(std::acosh(detail::half2float<detail::internal_t>(arg.data_))));
4270 #else
4271  int abs = arg.data_ & 0x7FFF;
4272  if ((arg.data_ & 0x8000) || abs < 0x3C00)
4273  return half(detail::binary, (abs <= 0x7C00) ? detail::invalid() : detail::signal(arg.data_));
4274  if (abs == 0x3C00)
4275  return half(detail::binary, 0);
4276  if (arg.data_ >= 0x7C00)
4277  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
4278  return half(detail::binary, detail::area<half::round_style, false>(arg.data_));
4279 #endif
4280 }
4281 
4291 inline half atanh(half arg)
4292 {
4293 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
4294  return half(detail::binary,
4295  detail::float2half<half::round_style>(std::atanh(detail::half2float<detail::internal_t>(arg.data_))));
4296 #else
4297  int abs = arg.data_ & 0x7FFF, exp = 0;
4298  if (!abs)
4299  return arg;
4300  if (abs >= 0x3C00)
4301  return half(detail::binary,
4302  (abs == 0x3C00) ? detail::pole(arg.data_ & 0x8000)
4303  : (abs <= 0x7C00) ? detail::invalid()
4304  : detail::signal(arg.data_));
4305  if (abs < 0x2700)
4306  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_, 0, 1));
4307  detail::uint32 m = static_cast<detail::uint32>((abs & 0x3FF) | ((abs > 0x3FF) << 10))
4308  << ((abs >> 10) + (abs <= 0x3FF) + 6),
4309  my = 0x80000000 + m, mx = 0x80000000 - m;
4310  for (; mx < 0x80000000; mx <<= 1, ++exp)
4311  ;
4312  int i = my >= mx, s;
4313  return half(detail::binary,
4314  detail::log2_post<half::round_style, 0xB8AA3B2A>(
4315  detail::log2((detail::divide64(my >> i, mx, s) + 1) >> 1, 27) + 0x10, exp + i - 1, 16, arg.data_ & 0x8000));
4316 #endif
4317 }
4318 
4323 
4332 inline half erf(half arg)
4333 {
4334 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
4335  return half(detail::binary,
4336  detail::float2half<half::round_style>(std::erf(detail::half2float<detail::internal_t>(arg.data_))));
4337 #else
4338  unsigned int abs = arg.data_ & 0x7FFF;
4339  if (!abs || abs >= 0x7C00)
4340  return (abs >= 0x7C00)
4341  ? half(detail::binary, (abs == 0x7C00) ? (arg.data_ - 0x4000) : detail::signal(arg.data_))
4342  : arg;
4343  if (abs >= 0x4200)
4344  return half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x3BFF, 1, 1));
4345  return half(detail::binary, detail::erf<half::round_style, false>(arg.data_));
4346 #endif
4347 }
4348 
4357 inline half erfc(half arg)
4358 {
4359 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
4360  return half(detail::binary,
4361  detail::float2half<half::round_style>(std::erfc(detail::half2float<detail::internal_t>(arg.data_))));
4362 #else
4363  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
4364  if (abs >= 0x7C00)
4365  return (abs >= 0x7C00) ? half(detail::binary, (abs == 0x7C00) ? (sign >> 1) : detail::signal(arg.data_)) : arg;
4366  if (!abs)
4367  return half(detail::binary, 0x3C00);
4368  if (abs >= 0x4400)
4369  return half(
4370  detail::binary, detail::rounded<half::round_style, true>((sign >> 1) - (sign >> 15), sign >> 15, 1));
4371  return half(detail::binary, detail::erf<half::round_style, true>(arg.data_));
4372 #endif
4373 }
4374 
4384 inline half lgamma(half arg)
4385 {
4386 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
4387  return half(detail::binary,
4388  detail::float2half<half::round_style>(std::lgamma(detail::half2float<detail::internal_t>(arg.data_))));
4389 #else
4390  int abs = arg.data_ & 0x7FFF;
4391  if (abs >= 0x7C00)
4392  return half(detail::binary, (abs == 0x7C00) ? 0x7C00 : detail::signal(arg.data_));
4393  if (!abs || arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(abs & ((1 << (25 - (abs >> 10))) - 1))))
4394  return half(detail::binary, detail::pole());
4395  if (arg.data_ == 0x3C00 || arg.data_ == 0x4000)
4396  return half(detail::binary, 0);
4397  return half(detail::binary, detail::gamma<half::round_style, true>(arg.data_));
4398 #endif
4399 }
4400 
4410 inline half tgamma(half arg)
4411 {
4412 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
4413  return half(detail::binary,
4414  detail::float2half<half::round_style>(std::tgamma(detail::half2float<detail::internal_t>(arg.data_))));
4415 #else
4416  unsigned int abs = arg.data_ & 0x7FFF;
4417  if (!abs)
4418  return half(detail::binary, detail::pole(arg.data_));
4419  if (abs >= 0x7C00)
4420  return (arg.data_ == 0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
4421  if (arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(abs & ((1 << (25 - (abs >> 10))) - 1))))
4422  return half(detail::binary, detail::invalid());
4423  if (arg.data_ >= 0xCA80)
4424  return half(
4425  detail::binary, detail::underflow<half::round_style>((1 - ((abs >> (25 - (abs >> 10))) & 1)) << 15));
4426  if (arg.data_ <= 0x100 || (arg.data_ >= 0x4900 && arg.data_ < 0x8000))
4427  return half(detail::binary, detail::overflow<half::round_style>());
4428  if (arg.data_ == 0x3C00)
4429  return arg;
4430  return half(detail::binary, detail::gamma<half::round_style, false>(arg.data_));
4431 #endif
4432 }
4433 
4438 
4445 inline half ceil(half arg)
4446 {
4447  return half(detail::binary, detail::integral<std::round_toward_infinity, true, true>(arg.data_));
4448 }
4449 
4456 inline half floor(half arg)
4457 {
4458  return half(detail::binary, detail::integral<std::round_toward_neg_infinity, true, true>(arg.data_));
4459 }
4460 
4467 inline half trunc(half arg)
4468 {
4469  return half(detail::binary, detail::integral<std::round_toward_zero, true, true>(arg.data_));
4470 }
4471 
4478 inline half round(half arg)
4479 {
4480  return half(detail::binary, detail::integral<std::round_to_nearest, false, true>(arg.data_));
4481 }
4482 
4488 inline long lround(half arg) { return detail::half2int<std::round_to_nearest, false, false, long>(arg.data_); }
4489 
4496 inline half rint(half arg) { return half(detail::binary, detail::integral<half::round_style, true, true>(arg.data_)); }
4497 
4504 inline long lrint(half arg) { return detail::half2int<half::round_style, true, true, long>(arg.data_); }
4505 
4511 inline half nearbyint(half arg)
4512 {
4513  return half(detail::binary, detail::integral<half::round_style, true, false>(arg.data_));
4514 }
4515 #if HALF_ENABLE_CPP11_LONG_LONG
4521 inline long long llround(half arg)
4522 {
4523  return detail::half2int<std::round_to_nearest, false, false, long long>(arg.data_);
4524 }
4525 
4532 inline long long llrint(half arg) { return detail::half2int<half::round_style, true, true, long long>(arg.data_); }
4533 #endif
4534 
4539 
4546 inline half frexp(half arg, int* exp)
4547 {
4548  *exp = 0;
4549  unsigned int abs = arg.data_ & 0x7FFF;
4550  if (abs >= 0x7C00 || !abs)
4551  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
4552  for (; abs < 0x400; abs <<= 1, --*exp)
4553  ;
4554  *exp += (abs >> 10) - 14;
4555  return half(detail::binary, (arg.data_ & 0x8000) | 0x3800 | (abs & 0x3FF));
4556 }
4557 
4567 inline half scalbln(half arg, long exp)
4568 {
4569  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
4570  if (abs >= 0x7C00 || !abs)
4571  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
4572  for (; abs < 0x400; abs <<= 1, --exp)
4573  ;
4574  exp += abs >> 10;
4575  if (exp > 30)
4576  return half(detail::binary, detail::overflow<half::round_style>(sign));
4577  else if (exp < -10)
4578  return half(detail::binary, detail::underflow<half::round_style>(sign));
4579  else if (exp > 0)
4580  return half(detail::binary, sign | (exp << 10) | (abs & 0x3FF));
4581  unsigned int m = (abs & 0x3FF) | 0x400;
4582  return half(detail::binary,
4583  detail::rounded<half::round_style, false>(
4584  sign | (m >> (1 - exp)), (m >> -exp) & 1, (m & ((1 << -exp) - 1)) != 0));
4585 }
4586 
4596 inline half scalbn(half arg, int exp) { return scalbln(arg, exp); }
4597 
4607 inline half ldexp(half arg, int exp) { return scalbln(arg, exp); }
4608 
4615 inline half modf(half arg, half* iptr)
4616 {
4617  unsigned int abs = arg.data_ & 0x7FFF;
4618  if (abs > 0x7C00) {
4619  arg = half(detail::binary, detail::signal(arg.data_));
4620  return *iptr = arg, arg;
4621  }
4622  if (abs >= 0x6400)
4623  return *iptr = arg, half(detail::binary, arg.data_ & 0x8000);
4624  if (abs < 0x3C00)
4625  return iptr->data_ = arg.data_ & 0x8000, arg;
4626  unsigned int exp = abs >> 10, mask = (1 << (25 - exp)) - 1, m = arg.data_ & mask;
4627  iptr->data_ = arg.data_ & ~mask;
4628  if (!m)
4629  return half(detail::binary, arg.data_ & 0x8000);
4630  for (; m < 0x400; m <<= 1, --exp)
4631  ;
4632  return half(detail::binary, (arg.data_ & 0x8000) | (exp << 10) | (m & 0x3FF));
4633 }
4634 
4643 inline int ilogb(half arg)
4644 {
4645  int abs = arg.data_ & 0x7FFF, exp;
4646  if (!abs || abs >= 0x7C00) {
4648  return !abs ? FP_ILOGB0 : (abs == 0x7C00) ? INT_MAX : FP_ILOGBNAN;
4649  }
4650  for (exp = (abs >> 10) - 15; abs < 0x200; abs <<= 1, --exp)
4651  ;
4652  return exp;
4653 }
4654 
4661 inline half logb(half arg)
4662 {
4663  int abs = arg.data_ & 0x7FFF, exp;
4664  if (!abs)
4665  return half(detail::binary, detail::pole(0x8000));
4666  if (abs >= 0x7C00)
4667  return half(detail::binary, (abs == 0x7C00) ? 0x7C00 : detail::signal(arg.data_));
4668  for (exp = (abs >> 10) - 15; abs < 0x200; abs <<= 1, --exp)
4669  ;
4670  unsigned int value = static_cast<unsigned>(exp < 0) << 15;
4671  if (exp) {
4672  unsigned int m = std::abs(exp) << 6;
4673  for (exp = 18; m < 0x400; m <<= 1, --exp)
4674  ;
4675  value |= (exp << 10) + m;
4676  }
4677  return half(detail::binary, value);
4678 }
4679 
4688 inline half nextafter(half from, half to)
4689 {
4690  int fabs = from.data_ & 0x7FFF, tabs = to.data_ & 0x7FFF;
4691  if (fabs > 0x7C00 || tabs > 0x7C00)
4692  return half(detail::binary, detail::signal(from.data_, to.data_));
4693  if (from.data_ == to.data_ || !(fabs | tabs))
4694  return to;
4695  if (!fabs) {
4697  return half(detail::binary, (to.data_ & 0x8000) + 1);
4698  }
4699  unsigned int out = from.data_ +
4700  (((from.data_ >> 15) ^
4701  static_cast<unsigned>((from.data_ ^ (0x8000 | (0x8000 - (from.data_ >> 15)))) <
4702  (to.data_ ^ (0x8000 | (0x8000 - (to.data_ >> 15))))))
4703  << 1) -
4704  1;
4705  detail::raise(FE_OVERFLOW, fabs < 0x7C00 && (out & 0x7C00) == 0x7C00);
4707  return half(detail::binary, out);
4708 }
4709 
4718 inline half nexttoward(half from, long double to)
4719 {
4720  int fabs = from.data_ & 0x7FFF;
4721  if (fabs > 0x7C00)
4722  return half(detail::binary, detail::signal(from.data_));
4723  long double lfrom = static_cast<long double>(from);
4724  if (detail::builtin_isnan(to) || lfrom == to)
4725  return half(static_cast<float>(to));
4726  if (!fabs) {
4728  return half(detail::binary, (static_cast<unsigned>(detail::builtin_signbit(to)) << 15) + 1);
4729  }
4730  unsigned int out = from.data_ + (((from.data_ >> 15) ^ static_cast<unsigned>(lfrom < to)) << 1) - 1;
4731  detail::raise(FE_OVERFLOW, (out & 0x7FFF) == 0x7C00);
4733  return half(detail::binary, out);
4734 }
4735 
4742 {
4743  return half(detail::binary, x.data_ ^ ((x.data_ ^ y.data_) & 0x8000));
4744 }
4745 
4750 
4760 {
4761  return !(arg.data_ & 0x7FFF) ? FP_ZERO
4762  : ((arg.data_ & 0x7FFF) < 0x400) ? FP_SUBNORMAL
4763  : ((arg.data_ & 0x7FFF) < 0x7C00) ? FP_NORMAL
4764  : ((arg.data_ & 0x7FFF) == 0x7C00) ? FP_INFINITE
4765  : FP_NAN;
4766 }
4767 
4773 inline HALF_CONSTEXPR bool isfinite(half arg) { return (arg.data_ & 0x7C00) != 0x7C00; }
4774 
4780 inline HALF_CONSTEXPR bool isinf(half arg) { return (arg.data_ & 0x7FFF) == 0x7C00; }
4781 
4787 inline HALF_CONSTEXPR bool isnan(half arg) { return (arg.data_ & 0x7FFF) > 0x7C00; }
4788 
4794 inline HALF_CONSTEXPR bool isnormal(half arg) { return ((arg.data_ & 0x7C00) != 0) & ((arg.data_ & 0x7C00) != 0x7C00); }
4795 
4801 inline HALF_CONSTEXPR bool signbit(half arg) { return (arg.data_ & 0x8000) != 0; }
4802 
4807 
4815 {
4816  return ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) >
4817  ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15)) &&
4818  !isnan(x) && !isnan(y);
4819 }
4820 
4826 {
4827  return ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) >=
4828  ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15)) &&
4829  !isnan(x) && !isnan(y);
4830 }
4831 
4838 inline HALF_CONSTEXPR bool isless(half x, half y)
4839 {
4840  return ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) <
4841  ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15)) &&
4842  !isnan(x) && !isnan(y);
4843 }
4844 
4852 {
4853  return ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) <=
4854  ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15)) &&
4855  !isnan(x) && !isnan(y);
4856 }
4857 
4865 {
4866  return x.data_ != y.data_ && ((x.data_ | y.data_) & 0x7FFF) && !isnan(x) && !isnan(y);
4867 }
4868 
4875 inline HALF_CONSTEXPR bool isunordered(half x, half y) { return isnan(x) || isnan(y); }
4876 
4881 
4896 template <typename T, typename U> T half_cast(U arg) { return detail::half_caster<T, U>::cast(arg); }
4897 
4913 template <typename T, std::float_round_style R, typename U> T half_cast(U arg)
4914 {
4916 }
4918 
4923 
4931 inline int feclearexcept(int excepts)
4932 {
4933  detail::errflags() &= ~excepts;
4934  return 0;
4935 }
4936 
4944 inline int fetestexcept(int excepts) { return detail::errflags() & excepts; }
4945 
4955 inline int feraiseexcept(int excepts)
4956 {
4957  detail::errflags() |= excepts;
4958  detail::raise(excepts);
4959  return 0;
4960 }
4961 
4970 inline int fegetexceptflag(int* flagp, int excepts)
4971 {
4972  *flagp = detail::errflags() & excepts;
4973  return 0;
4974 }
4975 
4985 inline int fesetexceptflag(const int* flagp, int excepts)
4986 {
4987  detail::errflags() = (detail::errflags() | (*flagp & excepts)) & (*flagp | ~excepts);
4988  return 0;
4989 }
4990 
5002 inline void fethrowexcept(int excepts, const char* msg = "")
5003 {
5004  excepts &= detail::errflags();
5005  if (excepts & (FE_INVALID | FE_DIVBYZERO))
5006  throw std::domain_error(msg);
5007  if (excepts & FE_OVERFLOW)
5008  throw std::overflow_error(msg);
5009  if (excepts & FE_UNDERFLOW)
5010  throw std::underflow_error(msg);
5011  if (excepts & FE_INEXACT)
5012  throw std::range_error(msg);
5013 }
5015 } // namespace half_float
5016 
5017 #undef HALF_UNUSED_NOERR
5018 #undef HALF_CONSTEXPR
5019 #undef HALF_CONSTEXPR_CONST
5020 #undef HALF_CONSTEXPR_NOERR
5021 #undef HALF_NOEXCEPT
5022 #undef HALF_NOTHROW
5023 #undef HALF_THREAD_LOCAL
5024 #undef HALF_TWOS_COMPLEMENT_INT
5025 #ifdef HALF_POP_WARNINGS
5026 #pragma warning(pop)
5027 #undef HALF_POP_WARNINGS
5028 #endif
5029 
5030 #endif
Half-precision floating-point type.
Definition: half.hpp:2206
friend half asinh(half)
Hyperbolic area sine.
Definition: half.hpp:4235
friend void sincos(half, half *, half *)
Compute sine and cosine simultaneously.
Definition: half.hpp:3799
friend half exp2(half)
Binary exponential.
Definition: half.hpp:3219
half operator++(int)
Postfix increment.
Definition: half.hpp:2311
friend half tanh(half)
Hyperbolic tangent.
Definition: half.hpp:4200
friend std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &, half)
Output operator.
Definition: half.hpp:2912
friend long lrint(half)
Nearest integer using half's internal rounding mode.
Definition: half.hpp:4504
friend half nanh(const char *)
Get NaN value.
Definition: half.hpp:3163
friend half atanh(half)
Hyperbolic area tangent.
Definition: half.hpp:4291
friend half atan(half)
Arc tangent function.
Definition: half.hpp:4039
friend half tan(half)
Tangent function.
Definition: half.hpp:3935
friend half nearbyint(half)
Nearest integer using half's internal rounding mode.
Definition: half.hpp:4511
friend half log1p(half)
Natural logarithm plus one.
Definition: half.hpp:3423
friend half pow(half, half)
Power function.
Definition: half.hpp:3721
half & operator-=(float rhs)
Arithmetic assignment.
Definition: half.hpp:2280
half & operator=(float rhs)
Assignment operator.
Definition: half.hpp:2232
friend half remquo(half, half, int *)
Remainder of division.
Definition: half.hpp:3011
HALF_CONSTEXPR half() HALF_NOEXCEPT
Default constructor.
Definition: half.hpp:2214
half & operator--()
Prefix decrement.
Definition: half.hpp:2306
friend half sqrt(half)
Square root.
Definition: half.hpp:3473
friend half ceil(half)
Nearest integer not less than half value.
Definition: half.hpp:4445
friend half erf(half)
Error function.
Definition: half.hpp:4332
friend half atan2(half, half)
Arc tangent function.
Definition: half.hpp:4073
half & operator/=(float rhs)
Arithmetic assignment.
Definition: half.hpp:2292
friend half modf(half, half *)
Extract integer and fractional parts.
Definition: half.hpp:4615
friend half operator*(half, half)
Multiplication.
Definition: half.hpp:2825
HALF_CONSTEXPR half(detail::binary_t, unsigned int bits) HALF_NOEXCEPT
Constructor.
Definition: half.hpp:2335
friend half sin(half)
Sine function.
Definition: half.hpp:3868
friend half trunc(half)
Nearest integer not greater in magnitude than half value.
Definition: half.hpp:4467
friend half nexttoward(half, long double)
Next representable value.
Definition: half.hpp:4718
friend half lgamma(half)
Natural logarithm of gamma function.
Definition: half.hpp:4384
friend HALF_CONSTEXPR bool isgreaterequal(half, half)
Quiet comparison for greater equal.
Definition: half.hpp:4825
friend half nextafter(half, half)
Next representable value.
Definition: half.hpp:4688
friend HALF_CONSTEXPR half copysign(half, half)
Take sign.
Definition: half.hpp:4741
friend half operator/(half, half)
Division.
Definition: half.hpp:2865
friend half tgamma(half)
Gamma function.
Definition: half.hpp:4410
half & operator/=(half rhs)
Arithmetic assignment.
Definition: half.hpp:2268
friend half exp(half)
Exponential function.
Definition: half.hpp:3184
friend HALF_CONSTEXPR half operator-(half)
Negation.
Definition: half.hpp:2740
friend half log10(half)
Common logarithm.
Definition: half.hpp:3332
friend HALF_CONSTEXPR bool isnan(half)
Check for NaN.
Definition: half.hpp:4787
friend half scalbln(half, long)
Multiply by power of two.
Definition: half.hpp:4567
friend half frexp(half, int *)
Decompress floating-point number.
Definition: half.hpp:4546
friend half cbrt(half)
Cubic root.
Definition: half.hpp:3546
friend half log(half)
Natural logarithm.
Definition: half.hpp:3301
friend HALF_CONSTEXPR half fabs(half)
Absolute value.
Definition: half.hpp:2952
friend HALF_CONSTEXPR bool islessgreater(half, half)
Quiet comarison for less or greater.
Definition: half.hpp:4864
friend HALF_CONSTEXPR bool isnormal(half)
Check if normal number.
Definition: half.hpp:4794
friend half fdim(half, half)
Positive difference.
Definition: half.hpp:3150
friend HALF_CONSTEXPR int fpclassify(half)
Classify floating-point value.
Definition: half.hpp:4759
half & operator*=(half rhs)
Arithmetic assignment.
Definition: half.hpp:2261
friend HALF_CONSTEXPR_NOERR bool operator==(half, half)
Comparison for equality.
Definition: half.hpp:2659
friend half cos(half)
Cosine function.
Definition: half.hpp:3905
detail::uint16 data_
Internal binary representation.
Definition: half.hpp:2338
half & operator+=(float rhs)
Arithmetic assignment.
Definition: half.hpp:2274
half & operator+=(half rhs)
Arithmetic assignment.
Definition: half.hpp:2247
friend HALF_CONSTEXPR bool isfinite(half)
Check if finite number.
Definition: half.hpp:4773
friend half rsqrt(half)
Inverse square root.
Definition: half.hpp:3500
friend HALF_CONSTEXPR bool isgreater(half, half)
Quiet comparison for greater than.
Definition: half.hpp:4814
friend half fmod(half, half)
Remainder of division.
Definition: half.hpp:2966
half(float rhs)
Conversion constructor.
Definition: half.hpp:2219
friend HALF_CONSTEXPR bool signbit(half)
Check sign.
Definition: half.hpp:4801
friend half acos(half)
Arc cosine function.
Definition: half.hpp:4009
half & operator*=(float rhs)
Arithmetic assignment.
Definition: half.hpp:2286
friend half remainder(half, half)
Remainder of division.
Definition: half.hpp:2989
friend half cosh(half)
Hyperbolic cosine.
Definition: half.hpp:4171
friend HALF_CONSTEXPR_NOERR half fmax(half, half)
Maximum of half expressions.
Definition: half.hpp:3116
friend long lround(half)
Nearest integer.
Definition: half.hpp:4488
friend HALF_CONSTEXPR_NOERR bool operator<=(half, half)
Comparison for less equal.
Definition: half.hpp:2707
friend std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &, half &)
Input operator.
Definition: half.hpp:2931
friend half acosh(half)
Hyperbolic area cosine.
Definition: half.hpp:4265
friend half log2(half)
Binary logarithm.
Definition: half.hpp:3373
friend half round(half)
Nearest integer.
Definition: half.hpp:4478
friend HALF_CONSTEXPR bool isless(half, half)
Quiet comparison for less than.
Definition: half.hpp:4838
friend half expm1(half)
Exponential minus one.
Definition: half.hpp:3248
friend HALF_CONSTEXPR_NOERR bool operator>=(half, half)
Comparison for greater equal.
Definition: half.hpp:2720
friend half hypot(half, half)
Hypotenuse function.
Definition: half.hpp:3600
half & operator-=(half rhs)
Arithmetic assignment.
Definition: half.hpp:2254
friend HALF_CONSTEXPR_NOERR bool operator!=(half, half)
Comparison for inequality.
Definition: half.hpp:2670
half & operator++()
Prefix increment.
Definition: half.hpp:2301
friend HALF_CONSTEXPR_NOERR bool operator<(half, half)
Comparison for less than.
Definition: half.hpp:2681
friend half erfc(half)
Complementary error function.
Definition: half.hpp:4357
friend half operator+(half, half)
Addition.
Definition: half.hpp:2749
friend half floor(half)
Nearest integer not greater than half value.
Definition: half.hpp:4456
friend HALF_CONSTEXPR_NOERR half fmin(half, half)
Minimum of half expressions.
Definition: half.hpp:3132
half operator--(int)
Postfix decrement.
Definition: half.hpp:2321
friend HALF_CONSTEXPR bool isinf(half)
Check for infinity.
Definition: half.hpp:4780
friend int ilogb(half)
Extract exponent.
Definition: half.hpp:4643
friend half fma(half, half, half)
Fused multiply add.
Definition: half.hpp:3038
friend half sinh(half)
Hyperbolic sine.
Definition: half.hpp:4140
friend half rint(half)
Nearest integer using half's internal rounding mode.
Definition: half.hpp:4496
friend HALF_CONSTEXPR bool islessequal(half, half)
Quiet comparison for less equal.
Definition: half.hpp:4851
friend half asin(half)
Arc sine.
Definition: half.hpp:3977
friend half logb(half)
Extract exponent.
Definition: half.hpp:4661
static const std::float_round_style round_style
Rounding mode to use.
Definition: half.hpp:2331
friend HALF_CONSTEXPR_NOERR bool operator>(half, half)
Comparison for greater than.
Definition: half.hpp:2694
static HALF_CONSTEXPR half_float::half max() HALF_NOTHROW
Largest finite value.
Definition: half.hpp:2583
static HALF_CONSTEXPR half_float::half quiet_NaN() HALF_NOTHROW
Quiet NaN.
Definition: half.hpp:2607
static HALF_CONSTEXPR half_float::half min() HALF_NOTHROW
Smallest positive normal value.
Definition: half.hpp:2571
static HALF_CONSTEXPR half_float::half round_error() HALF_NOTHROW
Maximum rounding error in ULP (units in the last place).
Definition: half.hpp:2595
static HALF_CONSTEXPR half_float::half infinity() HALF_NOTHROW
Positive infinity.
Definition: half.hpp:2601
static HALF_CONSTEXPR half_float::half epsilon() HALF_NOTHROW
Difference between 1 and next representable value.
Definition: half.hpp:2589
static HALF_CONSTEXPR half_float::half lowest() HALF_NOTHROW
Smallest finite value.
Definition: half.hpp:2577
static HALF_CONSTEXPR half_float::half signaling_NaN() HALF_NOTHROW
Signaling NaN.
Definition: half.hpp:2613
static HALF_CONSTEXPR half_float::half denorm_min() HALF_NOTHROW
Smallest positive subnormal value.
Definition: half.hpp:2619
#define FP_ILOGBNAN
Definition: half.hpp:415
#define HALF_NOEXCEPT
Definition: half.hpp:237
#define FP_NAN
Definition: half.hpp:424
#define HALF_CONSTEXPR_NOERR
Definition: half.hpp:229
#define FP_ZERO
Definition: half.hpp:421
#define FP_INFINITE
Definition: half.hpp:427
#define FE_UNDERFLOW
Definition: half.hpp:437
#define HALF_CONSTEXPR_CONST
Definition: half.hpp:228
#define FE_INVALID
Definition: half.hpp:434
#define FE_INEXACT
Definition: half.hpp:438
#define HALF_THREAD_LOCAL
Definition: half.hpp:245
#define HALF_NOTHROW
Definition: half.hpp:238
#define FP_ILOGB0
Definition: half.hpp:412
#define HALF_UNUSED_NOERR(name)
Definition: half.hpp:214
#define FE_DIVBYZERO
Definition: half.hpp:435
#define FP_NORMAL
Definition: half.hpp:430
#define HALF_CONSTEXPR
Definition: half.hpp:227
#define FE_OVERFLOW
Definition: half.hpp:436
#define FP_SUBNORMAL
Definition: half.hpp:418
#define HALF_ROUND_STYLE
Default rounding mode.
Definition: half.hpp:387
#define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
Raise INEXACT exception on underflow.
Definition: half.hpp:363
bool_type< false > false_type
Definition: half.hpp:485
HALF_CONSTEXPR_CONST binary_t binary
Tag for binary construction.
Definition: half.hpp:560
std::pair< uint32, uint32 > hyperbolic_args(unsigned int abs, int &exp, unsigned int n=32)
Get exponentials for hyperbolic computation.
Definition: half.hpp:1810
unsigned int integral(unsigned int value)
Round half-precision number to nearest integer value.
Definition: half.hpp:882
uint32 exp2(uint32 m, unsigned int n=32)
Fixed point binary exponential.
Definition: half.hpp:1660
bool builtin_signbit(T arg)
Check sign.
Definition: half.hpp:602
unsigned int hypot_post(uint32 r, int exp)
Hypotenuse square root and postprocessing.
Definition: half.hpp:1902
int & errflags()
Internal exception flags.
Definition: half.hpp:645
bool builtin_isnan(T arg)
Check for NaN.
Definition: half.hpp:586
unsigned short uint16
Unsigned integer of (at least) 16 bits width.
Definition: half.hpp:526
std::pair< uint32, uint32 > atan2_args(unsigned int abs)
Get arguments for atan2 function.
Definition: half.hpp:1782
HALF_CONSTEXPR_NOERR unsigned int check_underflow(unsigned int arg)
Check value for underflow.
Definition: half.hpp:798
unsigned int fixed2half(uint32 m, int exp=14, unsigned int sign=0, int s=0)
Convert fixed point to half-precision floating-point.
Definition: half.hpp:920
unsigned int mod(unsigned int x, unsigned int y, int *quo=NULL)
Half precision positive modulus.
Definition: half.hpp:1573
uint32 sqrt(uint32 &r, int &exp)
Fixed point square root.
Definition: half.hpp:1638
HALF_CONSTEXPR_NOERR unsigned int select(unsigned int x, unsigned int HALF_UNUSED_NOERR(y))
Select value or signaling NaN.
Definition: half.hpp:762
float half2float_impl(unsigned int value, float, true_type)
Convert half-precision to IEEE single-precision.
Definition: half.hpp:1148
HALF_CONSTEXPR_NOERR unsigned int overflow(unsigned int sign=0)
Half-precision overflow.
Definition: half.hpp:815
uint32 multiply64(uint32 x, uint32 y)
64-bit multiplication.
Definition: half.hpp:1531
T half2int(unsigned int value)
Convert half-precision floating-point to integer.
Definition: half.hpp:1476
uint32 mulhi(uint32 x, uint32 y)
upper part of 64-bit multiplication.
Definition: half.hpp:1517
bool_type< true > true_type
Definition: half.hpp:484
HALF_CONSTEXPR_NOERR bool compsignal(unsigned int x, unsigned int y)
Check and signal for any NaN.
Definition: half.hpp:708
uint32 atan2(uint32 my, uint32 mx, unsigned int n=31)
Fixed point arc tangent.
Definition: half.hpp:1732
long int32
Fastest unsigned integer of (at least) 32 bits width.
Definition: half.hpp:532
unsigned int float2half(T value)
Convert floating-point to half-precision.
Definition: half.hpp:1112
HALF_CONSTEXPR_NOERR unsigned int underflow(unsigned int sign=0)
Half-precision underflow.
Definition: half.hpp:831
HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int nan)
Signal and silence signaling NaN.
Definition: half.hpp:720
HALF_CONSTEXPR_NOERR unsigned int invalid()
Raise domain error and return NaN.
Definition: half.hpp:774
unsigned int gamma(unsigned int arg)
Gamma function and postprocessing.
Definition: half.hpp:2101
std::pair< uint32, uint32 > sincos(uint32 mz, unsigned int n=31)
Fixed point sine and cosine.
Definition: half.hpp:1708
uint32 arithmetic_shift(uint32 arg, int i)
Platform-independent arithmetic right shift.
Definition: half.hpp:629
uint32 log2(uint32 m, unsigned int n=32)
Fixed point binary logarithm.
Definition: half.hpp:1684
T half2float(unsigned int value)
Convert half-precision to floating-point.
Definition: half.hpp:1463
uint32 divide64(uint32 x, uint32 y, int &s)
64-bit division.
Definition: half.hpp:1546
void raise(int HALF_UNUSED_NOERR(flags), bool HALF_UNUSED_NOERR(cond)=true)
Raise floating-point exception.
Definition: half.hpp:654
uint32 angle_arg(unsigned int abs, int &k)
Reduce argument for trigonometric functions.
Definition: half.hpp:1754
unsigned int log2_post(uint32 m, int ilog, int exp, unsigned int sign=0)
Postprocessing for binary logarithm.
Definition: half.hpp:1876
unsigned int area(unsigned int arg)
Area function and postprocessing.
Definition: half.hpp:1945
HALF_CONSTEXPR_NOERR unsigned int rounded(unsigned int value, int g, int s)
Round half-precision number.
Definition: half.hpp:852
unsigned long uint32
Fastest unsigned integer of (at least) 32 bits width.
Definition: half.hpp:529
unsigned int float2half_impl(float value, true_type)
Convert IEEE single-precision to half-precision.
Definition: half.hpp:945
uint32 sign_mask(uint32 arg)
Platform-independent sign mask.
Definition: half.hpp:615
bool builtin_isinf(T arg)
Check for infinity.
Definition: half.hpp:570
unsigned int erf(unsigned int arg)
Error function and postprocessing.
Definition: half.hpp:2076
unsigned int int2half(T value)
Convert integer to half-precision floating-point.
Definition: half.hpp:1125
unsigned int tangent_post(uint32 my, uint32 mx, int exp, unsigned int sign=0)
Division and postprocessing for tangents.
Definition: half.hpp:1924
unsigned int exp2_post(uint32 m, int exp, bool esign, unsigned int sign=0, unsigned int n=32)
Postprocessing for binary exponential.
Definition: half.hpp:1845
HALF_CONSTEXPR_NOERR unsigned int pole(unsigned int sign=0)
Raise pole error and return infinity.
Definition: half.hpp:786
Main namespace for half-precision functionality.
Definition: half.hpp:444
half asinh(half arg)
Hyperbolic area sine.
Definition: half.hpp:4235
half sinh(half arg)
Hyperbolic sine.
Definition: half.hpp:4140
int feclearexcept(int excepts)
Clear exception flags.
Definition: half.hpp:4931
HALF_CONSTEXPR half fabs(half arg)
Absolute value.
Definition: half.hpp:2952
half nextafter(half from, half to)
Next representable value.
Definition: half.hpp:4688
half atan(half arg)
Arc tangent function.
Definition: half.hpp:4039
half hypot(half x, half y)
Hypotenuse function.
Definition: half.hpp:3600
HALF_CONSTEXPR bool isunordered(half x, half y)
Quiet check if unordered.
Definition: half.hpp:4875
half fdim(half x, half y)
Positive difference.
Definition: half.hpp:3150
half remquo(half x, half y, int *quo)
Remainder of division.
Definition: half.hpp:3011
int fegetexceptflag(int *flagp, int excepts)
Save exception flags.
Definition: half.hpp:4970
int ilogb(half arg)
Extract exponent.
Definition: half.hpp:4643
half lgamma(half arg)
Natural logarithm of gamma function.
Definition: half.hpp:4384
HALF_CONSTEXPR half copysign(half x, half y)
Take sign.
Definition: half.hpp:4741
HALF_CONSTEXPR bool isfinite(half arg)
Check if finite number.
Definition: half.hpp:4773
int fesetexceptflag(const int *flagp, int excepts)
Restore exception flags.
Definition: half.hpp:4985
HALF_CONSTEXPR half abs(half arg)
Absolute value.
Definition: half.hpp:2958
half fma(half x, half y, half z)
Fused multiply add.
Definition: half.hpp:3038
HALF_CONSTEXPR_NOERR half fmin(half x, half y)
Minimum of half expressions.
Definition: half.hpp:3132
half nearbyint(half arg)
Nearest integer using half's internal rounding mode.
Definition: half.hpp:4511
half expm1(half arg)
Exponential minus one.
Definition: half.hpp:3248
half ldexp(half arg, int exp)
Multiply by power of two.
Definition: half.hpp:4607
half sin(half arg)
Sine function.
Definition: half.hpp:3868
half tanh(half arg)
Hyperbolic tangent.
Definition: half.hpp:4200
std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &in, half &arg)
Input operator.
Definition: half.hpp:2931
half rint(half arg)
Nearest integer using half's internal rounding mode.
Definition: half.hpp:4496
HALF_CONSTEXPR_NOERR bool operator!=(half x, half y)
Comparison for inequality.
Definition: half.hpp:2670
HALF_CONSTEXPR_NOERR half fmax(half x, half y)
Maximum of half expressions.
Definition: half.hpp:3116
HALF_CONSTEXPR_NOERR bool operator<(half x, half y)
Comparison for less than.
Definition: half.hpp:2681
HALF_CONSTEXPR half operator-(half arg)
Negation.
Definition: half.hpp:2740
T half_cast(U arg)
Cast to or from half-precision floating-point number.
Definition: half.hpp:4896
half fmod(half x, half y)
Remainder of division.
Definition: half.hpp:2966
half log(half arg)
Natural logarithm.
Definition: half.hpp:3301
half cos(half arg)
Cosine function.
Definition: half.hpp:3905
half scalbn(half arg, int exp)
Multiply by power of two.
Definition: half.hpp:4596
half exp2(half arg)
Binary exponential.
Definition: half.hpp:3219
HALF_CONSTEXPR int fpclassify(half arg)
Classify floating-point value.
Definition: half.hpp:4759
HALF_CONSTEXPR_NOERR bool operator>=(half x, half y)
Comparison for greater equal.
Definition: half.hpp:2720
half atanh(half arg)
Hyperbolic area tangent.
Definition: half.hpp:4291
half nexttoward(half from, long double to)
Next representable value.
Definition: half.hpp:4718
half round(half arg)
Nearest integer.
Definition: half.hpp:4478
half log2(half arg)
Binary logarithm.
Definition: half.hpp:3373
HALF_CONSTEXPR bool isgreater(half x, half y)
Quiet comparison for greater than.
Definition: half.hpp:4814
half asin(half arg)
Arc sine.
Definition: half.hpp:3977
half sqrt(half arg)
Square root.
Definition: half.hpp:3473
half trunc(half arg)
Nearest integer not greater in magnitude than half value.
Definition: half.hpp:4467
half erfc(half arg)
Complementary error function.
Definition: half.hpp:4357
half tan(half arg)
Tangent function.
Definition: half.hpp:3935
HALF_CONSTEXPR half operator+(half arg)
Identity.
Definition: half.hpp:2735
half log10(half arg)
Common logarithm.
Definition: half.hpp:3332
half rsqrt(half arg)
Inverse square root.
Definition: half.hpp:3500
HALF_CONSTEXPR bool signbit(half arg)
Check sign.
Definition: half.hpp:4801
half floor(half arg)
Nearest integer not greater than half value.
Definition: half.hpp:4456
half acosh(half arg)
Hyperbolic area cosine.
Definition: half.hpp:4265
HALF_CONSTEXPR bool isnan(half arg)
Check for NaN.
Definition: half.hpp:4787
HALF_CONSTEXPR_NOERR bool operator<=(half x, half y)
Comparison for less equal.
Definition: half.hpp:2707
half operator*(half x, half y)
Multiplication.
Definition: half.hpp:2825
HALF_CONSTEXPR bool isnormal(half arg)
Check if normal number.
Definition: half.hpp:4794
std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &out, half arg)
Output operator.
Definition: half.hpp:2912
half atan2(half y, half x)
Arc tangent function.
Definition: half.hpp:4073
int feraiseexcept(int excepts)
Raise exception flags.
Definition: half.hpp:4955
HALF_CONSTEXPR bool isless(half x, half y)
Quiet comparison for less than.
Definition: half.hpp:4838
half scalbln(half arg, long exp)
Multiply by power of two.
Definition: half.hpp:4567
half tgamma(half arg)
Gamma function.
Definition: half.hpp:4410
HALF_CONSTEXPR_NOERR bool operator==(half x, half y)
Comparison for equality.
Definition: half.hpp:2659
long lrint(half arg)
Nearest integer using half's internal rounding mode.
Definition: half.hpp:4504
HALF_CONSTEXPR bool isinf(half arg)
Check for infinity.
Definition: half.hpp:4780
HALF_CONSTEXPR_NOERR bool operator>(half x, half y)
Comparison for greater than.
Definition: half.hpp:2694
half cosh(half arg)
Hyperbolic cosine.
Definition: half.hpp:4171
half logb(half arg)
Extract exponent.
Definition: half.hpp:4661
half erf(half arg)
Error function.
Definition: half.hpp:4332
void sincos(half arg, half *sin, half *cos)
Compute sine and cosine simultaneously.
Definition: half.hpp:3799
half ceil(half arg)
Nearest integer not less than half value.
Definition: half.hpp:4445
half frexp(half arg, int *exp)
Decompress floating-point number.
Definition: half.hpp:4546
half log1p(half arg)
Natural logarithm plus one.
Definition: half.hpp:3423
HALF_CONSTEXPR bool islessgreater(half x, half y)
Quiet comarison for less or greater.
Definition: half.hpp:4864
half hypot(half x, half y, half z)
Hypotenuse function.
Definition: half.hpp:3651
long lround(half arg)
Nearest integer.
Definition: half.hpp:4488
half acos(half arg)
Arc cosine function.
Definition: half.hpp:4009
HALF_CONSTEXPR bool islessequal(half x, half y)
Quiet comparison for less equal.
Definition: half.hpp:4851
half pow(half x, half y)
Power function.
Definition: half.hpp:3721
half nanh(const char *arg)
Get NaN value.
Definition: half.hpp:3163
half modf(half arg, half *iptr)
Extract integer and fractional parts.
Definition: half.hpp:4615
half cbrt(half arg)
Cubic root.
Definition: half.hpp:3546
void fethrowexcept(int excepts, const char *msg="")
Throw C++ exceptions based on set exception flags.
Definition: half.hpp:5002
HALF_CONSTEXPR bool isgreaterequal(half x, half y)
Quiet comparison for greater equal.
Definition: half.hpp:4825
int fetestexcept(int excepts)
Test exception flags.
Definition: half.hpp:4944
half exp(half arg)
Exponential function.
Definition: half.hpp:3184
half remainder(half x, half y)
Remainder of division.
Definition: half.hpp:2989
half operator/(half x, half y)
Division.
Definition: half.hpp:2865
Extensions to the C++ standard library.
Definition: big_integer.hpp:576
MICROSOFT_QUANTUM_DECL void T(_In_ uintq sid, _In_ uintq q)
(External API) "T" Gate
Definition: pinvoke_api.cpp:1658
MICROSOFT_QUANTUM_DECL void R(_In_ uintq sid, _In_ uintq b, _In_ double phi, _In_ uintq q)
(External API) Rotation around Pauli axes
Definition: pinvoke_api.cpp:2146
MICROSOFT_QUANTUM_DECL void S(_In_ uintq sid, _In_ uintq q)
(External API) "S" Gate
Definition: pinvoke_api.cpp:1616
MICROSOFT_QUANTUM_DECL void U(_In_ uintq sid, _In_ uintq q, _In_ double theta, _In_ double phi, _In_ double lambda)
(External API) 3-parameter unitary gate
Definition: pinvoke_api.cpp:1728
Tag type for binary construction.
Definition: half.hpp:557
unsigned long type
Definition: half.hpp:546
Type traits for floating-point bits.
Definition: half.hpp:498
unsigned char type
Definition: half.hpp:499
Helper for tag dispatching.
Definition: half.hpp:483
Conditional type.
Definition: half.hpp:475
T type
Definition: half.hpp:476
Class for 1.31 unsigned floating-point computation.
Definition: half.hpp:1990
friend f31 operator-(f31 a, f31 b)
Subtraction operator.
Definition: half.hpp:2029
int exp
exponent.
Definition: half.hpp:2063
friend f31 operator*(f31 a, f31 b)
Multiplication operator.
Definition: half.hpp:2044
friend f31 operator/(f31 a, f31 b)
Division operator.
Definition: half.hpp:2055
friend f31 operator+(f31 a, f31 b)
Addition operator.
Definition: half.hpp:2015
f31(unsigned int abs)
Constructor.
Definition: half.hpp:2002
HALF_CONSTEXPR f31(uint32 mant, int e)
Constructor.
Definition: half.hpp:1994
uint32 m
mantissa as 1.31.
Definition: half.hpp:2062
static T cast_impl(half arg, true_type)
Definition: half.hpp:2482
static T cast(half arg)
Definition: half.hpp:2479
static T cast_impl(half arg, false_type)
Definition: half.hpp:2483
static half cast_impl(U arg, false_type)
Definition: half.hpp:2472
static half cast(U arg)
Definition: half.hpp:2468
static half cast_impl(U arg, true_type)
Definition: half.hpp:2471
static half cast(half arg)
Definition: half.hpp:2486
Helper class for half casts.
Definition: half.hpp:2462
Type traits for floating-point types.
Definition: half.hpp:488