NVIDIA DeepStream SDK API Reference

9.2 Release
includes/half.hpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 // half - IEEE 754-based half-precision floating-point library.
19 //
20 // Copyright (c) 2012-2021 Christian Rau <rauy@users.sourceforge.net>
21 //
22 // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
23 // files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
24 // modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
25 // Software is furnished to do so, subject to the following conditions:
26 //
27 // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
28 //
29 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
30 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
31 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 
34 // Version 2.2.0
35 
38 
39 #ifndef HALF_HALF_HPP
40 #define HALF_HALF_HPP
41 
42 #define HALF_GCC_VERSION (__GNUC__*100+__GNUC_MINOR__)
43 
44 #if defined(__INTEL_COMPILER)
45  #define HALF_ICC_VERSION __INTEL_COMPILER
46 #elif defined(__ICC)
47  #define HALF_ICC_VERSION __ICC
48 #elif defined(__ICL)
49  #define HALF_ICC_VERSION __ICL
50 #else
51  #define HALF_ICC_VERSION 0
52 #endif
53 
54 // check C++11 language features
55 #if defined(__clang__) // clang
56  #if __has_feature(cxx_static_assert) && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
57  #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
58  #endif
59  #if __has_feature(cxx_constexpr) && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
60  #define HALF_ENABLE_CPP11_CONSTEXPR 1
61  #endif
62  #if __has_feature(cxx_noexcept) && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
63  #define HALF_ENABLE_CPP11_NOEXCEPT 1
64  #endif
65  #if __has_feature(cxx_user_literals) && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
66  #define HALF_ENABLE_CPP11_USER_LITERALS 1
67  #endif
68  #if __has_feature(cxx_thread_local) && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
69  #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
70  #endif
71  #if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) && !defined(HALF_ENABLE_CPP11_LONG_LONG)
72  #define HALF_ENABLE_CPP11_LONG_LONG 1
73  #endif
74 #elif HALF_ICC_VERSION && defined(__INTEL_CXX11_MODE__) // Intel C++
75  #if HALF_ICC_VERSION >= 1500 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
76  #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
77  #endif
78  #if HALF_ICC_VERSION >= 1500 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
79  #define HALF_ENABLE_CPP11_USER_LITERALS 1
80  #endif
81  #if HALF_ICC_VERSION >= 1400 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
82  #define HALF_ENABLE_CPP11_CONSTEXPR 1
83  #endif
84  #if HALF_ICC_VERSION >= 1400 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
85  #define HALF_ENABLE_CPP11_NOEXCEPT 1
86  #endif
87  #if HALF_ICC_VERSION >= 1110 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
88  #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
89  #endif
90  #if HALF_ICC_VERSION >= 1110 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
91  #define HALF_ENABLE_CPP11_LONG_LONG 1
92  #endif
93 #elif defined(__GNUC__) // gcc
94  #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
95  #if HALF_GCC_VERSION >= 408 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
96  #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
97  #endif
98  #if HALF_GCC_VERSION >= 407 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
99  #define HALF_ENABLE_CPP11_USER_LITERALS 1
100  #endif
101  #if HALF_GCC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
102  #define HALF_ENABLE_CPP11_CONSTEXPR 1
103  #endif
104  #if HALF_GCC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
105  #define HALF_ENABLE_CPP11_NOEXCEPT 1
106  #endif
107  #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
108  #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
109  #endif
110  #if !defined(HALF_ENABLE_CPP11_LONG_LONG)
111  #define HALF_ENABLE_CPP11_LONG_LONG 1
112  #endif
113  #endif
114  #define HALF_TWOS_COMPLEMENT_INT 1
115 #elif defined(_MSC_VER) // Visual C++
116  #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
117  #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
118  #endif
119  #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
120  #define HALF_ENABLE_CPP11_USER_LITERALS 1
121  #endif
122  #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
123  #define HALF_ENABLE_CPP11_CONSTEXPR 1
124  #endif
125  #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
126  #define HALF_ENABLE_CPP11_NOEXCEPT 1
127  #endif
128  #if _MSC_VER >= 1600 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
129  #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
130  #endif
131  #if _MSC_VER >= 1310 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
132  #define HALF_ENABLE_CPP11_LONG_LONG 1
133  #endif
134  #define HALF_TWOS_COMPLEMENT_INT 1
135  #define HALF_POP_WARNINGS 1
136  #pragma warning(push)
137  #pragma warning(disable : 4099 4127 4146) //struct vs class, constant in if, negative unsigned
138 #endif
139 
140 // check C++11 library features
141 #include <utility>
142 #if defined(_LIBCPP_VERSION) // libc++
143  #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
144  #ifndef HALF_ENABLE_CPP11_TYPE_TRAITS
145  #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
146  #endif
147  #ifndef HALF_ENABLE_CPP11_CSTDINT
148  #define HALF_ENABLE_CPP11_CSTDINT 1
149  #endif
150  #ifndef HALF_ENABLE_CPP11_CMATH
151  #define HALF_ENABLE_CPP11_CMATH 1
152  #endif
153  #ifndef HALF_ENABLE_CPP11_HASH
154  #define HALF_ENABLE_CPP11_HASH 1
155  #endif
156  #ifndef HALF_ENABLE_CPP11_CFENV
157  #define HALF_ENABLE_CPP11_CFENV 1
158  #endif
159  #endif
160 #elif defined(__GLIBCXX__) // libstdc++
161  #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
162  #ifdef __clang__
163  #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
164  #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
165  #endif
166  #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CSTDINT)
167  #define HALF_ENABLE_CPP11_CSTDINT 1
168  #endif
169  #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CMATH)
170  #define HALF_ENABLE_CPP11_CMATH 1
171  #endif
172  #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_HASH)
173  #define HALF_ENABLE_CPP11_HASH 1
174  #endif
175  #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CFENV)
176  #define HALF_ENABLE_CPP11_CFENV 1
177  #endif
178  #else
179  #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
180  #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
181  #endif
182  #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CSTDINT)
183  #define HALF_ENABLE_CPP11_CSTDINT 1
184  #endif
185  #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CMATH)
186  #define HALF_ENABLE_CPP11_CMATH 1
187  #endif
188  #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_HASH)
189  #define HALF_ENABLE_CPP11_HASH 1
190  #endif
191  #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CFENV)
192  #define HALF_ENABLE_CPP11_CFENV 1
193  #endif
194  #endif
195  #endif
196 #elif defined(_CPPLIB_VER) // Dinkumware/Visual C++
197  #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
198  #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
199  #endif
200  #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_CSTDINT)
201  #define HALF_ENABLE_CPP11_CSTDINT 1
202  #endif
203  #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_HASH)
204  #define HALF_ENABLE_CPP11_HASH 1
205  #endif
206  #if _CPPLIB_VER >= 610 && !defined(HALF_ENABLE_CPP11_CMATH)
207  #define HALF_ENABLE_CPP11_CMATH 1
208  #endif
209  #if _CPPLIB_VER >= 610 && !defined(HALF_ENABLE_CPP11_CFENV)
210  #define HALF_ENABLE_CPP11_CFENV 1
211  #endif
212 #endif
213 #undef HALF_GCC_VERSION
214 #undef HALF_ICC_VERSION
215 
216 // any error throwing C++ exceptions?
217 #if defined(HALF_ERRHANDLING_THROW_INVALID) || defined(HALF_ERRHANDLING_THROW_DIVBYZERO) || defined(HALF_ERRHANDLING_THROW_OVERFLOW) || defined(HALF_ERRHANDLING_THROW_UNDERFLOW) || defined(HALF_ERRHANDLING_THROW_INEXACT)
218 #define HALF_ERRHANDLING_THROWS 1
219 #endif
220 
221 // any error handling enabled?
222 #define HALF_ERRHANDLING (HALF_ERRHANDLING_FLAGS||HALF_ERRHANDLING_ERRNO||HALF_ERRHANDLING_FENV||HALF_ERRHANDLING_THROWS)
223 
224 #if HALF_ERRHANDLING
225  #define HALF_UNUSED_NOERR(name) name
226 #else
227  #define HALF_UNUSED_NOERR(name)
228 #endif
229 
230 // support constexpr
231 #if HALF_ENABLE_CPP11_CONSTEXPR
232  #define HALF_CONSTEXPR constexpr
233  #define HALF_CONSTEXPR_CONST constexpr
234  #if HALF_ERRHANDLING
235  #define HALF_CONSTEXPR_NOERR
236  #else
237  #define HALF_CONSTEXPR_NOERR constexpr
238  #endif
239 #else
240  #define HALF_CONSTEXPR
241  #define HALF_CONSTEXPR_CONST const
242  #define HALF_CONSTEXPR_NOERR
243 #endif
244 
245 // support noexcept
246 #if HALF_ENABLE_CPP11_NOEXCEPT
247  #define HALF_NOEXCEPT noexcept
248  #define HALF_NOTHROW noexcept
249 #else
250  #define HALF_NOEXCEPT
251  #define HALF_NOTHROW throw()
252 #endif
253 
254 // support thread storage
255 #if HALF_ENABLE_CPP11_THREAD_LOCAL
256  #define HALF_THREAD_LOCAL thread_local
257 #else
258  #define HALF_THREAD_LOCAL static
259 #endif
260 
261 #include <utility>
262 #include <algorithm>
263 #include <istream>
264 #include <ostream>
265 #include <limits>
266 #include <stdexcept>
267 #include <climits>
268 #include <cmath>
269 #include <cstring>
270 #include <cstdlib>
271 #if HALF_ENABLE_CPP11_TYPE_TRAITS
272  #include <type_traits>
273 #endif
274 #if HALF_ENABLE_CPP11_CSTDINT
275  #include <cstdint>
276 #endif
277 #if HALF_ERRHANDLING_ERRNO
278  #include <cerrno>
279 #endif
280 #if HALF_ENABLE_CPP11_CFENV
281  #include <cfenv>
282 #endif
283 #if HALF_ENABLE_CPP11_HASH
284  #include <functional>
285 #endif
286 
287 
288 #ifndef HALF_ENABLE_F16C_INTRINSICS
289  #define HALF_ENABLE_F16C_INTRINSICS __F16C__
296 #endif
297 #if HALF_ENABLE_F16C_INTRINSICS
298  #include <immintrin.h>
299 #endif
300 
301 #ifdef HALF_DOXYGEN_ONLY
302 #define HALF_ARITHMETIC_TYPE (undefined)
308 
312 #define HALF_ERRHANDLING_FLAGS 0
313 
319 #define HALF_ERRHANDLING_ERRNO 0
320 
327 #define HALF_ERRHANDLING_FENV 0
328 
332 #define HALF_ERRHANDLING_THROW_INVALID (undefined)
333 
337 #define HALF_ERRHANDLING_THROW_DIVBYZERO (undefined)
338 
342 #define HALF_ERRHANDLING_THROW_OVERFLOW (undefined)
343 
347 #define HALF_ERRHANDLING_THROW_UNDERFLOW (undefined)
348 
352 #define HALF_ERRHANDLING_THROW_INEXACT (undefined)
353 #endif
354 
355 #ifndef HALF_ERRHANDLING_OVERFLOW_TO_INEXACT
356 #define HALF_ERRHANDLING_OVERFLOW_TO_INEXACT 1
360 #endif
361 
362 #ifndef HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
363 #define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT 1
370 #endif
371 
390 #ifndef HALF_ROUND_STYLE
391  #define HALF_ROUND_STYLE 1 // = std::round_to_nearest
392 #endif
393 
399 #define HUGE_VALH std::numeric_limits<half_float::half>::infinity()
400 
406 #define FP_FAST_FMAH 1
407 
413 #define HLF_ROUNDS HALF_ROUND_STYLE
414 
415 #ifndef FP_ILOGB0
416  #define FP_ILOGB0 INT_MIN
417 #endif
418 #ifndef FP_ILOGBNAN
419  #define FP_ILOGBNAN INT_MAX
420 #endif
421 #ifndef FP_SUBNORMAL
422  #define FP_SUBNORMAL 0
423 #endif
424 #ifndef FP_ZERO
425  #define FP_ZERO 1
426 #endif
427 #ifndef FP_NAN
428  #define FP_NAN 2
429 #endif
430 #ifndef FP_INFINITE
431  #define FP_INFINITE 3
432 #endif
433 #ifndef FP_NORMAL
434  #define FP_NORMAL 4
435 #endif
436 
437 #if !HALF_ENABLE_CPP11_CFENV && !defined(FE_ALL_EXCEPT)
438  #define FE_INVALID 0x10
439  #define FE_DIVBYZERO 0x08
440  #define FE_OVERFLOW 0x04
441  #define FE_UNDERFLOW 0x02
442  #define FE_INEXACT 0x01
443  #define FE_ALL_EXCEPT (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW|FE_INEXACT)
444 #endif
445 
446 
449 namespace half_float
450 {
451  class half;
452 
453 #if HALF_ENABLE_CPP11_USER_LITERALS
454  namespace literal
461  {
462  half operator "" _h(long double);
463  }
464 #endif
465 
468  namespace detail
469  {
470  #if HALF_ENABLE_CPP11_TYPE_TRAITS
471  template<bool B,typename T,typename F> struct conditional : std::conditional<B,T,F> {};
473 
475  template<bool B> struct bool_type : std::integral_constant<bool,B> {};
476  using std::true_type;
477  using std::false_type;
478 
480  template<typename T> struct is_float : std::is_floating_point<T> {};
481  #else
482  template<bool,typename T,typename> struct conditional { typedef T type; };
484  template<typename T,typename F> struct conditional<false,T,F> { typedef F type; };
485 
487  template<bool> struct bool_type {};
490 
492  template<typename> struct is_float : false_type {};
493  template<typename T> struct is_float<const T> : is_float<T> {};
494  template<typename T> struct is_float<volatile T> : is_float<T> {};
495  template<typename T> struct is_float<const volatile T> : is_float<T> {};
496  template<> struct is_float<float> : true_type {};
497  template<> struct is_float<double> : true_type {};
498  template<> struct is_float<long double> : true_type {};
499  #endif
500 
502  template<typename T> struct bits { typedef unsigned char type; };
503  template<typename T> struct bits<const T> : bits<T> {};
504  template<typename T> struct bits<volatile T> : bits<T> {};
505  template<typename T> struct bits<const volatile T> : bits<T> {};
506 
507  #if HALF_ENABLE_CPP11_CSTDINT
508  typedef std::uint_least16_t uint16;
510 
512  typedef std::uint_fast32_t uint32;
513 
515  typedef std::int_fast32_t int32;
516 
518  template<> struct bits<float> { typedef std::uint_least32_t type; };
519 
521  template<> struct bits<double> { typedef std::uint_least64_t type; };
522  #else
523  typedef unsigned short uint16;
525 
527  typedef unsigned long uint32;
528 
530  typedef long int32;
531 
533  template<> struct bits<float> : conditional<std::numeric_limits<unsigned int>::digits>=32,unsigned int,unsigned long> {};
534 
535  #if HALF_ENABLE_CPP11_LONG_LONG
536  template<> struct bits<double> : conditional<std::numeric_limits<unsigned long>::digits>=64,unsigned long,unsigned long long> {};
538  #else
539  template<> struct bits<double> { typedef unsigned long type; };
541  #endif
542  #endif
543 
544  #ifdef HALF_ARITHMETIC_TYPE
545  typedef HALF_ARITHMETIC_TYPE internal_t;
547  #endif
548 
550  struct binary_t {};
551 
554 
557 
563  template<typename T> bool builtin_isinf(T arg)
564  {
565  #if HALF_ENABLE_CPP11_CMATH
566  return std::isinf(arg);
567  #elif defined(_MSC_VER)
568  return !::_finite(static_cast<double>(arg)) && !::_isnan(static_cast<double>(arg));
569  #else
570  return arg == std::numeric_limits<T>::infinity() || arg == -std::numeric_limits<T>::infinity();
571  #endif
572  }
573 
579  template<typename T> bool builtin_isnan(T arg)
580  {
581  #if HALF_ENABLE_CPP11_CMATH
582  return std::isnan(arg);
583  #elif defined(_MSC_VER)
584  return ::_isnan(static_cast<double>(arg)) != 0;
585  #else
586  return arg != arg;
587  #endif
588  }
589 
595  template<typename T> bool builtin_signbit(T arg)
596  {
597  #if HALF_ENABLE_CPP11_CMATH
598  return std::signbit(arg);
599  #else
600  return arg < T() || (arg == T() && T(1)/arg < T());
601  #endif
602  }
603 
608  inline uint32 sign_mask(uint32 arg)
609  {
610  static const int N = std::numeric_limits<uint32>::digits - 1;
611  #if HALF_TWOS_COMPLEMENT_INT
612  return static_cast<int32>(arg) >> N;
613  #else
614  return -((arg>>N)&1);
615  #endif
616  }
617 
622  inline uint32 arithmetic_shift(uint32 arg, int i)
623  {
624  #if HALF_TWOS_COMPLEMENT_INT
625  return static_cast<int32>(arg) >> i;
626  #else
627  return static_cast<int32>(arg)/(static_cast<int32>(1)<<i) - ((arg>>(std::numeric_limits<uint32>::digits-1))&1);
628  #endif
629  }
630 
634 
637  inline int& errflags() { HALF_THREAD_LOCAL int flags = 0; return flags; }
638 
642  inline void raise(int HALF_UNUSED_NOERR(flags), bool HALF_UNUSED_NOERR(cond) = true)
643  {
644  #if HALF_ERRHANDLING
645  if(!cond)
646  return;
647  #if HALF_ERRHANDLING_FLAGS
648  errflags() |= flags;
649  #endif
650  #if HALF_ERRHANDLING_ERRNO
651  if(flags & FE_INVALID)
652  errno = EDOM;
653  else if(flags & (FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW))
654  errno = ERANGE;
655  #endif
656  #if HALF_ERRHANDLING_FENV && HALF_ENABLE_CPP11_CFENV
657  std::feraiseexcept(flags);
658  #endif
659  #ifdef HALF_ERRHANDLING_THROW_INVALID
660  if(flags & FE_INVALID)
661  throw std::domain_error(HALF_ERRHANDLING_THROW_INVALID);
662  #endif
663  #ifdef HALF_ERRHANDLING_THROW_DIVBYZERO
664  if(flags & FE_DIVBYZERO)
665  throw std::domain_error(HALF_ERRHANDLING_THROW_DIVBYZERO);
666  #endif
667  #ifdef HALF_ERRHANDLING_THROW_OVERFLOW
668  if(flags & FE_OVERFLOW)
669  throw std::overflow_error(HALF_ERRHANDLING_THROW_OVERFLOW);
670  #endif
671  #ifdef HALF_ERRHANDLING_THROW_UNDERFLOW
672  if(flags & FE_UNDERFLOW)
673  throw std::underflow_error(HALF_ERRHANDLING_THROW_UNDERFLOW);
674  #endif
675  #ifdef HALF_ERRHANDLING_THROW_INEXACT
676  if(flags & FE_INEXACT)
677  throw std::range_error(HALF_ERRHANDLING_THROW_INEXACT);
678  #endif
679  #if HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
680  if((flags & FE_UNDERFLOW) && !(flags & FE_INEXACT))
681  raise(FE_INEXACT);
682  #endif
683  #if HALF_ERRHANDLING_OVERFLOW_TO_INEXACT
684  if((flags & FE_OVERFLOW) && !(flags & FE_INEXACT))
685  raise(FE_INEXACT);
686  #endif
687  #endif
688  }
689 
696  inline HALF_CONSTEXPR_NOERR bool compsignal(unsigned int x, unsigned int y)
697  {
698  #if HALF_ERRHANDLING
699  raise(FE_INVALID, (x&0x7FFF)>0x7C00 || (y&0x7FFF)>0x7C00);
700  #endif
701  return (x&0x7FFF) > 0x7C00 || (y&0x7FFF) > 0x7C00;
702  }
703 
708  inline HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int nan)
709  {
710  #if HALF_ERRHANDLING
711  raise(FE_INVALID, !(nan&0x200));
712  #endif
713  return nan | 0x200;
714  }
715 
721  inline HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int x, unsigned int y)
722  {
723  #if HALF_ERRHANDLING
724  raise(FE_INVALID, ((x&0x7FFF)>0x7C00 && !(x&0x200)) || ((y&0x7FFF)>0x7C00 && !(y&0x200)));
725  #endif
726  return ((x&0x7FFF)>0x7C00) ? (x|0x200) : (y|0x200);
727  }
728 
735  inline HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int x, unsigned int y, unsigned int z)
736  {
737  #if HALF_ERRHANDLING
738  raise(FE_INVALID, ((x&0x7FFF)>0x7C00 && !(x&0x200)) || ((y&0x7FFF)>0x7C00 && !(y&0x200)) || ((z&0x7FFF)>0x7C00 && !(z&0x200)));
739  #endif
740  return ((x&0x7FFF)>0x7C00) ? (x|0x200) : ((y&0x7FFF)>0x7C00) ? (y|0x200) : (z|0x200);
741  }
742 
748  inline HALF_CONSTEXPR_NOERR unsigned int select(unsigned int x, unsigned int HALF_UNUSED_NOERR(y))
749  {
750  #if HALF_ERRHANDLING
751  return (((y&0x7FFF)>0x7C00) && !(y&0x200)) ? signal(y) : x;
752  #else
753  return x;
754  #endif
755  }
756 
760  inline HALF_CONSTEXPR_NOERR unsigned int invalid()
761  {
762  #if HALF_ERRHANDLING
763  raise(FE_INVALID);
764  #endif
765  return 0x7FFF;
766  }
767 
772  inline HALF_CONSTEXPR_NOERR unsigned int pole(unsigned int sign = 0)
773  {
774  #if HALF_ERRHANDLING
775  raise(FE_DIVBYZERO);
776  #endif
777  return sign | 0x7C00;
778  }
779 
784  inline HALF_CONSTEXPR_NOERR unsigned int check_underflow(unsigned int arg)
785  {
786  #if HALF_ERRHANDLING && !HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
787  raise(FE_UNDERFLOW, !(arg&0x7C00));
788  #endif
789  return arg;
790  }
791 
795 
801  template<std::float_round_style R> HALF_CONSTEXPR_NOERR unsigned int overflow(unsigned int sign = 0)
802  {
803  #if HALF_ERRHANDLING
804  raise(FE_OVERFLOW);
805  #endif
806  return (R==std::round_toward_infinity) ? (sign+0x7C00-(sign>>15)) :
807  (R==std::round_toward_neg_infinity) ? (sign+0x7BFF+(sign>>15)) :
808  (R==std::round_toward_zero) ? (sign|0x7BFF) :
809  (sign|0x7C00);
810  }
811 
817  template<std::float_round_style R> HALF_CONSTEXPR_NOERR unsigned int underflow(unsigned int sign = 0)
818  {
819  #if HALF_ERRHANDLING
820  raise(FE_UNDERFLOW);
821  #endif
822  return (R==std::round_toward_infinity) ? (sign+1-(sign>>15)) :
823  (R==std::round_toward_neg_infinity) ? (sign+(sign>>15)) :
824  sign;
825  }
826 
837  template<std::float_round_style R,bool I> HALF_CONSTEXPR_NOERR unsigned int rounded(unsigned int value, int g, int s)
838  {
839  #if HALF_ERRHANDLING
840  value += (R==std::round_to_nearest) ? (g&(s|value)) :
841  (R==std::round_toward_infinity) ? (~(value>>15)&(g|s)) :
842  (R==std::round_toward_neg_infinity) ? ((value>>15)&(g|s)) : 0;
843  if((value&0x7C00) == 0x7C00)
844  raise(FE_OVERFLOW);
845  else if(value & 0x7C00)
846  raise(FE_INEXACT, I || (g|s)!=0);
847  else
848  raise(FE_UNDERFLOW, !(HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT) || I || (g|s)!=0);
849  return value;
850  #else
851  return (R==std::round_to_nearest) ? (value+(g&(s|value))) :
852  (R==std::round_toward_infinity) ? (value+(~(value>>15)&(g|s))) :
853  (R==std::round_toward_neg_infinity) ? (value+((value>>15)&(g|s))) :
854  value;
855  #endif
856  }
857 
866  template<std::float_round_style R,bool E,bool I> unsigned int integral(unsigned int value)
867  {
868  unsigned int abs = value & 0x7FFF;
869  if(abs < 0x3C00)
870  {
871  raise(FE_INEXACT, I);
872  return ((R==std::round_to_nearest) ? (0x3C00&-static_cast<unsigned>(abs>=(0x3800+E))) :
873  (R==std::round_toward_infinity) ? (0x3C00&-(~(value>>15)&(abs!=0))) :
874  (R==std::round_toward_neg_infinity) ? (0x3C00&-static_cast<unsigned>(value>0x8000)) :
875  0) | (value&0x8000);
876  }
877  if(abs >= 0x6400)
878  return (abs>0x7C00) ? signal(value) : value;
879  unsigned int exp = 25 - (abs>>10), mask = (1<<exp) - 1;
880  raise(FE_INEXACT, I && (value&mask));
881  return (( (R==std::round_to_nearest) ? ((1<<(exp-1))-(~(value>>exp)&E)) :
882  (R==std::round_toward_infinity) ? (mask&((value>>15)-1)) :
883  (R==std::round_toward_neg_infinity) ? (mask&-(value>>15)) :
884  0) + value) & ~mask;
885  }
886 
901  template<std::float_round_style R,unsigned int F,bool S,bool N,bool I> unsigned int fixed2half(uint32 m, int exp = 14, unsigned int sign = 0, int s = 0)
902  {
903  if(S)
904  {
905  uint32 msign = sign_mask(m);
906  m = (m^msign) - msign;
907  sign = msign & 0x8000;
908  }
909  if(N)
910  for(; m<(static_cast<uint32>(1)<<F) && exp; m<<=1,--exp) ;
911  else if(exp < 0)
912  return rounded<R,I>(sign+(m>>(F-10-exp)), (m>>(F-11-exp))&1, s|((m&((static_cast<uint32>(1)<<(F-11-exp))-1))!=0));
913  return rounded<R,I>(sign+(exp<<10)+(m>>(F-10)), (m>>(F-11))&1, s|((m&((static_cast<uint32>(1)<<(F-11))-1))!=0));
914  }
915 
924  template<std::float_round_style R> unsigned int float2half_impl(float value, true_type)
925  {
926  #if HALF_ENABLE_F16C_INTRINSICS
927  return _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_set_ss(value),
928  (R==std::round_to_nearest) ? _MM_FROUND_TO_NEAREST_INT :
929  (R==std::round_toward_zero) ? _MM_FROUND_TO_ZERO :
930  (R==std::round_toward_infinity) ? _MM_FROUND_TO_POS_INF :
931  (R==std::round_toward_neg_infinity) ? _MM_FROUND_TO_NEG_INF :
932  _MM_FROUND_CUR_DIRECTION));
933  #else
934  bits<float>::type fbits;
935  std::memcpy(&fbits, &value, sizeof(float));
936  #if 1
937  unsigned int sign = (fbits>>16) & 0x8000;
938  fbits &= 0x7FFFFFFF;
939  if(fbits >= 0x7F800000)
940  return sign | 0x7C00 | ((fbits>0x7F800000) ? (0x200|((fbits>>13)&0x3FF)) : 0);
941  if(fbits >= 0x47800000)
942  return overflow<R>(sign);
943  if(fbits >= 0x38800000)
944  return rounded<R,false>(sign|(((fbits>>23)-112)<<10)|((fbits>>13)&0x3FF), (fbits>>12)&1, (fbits&0xFFF)!=0);
945  if(fbits >= 0x33000000)
946  {
947  int i = 125 - (fbits>>23);
948  fbits = (fbits&0x7FFFFF) | 0x800000;
949  return rounded<R,false>(sign|(fbits>>(i+1)), (fbits>>i)&1, (fbits&((static_cast<uint32>(1)<<i)-1))!=0);
950  }
951  if(fbits != 0)
952  return underflow<R>(sign);
953  return sign;
954  #else
955  static const uint16 base_table[512] = {
956  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
957  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
958  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
959  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
960  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
961  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
962  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
963  0x0200, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00,
964  0x4000, 0x4400, 0x4800, 0x4C00, 0x5000, 0x5400, 0x5800, 0x5C00, 0x6000, 0x6400, 0x6800, 0x6C00, 0x7000, 0x7400, 0x7800, 0x7BFF,
965  0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
966  0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
967  0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
968  0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
969  0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
970  0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
971  0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7C00,
972  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
973  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
974  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
975  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
976  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
977  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
978  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001, 0x8002, 0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100,
979  0x8200, 0x8400, 0x8800, 0x8C00, 0x9000, 0x9400, 0x9800, 0x9C00, 0xA000, 0xA400, 0xA800, 0xAC00, 0xB000, 0xB400, 0xB800, 0xBC00,
980  0xC000, 0xC400, 0xC800, 0xCC00, 0xD000, 0xD400, 0xD800, 0xDC00, 0xE000, 0xE400, 0xE800, 0xEC00, 0xF000, 0xF400, 0xF800, 0xFBFF,
981  0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
982  0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
983  0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
984  0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
985  0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
986  0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
987  0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFC00 };
988  static const unsigned char shift_table[256] = {
989  24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
990  25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
991  25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
992  25, 25, 25, 25, 25, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
993  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
994  24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
995  24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
996  24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 13 };
997  int sexp = fbits >> 23, exp = sexp & 0xFF, i = shift_table[exp];
998  fbits &= 0x7FFFFF;
999  uint32 m = (fbits|((exp!=0)<<23)) & -static_cast<uint32>(exp!=0xFF);
1000  return rounded<R,false>(base_table[sexp]+(fbits>>i), (m>>(i-1))&1, (((static_cast<uint32>(1)<<(i-1))-1)&m)!=0);
1001  #endif
1002  #endif
1003  }
1004 
1012  template<std::float_round_style R> unsigned int float2half_impl(double value, true_type)
1013  {
1014  #if HALF_ENABLE_F16C_INTRINSICS
1015  if(R == std::round_indeterminate)
1016  return _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_cvtpd_ps(_mm_set_sd(value)), _MM_FROUND_CUR_DIRECTION));
1017  #endif
1018  bits<double>::type dbits;
1019  std::memcpy(&dbits, &value, sizeof(double));
1020  uint32 hi = dbits >> 32, lo = dbits & 0xFFFFFFFF;
1021  unsigned int sign = (hi>>16) & 0x8000;
1022  hi &= 0x7FFFFFFF;
1023  if(hi >= 0x7FF00000)
1024  return sign | 0x7C00 | ((dbits&0xFFFFFFFFFFFFF) ? (0x200|((hi>>10)&0x3FF)) : 0);
1025  if(hi >= 0x40F00000)
1026  return overflow<R>(sign);
1027  if(hi >= 0x3F100000)
1028  return rounded<R,false>(sign|(((hi>>20)-1008)<<10)|((hi>>10)&0x3FF), (hi>>9)&1, ((hi&0x1FF)|lo)!=0);
1029  if(hi >= 0x3E600000)
1030  {
1031  int i = 1018 - (hi>>20);
1032  hi = (hi&0xFFFFF) | 0x100000;
1033  return rounded<R,false>(sign|(hi>>(i+1)), (hi>>i)&1, ((hi&((static_cast<uint32>(1)<<i)-1))|lo)!=0);
1034  }
1035  if((hi|lo) != 0)
1036  return underflow<R>(sign);
1037  return sign;
1038  }
1039 
1048  template<std::float_round_style R,typename T> unsigned int float2half_impl(T value, ...)
1049  {
1050  unsigned int hbits = static_cast<unsigned>(builtin_signbit(value)) << 15;
1051  if(value == T())
1052  return hbits;
1053  if(builtin_isnan(value))
1054  return hbits | 0x7FFF;
1055  if(builtin_isinf(value))
1056  return hbits | 0x7C00;
1057  int exp;
1058  std::frexp(value, &exp);
1059  if(exp > 16)
1060  return overflow<R>(hbits);
1061  if(exp < -13)
1062  value = std::ldexp(value, 25);
1063  else
1064  {
1065  value = std::ldexp(value, 12-exp);
1066  hbits |= ((exp+13)<<10);
1067  }
1068  T ival, frac = std::modf(value, &ival);
1069  int m = std::abs(static_cast<int>(ival));
1070  return rounded<R,false>(hbits+(m>>1), m&1, frac!=T());
1071  }
1072 
1081  template<std::float_round_style R,typename T> unsigned int float2half(T value)
1082  {
1083  return float2half_impl<R>(value, bool_type<std::numeric_limits<T>::is_iec559&&sizeof(typename bits<T>::type)==sizeof(T)>());
1084  }
1085 
1093  template<std::float_round_style R,typename T> unsigned int int2half(T value)
1094  {
1095  unsigned int bits = static_cast<unsigned>(value<0) << 15;
1096  if(!value)
1097  return bits;
1098  if(bits)
1099  value = -value;
1100  if(value > 0xFFFF)
1101  return overflow<R>(bits);
1102  unsigned int m = static_cast<unsigned int>(value), exp = 24;
1103  for(; m<0x400; m<<=1,--exp) ;
1104  for(; m>0x7FF; m>>=1,++exp) ;
1105  bits |= (exp<<10) + m;
1106  return (exp>24) ? rounded<R,false>(bits, (value>>(exp-25))&1, (((1<<(exp-25))-1)&value)!=0) : bits;
1107  }
1108 
1113  inline float half2float_impl(unsigned int value, float, true_type)
1114  {
1115  #if HALF_ENABLE_F16C_INTRINSICS
1116  return _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128(value)));
1117  #else
1118  #if 0
1119  bits<float>::type fbits = static_cast<bits<float>::type>(value&0x8000) << 16;
1120  int abs = value & 0x7FFF;
1121  if(abs)
1122  {
1123  fbits |= 0x38000000 << static_cast<unsigned>(abs>=0x7C00);
1124  for(; abs<0x400; abs<<=1,fbits-=0x800000) ;
1125  fbits += static_cast<bits<float>::type>(abs) << 13;
1126  }
1127  #else
1128  static const bits<float>::type mantissa_table[2048] = {
1129  0x00000000, 0x33800000, 0x34000000, 0x34400000, 0x34800000, 0x34A00000, 0x34C00000, 0x34E00000, 0x35000000, 0x35100000, 0x35200000, 0x35300000, 0x35400000, 0x35500000, 0x35600000, 0x35700000,
1130  0x35800000, 0x35880000, 0x35900000, 0x35980000, 0x35A00000, 0x35A80000, 0x35B00000, 0x35B80000, 0x35C00000, 0x35C80000, 0x35D00000, 0x35D80000, 0x35E00000, 0x35E80000, 0x35F00000, 0x35F80000,
1131  0x36000000, 0x36040000, 0x36080000, 0x360C0000, 0x36100000, 0x36140000, 0x36180000, 0x361C0000, 0x36200000, 0x36240000, 0x36280000, 0x362C0000, 0x36300000, 0x36340000, 0x36380000, 0x363C0000,
1132  0x36400000, 0x36440000, 0x36480000, 0x364C0000, 0x36500000, 0x36540000, 0x36580000, 0x365C0000, 0x36600000, 0x36640000, 0x36680000, 0x366C0000, 0x36700000, 0x36740000, 0x36780000, 0x367C0000,
1133  0x36800000, 0x36820000, 0x36840000, 0x36860000, 0x36880000, 0x368A0000, 0x368C0000, 0x368E0000, 0x36900000, 0x36920000, 0x36940000, 0x36960000, 0x36980000, 0x369A0000, 0x369C0000, 0x369E0000,
1134  0x36A00000, 0x36A20000, 0x36A40000, 0x36A60000, 0x36A80000, 0x36AA0000, 0x36AC0000, 0x36AE0000, 0x36B00000, 0x36B20000, 0x36B40000, 0x36B60000, 0x36B80000, 0x36BA0000, 0x36BC0000, 0x36BE0000,
1135  0x36C00000, 0x36C20000, 0x36C40000, 0x36C60000, 0x36C80000, 0x36CA0000, 0x36CC0000, 0x36CE0000, 0x36D00000, 0x36D20000, 0x36D40000, 0x36D60000, 0x36D80000, 0x36DA0000, 0x36DC0000, 0x36DE0000,
1136  0x36E00000, 0x36E20000, 0x36E40000, 0x36E60000, 0x36E80000, 0x36EA0000, 0x36EC0000, 0x36EE0000, 0x36F00000, 0x36F20000, 0x36F40000, 0x36F60000, 0x36F80000, 0x36FA0000, 0x36FC0000, 0x36FE0000,
1137  0x37000000, 0x37010000, 0x37020000, 0x37030000, 0x37040000, 0x37050000, 0x37060000, 0x37070000, 0x37080000, 0x37090000, 0x370A0000, 0x370B0000, 0x370C0000, 0x370D0000, 0x370E0000, 0x370F0000,
1138  0x37100000, 0x37110000, 0x37120000, 0x37130000, 0x37140000, 0x37150000, 0x37160000, 0x37170000, 0x37180000, 0x37190000, 0x371A0000, 0x371B0000, 0x371C0000, 0x371D0000, 0x371E0000, 0x371F0000,
1139  0x37200000, 0x37210000, 0x37220000, 0x37230000, 0x37240000, 0x37250000, 0x37260000, 0x37270000, 0x37280000, 0x37290000, 0x372A0000, 0x372B0000, 0x372C0000, 0x372D0000, 0x372E0000, 0x372F0000,
1140  0x37300000, 0x37310000, 0x37320000, 0x37330000, 0x37340000, 0x37350000, 0x37360000, 0x37370000, 0x37380000, 0x37390000, 0x373A0000, 0x373B0000, 0x373C0000, 0x373D0000, 0x373E0000, 0x373F0000,
1141  0x37400000, 0x37410000, 0x37420000, 0x37430000, 0x37440000, 0x37450000, 0x37460000, 0x37470000, 0x37480000, 0x37490000, 0x374A0000, 0x374B0000, 0x374C0000, 0x374D0000, 0x374E0000, 0x374F0000,
1142  0x37500000, 0x37510000, 0x37520000, 0x37530000, 0x37540000, 0x37550000, 0x37560000, 0x37570000, 0x37580000, 0x37590000, 0x375A0000, 0x375B0000, 0x375C0000, 0x375D0000, 0x375E0000, 0x375F0000,
1143  0x37600000, 0x37610000, 0x37620000, 0x37630000, 0x37640000, 0x37650000, 0x37660000, 0x37670000, 0x37680000, 0x37690000, 0x376A0000, 0x376B0000, 0x376C0000, 0x376D0000, 0x376E0000, 0x376F0000,
1144  0x37700000, 0x37710000, 0x37720000, 0x37730000, 0x37740000, 0x37750000, 0x37760000, 0x37770000, 0x37780000, 0x37790000, 0x377A0000, 0x377B0000, 0x377C0000, 0x377D0000, 0x377E0000, 0x377F0000,
1145  0x37800000, 0x37808000, 0x37810000, 0x37818000, 0x37820000, 0x37828000, 0x37830000, 0x37838000, 0x37840000, 0x37848000, 0x37850000, 0x37858000, 0x37860000, 0x37868000, 0x37870000, 0x37878000,
1146  0x37880000, 0x37888000, 0x37890000, 0x37898000, 0x378A0000, 0x378A8000, 0x378B0000, 0x378B8000, 0x378C0000, 0x378C8000, 0x378D0000, 0x378D8000, 0x378E0000, 0x378E8000, 0x378F0000, 0x378F8000,
1147  0x37900000, 0x37908000, 0x37910000, 0x37918000, 0x37920000, 0x37928000, 0x37930000, 0x37938000, 0x37940000, 0x37948000, 0x37950000, 0x37958000, 0x37960000, 0x37968000, 0x37970000, 0x37978000,
1148  0x37980000, 0x37988000, 0x37990000, 0x37998000, 0x379A0000, 0x379A8000, 0x379B0000, 0x379B8000, 0x379C0000, 0x379C8000, 0x379D0000, 0x379D8000, 0x379E0000, 0x379E8000, 0x379F0000, 0x379F8000,
1149  0x37A00000, 0x37A08000, 0x37A10000, 0x37A18000, 0x37A20000, 0x37A28000, 0x37A30000, 0x37A38000, 0x37A40000, 0x37A48000, 0x37A50000, 0x37A58000, 0x37A60000, 0x37A68000, 0x37A70000, 0x37A78000,
1150  0x37A80000, 0x37A88000, 0x37A90000, 0x37A98000, 0x37AA0000, 0x37AA8000, 0x37AB0000, 0x37AB8000, 0x37AC0000, 0x37AC8000, 0x37AD0000, 0x37AD8000, 0x37AE0000, 0x37AE8000, 0x37AF0000, 0x37AF8000,
1151  0x37B00000, 0x37B08000, 0x37B10000, 0x37B18000, 0x37B20000, 0x37B28000, 0x37B30000, 0x37B38000, 0x37B40000, 0x37B48000, 0x37B50000, 0x37B58000, 0x37B60000, 0x37B68000, 0x37B70000, 0x37B78000,
1152  0x37B80000, 0x37B88000, 0x37B90000, 0x37B98000, 0x37BA0000, 0x37BA8000, 0x37BB0000, 0x37BB8000, 0x37BC0000, 0x37BC8000, 0x37BD0000, 0x37BD8000, 0x37BE0000, 0x37BE8000, 0x37BF0000, 0x37BF8000,
1153  0x37C00000, 0x37C08000, 0x37C10000, 0x37C18000, 0x37C20000, 0x37C28000, 0x37C30000, 0x37C38000, 0x37C40000, 0x37C48000, 0x37C50000, 0x37C58000, 0x37C60000, 0x37C68000, 0x37C70000, 0x37C78000,
1154  0x37C80000, 0x37C88000, 0x37C90000, 0x37C98000, 0x37CA0000, 0x37CA8000, 0x37CB0000, 0x37CB8000, 0x37CC0000, 0x37CC8000, 0x37CD0000, 0x37CD8000, 0x37CE0000, 0x37CE8000, 0x37CF0000, 0x37CF8000,
1155  0x37D00000, 0x37D08000, 0x37D10000, 0x37D18000, 0x37D20000, 0x37D28000, 0x37D30000, 0x37D38000, 0x37D40000, 0x37D48000, 0x37D50000, 0x37D58000, 0x37D60000, 0x37D68000, 0x37D70000, 0x37D78000,
1156  0x37D80000, 0x37D88000, 0x37D90000, 0x37D98000, 0x37DA0000, 0x37DA8000, 0x37DB0000, 0x37DB8000, 0x37DC0000, 0x37DC8000, 0x37DD0000, 0x37DD8000, 0x37DE0000, 0x37DE8000, 0x37DF0000, 0x37DF8000,
1157  0x37E00000, 0x37E08000, 0x37E10000, 0x37E18000, 0x37E20000, 0x37E28000, 0x37E30000, 0x37E38000, 0x37E40000, 0x37E48000, 0x37E50000, 0x37E58000, 0x37E60000, 0x37E68000, 0x37E70000, 0x37E78000,
1158  0x37E80000, 0x37E88000, 0x37E90000, 0x37E98000, 0x37EA0000, 0x37EA8000, 0x37EB0000, 0x37EB8000, 0x37EC0000, 0x37EC8000, 0x37ED0000, 0x37ED8000, 0x37EE0000, 0x37EE8000, 0x37EF0000, 0x37EF8000,
1159  0x37F00000, 0x37F08000, 0x37F10000, 0x37F18000, 0x37F20000, 0x37F28000, 0x37F30000, 0x37F38000, 0x37F40000, 0x37F48000, 0x37F50000, 0x37F58000, 0x37F60000, 0x37F68000, 0x37F70000, 0x37F78000,
1160  0x37F80000, 0x37F88000, 0x37F90000, 0x37F98000, 0x37FA0000, 0x37FA8000, 0x37FB0000, 0x37FB8000, 0x37FC0000, 0x37FC8000, 0x37FD0000, 0x37FD8000, 0x37FE0000, 0x37FE8000, 0x37FF0000, 0x37FF8000,
1161  0x38000000, 0x38004000, 0x38008000, 0x3800C000, 0x38010000, 0x38014000, 0x38018000, 0x3801C000, 0x38020000, 0x38024000, 0x38028000, 0x3802C000, 0x38030000, 0x38034000, 0x38038000, 0x3803C000,
1162  0x38040000, 0x38044000, 0x38048000, 0x3804C000, 0x38050000, 0x38054000, 0x38058000, 0x3805C000, 0x38060000, 0x38064000, 0x38068000, 0x3806C000, 0x38070000, 0x38074000, 0x38078000, 0x3807C000,
1163  0x38080000, 0x38084000, 0x38088000, 0x3808C000, 0x38090000, 0x38094000, 0x38098000, 0x3809C000, 0x380A0000, 0x380A4000, 0x380A8000, 0x380AC000, 0x380B0000, 0x380B4000, 0x380B8000, 0x380BC000,
1164  0x380C0000, 0x380C4000, 0x380C8000, 0x380CC000, 0x380D0000, 0x380D4000, 0x380D8000, 0x380DC000, 0x380E0000, 0x380E4000, 0x380E8000, 0x380EC000, 0x380F0000, 0x380F4000, 0x380F8000, 0x380FC000,
1165  0x38100000, 0x38104000, 0x38108000, 0x3810C000, 0x38110000, 0x38114000, 0x38118000, 0x3811C000, 0x38120000, 0x38124000, 0x38128000, 0x3812C000, 0x38130000, 0x38134000, 0x38138000, 0x3813C000,
1166  0x38140000, 0x38144000, 0x38148000, 0x3814C000, 0x38150000, 0x38154000, 0x38158000, 0x3815C000, 0x38160000, 0x38164000, 0x38168000, 0x3816C000, 0x38170000, 0x38174000, 0x38178000, 0x3817C000,
1167  0x38180000, 0x38184000, 0x38188000, 0x3818C000, 0x38190000, 0x38194000, 0x38198000, 0x3819C000, 0x381A0000, 0x381A4000, 0x381A8000, 0x381AC000, 0x381B0000, 0x381B4000, 0x381B8000, 0x381BC000,
1168  0x381C0000, 0x381C4000, 0x381C8000, 0x381CC000, 0x381D0000, 0x381D4000, 0x381D8000, 0x381DC000, 0x381E0000, 0x381E4000, 0x381E8000, 0x381EC000, 0x381F0000, 0x381F4000, 0x381F8000, 0x381FC000,
1169  0x38200000, 0x38204000, 0x38208000, 0x3820C000, 0x38210000, 0x38214000, 0x38218000, 0x3821C000, 0x38220000, 0x38224000, 0x38228000, 0x3822C000, 0x38230000, 0x38234000, 0x38238000, 0x3823C000,
1170  0x38240000, 0x38244000, 0x38248000, 0x3824C000, 0x38250000, 0x38254000, 0x38258000, 0x3825C000, 0x38260000, 0x38264000, 0x38268000, 0x3826C000, 0x38270000, 0x38274000, 0x38278000, 0x3827C000,
1171  0x38280000, 0x38284000, 0x38288000, 0x3828C000, 0x38290000, 0x38294000, 0x38298000, 0x3829C000, 0x382A0000, 0x382A4000, 0x382A8000, 0x382AC000, 0x382B0000, 0x382B4000, 0x382B8000, 0x382BC000,
1172  0x382C0000, 0x382C4000, 0x382C8000, 0x382CC000, 0x382D0000, 0x382D4000, 0x382D8000, 0x382DC000, 0x382E0000, 0x382E4000, 0x382E8000, 0x382EC000, 0x382F0000, 0x382F4000, 0x382F8000, 0x382FC000,
1173  0x38300000, 0x38304000, 0x38308000, 0x3830C000, 0x38310000, 0x38314000, 0x38318000, 0x3831C000, 0x38320000, 0x38324000, 0x38328000, 0x3832C000, 0x38330000, 0x38334000, 0x38338000, 0x3833C000,
1174  0x38340000, 0x38344000, 0x38348000, 0x3834C000, 0x38350000, 0x38354000, 0x38358000, 0x3835C000, 0x38360000, 0x38364000, 0x38368000, 0x3836C000, 0x38370000, 0x38374000, 0x38378000, 0x3837C000,
1175  0x38380000, 0x38384000, 0x38388000, 0x3838C000, 0x38390000, 0x38394000, 0x38398000, 0x3839C000, 0x383A0000, 0x383A4000, 0x383A8000, 0x383AC000, 0x383B0000, 0x383B4000, 0x383B8000, 0x383BC000,
1176  0x383C0000, 0x383C4000, 0x383C8000, 0x383CC000, 0x383D0000, 0x383D4000, 0x383D8000, 0x383DC000, 0x383E0000, 0x383E4000, 0x383E8000, 0x383EC000, 0x383F0000, 0x383F4000, 0x383F8000, 0x383FC000,
1177  0x38400000, 0x38404000, 0x38408000, 0x3840C000, 0x38410000, 0x38414000, 0x38418000, 0x3841C000, 0x38420000, 0x38424000, 0x38428000, 0x3842C000, 0x38430000, 0x38434000, 0x38438000, 0x3843C000,
1178  0x38440000, 0x38444000, 0x38448000, 0x3844C000, 0x38450000, 0x38454000, 0x38458000, 0x3845C000, 0x38460000, 0x38464000, 0x38468000, 0x3846C000, 0x38470000, 0x38474000, 0x38478000, 0x3847C000,
1179  0x38480000, 0x38484000, 0x38488000, 0x3848C000, 0x38490000, 0x38494000, 0x38498000, 0x3849C000, 0x384A0000, 0x384A4000, 0x384A8000, 0x384AC000, 0x384B0000, 0x384B4000, 0x384B8000, 0x384BC000,
1180  0x384C0000, 0x384C4000, 0x384C8000, 0x384CC000, 0x384D0000, 0x384D4000, 0x384D8000, 0x384DC000, 0x384E0000, 0x384E4000, 0x384E8000, 0x384EC000, 0x384F0000, 0x384F4000, 0x384F8000, 0x384FC000,
1181  0x38500000, 0x38504000, 0x38508000, 0x3850C000, 0x38510000, 0x38514000, 0x38518000, 0x3851C000, 0x38520000, 0x38524000, 0x38528000, 0x3852C000, 0x38530000, 0x38534000, 0x38538000, 0x3853C000,
1182  0x38540000, 0x38544000, 0x38548000, 0x3854C000, 0x38550000, 0x38554000, 0x38558000, 0x3855C000, 0x38560000, 0x38564000, 0x38568000, 0x3856C000, 0x38570000, 0x38574000, 0x38578000, 0x3857C000,
1183  0x38580000, 0x38584000, 0x38588000, 0x3858C000, 0x38590000, 0x38594000, 0x38598000, 0x3859C000, 0x385A0000, 0x385A4000, 0x385A8000, 0x385AC000, 0x385B0000, 0x385B4000, 0x385B8000, 0x385BC000,
1184  0x385C0000, 0x385C4000, 0x385C8000, 0x385CC000, 0x385D0000, 0x385D4000, 0x385D8000, 0x385DC000, 0x385E0000, 0x385E4000, 0x385E8000, 0x385EC000, 0x385F0000, 0x385F4000, 0x385F8000, 0x385FC000,
1185  0x38600000, 0x38604000, 0x38608000, 0x3860C000, 0x38610000, 0x38614000, 0x38618000, 0x3861C000, 0x38620000, 0x38624000, 0x38628000, 0x3862C000, 0x38630000, 0x38634000, 0x38638000, 0x3863C000,
1186  0x38640000, 0x38644000, 0x38648000, 0x3864C000, 0x38650000, 0x38654000, 0x38658000, 0x3865C000, 0x38660000, 0x38664000, 0x38668000, 0x3866C000, 0x38670000, 0x38674000, 0x38678000, 0x3867C000,
1187  0x38680000, 0x38684000, 0x38688000, 0x3868C000, 0x38690000, 0x38694000, 0x38698000, 0x3869C000, 0x386A0000, 0x386A4000, 0x386A8000, 0x386AC000, 0x386B0000, 0x386B4000, 0x386B8000, 0x386BC000,
1188  0x386C0000, 0x386C4000, 0x386C8000, 0x386CC000, 0x386D0000, 0x386D4000, 0x386D8000, 0x386DC000, 0x386E0000, 0x386E4000, 0x386E8000, 0x386EC000, 0x386F0000, 0x386F4000, 0x386F8000, 0x386FC000,
1189  0x38700000, 0x38704000, 0x38708000, 0x3870C000, 0x38710000, 0x38714000, 0x38718000, 0x3871C000, 0x38720000, 0x38724000, 0x38728000, 0x3872C000, 0x38730000, 0x38734000, 0x38738000, 0x3873C000,
1190  0x38740000, 0x38744000, 0x38748000, 0x3874C000, 0x38750000, 0x38754000, 0x38758000, 0x3875C000, 0x38760000, 0x38764000, 0x38768000, 0x3876C000, 0x38770000, 0x38774000, 0x38778000, 0x3877C000,
1191  0x38780000, 0x38784000, 0x38788000, 0x3878C000, 0x38790000, 0x38794000, 0x38798000, 0x3879C000, 0x387A0000, 0x387A4000, 0x387A8000, 0x387AC000, 0x387B0000, 0x387B4000, 0x387B8000, 0x387BC000,
1192  0x387C0000, 0x387C4000, 0x387C8000, 0x387CC000, 0x387D0000, 0x387D4000, 0x387D8000, 0x387DC000, 0x387E0000, 0x387E4000, 0x387E8000, 0x387EC000, 0x387F0000, 0x387F4000, 0x387F8000, 0x387FC000,
1193  0x38000000, 0x38002000, 0x38004000, 0x38006000, 0x38008000, 0x3800A000, 0x3800C000, 0x3800E000, 0x38010000, 0x38012000, 0x38014000, 0x38016000, 0x38018000, 0x3801A000, 0x3801C000, 0x3801E000,
1194  0x38020000, 0x38022000, 0x38024000, 0x38026000, 0x38028000, 0x3802A000, 0x3802C000, 0x3802E000, 0x38030000, 0x38032000, 0x38034000, 0x38036000, 0x38038000, 0x3803A000, 0x3803C000, 0x3803E000,
1195  0x38040000, 0x38042000, 0x38044000, 0x38046000, 0x38048000, 0x3804A000, 0x3804C000, 0x3804E000, 0x38050000, 0x38052000, 0x38054000, 0x38056000, 0x38058000, 0x3805A000, 0x3805C000, 0x3805E000,
1196  0x38060000, 0x38062000, 0x38064000, 0x38066000, 0x38068000, 0x3806A000, 0x3806C000, 0x3806E000, 0x38070000, 0x38072000, 0x38074000, 0x38076000, 0x38078000, 0x3807A000, 0x3807C000, 0x3807E000,
1197  0x38080000, 0x38082000, 0x38084000, 0x38086000, 0x38088000, 0x3808A000, 0x3808C000, 0x3808E000, 0x38090000, 0x38092000, 0x38094000, 0x38096000, 0x38098000, 0x3809A000, 0x3809C000, 0x3809E000,
1198  0x380A0000, 0x380A2000, 0x380A4000, 0x380A6000, 0x380A8000, 0x380AA000, 0x380AC000, 0x380AE000, 0x380B0000, 0x380B2000, 0x380B4000, 0x380B6000, 0x380B8000, 0x380BA000, 0x380BC000, 0x380BE000,
1199  0x380C0000, 0x380C2000, 0x380C4000, 0x380C6000, 0x380C8000, 0x380CA000, 0x380CC000, 0x380CE000, 0x380D0000, 0x380D2000, 0x380D4000, 0x380D6000, 0x380D8000, 0x380DA000, 0x380DC000, 0x380DE000,
1200  0x380E0000, 0x380E2000, 0x380E4000, 0x380E6000, 0x380E8000, 0x380EA000, 0x380EC000, 0x380EE000, 0x380F0000, 0x380F2000, 0x380F4000, 0x380F6000, 0x380F8000, 0x380FA000, 0x380FC000, 0x380FE000,
1201  0x38100000, 0x38102000, 0x38104000, 0x38106000, 0x38108000, 0x3810A000, 0x3810C000, 0x3810E000, 0x38110000, 0x38112000, 0x38114000, 0x38116000, 0x38118000, 0x3811A000, 0x3811C000, 0x3811E000,
1202  0x38120000, 0x38122000, 0x38124000, 0x38126000, 0x38128000, 0x3812A000, 0x3812C000, 0x3812E000, 0x38130000, 0x38132000, 0x38134000, 0x38136000, 0x38138000, 0x3813A000, 0x3813C000, 0x3813E000,
1203  0x38140000, 0x38142000, 0x38144000, 0x38146000, 0x38148000, 0x3814A000, 0x3814C000, 0x3814E000, 0x38150000, 0x38152000, 0x38154000, 0x38156000, 0x38158000, 0x3815A000, 0x3815C000, 0x3815E000,
1204  0x38160000, 0x38162000, 0x38164000, 0x38166000, 0x38168000, 0x3816A000, 0x3816C000, 0x3816E000, 0x38170000, 0x38172000, 0x38174000, 0x38176000, 0x38178000, 0x3817A000, 0x3817C000, 0x3817E000,
1205  0x38180000, 0x38182000, 0x38184000, 0x38186000, 0x38188000, 0x3818A000, 0x3818C000, 0x3818E000, 0x38190000, 0x38192000, 0x38194000, 0x38196000, 0x38198000, 0x3819A000, 0x3819C000, 0x3819E000,
1206  0x381A0000, 0x381A2000, 0x381A4000, 0x381A6000, 0x381A8000, 0x381AA000, 0x381AC000, 0x381AE000, 0x381B0000, 0x381B2000, 0x381B4000, 0x381B6000, 0x381B8000, 0x381BA000, 0x381BC000, 0x381BE000,
1207  0x381C0000, 0x381C2000, 0x381C4000, 0x381C6000, 0x381C8000, 0x381CA000, 0x381CC000, 0x381CE000, 0x381D0000, 0x381D2000, 0x381D4000, 0x381D6000, 0x381D8000, 0x381DA000, 0x381DC000, 0x381DE000,
1208  0x381E0000, 0x381E2000, 0x381E4000, 0x381E6000, 0x381E8000, 0x381EA000, 0x381EC000, 0x381EE000, 0x381F0000, 0x381F2000, 0x381F4000, 0x381F6000, 0x381F8000, 0x381FA000, 0x381FC000, 0x381FE000,
1209  0x38200000, 0x38202000, 0x38204000, 0x38206000, 0x38208000, 0x3820A000, 0x3820C000, 0x3820E000, 0x38210000, 0x38212000, 0x38214000, 0x38216000, 0x38218000, 0x3821A000, 0x3821C000, 0x3821E000,
1210  0x38220000, 0x38222000, 0x38224000, 0x38226000, 0x38228000, 0x3822A000, 0x3822C000, 0x3822E000, 0x38230000, 0x38232000, 0x38234000, 0x38236000, 0x38238000, 0x3823A000, 0x3823C000, 0x3823E000,
1211  0x38240000, 0x38242000, 0x38244000, 0x38246000, 0x38248000, 0x3824A000, 0x3824C000, 0x3824E000, 0x38250000, 0x38252000, 0x38254000, 0x38256000, 0x38258000, 0x3825A000, 0x3825C000, 0x3825E000,
1212  0x38260000, 0x38262000, 0x38264000, 0x38266000, 0x38268000, 0x3826A000, 0x3826C000, 0x3826E000, 0x38270000, 0x38272000, 0x38274000, 0x38276000, 0x38278000, 0x3827A000, 0x3827C000, 0x3827E000,
1213  0x38280000, 0x38282000, 0x38284000, 0x38286000, 0x38288000, 0x3828A000, 0x3828C000, 0x3828E000, 0x38290000, 0x38292000, 0x38294000, 0x38296000, 0x38298000, 0x3829A000, 0x3829C000, 0x3829E000,
1214  0x382A0000, 0x382A2000, 0x382A4000, 0x382A6000, 0x382A8000, 0x382AA000, 0x382AC000, 0x382AE000, 0x382B0000, 0x382B2000, 0x382B4000, 0x382B6000, 0x382B8000, 0x382BA000, 0x382BC000, 0x382BE000,
1215  0x382C0000, 0x382C2000, 0x382C4000, 0x382C6000, 0x382C8000, 0x382CA000, 0x382CC000, 0x382CE000, 0x382D0000, 0x382D2000, 0x382D4000, 0x382D6000, 0x382D8000, 0x382DA000, 0x382DC000, 0x382DE000,
1216  0x382E0000, 0x382E2000, 0x382E4000, 0x382E6000, 0x382E8000, 0x382EA000, 0x382EC000, 0x382EE000, 0x382F0000, 0x382F2000, 0x382F4000, 0x382F6000, 0x382F8000, 0x382FA000, 0x382FC000, 0x382FE000,
1217  0x38300000, 0x38302000, 0x38304000, 0x38306000, 0x38308000, 0x3830A000, 0x3830C000, 0x3830E000, 0x38310000, 0x38312000, 0x38314000, 0x38316000, 0x38318000, 0x3831A000, 0x3831C000, 0x3831E000,
1218  0x38320000, 0x38322000, 0x38324000, 0x38326000, 0x38328000, 0x3832A000, 0x3832C000, 0x3832E000, 0x38330000, 0x38332000, 0x38334000, 0x38336000, 0x38338000, 0x3833A000, 0x3833C000, 0x3833E000,
1219  0x38340000, 0x38342000, 0x38344000, 0x38346000, 0x38348000, 0x3834A000, 0x3834C000, 0x3834E000, 0x38350000, 0x38352000, 0x38354000, 0x38356000, 0x38358000, 0x3835A000, 0x3835C000, 0x3835E000,
1220  0x38360000, 0x38362000, 0x38364000, 0x38366000, 0x38368000, 0x3836A000, 0x3836C000, 0x3836E000, 0x38370000, 0x38372000, 0x38374000, 0x38376000, 0x38378000, 0x3837A000, 0x3837C000, 0x3837E000,
1221  0x38380000, 0x38382000, 0x38384000, 0x38386000, 0x38388000, 0x3838A000, 0x3838C000, 0x3838E000, 0x38390000, 0x38392000, 0x38394000, 0x38396000, 0x38398000, 0x3839A000, 0x3839C000, 0x3839E000,
1222  0x383A0000, 0x383A2000, 0x383A4000, 0x383A6000, 0x383A8000, 0x383AA000, 0x383AC000, 0x383AE000, 0x383B0000, 0x383B2000, 0x383B4000, 0x383B6000, 0x383B8000, 0x383BA000, 0x383BC000, 0x383BE000,
1223  0x383C0000, 0x383C2000, 0x383C4000, 0x383C6000, 0x383C8000, 0x383CA000, 0x383CC000, 0x383CE000, 0x383D0000, 0x383D2000, 0x383D4000, 0x383D6000, 0x383D8000, 0x383DA000, 0x383DC000, 0x383DE000,
1224  0x383E0000, 0x383E2000, 0x383E4000, 0x383E6000, 0x383E8000, 0x383EA000, 0x383EC000, 0x383EE000, 0x383F0000, 0x383F2000, 0x383F4000, 0x383F6000, 0x383F8000, 0x383FA000, 0x383FC000, 0x383FE000,
1225  0x38400000, 0x38402000, 0x38404000, 0x38406000, 0x38408000, 0x3840A000, 0x3840C000, 0x3840E000, 0x38410000, 0x38412000, 0x38414000, 0x38416000, 0x38418000, 0x3841A000, 0x3841C000, 0x3841E000,
1226  0x38420000, 0x38422000, 0x38424000, 0x38426000, 0x38428000, 0x3842A000, 0x3842C000, 0x3842E000, 0x38430000, 0x38432000, 0x38434000, 0x38436000, 0x38438000, 0x3843A000, 0x3843C000, 0x3843E000,
1227  0x38440000, 0x38442000, 0x38444000, 0x38446000, 0x38448000, 0x3844A000, 0x3844C000, 0x3844E000, 0x38450000, 0x38452000, 0x38454000, 0x38456000, 0x38458000, 0x3845A000, 0x3845C000, 0x3845E000,
1228  0x38460000, 0x38462000, 0x38464000, 0x38466000, 0x38468000, 0x3846A000, 0x3846C000, 0x3846E000, 0x38470000, 0x38472000, 0x38474000, 0x38476000, 0x38478000, 0x3847A000, 0x3847C000, 0x3847E000,
1229  0x38480000, 0x38482000, 0x38484000, 0x38486000, 0x38488000, 0x3848A000, 0x3848C000, 0x3848E000, 0x38490000, 0x38492000, 0x38494000, 0x38496000, 0x38498000, 0x3849A000, 0x3849C000, 0x3849E000,
1230  0x384A0000, 0x384A2000, 0x384A4000, 0x384A6000, 0x384A8000, 0x384AA000, 0x384AC000, 0x384AE000, 0x384B0000, 0x384B2000, 0x384B4000, 0x384B6000, 0x384B8000, 0x384BA000, 0x384BC000, 0x384BE000,
1231  0x384C0000, 0x384C2000, 0x384C4000, 0x384C6000, 0x384C8000, 0x384CA000, 0x384CC000, 0x384CE000, 0x384D0000, 0x384D2000, 0x384D4000, 0x384D6000, 0x384D8000, 0x384DA000, 0x384DC000, 0x384DE000,
1232  0x384E0000, 0x384E2000, 0x384E4000, 0x384E6000, 0x384E8000, 0x384EA000, 0x384EC000, 0x384EE000, 0x384F0000, 0x384F2000, 0x384F4000, 0x384F6000, 0x384F8000, 0x384FA000, 0x384FC000, 0x384FE000,
1233  0x38500000, 0x38502000, 0x38504000, 0x38506000, 0x38508000, 0x3850A000, 0x3850C000, 0x3850E000, 0x38510000, 0x38512000, 0x38514000, 0x38516000, 0x38518000, 0x3851A000, 0x3851C000, 0x3851E000,
1234  0x38520000, 0x38522000, 0x38524000, 0x38526000, 0x38528000, 0x3852A000, 0x3852C000, 0x3852E000, 0x38530000, 0x38532000, 0x38534000, 0x38536000, 0x38538000, 0x3853A000, 0x3853C000, 0x3853E000,
1235  0x38540000, 0x38542000, 0x38544000, 0x38546000, 0x38548000, 0x3854A000, 0x3854C000, 0x3854E000, 0x38550000, 0x38552000, 0x38554000, 0x38556000, 0x38558000, 0x3855A000, 0x3855C000, 0x3855E000,
1236  0x38560000, 0x38562000, 0x38564000, 0x38566000, 0x38568000, 0x3856A000, 0x3856C000, 0x3856E000, 0x38570000, 0x38572000, 0x38574000, 0x38576000, 0x38578000, 0x3857A000, 0x3857C000, 0x3857E000,
1237  0x38580000, 0x38582000, 0x38584000, 0x38586000, 0x38588000, 0x3858A000, 0x3858C000, 0x3858E000, 0x38590000, 0x38592000, 0x38594000, 0x38596000, 0x38598000, 0x3859A000, 0x3859C000, 0x3859E000,
1238  0x385A0000, 0x385A2000, 0x385A4000, 0x385A6000, 0x385A8000, 0x385AA000, 0x385AC000, 0x385AE000, 0x385B0000, 0x385B2000, 0x385B4000, 0x385B6000, 0x385B8000, 0x385BA000, 0x385BC000, 0x385BE000,
1239  0x385C0000, 0x385C2000, 0x385C4000, 0x385C6000, 0x385C8000, 0x385CA000, 0x385CC000, 0x385CE000, 0x385D0000, 0x385D2000, 0x385D4000, 0x385D6000, 0x385D8000, 0x385DA000, 0x385DC000, 0x385DE000,
1240  0x385E0000, 0x385E2000, 0x385E4000, 0x385E6000, 0x385E8000, 0x385EA000, 0x385EC000, 0x385EE000, 0x385F0000, 0x385F2000, 0x385F4000, 0x385F6000, 0x385F8000, 0x385FA000, 0x385FC000, 0x385FE000,
1241  0x38600000, 0x38602000, 0x38604000, 0x38606000, 0x38608000, 0x3860A000, 0x3860C000, 0x3860E000, 0x38610000, 0x38612000, 0x38614000, 0x38616000, 0x38618000, 0x3861A000, 0x3861C000, 0x3861E000,
1242  0x38620000, 0x38622000, 0x38624000, 0x38626000, 0x38628000, 0x3862A000, 0x3862C000, 0x3862E000, 0x38630000, 0x38632000, 0x38634000, 0x38636000, 0x38638000, 0x3863A000, 0x3863C000, 0x3863E000,
1243  0x38640000, 0x38642000, 0x38644000, 0x38646000, 0x38648000, 0x3864A000, 0x3864C000, 0x3864E000, 0x38650000, 0x38652000, 0x38654000, 0x38656000, 0x38658000, 0x3865A000, 0x3865C000, 0x3865E000,
1244  0x38660000, 0x38662000, 0x38664000, 0x38666000, 0x38668000, 0x3866A000, 0x3866C000, 0x3866E000, 0x38670000, 0x38672000, 0x38674000, 0x38676000, 0x38678000, 0x3867A000, 0x3867C000, 0x3867E000,
1245  0x38680000, 0x38682000, 0x38684000, 0x38686000, 0x38688000, 0x3868A000, 0x3868C000, 0x3868E000, 0x38690000, 0x38692000, 0x38694000, 0x38696000, 0x38698000, 0x3869A000, 0x3869C000, 0x3869E000,
1246  0x386A0000, 0x386A2000, 0x386A4000, 0x386A6000, 0x386A8000, 0x386AA000, 0x386AC000, 0x386AE000, 0x386B0000, 0x386B2000, 0x386B4000, 0x386B6000, 0x386B8000, 0x386BA000, 0x386BC000, 0x386BE000,
1247  0x386C0000, 0x386C2000, 0x386C4000, 0x386C6000, 0x386C8000, 0x386CA000, 0x386CC000, 0x386CE000, 0x386D0000, 0x386D2000, 0x386D4000, 0x386D6000, 0x386D8000, 0x386DA000, 0x386DC000, 0x386DE000,
1248  0x386E0000, 0x386E2000, 0x386E4000, 0x386E6000, 0x386E8000, 0x386EA000, 0x386EC000, 0x386EE000, 0x386F0000, 0x386F2000, 0x386F4000, 0x386F6000, 0x386F8000, 0x386FA000, 0x386FC000, 0x386FE000,
1249  0x38700000, 0x38702000, 0x38704000, 0x38706000, 0x38708000, 0x3870A000, 0x3870C000, 0x3870E000, 0x38710000, 0x38712000, 0x38714000, 0x38716000, 0x38718000, 0x3871A000, 0x3871C000, 0x3871E000,
1250  0x38720000, 0x38722000, 0x38724000, 0x38726000, 0x38728000, 0x3872A000, 0x3872C000, 0x3872E000, 0x38730000, 0x38732000, 0x38734000, 0x38736000, 0x38738000, 0x3873A000, 0x3873C000, 0x3873E000,
1251  0x38740000, 0x38742000, 0x38744000, 0x38746000, 0x38748000, 0x3874A000, 0x3874C000, 0x3874E000, 0x38750000, 0x38752000, 0x38754000, 0x38756000, 0x38758000, 0x3875A000, 0x3875C000, 0x3875E000,
1252  0x38760000, 0x38762000, 0x38764000, 0x38766000, 0x38768000, 0x3876A000, 0x3876C000, 0x3876E000, 0x38770000, 0x38772000, 0x38774000, 0x38776000, 0x38778000, 0x3877A000, 0x3877C000, 0x3877E000,
1253  0x38780000, 0x38782000, 0x38784000, 0x38786000, 0x38788000, 0x3878A000, 0x3878C000, 0x3878E000, 0x38790000, 0x38792000, 0x38794000, 0x38796000, 0x38798000, 0x3879A000, 0x3879C000, 0x3879E000,
1254  0x387A0000, 0x387A2000, 0x387A4000, 0x387A6000, 0x387A8000, 0x387AA000, 0x387AC000, 0x387AE000, 0x387B0000, 0x387B2000, 0x387B4000, 0x387B6000, 0x387B8000, 0x387BA000, 0x387BC000, 0x387BE000,
1255  0x387C0000, 0x387C2000, 0x387C4000, 0x387C6000, 0x387C8000, 0x387CA000, 0x387CC000, 0x387CE000, 0x387D0000, 0x387D2000, 0x387D4000, 0x387D6000, 0x387D8000, 0x387DA000, 0x387DC000, 0x387DE000,
1256  0x387E0000, 0x387E2000, 0x387E4000, 0x387E6000, 0x387E8000, 0x387EA000, 0x387EC000, 0x387EE000, 0x387F0000, 0x387F2000, 0x387F4000, 0x387F6000, 0x387F8000, 0x387FA000, 0x387FC000, 0x387FE000 };
1257  static const bits<float>::type exponent_table[64] = {
1258  0x00000000, 0x00800000, 0x01000000, 0x01800000, 0x02000000, 0x02800000, 0x03000000, 0x03800000, 0x04000000, 0x04800000, 0x05000000, 0x05800000, 0x06000000, 0x06800000, 0x07000000, 0x07800000,
1259  0x08000000, 0x08800000, 0x09000000, 0x09800000, 0x0A000000, 0x0A800000, 0x0B000000, 0x0B800000, 0x0C000000, 0x0C800000, 0x0D000000, 0x0D800000, 0x0E000000, 0x0E800000, 0x0F000000, 0x47800000,
1260  0x80000000, 0x80800000, 0x81000000, 0x81800000, 0x82000000, 0x82800000, 0x83000000, 0x83800000, 0x84000000, 0x84800000, 0x85000000, 0x85800000, 0x86000000, 0x86800000, 0x87000000, 0x87800000,
1261  0x88000000, 0x88800000, 0x89000000, 0x89800000, 0x8A000000, 0x8A800000, 0x8B000000, 0x8B800000, 0x8C000000, 0x8C800000, 0x8D000000, 0x8D800000, 0x8E000000, 0x8E800000, 0x8F000000, 0xC7800000 };
1262  static const unsigned short offset_table[64] = {
1263  0, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1264  0, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024 };
1265  bits<float>::type fbits = mantissa_table[offset_table[value>>10]+(value&0x3FF)] + exponent_table[value>>10];
1266  #endif
1267  float out;
1268  std::memcpy(&out, &fbits, sizeof(float));
1269  return out;
1270  #endif
1271  }
1272 
1276  inline double half2float_impl(unsigned int value, double, true_type)
1277  {
1278  #if HALF_ENABLE_F16C_INTRINSICS
1279  return _mm_cvtsd_f64(_mm_cvtps_pd(_mm_cvtph_ps(_mm_cvtsi32_si128(value))));
1280  #else
1281  uint32 hi = static_cast<uint32>(value&0x8000) << 16;
1282  unsigned int abs = value & 0x7FFF;
1283  if(abs)
1284  {
1285  hi |= 0x3F000000 << static_cast<unsigned>(abs>=0x7C00);
1286  for(; abs<0x400; abs<<=1,hi-=0x100000) ;
1287  hi += static_cast<uint32>(abs) << 10;
1288  }
1289  bits<double>::type dbits = static_cast<bits<double>::type>(hi) << 32;
1290  double out;
1291  std::memcpy(&out, &dbits, sizeof(double));
1292  return out;
1293  #endif
1294  }
1295 
1300  template<typename T> T half2float_impl(unsigned int value, T, ...)
1301  {
1302  T out;
1303  unsigned int abs = value & 0x7FFF;
1304  if(abs > 0x7C00)
1305  out = (std::numeric_limits<T>::has_signaling_NaN && !(abs&0x200)) ? std::numeric_limits<T>::signaling_NaN() :
1306  std::numeric_limits<T>::has_quiet_NaN ? std::numeric_limits<T>::quiet_NaN() : T();
1307  else if(abs == 0x7C00)
1308  out = std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : std::numeric_limits<T>::max();
1309  else if(abs > 0x3FF)
1310  out = std::ldexp(static_cast<T>((abs&0x3FF)|0x400), (abs>>10)-25);
1311  else
1312  out = std::ldexp(static_cast<T>(abs), -24);
1313  return (value&0x8000) ? -out : out;
1314  }
1315 
1320  template<typename T> T half2float(unsigned int value)
1321  {
1322  return half2float_impl(value, T(), bool_type<std::numeric_limits<T>::is_iec559&&sizeof(typename bits<T>::type)==sizeof(T)>());
1323  }
1324 
1334  template<std::float_round_style R,bool E,bool I,typename T> T half2int(unsigned int value)
1335  {
1336  unsigned int abs = value & 0x7FFF;
1337  if(abs >= 0x7C00)
1338  {
1339  raise(FE_INVALID);
1340  return (value&0x8000) ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max();
1341  }
1342  if(abs < 0x3800)
1343  {
1344  raise(FE_INEXACT, I);
1345  return (R==std::round_toward_infinity) ? T(~(value>>15)&(abs!=0)) :
1346  (R==std::round_toward_neg_infinity) ? -T(value>0x8000) :
1347  T();
1348  }
1349  int exp = 25 - (abs>>10);
1350  unsigned int m = (value&0x3FF) | 0x400;
1351  int32 i = static_cast<int32>((exp<=0) ? (m<<-exp) : ((m+(
1352  (R==std::round_to_nearest) ? ((1<<(exp-1))-(~(m>>exp)&E)) :
1353  (R==std::round_toward_infinity) ? (((1<<exp)-1)&((value>>15)-1)) :
1354  (R==std::round_toward_neg_infinity) ? (((1<<exp)-1)&-(value>>15)) : 0))>>exp));
1355  if((!std::numeric_limits<T>::is_signed && (value&0x8000)) || (std::numeric_limits<T>::digits<16 &&
1356  ((value&0x8000) ? (-i<std::numeric_limits<T>::min()) : (i>std::numeric_limits<T>::max()))))
1357  raise(FE_INVALID);
1358  else if(I && exp > 0 && (m&((1<<exp)-1)))
1359  raise(FE_INEXACT);
1360  return static_cast<T>((value&0x8000) ? -i : i);
1361  }
1362 
1366 
1372  template<std::float_round_style R> uint32 mulhi(uint32 x, uint32 y)
1373  {
1374  uint32 xy = (x>>16) * (y&0xFFFF), yx = (x&0xFFFF) * (y>>16), c = (xy&0xFFFF) + (yx&0xFFFF) + (((x&0xFFFF)*(y&0xFFFF))>>16);
1375  return (x>>16)*(y>>16) + (xy>>16) + (yx>>16) + (c>>16) +
1376  ((R==std::round_to_nearest) ? ((c>>15)&1) : (R==std::round_toward_infinity) ? ((c&0xFFFF)!=0) : 0);
1377  }
1378 
1384  {
1385  #if HALF_ENABLE_CPP11_LONG_LONG
1386  return static_cast<uint32>((static_cast<unsigned long long>(x)*static_cast<unsigned long long>(y)+0x80000000)>>32);
1387  #else
1388  return mulhi<std::round_to_nearest>(x, y);
1389  #endif
1390  }
1391 
1397  inline uint32 divide64(uint32 x, uint32 y, int &s)
1398  {
1399  #if HALF_ENABLE_CPP11_LONG_LONG
1400  unsigned long long xx = static_cast<unsigned long long>(x) << 32;
1401  return s = (xx%y!=0), static_cast<uint32>(xx/y);
1402  #else
1403  y >>= 1;
1404  uint32 rem = x, div = 0;
1405  for(unsigned int i=0; i<32; ++i)
1406  {
1407  div <<= 1;
1408  if(rem >= y)
1409  {
1410  rem -= y;
1411  div |= 1;
1412  }
1413  rem <<= 1;
1414  }
1415  return s = rem > 1, div;
1416  #endif
1417  }
1418 
1426  template<bool Q,bool R> unsigned int mod(unsigned int x, unsigned int y, int *quo = NULL)
1427  {
1428  unsigned int q = 0;
1429  if(x > y)
1430  {
1431  int absx = x, absy = y, expx = 0, expy = 0;
1432  for(; absx<0x400; absx<<=1,--expx) ;
1433  for(; absy<0x400; absy<<=1,--expy) ;
1434  expx += absx >> 10;
1435  expy += absy >> 10;
1436  int mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400;
1437  for(int d=expx-expy; d; --d)
1438  {
1439  if(!Q && mx == my)
1440  return 0;
1441  if(mx >= my)
1442  {
1443  mx -= my;
1444  q += Q;
1445  }
1446  mx <<= 1;
1447  q <<= static_cast<int>(Q);
1448  }
1449  if(!Q && mx == my)
1450  return 0;
1451  if(mx >= my)
1452  {
1453  mx -= my;
1454  ++q;
1455  }
1456  if(Q)
1457  {
1458  q &= (1<<(std::numeric_limits<int>::digits-1)) - 1;
1459  if(!mx)
1460  return *quo = q, 0;
1461  }
1462  for(; mx<0x400; mx<<=1,--expy) ;
1463  x = (expy>0) ? ((expy<<10)|(mx&0x3FF)) : (mx>>(1-expy));
1464  }
1465  if(R)
1466  {
1467  unsigned int a, b;
1468  if(y < 0x800)
1469  {
1470  a = (x<0x400) ? (x<<1) : (x+0x400);
1471  b = y;
1472  }
1473  else
1474  {
1475  a = x;
1476  b = y - 0x400;
1477  }
1478  if(a > b || (a == b && (q&1)))
1479  {
1480  int exp = (y>>10) + (y<=0x3FF), d = exp - (x>>10) - (x<=0x3FF);
1481  int m = (((y&0x3FF)|((y>0x3FF)<<10))<<1) - (((x&0x3FF)|((x>0x3FF)<<10))<<(1-d));
1482  for(; m<0x800 && exp>1; m<<=1,--exp) ;
1483  x = 0x8000 + ((exp-1)<<10) + (m>>1);
1484  q += Q;
1485  }
1486  }
1487  if(Q)
1488  *quo = q;
1489  return x;
1490  }
1491 
1497  template<unsigned int F> uint32 sqrt(uint32 &r, int &exp)
1498  {
1499  int i = exp & 1;
1500  r <<= i;
1501  exp = (exp-i) / 2;
1502  uint32 m = 0;
1503  for(uint32 bit=static_cast<uint32>(1)<<F; bit; bit>>=2)
1504  {
1505  if(r < m+bit)
1506  m >>= 1;
1507  else
1508  {
1509  r -= m + bit;
1510  m = (m>>1) + bit;
1511  }
1512  }
1513  return m;
1514  }
1515 
1521  inline uint32 exp2(uint32 m, unsigned int n = 32)
1522  {
1523  static const uint32 logs[] = {
1524  0x80000000, 0x4AE00D1D, 0x2934F098, 0x15C01A3A, 0x0B31FB7D, 0x05AEB4DD, 0x02DCF2D1, 0x016FE50B,
1525  0x00B84E23, 0x005C3E10, 0x002E24CA, 0x001713D6, 0x000B8A47, 0x0005C53B, 0x0002E2A3, 0x00017153,
1526  0x0000B8AA, 0x00005C55, 0x00002E2B, 0x00001715, 0x00000B8B, 0x000005C5, 0x000002E3, 0x00000171,
1527  0x000000B9, 0x0000005C, 0x0000002E, 0x00000017, 0x0000000C, 0x00000006, 0x00000003, 0x00000001 };
1528  if(!m)
1529  return 0x80000000;
1530  uint32 mx = 0x80000000, my = 0;
1531  for(unsigned int i=1; i<n; ++i)
1532  {
1533  uint32 mz = my + logs[i];
1534  if(mz <= m)
1535  {
1536  my = mz;
1537  mx += mx >> i;
1538  }
1539  }
1540  return mx;
1541  }
1542 
1548  inline uint32 log2(uint32 m, unsigned int n = 32)
1549  {
1550  static const uint32 logs[] = {
1551  0x80000000, 0x4AE00D1D, 0x2934F098, 0x15C01A3A, 0x0B31FB7D, 0x05AEB4DD, 0x02DCF2D1, 0x016FE50B,
1552  0x00B84E23, 0x005C3E10, 0x002E24CA, 0x001713D6, 0x000B8A47, 0x0005C53B, 0x0002E2A3, 0x00017153,
1553  0x0000B8AA, 0x00005C55, 0x00002E2B, 0x00001715, 0x00000B8B, 0x000005C5, 0x000002E3, 0x00000171,
1554  0x000000B9, 0x0000005C, 0x0000002E, 0x00000017, 0x0000000C, 0x00000006, 0x00000003, 0x00000001 };
1555  if(m == 0x40000000)
1556  return 0;
1557  uint32 mx = 0x40000000, my = 0;
1558  for(unsigned int i=1; i<n; ++i)
1559  {
1560  uint32 mz = mx + (mx>>i);
1561  if(mz <= m)
1562  {
1563  mx = mz;
1564  my += logs[i];
1565  }
1566  }
1567  return my;
1568  }
1569 
1575  inline std::pair<uint32,uint32> sincos(uint32 mz, unsigned int n = 31)
1576  {
1577  static const uint32 angles[] = {
1578  0x3243F6A9, 0x1DAC6705, 0x0FADBAFD, 0x07F56EA7, 0x03FEAB77, 0x01FFD55C, 0x00FFFAAB, 0x007FFF55,
1579  0x003FFFEB, 0x001FFFFD, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, 0x00008000,
1580  0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080,
1581  0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 };
1582  uint32 mx = 0x26DD3B6A, my = 0;
1583  for(unsigned int i=0; i<n; ++i)
1584  {
1585  uint32 sign = sign_mask(mz);
1586  uint32 tx = mx - (arithmetic_shift(my, i)^sign) + sign;
1587  uint32 ty = my + (arithmetic_shift(mx, i)^sign) - sign;
1588  mx = tx; my = ty; mz -= (angles[i]^sign) - sign;
1589  }
1590  return std::make_pair(my, mx);
1591  }
1592 
1599  inline uint32 atan2(uint32 my, uint32 mx, unsigned int n = 31)
1600  {
1601  static const uint32 angles[] = {
1602  0x3243F6A9, 0x1DAC6705, 0x0FADBAFD, 0x07F56EA7, 0x03FEAB77, 0x01FFD55C, 0x00FFFAAB, 0x007FFF55,
1603  0x003FFFEB, 0x001FFFFD, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, 0x00008000,
1604  0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080,
1605  0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 };
1606  uint32 mz = 0;
1607  for(unsigned int i=0; i<n; ++i)
1608  {
1609  uint32 sign = sign_mask(my);
1610  uint32 tx = mx + (arithmetic_shift(my, i)^sign) - sign;
1611  uint32 ty = my - (arithmetic_shift(mx, i)^sign) + sign;
1612  mx = tx; my = ty; mz += (angles[i]^sign) - sign;
1613  }
1614  return mz;
1615  }
1616 
1621  inline uint32 angle_arg(unsigned int abs, int &k)
1622  {
1623  uint32 m = (abs&0x3FF) | ((abs>0x3FF)<<10);
1624  int exp = (abs>>10) + (abs<=0x3FF) - 15;
1625  if(abs < 0x3A48)
1626  return k = 0, m << (exp+20);
1627  #if HALF_ENABLE_CPP11_LONG_LONG
1628  unsigned long long y = m * 0xA2F9836E4E442, mask = (1ULL<<(62-exp)) - 1, yi = (y+(mask>>1)) & ~mask, f = y - yi;
1629  uint32 sign = -static_cast<uint32>(f>>63);
1630  k = static_cast<int>(yi>>(62-exp));
1631  return (multiply64(static_cast<uint32>((sign ? -f : f)>>(31-exp)), 0xC90FDAA2)^sign) - sign;
1632  #else
1633  uint32 yh = m*0xA2F98 + mulhi<std::round_toward_zero>(m, 0x36E4E442), yl = (m*0x36E4E442) & 0xFFFFFFFF;
1634  uint32 mask = (static_cast<uint32>(1)<<(30-exp)) - 1, yi = (yh+(mask>>1)) & ~mask, sign = -static_cast<uint32>(yi>yh);
1635  k = static_cast<int>(yi>>(30-exp));
1636  uint32 fh = (yh^sign) + (yi^~sign) - ~sign, fl = (yl^sign) - sign;
1637  return (multiply64((exp>-1) ? (((fh<<(1+exp))&0xFFFFFFFF)|((fl&0xFFFFFFFF)>>(31-exp))) : fh, 0xC90FDAA2)^sign) - sign;
1638  #endif
1639  }
1640 
1644  inline std::pair<uint32,uint32> atan2_args(unsigned int abs)
1645  {
1646  int exp = -15;
1647  for(; abs<0x400; abs<<=1,--exp) ;
1648  exp += abs >> 10;
1649  uint32 my = ((abs&0x3FF)|0x400) << 5, r = my * my;
1650  int rexp = 2 * exp;
1651  r = 0x40000000 - ((rexp>-31) ? ((r>>-rexp)|((r&((static_cast<uint32>(1)<<-rexp)-1))!=0)) : 1);
1652  for(rexp=0; r<0x40000000; r<<=1,--rexp) ;
1653  uint32 mx = sqrt<30>(r, rexp);
1654  int d = exp - rexp;
1655  if(d < 0)
1656  return std::make_pair((d<-14) ? ((my>>(-d-14))+((my>>(-d-15))&1)) : (my<<(14+d)), (mx<<14)+(r<<13)/mx);
1657  if(d > 0)
1658  return std::make_pair(my<<14, (d>14) ? ((mx>>(d-14))+((mx>>(d-15))&1)) : ((d==14) ? mx : ((mx<<(14-d))+(r<<(13-d))/mx)));
1659  return std::make_pair(my<<13, (mx<<13)+(r<<12)/mx);
1660  }
1661 
1667  inline std::pair<uint32,uint32> hyperbolic_args(unsigned int abs, int &exp, unsigned int n = 32)
1668  {
1669  uint32 mx = detail::multiply64(static_cast<uint32>((abs&0x3FF)+((abs>0x3FF)<<10))<<21, 0xB8AA3B29), my;
1670  int e = (abs>>10) + (abs<=0x3FF);
1671  if(e < 14)
1672  {
1673  exp = 0;
1674  mx >>= 14 - e;
1675  }
1676  else
1677  {
1678  exp = mx >> (45-e);
1679  mx = (mx<<(e-14)) & 0x7FFFFFFF;
1680  }
1681  mx = exp2(mx, n);
1682  int d = exp << 1, s;
1683  if(mx > 0x80000000)
1684  {
1685  my = divide64(0x80000000, mx, s);
1686  my |= s;
1687  ++d;
1688  }
1689  else
1690  my = mx;
1691  return std::make_pair(mx, (d<31) ? ((my>>d)|((my&((static_cast<uint32>(1)<<d)-1))!=0)) : 1);
1692  }
1693 
1705  template<std::float_round_style R> unsigned int exp2_post(uint32 m, int exp, bool esign, unsigned int sign = 0, unsigned int n = 32)
1706  {
1707  if(esign)
1708  {
1709  exp = -exp - (m!=0);
1710  if(exp < -25)
1711  return underflow<R>(sign);
1712  else if(exp == -25)
1713  return rounded<R,false>(sign, 1, m!=0);
1714  }
1715  else if(exp > 15)
1716  return overflow<R>(sign);
1717  if(!m)
1718  return sign | (((exp+=15)>0) ? (exp<<10) : check_underflow(0x200>>-exp));
1719  m = exp2(m, n);
1720  int s = 0;
1721  if(esign)
1722  m = divide64(0x80000000, m, s);
1723  return fixed2half<R,31,false,false,true>(m, exp+14, sign, s);
1724  }
1725 
1737  template<std::float_round_style R,uint32 L> unsigned int log2_post(uint32 m, int ilog, int exp, unsigned int sign = 0)
1738  {
1739  uint32 msign = sign_mask(ilog);
1740  m = (((static_cast<uint32>(ilog)<<27)+(m>>4))^msign) - msign;
1741  if(!m)
1742  return 0;
1743  for(; m<0x80000000; m<<=1,--exp) ;
1744  int i = m >= L, s;
1745  exp += i;
1746  m >>= 1 + i;
1747  sign ^= msign & 0x8000;
1748  if(exp < -11)
1749  return underflow<R>(sign);
1750  m = divide64(m, L, s);
1751  return fixed2half<R,30,false,false,true>(m, exp, sign, 1);
1752  }
1753 
1762  template<std::float_round_style R> unsigned int hypot_post(uint32 r, int exp)
1763  {
1764  int i = r >> 31;
1765  if((exp+=i) > 46)
1766  return overflow<R>();
1767  if(exp < -34)
1768  return underflow<R>();
1769  r = (r>>i) | (r&i);
1770  uint32 m = sqrt<30>(r, exp+=15);
1771  return fixed2half<R,15,false,false,false>(m, exp-1, 0, r!=0);
1772  }
1773 
1784  template<std::float_round_style R> unsigned int tangent_post(uint32 my, uint32 mx, int exp, unsigned int sign = 0)
1785  {
1786  int i = my >= mx, s;
1787  exp += i;
1788  if(exp > 29)
1789  return overflow<R>(sign);
1790  if(exp < -11)
1791  return underflow<R>(sign);
1792  uint32 m = divide64(my>>(i+1), mx, s);
1793  return fixed2half<R,30,false,false,true>(m, exp, sign, s);
1794  }
1795 
1805  template<std::float_round_style R,bool S> unsigned int area(unsigned int arg)
1806  {
1807  int abs = arg & 0x7FFF, expx = (abs>>10) + (abs<=0x3FF) - 15, expy = -15, ilog, i;
1808  uint32 mx = static_cast<uint32>((abs&0x3FF)|((abs>0x3FF)<<10)) << 20, my, r;
1809  for(; abs<0x400; abs<<=1,--expy) ;
1810  expy += abs >> 10;
1811  r = ((abs&0x3FF)|0x400) << 5;
1812  r *= r;
1813  i = r >> 31;
1814  expy = 2*expy + i;
1815  r >>= i;
1816  if(S)
1817  {
1818  if(expy < 0)
1819  {
1820  r = 0x40000000 + ((expy>-30) ? ((r>>-expy)|((r&((static_cast<uint32>(1)<<-expy)-1))!=0)) : 1);
1821  expy = 0;
1822  }
1823  else
1824  {
1825  r += 0x40000000 >> expy;
1826  i = r >> 31;
1827  r = (r>>i) | (r&i);
1828  expy += i;
1829  }
1830  }
1831  else
1832  {
1833  r -= 0x40000000 >> expy;
1834  for(; r<0x40000000; r<<=1,--expy) ;
1835  }
1836  my = sqrt<30>(r, expy);
1837  my = (my<<15) + (r<<14)/my;
1838  if(S)
1839  {
1840  mx >>= expy - expx;
1841  ilog = expy;
1842  }
1843  else
1844  {
1845  my >>= expx - expy;
1846  ilog = expx;
1847  }
1848  my += mx;
1849  i = my >> 31;
1850  static const int G = S && (R==std::round_to_nearest);
1851  return log2_post<R,0xB8AA3B2A>(log2(my>>i, 26+S+G)+(G<<3), ilog+i, 17, arg&(static_cast<unsigned>(S)<<15));
1852  }
1853 
1855  struct f31
1856  {
1860  HALF_CONSTEXPR f31(uint32 mant, int e) : m(mant), exp(e) {}
1861 
1864  f31(unsigned int abs) : exp(-15)
1865  {
1866  for(; abs<0x400; abs<<=1,--exp) ;
1867  m = static_cast<uint32>((abs&0x3FF)|0x400) << 21;
1868  exp += (abs>>10);
1869  }
1870 
1875  friend f31 operator+(f31 a, f31 b)
1876  {
1877  if(b.exp > a.exp)
1878  std::swap(a, b);
1879  int d = a.exp - b.exp;
1880  uint32 m = a.m + ((d<32) ? (b.m>>d) : 0);
1881  int i = (m&0xFFFFFFFF) < a.m;
1882  return f31(((m+i)>>i)|0x80000000, a.exp+i);
1883  }
1884 
1889  friend f31 operator-(f31 a, f31 b)
1890  {
1891  int d = a.exp - b.exp, exp = a.exp;
1892  uint32 m = a.m - ((d<32) ? (b.m>>d) : 0);
1893  if(!m)
1894  return f31(0, -32);
1895  for(; m<0x80000000; m<<=1,--exp) ;
1896  return f31(m, exp);
1897  }
1898 
1903  friend f31 operator*(f31 a, f31 b)
1904  {
1905  uint32 m = multiply64(a.m, b.m);
1906  int i = m >> 31;
1907  return f31(m<<(1-i), a.exp + b.exp + i);
1908  }
1909 
1914  friend f31 operator/(f31 a, f31 b)
1915  {
1916  int i = a.m >= b.m, s;
1917  uint32 m = divide64((a.m+i)>>i, b.m, s);
1918  return f31(m, a.exp - b.exp + i - 1);
1919  }
1920 
1922  int exp;
1923  };
1924 
1935  template<std::float_round_style R,bool C> unsigned int erf(unsigned int arg)
1936  {
1937  unsigned int abs = arg & 0x7FFF, sign = arg & 0x8000;
1938  f31 x(abs), x2 = x * x * f31(0xB8AA3B29, 0), t = f31(0x80000000, 0) / (f31(0x80000000, 0)+f31(0xA7BA054A, -2)*x), t2 = t * t;
1939  f31 e = ((f31(0x87DC2213, 0)*t2+f31(0xB5F0E2AE, 0))*t2+f31(0x82790637, -2)-(f31(0xBA00E2B8, 0)*t2+f31(0x91A98E62, -2))*t) * t /
1940  ((x2.exp<0) ? f31(exp2((x2.exp>-32) ? (x2.m>>-x2.exp) : 0, 30), 0) : f31(exp2((x2.m<<x2.exp)&0x7FFFFFFF, 22), x2.m>>(31-x2.exp)));
1941  return (!C || sign) ? fixed2half<R,31,false,true,true>(0x80000000-(e.m>>(C-e.exp)), 14+C, sign&(C-1U)) :
1942  (e.exp<-25) ? underflow<R>() : fixed2half<R,30,false,false,true>(e.m>>1, e.exp+14, 0, e.m&1);
1943  }
1944 
1954  template<std::float_round_style R,bool L> unsigned int gamma(unsigned int arg)
1955  {
1956 /* static const double p[] ={ 2.50662827563479526904, 225.525584619175212544, -268.295973841304927459, 80.9030806934622512966, -5.00757863970517583837, 0.0114684895434781459556 };
1957  double t = arg + 4.65, s = p[0];
1958  for(unsigned int i=0; i<5; ++i)
1959  s += p[i+1] / (arg+i);
1960  return std::log(s) + (arg-0.5)*std::log(t) - t;
1961 */ static const f31 pi(0xC90FDAA2, 1), lbe(0xB8AA3B29, 0);
1962  unsigned int abs = arg & 0x7FFF, sign = arg & 0x8000;
1963  bool bsign = sign != 0;
1964  f31 z(abs), x = sign ? (z+f31(0x80000000, 0)) : z, t = x + f31(0x94CCCCCD, 2), s =
1965  f31(0xA06C9901, 1) + f31(0xBBE654E2, -7)/(x+f31(0x80000000, 2)) + f31(0xA1CE6098, 6)/(x+f31(0x80000000, 1))
1966  + f31(0xE1868CB7, 7)/x - f31(0x8625E279, 8)/(x+f31(0x80000000, 0)) - f31(0xA03E158F, 2)/(x+f31(0xC0000000, 1));
1967  int i = (s.exp>=2) + (s.exp>=4) + (s.exp>=8) + (s.exp>=16);
1968  s = f31((static_cast<uint32>(s.exp)<<(31-i))+(log2(s.m>>1, 28)>>i), i) / lbe;
1969  if(x.exp != -1 || x.m != 0x80000000)
1970  {
1971  i = (t.exp>=2) + (t.exp>=4) + (t.exp>=8);
1972  f31 l = f31((static_cast<uint32>(t.exp)<<(31-i))+(log2(t.m>>1, 30)>>i), i) / lbe;
1973  s = (x.exp<-1) ? (s-(f31(0x80000000, -1)-x)*l) : (s+(x-f31(0x80000000, -1))*l);
1974  }
1975  s = x.exp ? (s-t) : (t-s);
1976  if(bsign)
1977  {
1978  if(z.exp >= 0)
1979  {
1980  sign &= (L|((z.m>>(31-z.exp))&1)) - 1;
1981  for(z=f31((z.m<<(1+z.exp))&0xFFFFFFFF, -1); z.m<0x80000000; z.m<<=1,--z.exp) ;
1982  }
1983  if(z.exp == -1)
1984  z = f31(0x80000000, 0) - z;
1985  if(z.exp < -1)
1986  {
1987  z = z * pi;
1988  z.m = sincos(z.m>>(1-z.exp), 30).first;
1989  for(z.exp=1; z.m<0x80000000; z.m<<=1,--z.exp) ;
1990  }
1991  else
1992  z = f31(0x80000000, 0);
1993  }
1994  if(L)
1995  {
1996  if(bsign)
1997  {
1998  f31 l(0x92868247, 0);
1999  if(z.exp < 0)
2000  {
2001  uint32 m = log2((z.m+1)>>1, 27);
2002  z = f31(-((static_cast<uint32>(z.exp)<<26)+(m>>5)), 5);
2003  for(; z.m<0x80000000; z.m<<=1,--z.exp) ;
2004  l = l + z / lbe;
2005  }
2006  sign = static_cast<unsigned>(x.exp&&(l.exp<s.exp||(l.exp==s.exp&&l.m<s.m))) << 15;
2007  s = sign ? (s-l) : x.exp ? (l-s) : (l+s);
2008  }
2009  else
2010  {
2011  sign = static_cast<unsigned>(x.exp==0) << 15;
2012  if(s.exp < -24)
2013  return underflow<R>(sign);
2014  if(s.exp > 15)
2015  return overflow<R>(sign);
2016  }
2017  }
2018  else
2019  {
2020  s = s * lbe;
2021  uint32 m;
2022  if(s.exp < 0)
2023  {
2024  m = s.m >> -s.exp;
2025  s.exp = 0;
2026  }
2027  else
2028  {
2029  m = (s.m<<s.exp) & 0x7FFFFFFF;
2030  s.exp = (s.m>>(31-s.exp));
2031  }
2032  s.m = exp2(m, 27);
2033  if(!x.exp)
2034  s = f31(0x80000000, 0) / s;
2035  if(bsign)
2036  {
2037  if(z.exp < 0)
2038  s = s * z;
2039  s = pi / s;
2040  if(s.exp < -24)
2041  return underflow<R>(sign);
2042  }
2043  else if(z.exp > 0 && !(z.m&((1<<(31-z.exp))-1)))
2044  return ((s.exp+14)<<10) + (s.m>>21);
2045  if(s.exp > 15)
2046  return overflow<R>(sign);
2047  }
2048  return fixed2half<R,31,false,false,true>(s.m, s.exp+14, sign);
2049  }
2051 
2052  template<typename,typename,std::float_round_style> struct half_caster;
2053  }
2054 
2072  class half
2073  {
2074  public:
2077 
2082 
2086  explicit half(float rhs) : data_(static_cast<detail::uint16>(detail::float2half<round_style>(rhs))) {}
2087 
2090  operator float() const { return detail::half2float<float>(data_); }
2091 
2096  half& operator=(float rhs) { data_ = static_cast<detail::uint16>(detail::float2half<round_style>(rhs)); return *this; }
2097 
2101 
2107  half& operator+=(half rhs) { return *this = *this + rhs; }
2108 
2114  half& operator-=(half rhs) { return *this = *this - rhs; }
2115 
2121  half& operator*=(half rhs) { return *this = *this * rhs; }
2122 
2128  half& operator/=(half rhs) { return *this = *this / rhs; }
2129 
2134  half& operator+=(float rhs) { return *this = *this + rhs; }
2135 
2140  half& operator-=(float rhs) { return *this = *this - rhs; }
2141 
2146  half& operator*=(float rhs) { return *this = *this * rhs; }
2147 
2152  half& operator/=(float rhs) { return *this = *this / rhs; }
2153 
2157 
2161  half& operator++() { return *this = *this + half(detail::binary, 0x3C00); }
2162 
2166  half& operator--() { return *this = *this + half(detail::binary, 0xBC00); }
2167 
2171  half operator++(int) { half out(*this); ++*this; return out; }
2172 
2176  half operator--(int) { half out(*this); --*this; return out; }
2178 
2179  private:
2181  static const std::float_round_style round_style = (std::float_round_style)(HALF_ROUND_STYLE);
2182 
2185  HALF_CONSTEXPR half(detail::binary_t, unsigned int bits) HALF_NOEXCEPT : data_(static_cast<detail::uint16>(bits)) {}
2186 
2188  detail::uint16 data_;
2189 
2190  #ifndef HALF_DOXYGEN_ONLY
2191  friend HALF_CONSTEXPR_NOERR bool operator==(half, half);
2192  friend HALF_CONSTEXPR_NOERR bool operator!=(half, half);
2193  friend HALF_CONSTEXPR_NOERR bool operator<(half, half);
2194  friend HALF_CONSTEXPR_NOERR bool operator>(half, half);
2195  friend HALF_CONSTEXPR_NOERR bool operator<=(half, half);
2196  friend HALF_CONSTEXPR_NOERR bool operator>=(half, half);
2198  friend half operator+(half, half);
2199  friend half operator-(half, half);
2200  friend half operator*(half, half);
2201  friend half operator/(half, half);
2202  template<typename charT,typename traits> friend std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT,traits>&, half);
2203  template<typename charT,typename traits> friend std::basic_istream<charT,traits>& operator>>(std::basic_istream<charT,traits>&, half&);
2204  friend HALF_CONSTEXPR half fabs(half);
2205  friend half fmod(half, half);
2206  friend half remainder(half, half);
2207  friend half remquo(half, half, int*);
2208  friend half fma(half, half, half);
2211  friend half fdim(half, half);
2212  friend half nanh(const char*);
2213  friend half exp(half);
2214  friend half exp2(half);
2215  friend half expm1(half);
2216  friend half log(half);
2217  friend half log10(half);
2218  friend half log2(half);
2219  friend half log1p(half);
2220  friend half sqrt(half);
2221  friend half rsqrt(half);
2222  friend half cbrt(half);
2223  friend half hypot(half, half);
2224  friend half hypot(half, half, half);
2225  friend half pow(half, half);
2226  friend void sincos(half, half*, half*);
2227  friend half sin(half);
2228  friend half cos(half);
2229  friend half tan(half);
2230  friend half asin(half);
2231  friend half acos(half);
2232  friend half atan(half);
2233  friend half atan2(half, half);
2234  friend half sinh(half);
2235  friend half cosh(half);
2236  friend half tanh(half);
2237  friend half asinh(half);
2238  friend half acosh(half);
2239  friend half atanh(half);
2240  friend half erf(half);
2241  friend half erfc(half);
2242  friend half lgamma(half);
2243  friend half tgamma(half);
2244  friend half ceil(half);
2245  friend half floor(half);
2246  friend half trunc(half);
2247  friend half round(half);
2248  friend long lround(half);
2249  friend half rint(half);
2250  friend long lrint(half);
2251  friend half nearbyint(half);
2252  #ifdef HALF_ENABLE_CPP11_LONG_LONG
2253  friend long long llround(half);
2254  friend long long llrint(half);
2255  #endif
2256  friend half frexp(half, int*);
2257  friend half scalbln(half, long);
2258  friend half modf(half, half*);
2259  friend int ilogb(half);
2260  friend half logb(half);
2261  friend half nextafter(half, half);
2262  friend half nexttoward(half, long double);
2264  friend HALF_CONSTEXPR int fpclassify(half);
2265  friend HALF_CONSTEXPR bool isfinite(half);
2266  friend HALF_CONSTEXPR bool isinf(half);
2267  friend HALF_CONSTEXPR bool isnan(half);
2268  friend HALF_CONSTEXPR bool isnormal(half);
2269  friend HALF_CONSTEXPR bool signbit(half);
2270  friend HALF_CONSTEXPR bool isgreater(half, half);
2271  friend HALF_CONSTEXPR bool isgreaterequal(half, half);
2272  friend HALF_CONSTEXPR bool isless(half, half);
2273  friend HALF_CONSTEXPR bool islessequal(half, half);
2274  friend HALF_CONSTEXPR bool islessgreater(half, half);
2275  template<typename,typename,std::float_round_style> friend struct detail::half_caster;
2276  friend class std::numeric_limits<half>;
2277  #if HALF_ENABLE_CPP11_HASH
2278  friend struct std::hash<half>;
2279  #endif
2280  #if HALF_ENABLE_CPP11_USER_LITERALS
2281  friend half literal::operator "" _h(long double);
2282  #endif
2283  #endif
2284  };
2285 
2286 #if HALF_ENABLE_CPP11_USER_LITERALS
2287  namespace literal
2288  {
2296  inline half operator "" _h(long double value) { return half(detail::binary, detail::float2half<half::round_style>(value)); }
2297  }
2298 #endif
2299 
2300  namespace detail
2301  {
2308  template<typename T,typename U,std::float_round_style R=(std::float_round_style)(HALF_ROUND_STYLE)> struct half_caster {};
2309  template<typename U,std::float_round_style R> struct half_caster<half,U,R>
2310  {
2311  #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
2312  static_assert(std::is_arithmetic<U>::value, "half_cast from non-arithmetic type unsupported");
2313  #endif
2314 
2315  static half cast(U arg) { return cast_impl(arg, is_float<U>()); };
2316 
2317  private:
2318  static half cast_impl(U arg, true_type) { return half(binary, float2half<R>(arg)); }
2319  static half cast_impl(U arg, false_type) { return half(binary, int2half<R>(arg)); }
2320  };
2321  template<typename T,std::float_round_style R> struct half_caster<T,half,R>
2322  {
2323  #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
2324  static_assert(std::is_arithmetic<T>::value, "half_cast to non-arithmetic type unsupported");
2325  #endif
2326 
2327  static T cast(half arg) { return cast_impl(arg, is_float<T>()); }
2328 
2329  private:
2330  static T cast_impl(half arg, true_type) { return half2float<T>(arg.data_); }
2331  static T cast_impl(half arg, false_type) { return half2int<R,true,true,T>(arg.data_); }
2332  };
2333  template<std::float_round_style R> struct half_caster<half,half,R>
2334  {
2335  static half cast(half arg) { return arg; }
2336  };
2337  }
2338 }
2339 
2341 namespace std
2342 {
2345  template<> class numeric_limits<half_float::half>
2346  {
2347  public:
2349  static HALF_CONSTEXPR_CONST bool is_specialized = true;
2350 
2352  static HALF_CONSTEXPR_CONST bool is_signed = true;
2353 
2355  static HALF_CONSTEXPR_CONST bool is_integer = false;
2356 
2358  static HALF_CONSTEXPR_CONST bool is_exact = false;
2359 
2361  static HALF_CONSTEXPR_CONST bool is_modulo = false;
2362 
2364  static HALF_CONSTEXPR_CONST bool is_bounded = true;
2365 
2367  static HALF_CONSTEXPR_CONST bool is_iec559 = true;
2368 
2370  static HALF_CONSTEXPR_CONST bool has_infinity = true;
2371 
2373  static HALF_CONSTEXPR_CONST bool has_quiet_NaN = true;
2374 
2376  static HALF_CONSTEXPR_CONST bool has_signaling_NaN = true;
2377 
2379  static HALF_CONSTEXPR_CONST float_denorm_style has_denorm = denorm_present;
2380 
2382  static HALF_CONSTEXPR_CONST bool has_denorm_loss = false;
2383 
2384  #if HALF_ERRHANDLING_THROWS
2385  static HALF_CONSTEXPR_CONST bool traps = true;
2386  #else
2387  static HALF_CONSTEXPR_CONST bool traps = false;
2389  #endif
2390 
2392  static HALF_CONSTEXPR_CONST bool tinyness_before = false;
2393 
2395  static HALF_CONSTEXPR_CONST float_round_style round_style = half_float::half::round_style;
2396 
2398  static HALF_CONSTEXPR_CONST int digits = 11;
2399 
2401  static HALF_CONSTEXPR_CONST int digits10 = 3;
2402 
2404  static HALF_CONSTEXPR_CONST int max_digits10 = 5;
2405 
2407  static HALF_CONSTEXPR_CONST int radix = 2;
2408 
2410  static HALF_CONSTEXPR_CONST int min_exponent = -13;
2411 
2413  static HALF_CONSTEXPR_CONST int min_exponent10 = -4;
2414 
2416  static HALF_CONSTEXPR_CONST int max_exponent = 16;
2417 
2419  static HALF_CONSTEXPR_CONST int max_exponent10 = 4;
2420 
2423 
2426 
2429 
2432 
2435  { return half_float::half(half_float::detail::binary, (round_style==std::round_to_nearest) ? 0x3800 : 0x3C00); }
2436 
2439 
2442 
2445 
2448  };
2449 
2450 #if HALF_ENABLE_CPP11_HASH
2451  template<> struct hash<half_float::half>
2456  {
2458  typedef half_float::half argument_type;
2459 
2461  typedef size_t result_type;
2462 
2466  result_type operator()(argument_type arg) const { return hash<half_float::detail::uint16>()(arg.data_&-static_cast<unsigned>(arg.data_!=0x8000)); }
2467  };
2468 #endif
2469 }
2470 
2471 namespace half_float
2472 {
2476 
2484  {
2485  return !detail::compsignal(x.data_, y.data_) && (x.data_==y.data_ || !((x.data_|y.data_)&0x7FFF));
2486  }
2487 
2495  {
2496  return detail::compsignal(x.data_, y.data_) || (x.data_!=y.data_ && ((x.data_|y.data_)&0x7FFF));
2497  }
2498 
2506  {
2507  return !detail::compsignal(x.data_, y.data_) &&
2508  ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) < ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15));
2509  }
2510 
2518  {
2519  return !detail::compsignal(x.data_, y.data_) &&
2520  ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) > ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15));
2521  }
2522 
2530  {
2531  return !detail::compsignal(x.data_, y.data_) &&
2532  ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) <= ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15));
2533  }
2534 
2542  {
2543  return !detail::compsignal(x.data_, y.data_) &&
2544  ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) >= ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15));
2545  }
2546 
2551 
2555  inline HALF_CONSTEXPR half operator+(half arg) { return arg; }
2556 
2560  inline HALF_CONSTEXPR half operator-(half arg) { return half(detail::binary, arg.data_^0x8000); }
2561 
2569  inline half operator+(half x, half y)
2570  {
2571  #ifdef HALF_ARITHMETIC_TYPE
2572  return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_)+detail::half2float<detail::internal_t>(y.data_)));
2573  #else
2574  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF;
2575  bool sub = ((x.data_^y.data_)&0x8000) != 0;
2576  if(absx >= 0x7C00 || absy >= 0x7C00)
2577  return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) : (absy!=0x7C00) ? x.data_ :
2578  (sub && absx==0x7C00) ? detail::invalid() : y.data_);
2579  if(!absx)
2580  return absy ? y : half(detail::binary, (half::round_style==std::round_toward_neg_infinity) ? (x.data_|y.data_) : (x.data_&y.data_));
2581  if(!absy)
2582  return x;
2583  unsigned int sign = ((sub && absy>absx) ? y.data_ : x.data_) & 0x8000;
2584  if(absy > absx)
2585  std::swap(absx, absy);
2586  int exp = (absx>>10) + (absx<=0x3FF), d = exp - (absy>>10) - (absy<=0x3FF), mx = ((absx&0x3FF)|((absx>0x3FF)<<10)) << 3, my;
2587  if(d < 13)
2588  {
2589  my = ((absy&0x3FF)|((absy>0x3FF)<<10)) << 3;
2590  my = (my>>d) | ((my&((1<<d)-1))!=0);
2591  }
2592  else
2593  my = 1;
2594  if(sub)
2595  {
2596  if(!(mx-=my))
2597  return half(detail::binary, static_cast<unsigned>(half::round_style==std::round_toward_neg_infinity)<<15);
2598  for(; mx<0x2000 && exp>1; mx<<=1,--exp) ;
2599  }
2600  else
2601  {
2602  mx += my;
2603  int i = mx >> 14;
2604  if((exp+=i) > 30)
2605  return half(detail::binary, detail::overflow<half::round_style>(sign));
2606  mx = (mx>>i) | (mx&i);
2607  }
2608  return half(detail::binary, detail::rounded<half::round_style,false>(sign+((exp-1)<<10)+(mx>>3), (mx>>2)&1, (mx&0x3)!=0));
2609  #endif
2610  }
2611 
2619  inline half operator-(half x, half y)
2620  {
2621  #ifdef HALF_ARITHMETIC_TYPE
2622  return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_)-detail::half2float<detail::internal_t>(y.data_)));
2623  #else
2624  return x + -y;
2625  #endif
2626  }
2627 
2635  inline half operator*(half x, half y)
2636  {
2637  #ifdef HALF_ARITHMETIC_TYPE
2638  return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_)*detail::half2float<detail::internal_t>(y.data_)));
2639  #else
2640  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -16;
2641  unsigned int sign = (x.data_^y.data_) & 0x8000;
2642  if(absx >= 0x7C00 || absy >= 0x7C00)
2643  return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2644  ((absx==0x7C00 && !absy)||(absy==0x7C00 && !absx)) ? detail::invalid() : (sign|0x7C00));
2645  if(!absx || !absy)
2646  return half(detail::binary, sign);
2647  for(; absx<0x400; absx<<=1,--exp) ;
2648  for(; absy<0x400; absy<<=1,--exp) ;
2649  detail::uint32 m = static_cast<detail::uint32>((absx&0x3FF)|0x400) * static_cast<detail::uint32>((absy&0x3FF)|0x400);
2650  int i = m >> 21, s = m & i;
2651  exp += (absx>>10) + (absy>>10) + i;
2652  if(exp > 29)
2653  return half(detail::binary, detail::overflow<half::round_style>(sign));
2654  else if(exp < -11)
2655  return half(detail::binary, detail::underflow<half::round_style>(sign));
2656  return half(detail::binary, detail::fixed2half<half::round_style,20,false,false,false>(m>>i, exp, sign, s));
2657  #endif
2658  }
2659 
2668  inline half operator/(half x, half y)
2669  {
2670  #ifdef HALF_ARITHMETIC_TYPE
2671  return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_)/detail::half2float<detail::internal_t>(y.data_)));
2672  #else
2673  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = 14;
2674  unsigned int sign = (x.data_^y.data_) & 0x8000;
2675  if(absx >= 0x7C00 || absy >= 0x7C00)
2676  return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2677  (absx==absy) ? detail::invalid() : (sign|((absx==0x7C00) ? 0x7C00 : 0)));
2678  if(!absx)
2679  return half(detail::binary, absy ? sign : detail::invalid());
2680  if(!absy)
2681  return half(detail::binary, detail::pole(sign));
2682  for(; absx<0x400; absx<<=1,--exp) ;
2683  for(; absy<0x400; absy<<=1,++exp) ;
2684  detail::uint32 mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400;
2685  int i = mx < my;
2686  exp += (absx>>10) - (absy>>10) - i;
2687  if(exp > 29)
2688  return half(detail::binary, detail::overflow<half::round_style>(sign));
2689  else if(exp < -11)
2690  return half(detail::binary, detail::underflow<half::round_style>(sign));
2691  mx <<= 12 + i;
2692  my <<= 1;
2693  return half(detail::binary, detail::fixed2half<half::round_style,11,false,false,false>(mx/my, exp, sign, mx%my!=0));
2694  #endif
2695  }
2696 
2701 
2707  template<typename charT,typename traits> std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT,traits> &out, half arg)
2708  {
2709  #ifdef HALF_ARITHMETIC_TYPE
2710  return out << detail::half2float<detail::internal_t>(arg.data_);
2711  #else
2712  return out << detail::half2float<float>(arg.data_);
2713  #endif
2714  }
2715 
2725  template<typename charT,typename traits> std::basic_istream<charT,traits>& operator>>(std::basic_istream<charT,traits> &in, half &arg)
2726  {
2727  #ifdef HALF_ARITHMETIC_TYPE
2728  detail::internal_t f;
2729  #else
2730  double f;
2731  #endif
2732  if(in >> f)
2733  arg.data_ = detail::float2half<half::round_style>(f);
2734  return in;
2735  }
2736 
2741 
2746  inline HALF_CONSTEXPR half fabs(half arg) { return half(detail::binary, arg.data_&0x7FFF); }
2747 
2752  inline HALF_CONSTEXPR half abs(half arg) { return fabs(arg); }
2753 
2760  inline half fmod(half x, half y)
2761  {
2762  unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000;
2763  if(absx >= 0x7C00 || absy >= 0x7C00)
2764  return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2765  (absx==0x7C00) ? detail::invalid() : x.data_);
2766  if(!absy)
2767  return half(detail::binary, detail::invalid());
2768  if(!absx)
2769  return x;
2770  if(absx == absy)
2771  return half(detail::binary, sign);
2772  return half(detail::binary, sign|detail::mod<false,false>(absx, absy));
2773  }
2774 
2781  inline half remainder(half x, half y)
2782  {
2783  unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000;
2784  if(absx >= 0x7C00 || absy >= 0x7C00)
2785  return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2786  (absx==0x7C00) ? detail::invalid() : x.data_);
2787  if(!absy)
2788  return half(detail::binary, detail::invalid());
2789  if(absx == absy)
2790  return half(detail::binary, sign);
2791  return half(detail::binary, sign^detail::mod<false,true>(absx, absy));
2792  }
2793 
2801  inline half remquo(half x, half y, int *quo)
2802  {
2803  unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, value = x.data_ & 0x8000;
2804  if(absx >= 0x7C00 || absy >= 0x7C00)
2805  return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2806  (absx==0x7C00) ? detail::invalid() : (*quo = 0, x.data_));
2807  if(!absy)
2808  return half(detail::binary, detail::invalid());
2809  bool qsign = ((value^y.data_)&0x8000) != 0;
2810  int q = 1;
2811  if(absx != absy)
2812  value ^= detail::mod<true, true>(absx, absy, &q);
2813  return *quo = qsign ? -q : q, half(detail::binary, value);
2814  }
2815 
2826  inline half fma(half x, half y, half z)
2827  {
2828  #ifdef HALF_ARITHMETIC_TYPE
2829  detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_), fz = detail::half2float<detail::internal_t>(z.data_);
2830  #if HALF_ENABLE_CPP11_CMATH && FP_FAST_FMA
2831  return half(detail::binary, detail::float2half<half::round_style>(std::fma(fx, fy, fz)));
2832  #else
2833  return half(detail::binary, detail::float2half<half::round_style>(fx*fy+fz));
2834  #endif
2835  #else
2836  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, exp = -15;
2837  unsigned int sign = (x.data_^y.data_) & 0x8000;
2838  bool sub = ((sign^z.data_)&0x8000) != 0;
2839  if(absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
2840  return (absx>0x7C00 || absy>0x7C00 || absz>0x7C00) ? half(detail::binary, detail::signal(x.data_, y.data_, z.data_)) :
2841  (absx==0x7C00) ? half(detail::binary, (!absy || (sub && absz==0x7C00)) ? detail::invalid() : (sign|0x7C00)) :
2842  (absy==0x7C00) ? half(detail::binary, (!absx || (sub && absz==0x7C00)) ? detail::invalid() : (sign|0x7C00)) : z;
2843  if(!absx || !absy)
2844  return absz ? z : half(detail::binary, (half::round_style==std::round_toward_neg_infinity) ? (z.data_|sign) : (z.data_&sign));
2845  for(; absx<0x400; absx<<=1,--exp) ;
2846  for(; absy<0x400; absy<<=1,--exp) ;
2847  detail::uint32 m = static_cast<detail::uint32>((absx&0x3FF)|0x400) * static_cast<detail::uint32>((absy&0x3FF)|0x400);
2848  int i = m >> 21;
2849  exp += (absx>>10) + (absy>>10) + i;
2850  m <<= 3 - i;
2851  if(absz)
2852  {
2853  int expz = 0;
2854  for(; absz<0x400; absz<<=1,--expz) ;
2855  expz += absz >> 10;
2856  detail::uint32 mz = static_cast<detail::uint32>((absz&0x3FF)|0x400) << 13;
2857  if(expz > exp || (expz == exp && mz > m))
2858  {
2859  std::swap(m, mz);
2860  std::swap(exp, expz);
2861  if(sub)
2862  sign = z.data_ & 0x8000;
2863  }
2864  int d = exp - expz;
2865  mz = (d<23) ? ((mz>>d)|((mz&((static_cast<detail::uint32>(1)<<d)-1))!=0)) : 1;
2866  if(sub)
2867  {
2868  m = m - mz;
2869  if(!m)
2870  return half(detail::binary, static_cast<unsigned>(half::round_style==std::round_toward_neg_infinity)<<15);
2871  for(; m<0x800000; m<<=1,--exp) ;
2872  }
2873  else
2874  {
2875  m += mz;
2876  i = m >> 24;
2877  m = (m>>i) | (m&i);
2878  exp += i;
2879  }
2880  }
2881  if(exp > 30)
2882  return half(detail::binary, detail::overflow<half::round_style>(sign));
2883  else if(exp < -10)
2884  return half(detail::binary, detail::underflow<half::round_style>(sign));
2885  return half(detail::binary, detail::fixed2half<half::round_style,23,false,false,false>(m, exp-1, sign));
2886  #endif
2887  }
2888 
2896  {
2897  return half(detail::binary, (!isnan(y) && (isnan(x) || (x.data_^(0x8000|(0x8000-(x.data_>>15)))) <
2898  (y.data_^(0x8000|(0x8000-(y.data_>>15)))))) ? detail::select(y.data_, x.data_) : detail::select(x.data_, y.data_));
2899  }
2900 
2908  {
2909  return half(detail::binary, (!isnan(y) && (isnan(x) || (x.data_^(0x8000|(0x8000-(x.data_>>15)))) >
2910  (y.data_^(0x8000|(0x8000-(y.data_>>15)))))) ? detail::select(y.data_, x.data_) : detail::select(x.data_, y.data_));
2911  }
2912 
2921  inline half fdim(half x, half y)
2922  {
2923  if(isnan(x) || isnan(y))
2924  return half(detail::binary, detail::signal(x.data_, y.data_));
2925  return (x.data_^(0x8000|(0x8000-(x.data_>>15)))) <= (y.data_^(0x8000|(0x8000-(y.data_>>15)))) ? half(detail::binary, 0) : (x-y);
2926  }
2927 
2932  inline half nanh(const char *arg)
2933  {
2934  unsigned int value = 0x7FFF;
2935  while(*arg)
2936  value ^= static_cast<unsigned>(*arg++) & 0xFF;
2937  return half(detail::binary, value);
2938  }
2939 
2944 
2953  inline half exp(half arg)
2954  {
2955  #ifdef HALF_ARITHMETIC_TYPE
2956  return half(detail::binary, detail::float2half<half::round_style>(std::exp(detail::half2float<detail::internal_t>(arg.data_))));
2957  #else
2958  int abs = arg.data_ & 0x7FFF, e = (abs>>10) + (abs<=0x3FF), exp;
2959  if(!abs)
2960  return half(detail::binary, 0x3C00);
2961  if(abs >= 0x7C00)
2962  return half(detail::binary, (abs==0x7C00) ? (0x7C00&((arg.data_>>15)-1U)) : detail::signal(arg.data_));
2963  if(abs >= 0x4C80)
2964  return half(detail::binary, (arg.data_&0x8000) ? detail::underflow<half::round_style>() : detail::overflow<half::round_style>());
2965  detail::uint32 m = detail::multiply64(static_cast<detail::uint32>((abs&0x3FF)+((abs>0x3FF)<<10))<<21, 0xB8AA3B29);
2966  if(e < 14)
2967  {
2968  exp = 0;
2969  m >>= 14 - e;
2970  }
2971  else
2972  {
2973  exp = m >> (45-e);
2974  m = (m<<(e-14)) & 0x7FFFFFFF;
2975  }
2976  return half(detail::binary, detail::exp2_post<half::round_style>(m, exp, (arg.data_&0x8000)!=0, 0, 26));
2977  #endif
2978  }
2979 
2988  inline half exp2(half arg)
2989  {
2990  #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
2991  return half(detail::binary, detail::float2half<half::round_style>(std::exp2(detail::half2float<detail::internal_t>(arg.data_))));
2992  #else
2993  int abs = arg.data_ & 0x7FFF, e = (abs>>10) + (abs<=0x3FF), exp = (abs&0x3FF) + ((abs>0x3FF)<<10);
2994  if(!abs)
2995  return half(detail::binary, 0x3C00);
2996  if(abs >= 0x7C00)
2997  return half(detail::binary, (abs==0x7C00) ? (0x7C00&((arg.data_>>15)-1U)) : detail::signal(arg.data_));
2998  if(abs >= 0x4E40)
2999  return half(detail::binary, (arg.data_&0x8000) ? detail::underflow<half::round_style>() : detail::overflow<half::round_style>());
3000  return half(detail::binary, detail::exp2_post<half::round_style>(
3001  (static_cast<detail::uint32>(exp)<<(6+e))&0x7FFFFFFF, exp>>(25-e), (arg.data_&0x8000)!=0, 0, 28));
3002  #endif
3003  }
3004 
3014  inline half expm1(half arg)
3015  {
3016  #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3017  return half(detail::binary, detail::float2half<half::round_style>(std::expm1(detail::half2float<detail::internal_t>(arg.data_))));
3018  #else
3019  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000, e = (abs>>10) + (abs<=0x3FF), exp;
3020  if(!abs)
3021  return arg;
3022  if(abs >= 0x7C00)
3023  return half(detail::binary, (abs==0x7C00) ? (0x7C00+(sign>>1)) : detail::signal(arg.data_));
3024  if(abs >= 0x4A00)
3025  return half(detail::binary, (arg.data_&0x8000) ? detail::rounded<half::round_style,true>(0xBBFF, 1, 1) : detail::overflow<half::round_style>());
3026  detail::uint32 m = detail::multiply64(static_cast<detail::uint32>((abs&0x3FF)+((abs>0x3FF)<<10))<<21, 0xB8AA3B29);
3027  if(e < 14)
3028  {
3029  exp = 0;
3030  m >>= 14 - e;
3031  }
3032  else
3033  {
3034  exp = m >> (45-e);
3035  m = (m<<(e-14)) & 0x7FFFFFFF;
3036  }
3037  m = detail::exp2(m);
3038  if(sign)
3039  {
3040  int s = 0;
3041  if(m > 0x80000000)
3042  {
3043  ++exp;
3044  m = detail::divide64(0x80000000, m, s);
3045  }
3046  m = 0x80000000 - ((m>>exp)|((m&((static_cast<detail::uint32>(1)<<exp)-1))!=0)|s);
3047  exp = 0;
3048  }
3049  else
3050  m -= (exp<31) ? (0x80000000>>exp) : 1;
3051  for(exp+=14; m<0x80000000 && exp; m<<=1,--exp) ;
3052  if(exp > 29)
3053  return half(detail::binary, detail::overflow<half::round_style>());
3054  return half(detail::binary, detail::rounded<half::round_style,true>(sign+(exp<<10)+(m>>21), (m>>20)&1, (m&0xFFFFF)!=0));
3055  #endif
3056  }
3057 
3067  inline half log(half arg)
3068  {
3069  #ifdef HALF_ARITHMETIC_TYPE
3070  return half(detail::binary, detail::float2half<half::round_style>(std::log(detail::half2float<detail::internal_t>(arg.data_))));
3071  #else
3072  int abs = arg.data_ & 0x7FFF, exp = -15;
3073  if(!abs)
3074  return half(detail::binary, detail::pole(0x8000));
3075  if(arg.data_ & 0x8000)
3076  return half(detail::binary, (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3077  if(abs >= 0x7C00)
3078  return (abs==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
3079  for(; abs<0x400; abs<<=1,--exp) ;
3080  exp += abs >> 10;
3081  return half(detail::binary, detail::log2_post<half::round_style,0xB8AA3B2A>(
3082  detail::log2(static_cast<detail::uint32>((abs&0x3FF)|0x400)<<20, 27)+8, exp, 17));
3083  #endif
3084  }
3085 
3095  inline half log10(half arg)
3096  {
3097  #ifdef HALF_ARITHMETIC_TYPE
3098  return half(detail::binary, detail::float2half<half::round_style>(std::log10(detail::half2float<detail::internal_t>(arg.data_))));
3099  #else
3100  int abs = arg.data_ & 0x7FFF, exp = -15;
3101  if(!abs)
3102  return half(detail::binary, detail::pole(0x8000));
3103  if(arg.data_ & 0x8000)
3104  return half(detail::binary, (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3105  if(abs >= 0x7C00)
3106  return (abs==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
3107  switch(abs)
3108  {
3109  case 0x4900: return half(detail::binary, 0x3C00);
3110  case 0x5640: return half(detail::binary, 0x4000);
3111  case 0x63D0: return half(detail::binary, 0x4200);
3112  case 0x70E2: return half(detail::binary, 0x4400);
3113  }
3114  for(; abs<0x400; abs<<=1,--exp) ;
3115  exp += abs >> 10;
3116  return half(detail::binary, detail::log2_post<half::round_style,0xD49A784C>(
3117  detail::log2(static_cast<detail::uint32>((abs&0x3FF)|0x400)<<20, 27)+8, exp, 16));
3118  #endif
3119  }
3120 
3130  inline half log2(half arg)
3131  {
3132  #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3133  return half(detail::binary, detail::float2half<half::round_style>(std::log2(detail::half2float<detail::internal_t>(arg.data_))));
3134  #else
3135  int abs = arg.data_ & 0x7FFF, exp = -15, s = 0;
3136  if(!abs)
3137  return half(detail::binary, detail::pole(0x8000));
3138  if(arg.data_ & 0x8000)
3139  return half(detail::binary, (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3140  if(abs >= 0x7C00)
3141  return (abs==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
3142  if(abs == 0x3C00)
3143  return half(detail::binary, 0);
3144  for(; abs<0x400; abs<<=1,--exp) ;
3145  exp += (abs>>10);
3146  if(!(abs&0x3FF))
3147  {
3148  unsigned int value = static_cast<unsigned>(exp<0) << 15, m = std::abs(exp) << 6;
3149  for(exp=18; m<0x400; m<<=1,--exp) ;
3150  return half(detail::binary, value+(exp<<10)+m);
3151  }
3152  detail::uint32 ilog = exp, sign = detail::sign_mask(ilog), m =
3153  (((ilog<<27)+(detail::log2(static_cast<detail::uint32>((abs&0x3FF)|0x400)<<20, 28)>>4))^sign) - sign;
3154  if(!m)
3155  return half(detail::binary, 0);
3156  for(exp=14; m<0x8000000 && exp; m<<=1,--exp) ;
3157  for(; m>0xFFFFFFF; m>>=1,++exp)
3158  s |= m & 1;
3159  return half(detail::binary, detail::fixed2half<half::round_style,27,false,false,true>(m, exp, sign&0x8000, s));
3160  #endif
3161  }
3162 
3173  inline half log1p(half arg)
3174  {
3175  #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3176  return half(detail::binary, detail::float2half<half::round_style>(std::log1p(detail::half2float<detail::internal_t>(arg.data_))));
3177  #else
3178  if(arg.data_ >= 0xBC00)
3179  return half(detail::binary, (arg.data_==0xBC00) ? detail::pole(0x8000) : (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3180  int abs = arg.data_ & 0x7FFF, exp = -15;
3181  if(!abs || abs >= 0x7C00)
3182  return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3183  for(; abs<0x400; abs<<=1,--exp) ;
3184  exp += abs >> 10;
3185  detail::uint32 m = static_cast<detail::uint32>((abs&0x3FF)|0x400) << 20;
3186  if(arg.data_ & 0x8000)
3187  {
3188  m = 0x40000000 - (m>>-exp);
3189  for(exp=0; m<0x40000000; m<<=1,--exp) ;
3190  }
3191  else
3192  {
3193  if(exp < 0)
3194  {
3195  m = 0x40000000 + (m>>-exp);
3196  exp = 0;
3197  }
3198  else
3199  {
3200  m += 0x40000000 >> exp;
3201  int i = m >> 31;
3202  m >>= i;
3203  exp += i;
3204  }
3205  }
3206  return half(detail::binary, detail::log2_post<half::round_style,0xB8AA3B2A>(detail::log2(m), exp, 17));
3207  #endif
3208  }
3209 
3214 
3223  inline half sqrt(half arg)
3224  {
3225  #ifdef HALF_ARITHMETIC_TYPE
3226  return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(detail::half2float<detail::internal_t>(arg.data_))));
3227  #else
3228  int abs = arg.data_ & 0x7FFF, exp = 15;
3229  if(!abs || arg.data_ >= 0x7C00)
3230  return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (arg.data_>0x8000) ? detail::invalid() : arg.data_);
3231  for(; abs<0x400; abs<<=1,--exp) ;
3232  detail::uint32 r = static_cast<detail::uint32>((abs&0x3FF)|0x400) << 10, m = detail::sqrt<20>(r, exp+=abs>>10);
3233  return half(detail::binary, detail::rounded<half::round_style,false>((exp<<10)+(m&0x3FF), r>m, r!=0));
3234  #endif
3235  }
3236 
3244  inline half rsqrt(half arg)
3245  {
3246  #ifdef HALF_ARITHMETIC_TYPE
3247  return half(detail::binary, detail::float2half<half::round_style>(detail::internal_t(1)/std::sqrt(detail::half2float<detail::internal_t>(arg.data_))));
3248  #else
3249  unsigned int abs = arg.data_ & 0x7FFF, bias = 0x4000;
3250  if(!abs || arg.data_ >= 0x7C00)
3251  return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (arg.data_>0x8000) ?
3252  detail::invalid() : !abs ? detail::pole(arg.data_&0x8000) : 0);
3253  for(; abs<0x400; abs<<=1,bias-=0x400) ;
3254  unsigned int frac = (abs+=bias) & 0x7FF;
3255  if(frac == 0x400)
3256  return half(detail::binary, 0x7A00-(abs>>1));
3257  if((half::round_style == std::round_to_nearest && (frac == 0x3FE || frac == 0x76C)) ||
3258  (half::round_style != std::round_to_nearest && (frac == 0x15A || frac == 0x3FC || frac == 0x401 || frac == 0x402 || frac == 0x67B)))
3259  return pow(arg, half(detail::binary, 0xB800));
3260  detail::uint32 f = 0x17376 - abs, mx = (abs&0x3FF) | 0x400, my = ((f>>1)&0x3FF) | 0x400, mz = my * my;
3261  int expy = (f>>11) - 31, expx = 32 - (abs>>10), i = mz >> 21;
3262  for(mz=0x60000000-(((mz>>i)*mx)>>(expx-2*expy-i)); mz<0x40000000; mz<<=1,--expy) ;
3263  i = (my*=mz>>10) >> 31;
3264  expy += i;
3265  my = (my>>(20+i)) + 1;
3266  i = (mz=my*my) >> 21;
3267  for(mz=0x60000000-(((mz>>i)*mx)>>(expx-2*expy-i)); mz<0x40000000; mz<<=1,--expy) ;
3268  i = (my*=(mz>>10)+1) >> 31;
3269  return half(detail::binary, detail::fixed2half<half::round_style,30,false,false,true>(my>>i, expy+i+14));
3270  #endif
3271  }
3272 
3281  inline half cbrt(half arg)
3282  {
3283  #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3284  return half(detail::binary, detail::float2half<half::round_style>(std::cbrt(detail::half2float<detail::internal_t>(arg.data_))));
3285  #else
3286  int abs = arg.data_ & 0x7FFF, exp = -15;
3287  if(!abs || abs == 0x3C00 || abs >= 0x7C00)
3288  return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3289  for(; abs<0x400; abs<<=1, --exp);
3290  detail::uint32 ilog = exp + (abs>>10), sign = detail::sign_mask(ilog), f, m =
3291  (((ilog<<27)+(detail::log2(static_cast<detail::uint32>((abs&0x3FF)|0x400)<<20, 24)>>4))^sign) - sign;
3292  for(exp=2; m<0x80000000; m<<=1,--exp) ;
3293  m = detail::multiply64(m, 0xAAAAAAAB);
3294  int i = m >> 31, s;
3295  exp += i;
3296  m <<= 1 - i;
3297  if(exp < 0)
3298  {
3299  f = m >> -exp;
3300  exp = 0;
3301  }
3302  else
3303  {
3304  f = (m<<exp) & 0x7FFFFFFF;
3305  exp = m >> (31-exp);
3306  }
3307  m = detail::exp2(f, (half::round_style==std::round_to_nearest) ? 29 : 26);
3308  if(sign)
3309  {
3310  if(m > 0x80000000)
3311  {
3312  m = detail::divide64(0x80000000, m, s);
3313  ++exp;
3314  }
3315  exp = -exp;
3316  }
3317  return half(detail::binary, (half::round_style==std::round_to_nearest) ?
3318  detail::fixed2half<half::round_style,31,false,false,false>(m, exp+14, arg.data_&0x8000) :
3319  detail::fixed2half<half::round_style,23,false,false,false>((m+0x80)>>8, exp+14, arg.data_&0x8000));
3320  #endif
3321  }
3322 
3332  inline half hypot(half x, half y)
3333  {
3334  #ifdef HALF_ARITHMETIC_TYPE
3335  detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_);
3336  #if HALF_ENABLE_CPP11_CMATH
3337  return half(detail::binary, detail::float2half<half::round_style>(std::hypot(fx, fy)));
3338  #else
3339  return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(fx*fx+fy*fy)));
3340  #endif
3341  #else
3342  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, expx = 0, expy = 0;
3343  if(absx >= 0x7C00 || absy >= 0x7C00)
3344  return half(detail::binary, (absx==0x7C00) ? detail::select(0x7C00, y.data_) :
3345  (absy==0x7C00) ? detail::select(0x7C00, x.data_) : detail::signal(x.data_, y.data_));
3346  if(!absx)
3347  return half(detail::binary, absy ? detail::check_underflow(absy) : 0);
3348  if(!absy)
3350  if(absy > absx)
3351  std::swap(absx, absy);
3352  for(; absx<0x400; absx<<=1,--expx) ;
3353  for(; absy<0x400; absy<<=1,--expy) ;
3354  detail::uint32 mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400;
3355  mx *= mx;
3356  my *= my;
3357  int ix = mx >> 21, iy = my >> 21;
3358  expx = 2*(expx+(absx>>10)) - 15 + ix;
3359  expy = 2*(expy+(absy>>10)) - 15 + iy;
3360  mx <<= 10 - ix;
3361  my <<= 10 - iy;
3362  int d = expx - expy;
3363  my = (d<30) ? ((my>>d)|((my&((static_cast<detail::uint32>(1)<<d)-1))!=0)) : 1;
3364  return half(detail::binary, detail::hypot_post<half::round_style>(mx+my, expx));
3365  #endif
3366  }
3367 
3378  inline half hypot(half x, half y, half z)
3379  {
3380  #ifdef HALF_ARITHMETIC_TYPE
3381  detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_), fz = detail::half2float<detail::internal_t>(z.data_);
3382  return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(fx*fx+fy*fy+fz*fz)));
3383  #else
3384  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, expx = 0, expy = 0, expz = 0;
3385  if(!absx)
3386  return hypot(y, z);
3387  if(!absy)
3388  return hypot(x, z);
3389  if(!absz)
3390  return hypot(x, y);
3391  if(absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
3392  return half(detail::binary, (absx==0x7C00) ? detail::select(0x7C00, detail::select(y.data_, z.data_)) :
3393  (absy==0x7C00) ? detail::select(0x7C00, detail::select(x.data_, z.data_)) :
3394  (absz==0x7C00) ? detail::select(0x7C00, detail::select(x.data_, y.data_)) :
3395  detail::signal(x.data_, y.data_, z.data_));
3396  if(absz > absy)
3397  std::swap(absy, absz);
3398  if(absy > absx)
3399  std::swap(absx, absy);
3400  if(absz > absy)
3401  std::swap(absy, absz);
3402  for(; absx<0x400; absx<<=1,--expx) ;
3403  for(; absy<0x400; absy<<=1,--expy) ;
3404  for(; absz<0x400; absz<<=1,--expz) ;
3405  detail::uint32 mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400, mz = (absz&0x3FF) | 0x400;
3406  mx *= mx;
3407  my *= my;
3408  mz *= mz;
3409  int ix = mx >> 21, iy = my >> 21, iz = mz >> 21;
3410  expx = 2*(expx+(absx>>10)) - 15 + ix;
3411  expy = 2*(expy+(absy>>10)) - 15 + iy;
3412  expz = 2*(expz+(absz>>10)) - 15 + iz;
3413  mx <<= 10 - ix;
3414  my <<= 10 - iy;
3415  mz <<= 10 - iz;
3416  int d = expy - expz;
3417  mz = (d<30) ? ((mz>>d)|((mz&((static_cast<detail::uint32>(1)<<d)-1))!=0)) : 1;
3418  my += mz;
3419  if(my & 0x80000000)
3420  {
3421  my = (my>>1) | (my&1);
3422  if(++expy > expx)
3423  {
3424  std::swap(mx, my);
3425  std::swap(expx, expy);
3426  }
3427  }
3428  d = expx - expy;
3429  my = (d<30) ? ((my>>d)|((my&((static_cast<detail::uint32>(1)<<d)-1))!=0)) : 1;
3430  return half(detail::binary, detail::hypot_post<half::round_style>(mx+my, expx));
3431  #endif
3432  }
3433 
3444  inline half pow(half x, half y)
3445  {
3446  #ifdef HALF_ARITHMETIC_TYPE
3447  return half(detail::binary, detail::float2half<half::round_style>(std::pow(detail::half2float<detail::internal_t>(x.data_), detail::half2float<detail::internal_t>(y.data_))));
3448  #else
3449  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -15;
3450  if(!absy || x.data_ == 0x3C00)
3451  return half(detail::binary, detail::select(0x3C00, (x.data_==0x3C00) ? y.data_ : x.data_));
3452  bool is_int = absy >= 0x6400 || (absy>=0x3C00 && !(absy&((1<<(25-(absy>>10)))-1)));
3453  unsigned int sign = x.data_ & (static_cast<unsigned>((absy<0x6800)&&is_int&&((absy>>(25-(absy>>10)))&1))<<15);
3454  if(absx >= 0x7C00 || absy >= 0x7C00)
3455  return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
3456  (absy==0x7C00) ? ((absx==0x3C00) ? 0x3C00 : (!absx && y.data_==0xFC00) ? detail::pole() :
3457  (0x7C00&-((y.data_>>15)^(absx>0x3C00)))) : (sign|(0x7C00&((y.data_>>15)-1U))));
3458  if(!absx)
3459  return half(detail::binary, (y.data_&0x8000) ? detail::pole(sign) : sign);
3460  if((x.data_&0x8000) && !is_int)
3461  return half(detail::binary, detail::invalid());
3462  if(x.data_ == 0xBC00)
3463  return half(detail::binary, sign|0x3C00);
3464  switch(y.data_)
3465  {
3466  case 0x3800: return sqrt(x);
3467  case 0x3C00: return half(detail::binary, detail::check_underflow(x.data_));
3468  case 0x4000: return x * x;
3469  case 0xBC00: return half(detail::binary, 0x3C00) / x;
3470  }
3471  for(; absx<0x400; absx<<=1,--exp) ;
3472  detail::uint32 ilog = exp + (absx>>10), msign = detail::sign_mask(ilog), f, m =
3473  (((ilog<<27)+((detail::log2(static_cast<detail::uint32>((absx&0x3FF)|0x400)<<20)+8)>>4))^msign) - msign;
3474  for(exp=-11; m<0x80000000; m<<=1,--exp) ;
3475  for(; absy<0x400; absy<<=1,--exp) ;
3476  m = detail::multiply64(m, static_cast<detail::uint32>((absy&0x3FF)|0x400)<<21);
3477  int i = m >> 31;
3478  exp += (absy>>10) + i;
3479  m <<= 1 - i;
3480  if(exp < 0)
3481  {
3482  f = m >> -exp;
3483  exp = 0;
3484  }
3485  else
3486  {
3487  f = (m<<exp) & 0x7FFFFFFF;
3488  exp = m >> (31-exp);
3489  }
3490  return half(detail::binary, detail::exp2_post<half::round_style>(f, exp, ((msign&1)^(y.data_>>15))!=0, sign));
3491  #endif
3492  }
3493 
3498 
3508  inline void sincos(half arg, half *sin, half *cos)
3509  {
3510  #ifdef HALF_ARITHMETIC_TYPE
3511  detail::internal_t f = detail::half2float<detail::internal_t>(arg.data_);
3512  *sin = half(detail::binary, detail::float2half<half::round_style>(std::sin(f)));
3513  *cos = half(detail::binary, detail::float2half<half::round_style>(std::cos(f)));
3514  #else
3515  int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15, k;
3516  if(abs >= 0x7C00)
3517  *sin = *cos = half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3518  else if(!abs)
3519  {
3520  *sin = arg;
3521  *cos = half(detail::binary, 0x3C00);
3522  }
3523  else if(abs < 0x2500)
3524  {
3525  *sin = half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-1, 1, 1));
3526  *cos = half(detail::binary, detail::rounded<half::round_style,true>(0x3BFF, 1, 1));
3527  }
3528  else
3529  {
3530  if(half::round_style != std::round_to_nearest)
3531  {
3532  switch(abs)
3533  {
3534  case 0x48B7:
3535  *sin = half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x1D07, 1, 1));
3536  *cos = half(detail::binary, detail::rounded<half::round_style,true>(0xBBFF, 1, 1));
3537  return;
3538  case 0x598C:
3539  *sin = half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x3BFF, 1, 1));
3540  *cos = half(detail::binary, detail::rounded<half::round_style,true>(0x80FC, 1, 1));
3541  return;
3542  case 0x6A64:
3543  *sin = half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x3BFE, 1, 1));
3544  *cos = half(detail::binary, detail::rounded<half::round_style,true>(0x27FF, 1, 1));
3545  return;
3546  case 0x6D8C:
3547  *sin = half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x0FE6, 1, 1));
3548  *cos = half(detail::binary, detail::rounded<half::round_style,true>(0x3BFF, 1, 1));
3549  return;
3550  }
3551  }
3552  std::pair<detail::uint32,detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
3553  switch(k & 3)
3554  {
3555  case 1: sc = std::make_pair(sc.second, -sc.first); break;
3556  case 2: sc = std::make_pair(-sc.first, -sc.second); break;
3557  case 3: sc = std::make_pair(-sc.second, sc.first); break;
3558  }
3559  *sin = half(detail::binary, detail::fixed2half<half::round_style,30,true,true,true>((sc.first^-static_cast<detail::uint32>(sign))+sign));
3560  *cos = half(detail::binary, detail::fixed2half<half::round_style,30,true,true,true>(sc.second));
3561  }
3562  #endif
3563  }
3564 
3573  inline half sin(half arg)
3574  {
3575  #ifdef HALF_ARITHMETIC_TYPE
3576  return half(detail::binary, detail::float2half<half::round_style>(std::sin(detail::half2float<detail::internal_t>(arg.data_))));
3577  #else
3578  int abs = arg.data_ & 0x7FFF, k;
3579  if(!abs)
3580  return arg;
3581  if(abs >= 0x7C00)
3582  return half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3583  if(abs < 0x2900)
3584  return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-1, 1, 1));
3585  if(half::round_style != std::round_to_nearest)
3586  switch(abs)
3587  {
3588  case 0x48B7: return half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x1D07, 1, 1));
3589  case 0x6A64: return half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x3BFE, 1, 1));
3590  case 0x6D8C: return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x0FE6, 1, 1));
3591  }
3592  std::pair<detail::uint32,detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
3593  detail::uint32 sign = -static_cast<detail::uint32>(((k>>1)&1)^(arg.data_>>15));
3594  return half(detail::binary, detail::fixed2half<half::round_style,30,true,true,true>((((k&1) ? sc.second : sc.first)^sign) - sign));
3595  #endif
3596  }
3597 
3606  inline half cos(half arg)
3607  {
3608  #ifdef HALF_ARITHMETIC_TYPE
3609  return half(detail::binary, detail::float2half<half::round_style>(std::cos(detail::half2float<detail::internal_t>(arg.data_))));
3610  #else
3611  int abs = arg.data_ & 0x7FFF, k;
3612  if(!abs)
3613  return half(detail::binary, 0x3C00);
3614  if(abs >= 0x7C00)
3615  return half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3616  if(abs < 0x2500)
3617  return half(detail::binary, detail::rounded<half::round_style,true>(0x3BFF, 1, 1));
3618  if(half::round_style != std::round_to_nearest && abs == 0x598C)
3619  return half(detail::binary, detail::rounded<half::round_style,true>(0x80FC, 1, 1));
3620  std::pair<detail::uint32,detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
3621  detail::uint32 sign = -static_cast<detail::uint32>(((k>>1)^k)&1);
3622  return half(detail::binary, detail::fixed2half<half::round_style,30,true,true,true>((((k&1) ? sc.first : sc.second)^sign) - sign));
3623  #endif
3624  }
3625 
3634  inline half tan(half arg)
3635  {
3636  #ifdef HALF_ARITHMETIC_TYPE
3637  return half(detail::binary, detail::float2half<half::round_style>(std::tan(detail::half2float<detail::internal_t>(arg.data_))));
3638  #else
3639  int abs = arg.data_ & 0x7FFF, exp = 13, k;
3640  if(!abs)
3641  return arg;
3642  if(abs >= 0x7C00)
3643  return half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3644  if(abs < 0x2700)
3645  return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_, 0, 1));
3646  if(half::round_style != std::round_to_nearest)
3647  switch(abs)
3648  {
3649  case 0x658C: return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x07E6, 1, 1));
3650  case 0x7330: return half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x4B62, 1, 1));
3651  }
3652  std::pair<detail::uint32,detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 30);
3653  if(k & 1)
3654  sc = std::make_pair(-sc.second, sc.first);
3655  detail::uint32 signy = detail::sign_mask(sc.first), signx = detail::sign_mask(sc.second);
3656  detail::uint32 my = (sc.first^signy) - signy, mx = (sc.second^signx) - signx;
3657  for(; my<0x80000000; my<<=1,--exp) ;
3658  for(; mx<0x80000000; mx<<=1,++exp) ;
3659  return half(detail::binary, detail::tangent_post<half::round_style>(my, mx, exp, (signy^signx^arg.data_)&0x8000));
3660  #endif
3661  }
3662 
3671  inline half asin(half arg)
3672  {
3673  #ifdef HALF_ARITHMETIC_TYPE
3674  return half(detail::binary, detail::float2half<half::round_style>(std::asin(detail::half2float<detail::internal_t>(arg.data_))));
3675  #else
3676  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
3677  if(!abs)
3678  return arg;
3679  if(abs >= 0x3C00)
3680  return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (abs>0x3C00) ? detail::invalid() :
3681  detail::rounded<half::round_style,true>(sign|0x3E48, 0, 1));
3682  if(abs < 0x2900)
3683  return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_, 0, 1));
3684  if(half::round_style != std::round_to_nearest && (abs == 0x2B44 || abs == 0x2DC3))
3685  return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_+1, 1, 1));
3686  std::pair<detail::uint32,detail::uint32> sc = detail::atan2_args(abs);
3687  detail::uint32 m = detail::atan2(sc.first, sc.second, (half::round_style==std::round_to_nearest) ? 27 : 26);
3688  return half(detail::binary, detail::fixed2half<half::round_style,30,false,true,true>(m, 14, sign));
3689  #endif
3690  }
3691 
3700  inline half acos(half arg)
3701  {
3702  #ifdef HALF_ARITHMETIC_TYPE
3703  return half(detail::binary, detail::float2half<half::round_style>(std::acos(detail::half2float<detail::internal_t>(arg.data_))));
3704  #else
3705  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15;
3706  if(!abs)
3707  return half(detail::binary, detail::rounded<half::round_style,true>(0x3E48, 0, 1));
3708  if(abs >= 0x3C00)
3709  return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (abs>0x3C00) ? detail::invalid() :
3710  sign ? detail::rounded<half::round_style,true>(0x4248, 0, 1) : 0);
3711  std::pair<detail::uint32,detail::uint32> cs = detail::atan2_args(abs);
3712  detail::uint32 m = detail::atan2(cs.second, cs.first, 28);
3713  return half(detail::binary, detail::fixed2half<half::round_style,31,false,true,true>(sign ? (0xC90FDAA2-m) : m, 15, 0, sign));
3714  #endif
3715  }
3716 
3725  inline half atan(half arg)
3726  {
3727  #ifdef HALF_ARITHMETIC_TYPE
3728  return half(detail::binary, detail::float2half<half::round_style>(std::atan(detail::half2float<detail::internal_t>(arg.data_))));
3729  #else
3730  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
3731  if(!abs)
3732  return arg;
3733  if(abs >= 0x7C00)
3734  return half(detail::binary, (abs==0x7C00) ? detail::rounded<half::round_style,true>(sign|0x3E48, 0, 1) : detail::signal(arg.data_));
3735  if(abs <= 0x2700)
3736  return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-1, 1, 1));
3737  int exp = (abs>>10) + (abs<=0x3FF);
3738  detail::uint32 my = (abs&0x3FF) | ((abs>0x3FF)<<10);
3739  detail::uint32 m = (exp>15) ? detail::atan2(my<<19, 0x20000000>>(exp-15), (half::round_style==std::round_to_nearest) ? 26 : 24) :
3740  detail::atan2(my<<(exp+4), 0x20000000, (half::round_style==std::round_to_nearest) ? 30 : 28);
3741  return half(detail::binary, detail::fixed2half<half::round_style,30,false,true,true>(m, 14, sign));
3742  #endif
3743  }
3744 
3755  inline half atan2(half y, half x)
3756  {
3757  #ifdef HALF_ARITHMETIC_TYPE
3758  return half(detail::binary, detail::float2half<half::round_style>(std::atan2(detail::half2float<detail::internal_t>(y.data_), detail::half2float<detail::internal_t>(x.data_))));
3759  #else
3760  unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, signx = x.data_ >> 15, signy = y.data_ & 0x8000;
3761  if(absx >= 0x7C00 || absy >= 0x7C00)
3762  {
3763  if(absx > 0x7C00 || absy > 0x7C00)
3764  return half(detail::binary, detail::signal(x.data_, y.data_));
3765  if(absy == 0x7C00)
3766  return half(detail::binary, (absx<0x7C00) ? detail::rounded<half::round_style,true>(signy|0x3E48, 0, 1) :
3767  signx ? detail::rounded<half::round_style,true>(signy|0x40B6, 0, 1) :
3768  detail::rounded<half::round_style,true>(signy|0x3A48, 0, 1));
3769  return (x.data_==0x7C00) ? half(detail::binary, signy) : half(detail::binary, detail::rounded<half::round_style,true>(signy|0x4248, 0, 1));
3770  }
3771  if(!absy)
3772  return signx ? half(detail::binary, detail::rounded<half::round_style,true>(signy|0x4248, 0, 1)) : y;
3773  if(!absx)
3774  return half(detail::binary, detail::rounded<half::round_style,true>(signy|0x3E48, 0, 1));
3775  int d = (absy>>10) + (absy<=0x3FF) - (absx>>10) - (absx<=0x3FF);
3776  if(d > (signx ? 18 : 12))
3777  return half(detail::binary, detail::rounded<half::round_style,true>(signy|0x3E48, 0, 1));
3778  if(signx && d < -11)
3779  return half(detail::binary, detail::rounded<half::round_style,true>(signy|0x4248, 0, 1));
3780  if(!signx && d < ((half::round_style==std::round_toward_zero) ? -15 : -9))
3781  {
3782  for(; absy<0x400; absy<<=1,--d) ;
3783  detail::uint32 mx = ((absx<<1)&0x7FF) | 0x800, my = ((absy<<1)&0x7FF) | 0x800;
3784  int i = my < mx;
3785  d -= i;
3786  if(d < -25)
3787  return half(detail::binary, detail::underflow<half::round_style>(signy));
3788  my <<= 11 + i;
3789  return half(detail::binary, detail::fixed2half<half::round_style,11,false,false,true>(my/mx, d+14, signy, my%mx!=0));
3790  }
3791  detail::uint32 m = detail::atan2( ((absy&0x3FF)|((absy>0x3FF)<<10))<<(19+((d<0) ? d : (d>0) ? 0 : -1)),
3792  ((absx&0x3FF)|((absx>0x3FF)<<10))<<(19-((d>0) ? d : (d<0) ? 0 : 1)));
3793  return half(detail::binary, detail::fixed2half<half::round_style,31,false,true,true>(signx ? (0xC90FDAA2-m) : m, 15, signy, signx));
3794  #endif
3795  }
3796 
3801 
3810  inline half sinh(half arg)
3811  {
3812  #ifdef HALF_ARITHMETIC_TYPE
3813  return half(detail::binary, detail::float2half<half::round_style>(std::sinh(detail::half2float<detail::internal_t>(arg.data_))));
3814  #else
3815  int abs = arg.data_ & 0x7FFF, exp;
3816  if(!abs || abs >= 0x7C00)
3817  return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3818  if(abs <= 0x2900)
3819  return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_, 0, 1));
3820  std::pair<detail::uint32,detail::uint32> mm = detail::hyperbolic_args(abs, exp, (half::round_style==std::round_to_nearest) ? 29 : 27);
3821  detail::uint32 m = mm.first - mm.second;
3822  for(exp+=13; m<0x80000000 && exp; m<<=1,--exp) ;
3823  unsigned int sign = arg.data_ & 0x8000;
3824  if(exp > 29)
3825  return half(detail::binary, detail::overflow<half::round_style>(sign));
3826  return half(detail::binary, detail::fixed2half<half::round_style,31,false,false,true>(m, exp, sign));
3827  #endif
3828  }
3829 
3838  inline half cosh(half arg)
3839  {
3840  #ifdef HALF_ARITHMETIC_TYPE
3841  return half(detail::binary, detail::float2half<half::round_style>(std::cosh(detail::half2float<detail::internal_t>(arg.data_))));
3842  #else
3843  int abs = arg.data_ & 0x7FFF, exp;
3844  if(!abs)
3845  return half(detail::binary, 0x3C00);
3846  if(abs >= 0x7C00)
3847  return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : 0x7C00);
3848  std::pair<detail::uint32,detail::uint32> mm = detail::hyperbolic_args(abs, exp, (half::round_style==std::round_to_nearest) ? 23 : 26);
3849  detail::uint32 m = mm.first + mm.second, i = (~m&0xFFFFFFFF) >> 31;
3850  m = (m>>i) | (m&i) | 0x80000000;
3851  if((exp+=13+i) > 29)
3852  return half(detail::binary, detail::overflow<half::round_style>());
3853  return half(detail::binary, detail::fixed2half<half::round_style,31,false,false,true>(m, exp));
3854  #endif
3855  }
3856 
3865  inline half tanh(half arg)
3866  {
3867  #ifdef HALF_ARITHMETIC_TYPE
3868  return half(detail::binary, detail::float2half<half::round_style>(std::tanh(detail::half2float<detail::internal_t>(arg.data_))));
3869  #else
3870  int abs = arg.data_ & 0x7FFF, exp;
3871  if(!abs)
3872  return arg;
3873  if(abs >= 0x7C00)
3874  return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (arg.data_-0x4000));
3875  if(abs >= 0x4500)
3876  return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x3BFF, 1, 1));
3877  if(abs < 0x2700)
3878  return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-1, 1, 1));
3879  if(half::round_style != std::round_to_nearest && abs == 0x2D3F)
3880  return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-3, 0, 1));
3881  std::pair<detail::uint32,detail::uint32> mm = detail::hyperbolic_args(abs, exp, 27);
3882  detail::uint32 my = mm.first - mm.second - (half::round_style!=std::round_to_nearest), mx = mm.first + mm.second, i = (~mx&0xFFFFFFFF) >> 31;
3883  for(exp=13; my<0x80000000; my<<=1,--exp) ;
3884  mx = (mx>>i) | 0x80000000;
3885  return half(detail::binary, detail::tangent_post<half::round_style>(my, mx, exp-i, arg.data_&0x8000));
3886  #endif
3887  }
3888 
3897  inline half asinh(half arg)
3898  {
3899  #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3900  return half(detail::binary, detail::float2half<half::round_style>(std::asinh(detail::half2float<detail::internal_t>(arg.data_))));
3901  #else
3902  int abs = arg.data_ & 0x7FFF;
3903  if(!abs || abs >= 0x7C00)
3904  return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3905  if(abs <= 0x2900)
3906  return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-1, 1, 1));
3907  if(half::round_style != std::round_to_nearest)
3908  switch(abs)
3909  {
3910  case 0x32D4: return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-13, 1, 1));
3911  case 0x3B5B: return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-197, 1, 1));
3912  }
3913  return half(detail::binary, detail::area<half::round_style,true>(arg.data_));
3914  #endif
3915  }
3916 
3925  inline half acosh(half arg)
3926  {
3927  #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3928  return half(detail::binary, detail::float2half<half::round_style>(std::acosh(detail::half2float<detail::internal_t>(arg.data_))));
3929  #else
3930  int abs = arg.data_ & 0x7FFF;
3931  if((arg.data_&0x8000) || abs < 0x3C00)
3932  return half(detail::binary, (abs<=0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3933  if(abs == 0x3C00)
3934  return half(detail::binary, 0);
3935  if(arg.data_ >= 0x7C00)
3936  return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3937  return half(detail::binary, detail::area<half::round_style,false>(arg.data_));
3938  #endif
3939  }
3940 
3950  inline half atanh(half arg)
3951  {
3952  #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3953  return half(detail::binary, detail::float2half<half::round_style>(std::atanh(detail::half2float<detail::internal_t>(arg.data_))));
3954  #else
3955  int abs = arg.data_ & 0x7FFF, exp = 0;
3956  if(!abs)
3957  return arg;
3958  if(abs >= 0x3C00)
3959  return half(detail::binary, (abs==0x3C00) ? detail::pole(arg.data_&0x8000) : (abs<=0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3960  if(abs < 0x2700)
3961  return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_, 0, 1));
3962  detail::uint32 m = static_cast<detail::uint32>((abs&0x3FF)|((abs>0x3FF)<<10)) << ((abs>>10)+(abs<=0x3FF)+6), my = 0x80000000 + m, mx = 0x80000000 - m;
3963  for(; mx<0x80000000; mx<<=1,++exp) ;
3964  int i = my >= mx, s;
3965  return half(detail::binary, detail::log2_post<half::round_style,0xB8AA3B2A>(detail::log2(
3966  (detail::divide64(my>>i, mx, s)+1)>>1, 27)+0x10, exp+i-1, 16, arg.data_&0x8000));
3967  #endif
3968  }
3969 
3974 
3983  inline half erf(half arg)
3984  {
3985  #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3986  return half(detail::binary, detail::float2half<half::round_style>(std::erf(detail::half2float<detail::internal_t>(arg.data_))));
3987  #else
3988  unsigned int abs = arg.data_ & 0x7FFF;
3989  if(!abs || abs >= 0x7C00)
3990  return (abs>=0x7C00) ? half(detail::binary, (abs==0x7C00) ? (arg.data_-0x4000) : detail::signal(arg.data_)) : arg;
3991  if(abs >= 0x4200)
3992  return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x3BFF, 1, 1));
3993  return half(detail::binary, detail::erf<half::round_style,false>(arg.data_));
3994  #endif
3995  }
3996 
4005  inline half erfc(half arg)
4006  {
4007  #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
4008  return half(detail::binary, detail::float2half<half::round_style>(std::erfc(detail::half2float<detail::internal_t>(arg.data_))));
4009  #else
4010  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
4011  if(abs >= 0x7C00)
4012  return (abs>=0x7C00) ? half(detail::binary, (abs==0x7C00) ? (sign>>1) : detail::signal(arg.data_)) : arg;
4013  if(!abs)
4014  return half(detail::binary, 0x3C00);
4015  if(abs >= 0x4400)
4016  return half(detail::binary, detail::rounded<half::round_style,true>((sign>>1)-(sign>>15), sign>>15, 1));
4017  return half(detail::binary, detail::erf<half::round_style,true>(arg.data_));
4018  #endif
4019  }
4020 
4030  inline half lgamma(half arg)
4031  {
4032  #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
4033  return half(detail::binary, detail::float2half<half::round_style>(std::lgamma(detail::half2float<detail::internal_t>(arg.data_))));
4034  #else
4035  int abs = arg.data_ & 0x7FFF;
4036  if(abs >= 0x7C00)
4037  return half(detail::binary, (abs==0x7C00) ? 0x7C00 : detail::signal(arg.data_));
4038  if(!abs || arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(abs&((1<<(25-(abs>>10)))-1))))
4039  return half(detail::binary, detail::pole());
4040  if(arg.data_ == 0x3C00 || arg.data_ == 0x4000)
4041  return half(detail::binary, 0);
4042  return half(detail::binary, detail::gamma<half::round_style,true>(arg.data_));
4043  #endif
4044  }
4045 
4055  inline half tgamma(half arg)
4056  {
4057  #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
4058  return half(detail::binary, detail::float2half<half::round_style>(std::tgamma(detail::half2float<detail::internal_t>(arg.data_))));
4059  #else
4060  unsigned int abs = arg.data_ & 0x7FFF;
4061  if(!abs)
4062  return half(detail::binary, detail::pole(arg.data_));
4063  if(abs >= 0x7C00)
4064  return (arg.data_==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
4065  if(arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(abs&((1<<(25-(abs>>10)))-1))))
4066  return half(detail::binary, detail::invalid());
4067  if(arg.data_ >= 0xCA80)
4068  return half(detail::binary, detail::underflow<half::round_style>((1-((abs>>(25-(abs>>10)))&1))<<15));
4069  if(arg.data_ <= 0x100 || (arg.data_ >= 0x4900 && arg.data_ < 0x8000))
4070  return half(detail::binary, detail::overflow<half::round_style>());
4071  if(arg.data_ == 0x3C00)
4072  return arg;
4073  return half(detail::binary, detail::gamma<half::round_style,false>(arg.data_));
4074  #endif
4075  }
4076 
4081 
4088  inline half ceil(half arg) { return half(detail::binary, detail::integral<std::round_toward_infinity,true,true>(arg.data_)); }
4089 
4096  inline half floor(half arg) { return half(detail::binary, detail::integral<std::round_toward_neg_infinity,true,true>(arg.data_)); }
4097 
4104  inline half trunc(half arg) { return half(detail::binary, detail::integral<std::round_toward_zero,true,true>(arg.data_)); }
4105 
4112  inline half round(half arg) { return half(detail::binary, detail::integral<std::round_to_nearest,false,true>(arg.data_)); }
4113 
4119  inline long lround(half arg) { return detail::half2int<std::round_to_nearest,false,false,long>(arg.data_); }
4120 
4127  inline half rint(half arg) { return half(detail::binary, detail::integral<half::round_style,true,true>(arg.data_)); }
4128 
4135  inline long lrint(half arg) { return detail::half2int<half::round_style,true,true,long>(arg.data_); }
4136 
4142  inline half nearbyint(half arg) { return half(detail::binary, detail::integral<half::round_style,true,false>(arg.data_)); }
4143 #if HALF_ENABLE_CPP11_LONG_LONG
4144  inline long long llround(half arg) { return detail::half2int<std::round_to_nearest,false,false,long long>(arg.data_); }
4150 
4157  inline long long llrint(half arg) { return detail::half2int<half::round_style,true,true,long long>(arg.data_); }
4158 #endif
4159 
4164 
4171  inline half frexp(half arg, int *exp)
4172  {
4173  *exp = 0;
4174  unsigned int abs = arg.data_ & 0x7FFF;
4175  if(abs >= 0x7C00 || !abs)
4176  return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
4177  for(; abs<0x400; abs<<=1,--*exp) ;
4178  *exp += (abs>>10) - 14;
4179  return half(detail::binary, (arg.data_&0x8000)|0x3800|(abs&0x3FF));
4180  }
4181 
4191  inline half scalbln(half arg, long exp)
4192  {
4193  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
4194  if(abs >= 0x7C00 || !abs)
4195  return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
4196  for(; abs<0x400; abs<<=1,--exp) ;
4197  exp += abs >> 10;
4198  if(exp > 30)
4199  return half(detail::binary, detail::overflow<half::round_style>(sign));
4200  else if(exp < -10)
4201  return half(detail::binary, detail::underflow<half::round_style>(sign));
4202  else if(exp > 0)
4203  return half(detail::binary, sign|(exp<<10)|(abs&0x3FF));
4204  unsigned int m = (abs&0x3FF) | 0x400;
4205  return half(detail::binary, detail::rounded<half::round_style,false>(sign|(m>>(1-exp)), (m>>-exp)&1, (m&((1<<-exp)-1))!=0));
4206  }
4207 
4217  inline half scalbn(half arg, int exp) { return scalbln(arg, exp); }
4218 
4228  inline half ldexp(half arg, int exp) { return scalbln(arg, exp); }
4229 
4236  inline half modf(half arg, half *iptr)
4237  {
4238  unsigned int abs = arg.data_ & 0x7FFF;
4239  if(abs > 0x7C00)
4240  {
4241  arg = half(detail::binary, detail::signal(arg.data_));
4242  return *iptr = arg, arg;
4243  }
4244  if(abs >= 0x6400)
4245  return *iptr = arg, half(detail::binary, arg.data_&0x8000);
4246  if(abs < 0x3C00)
4247  return iptr->data_ = arg.data_ & 0x8000, arg;
4248  unsigned int exp = abs >> 10, mask = (1<<(25-exp)) - 1, m = arg.data_ & mask;
4249  iptr->data_ = arg.data_ & ~mask;
4250  if(!m)
4251  return half(detail::binary, arg.data_&0x8000);
4252  for(; m<0x400; m<<=1,--exp) ;
4253  return half(detail::binary, (arg.data_&0x8000)|(exp<<10)|(m&0x3FF));
4254  }
4255 
4264  inline int ilogb(half arg)
4265  {
4266  int abs = arg.data_ & 0x7FFF, exp;
4267  if(!abs || abs >= 0x7C00)
4268  {
4270  return !abs ? FP_ILOGB0 : (abs==0x7C00) ? INT_MAX : FP_ILOGBNAN;
4271  }
4272  for(exp=(abs>>10)-15; abs<0x200; abs<<=1,--exp) ;
4273  return exp;
4274  }
4275 
4282  inline half logb(half arg)
4283  {
4284  int abs = arg.data_ & 0x7FFF, exp;
4285  if(!abs)
4286  return half(detail::binary, detail::pole(0x8000));
4287  if(abs >= 0x7C00)
4288  return half(detail::binary, (abs==0x7C00) ? 0x7C00 : detail::signal(arg.data_));
4289  for(exp=(abs>>10)-15; abs<0x200; abs<<=1,--exp) ;
4290  unsigned int value = static_cast<unsigned>(exp<0) << 15;
4291  if(exp)
4292  {
4293  unsigned int m = std::abs(exp) << 6;
4294  for(exp=18; m<0x400; m<<=1,--exp) ;
4295  value |= (exp<<10) + m;
4296  }
4297  return half(detail::binary, value);
4298  }
4299 
4308  inline half nextafter(half from, half to)
4309  {
4310  int fabs = from.data_ & 0x7FFF, tabs = to.data_ & 0x7FFF;
4311  if(fabs > 0x7C00 || tabs > 0x7C00)
4312  return half(detail::binary, detail::signal(from.data_, to.data_));
4313  if(from.data_ == to.data_ || !(fabs|tabs))
4314  return to;
4315  if(!fabs)
4316  {
4318  return half(detail::binary, (to.data_&0x8000)+1);
4319  }
4320  unsigned int out = from.data_ + (((from.data_>>15)^static_cast<unsigned>(
4321  (from.data_^(0x8000|(0x8000-(from.data_>>15))))<(to.data_^(0x8000|(0x8000-(to.data_>>15))))))<<1) - 1;
4322  detail::raise(FE_OVERFLOW, fabs<0x7C00 && (out&0x7C00)==0x7C00);
4324  return half(detail::binary, out);
4325  }
4326 
4335  inline half nexttoward(half from, long double to)
4336  {
4337  int fabs = from.data_ & 0x7FFF;
4338  if(fabs > 0x7C00)
4339  return half(detail::binary, detail::signal(from.data_));
4340  long double lfrom = static_cast<long double>(from);
4341  if(detail::builtin_isnan(to) || lfrom == to)
4342  return half(static_cast<float>(to));
4343  if(!fabs)
4344  {
4346  return half(detail::binary, (static_cast<unsigned>(detail::builtin_signbit(to))<<15)+1);
4347  }
4348  unsigned int out = from.data_ + (((from.data_>>15)^static_cast<unsigned>(lfrom<to))<<1) - 1;
4349  detail::raise(FE_OVERFLOW, (out&0x7FFF)==0x7C00);
4351  return half(detail::binary, out);
4352  }
4353 
4359  inline HALF_CONSTEXPR half copysign(half x, half y) { return half(detail::binary, x.data_^((x.data_^y.data_)&0x8000)); }
4360 
4365 
4375  {
4376  return !(arg.data_&0x7FFF) ? FP_ZERO :
4377  ((arg.data_&0x7FFF)<0x400) ? FP_SUBNORMAL :
4378  ((arg.data_&0x7FFF)<0x7C00) ? FP_NORMAL :
4379  ((arg.data_&0x7FFF)==0x7C00) ? FP_INFINITE :
4380  FP_NAN;
4381  }
4382 
4388  inline HALF_CONSTEXPR bool isfinite(half arg) { return (arg.data_&0x7C00) != 0x7C00; }
4389 
4395  inline HALF_CONSTEXPR bool isinf(half arg) { return (arg.data_&0x7FFF) == 0x7C00; }
4396 
4402  inline HALF_CONSTEXPR bool isnan(half arg) { return (arg.data_&0x7FFF) > 0x7C00; }
4403 
4409  inline HALF_CONSTEXPR bool isnormal(half arg) { return ((arg.data_&0x7C00)!=0) & ((arg.data_&0x7C00)!=0x7C00); }
4410 
4416  inline HALF_CONSTEXPR bool signbit(half arg) { return (arg.data_&0x8000) != 0; }
4417 
4422 
4429  inline HALF_CONSTEXPR bool isgreater(half x, half y)
4430  {
4431  return ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) > ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15)) && !isnan(x) && !isnan(y);
4432  }
4433 
4441  {
4442  return ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) >= ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15)) && !isnan(x) && !isnan(y);
4443  }
4444 
4451  inline HALF_CONSTEXPR bool isless(half x, half y)
4452  {
4453  return ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) < ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15)) && !isnan(x) && !isnan(y);
4454  }
4455 
4463  {
4464  return ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) <= ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15)) && !isnan(x) && !isnan(y);
4465  }
4466 
4474  {
4475  return x.data_!=y.data_ && ((x.data_|y.data_)&0x7FFF) && !isnan(x) && !isnan(y);
4476  }
4477 
4484  inline HALF_CONSTEXPR bool isunordered(half x, half y) { return isnan(x) || isnan(y); }
4485 
4490 
4504  template<typename T,typename U> T half_cast(U arg) { return detail::half_caster<T,U>::cast(arg); }
4505 
4520  template<typename T,std::float_round_style R,typename U> T half_cast(U arg) { return detail::half_caster<T,U,R>::cast(arg); }
4522 
4527 
4535  inline int feclearexcept(int excepts) { detail::errflags() &= ~excepts; return 0; }
4536 
4544  inline int fetestexcept(int excepts) { return detail::errflags() & excepts; }
4545 
4555  inline int feraiseexcept(int excepts) { detail::errflags() |= excepts; detail::raise(excepts); return 0; }
4556 
4565  inline int fegetexceptflag(int *flagp, int excepts) { *flagp = detail::errflags() & excepts; return 0; }
4566 
4576  inline int fesetexceptflag(const int *flagp, int excepts) { detail::errflags() = (detail::errflags()|(*flagp&excepts)) & (*flagp|~excepts); return 0; }
4577 
4589  inline void fethrowexcept(int excepts, const char *msg = "")
4590  {
4591  excepts &= detail::errflags();
4592  if(excepts & (FE_INVALID|FE_DIVBYZERO))
4593  throw std::domain_error(msg);
4594  if(excepts & FE_OVERFLOW)
4595  throw std::overflow_error(msg);
4596  if(excepts & FE_UNDERFLOW)
4597  throw std::underflow_error(msg);
4598  if(excepts & FE_INEXACT)
4599  throw std::range_error(msg);
4600  }
4602 }
4603 
4604 
4605 #undef HALF_UNUSED_NOERR
4606 #undef HALF_CONSTEXPR
4607 #undef HALF_CONSTEXPR_CONST
4608 #undef HALF_CONSTEXPR_NOERR
4609 #undef HALF_NOEXCEPT
4610 #undef HALF_NOTHROW
4611 #undef HALF_THREAD_LOCAL
4612 #undef HALF_TWOS_COMPLEMENT_INT
4613 #ifdef HALF_POP_WARNINGS
4614  #pragma warning(pop)
4615  #undef HALF_POP_WARNINGS
4616 #endif
4617 
4618 #endif
half_float::half::isgreaterequal
friend HALF_CONSTEXPR bool isgreaterequal(half, half)
Quiet comparison for greater equal.
Definition: includes/half.hpp:4440
half_float::half::expm1
friend half expm1(half)
Exponential minus one.
Definition: includes/half.hpp:3014
half_float::round
half round(half arg)
Nearest integer.
Definition: includes/half.hpp:4112
half_float::acos
half acos(half arg)
Arc cosine function.
Definition: includes/half.hpp:3700
half_float::detail::underflow
HALF_CONSTEXPR_NOERR unsigned int underflow(unsigned int sign=0)
Half-precision underflow.
Definition: includes/half.hpp:817
half_float::detail::tangent_post
unsigned int tangent_post(uint32 my, uint32 mx, int exp, unsigned int sign=0)
Division and postprocessing for tangents.
Definition: includes/half.hpp:1784
half_float::detail::builtin_isnan
bool builtin_isnan(T arg)
Check for NaN.
Definition: includes/half.hpp:579
half_float::half::sqrt
friend half sqrt(half)
Square root.
Definition: includes/half.hpp:3223
HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
#define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
Raise INEXACT exception on underflow.
Definition: includes/half.hpp:369
half_float::fma
half fma(half x, half y, half z)
Fused multiply add.
Definition: includes/half.hpp:2826
half_float::detail::false_type
bool_type< false > false_type
Definition: includes/half.hpp:489
half_float::detail::f31::f31
f31(unsigned int abs)
Constructor.
Definition: includes/half.hpp:1864
half_float::operator-
HALF_CONSTEXPR half operator-(half arg)
Negation.
Definition: includes/half.hpp:2560
half_float::half::log1p
friend half log1p(half)
Natural logarithm plus one.
Definition: includes/half.hpp:3173
half_float::detail::half2int
T half2int(unsigned int value)
Convert half-precision floating-point to integer.
Definition: includes/half.hpp:1334
half_float::detail::gamma
unsigned int gamma(unsigned int arg)
Gamma function and postprocessing.
Definition: includes/half.hpp:1954
half_float::fdim
half fdim(half x, half y)
Positive difference.
Definition: includes/half.hpp:2921
half_float::operator+
HALF_CONSTEXPR half operator+(half arg)
Identity.
Definition: includes/half.hpp:2555
half_float::isless
HALF_CONSTEXPR bool isless(half x, half y)
Quiet comparison for less than.
Definition: includes/half.hpp:4451
half_float::detail::uint32
unsigned long uint32
Fastest unsigned integer of (at least) 32 bits width.
Definition: includes/half.hpp:527
half_float::detail::float2half
unsigned int float2half(T value)
Convert floating-point to half-precision.
Definition: includes/half.hpp:1081
half_float::detail::check_underflow
HALF_CONSTEXPR_NOERR unsigned int check_underflow(unsigned int arg)
Check value for underflow.
Definition: includes/half.hpp:784
half_float::detail::float2half_impl
unsigned int float2half_impl(float value, true_type)
Convert IEEE single-precision to half-precision.
Definition: includes/half.hpp:924
half_float::half::hypot
friend half hypot(half, half)
Hypotenuse function.
Definition: includes/half.hpp:3332
half_float::hypot
half hypot(half x, half y)
Hypotenuse function.
Definition: includes/half.hpp:3332
half_float::half::copysign
friend HALF_CONSTEXPR half copysign(half, half)
Take sign.
Definition: includes/half.hpp:4359
half_float::sinh
half sinh(half arg)
Hyperbolic sine.
Definition: includes/half.hpp:3810
half_float::operator>>
std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &in, half &arg)
Input operator.
Definition: includes/half.hpp:2725
half_float::detail::area
unsigned int area(unsigned int arg)
Area function and postprocessing.
Definition: includes/half.hpp:1805
half_float::half::tgamma
friend half tgamma(half)
Gamma function.
Definition: includes/half.hpp:4055
half_float::half::fabs
friend HALF_CONSTEXPR half fabs(half)
Absolute value.
Definition: includes/half.hpp:2746
HALF_CONSTEXPR_CONST
#define HALF_CONSTEXPR_CONST
Definition: includes/half.hpp:241
half_float::half::operator++
half operator++(int)
Postfix increment.
Definition: includes/half.hpp:2171
std::numeric_limits< half_float::half >::min
static HALF_CONSTEXPR half_float::half min() HALF_NOTHROW
Smallest positive normal value.
Definition: includes/half.hpp:2422
half_float::lrint
long lrint(half arg)
Nearest integer using half's internal rounding mode.
Definition: includes/half.hpp:4135
half_float::fmod
half fmod(half x, half y)
Remainder of division.
Definition: includes/half.hpp:2760
half_float::half::isnan
friend HALF_CONSTEXPR bool isnan(half)
Check for NaN.
Definition: includes/half.hpp:4402
FP_INFINITE
#define FP_INFINITE
Definition: includes/half.hpp:431
half_float::isinf
HALF_CONSTEXPR bool isinf(half arg)
Check for infinity.
Definition: includes/half.hpp:4395
half_float::hypot
half hypot(half x, half y, half z)
Hypotenuse function.
Definition: includes/half.hpp:3378
half_float::remainder
half remainder(half x, half y)
Remainder of division.
Definition: includes/half.hpp:2781
half_float::islessequal
HALF_CONSTEXPR bool islessequal(half x, half y)
Quiet comparison for less equal.
Definition: includes/half.hpp:4462
half_float::asin
half asin(half arg)
Arc sine.
Definition: includes/half.hpp:3671
FP_ZERO
#define FP_ZERO
Definition: includes/half.hpp:425
half_float::remquo
half remquo(half x, half y, int *quo)
Remainder of division.
Definition: includes/half.hpp:2801
half_float::half
Half-precision floating-point type.
Definition: includes/half.hpp:2072
half_float::detail::is_float
Type traits for floating-point types.
Definition: includes/half.hpp:492
half_float::detail::sincos
std::pair< uint32, uint32 > sincos(uint32 mz, unsigned int n=31)
Fixed point sine and cosine.
Definition: includes/half.hpp:1575
half_float::detail::divide64
uint32 divide64(uint32 x, uint32 y, int &s)
64-bit division.
Definition: includes/half.hpp:1397
half_float::detail::f31::f31
HALF_CONSTEXPR f31(uint32 mant, int e)
Constructor.
Definition: includes/half.hpp:1860
half_float::half::atan2
friend half atan2(half, half)
Arc tangent function.
Definition: includes/half.hpp:3755
half_float::detail::bits::type
unsigned char type
Definition: includes/half.hpp:502
half_float::sincos
void sincos(half arg, half *sin, half *cos)
Compute sine and cosine simultaneously.
Definition: includes/half.hpp:3508
half_float::half::operator>>
friend std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &, half &)
Input operator.
Definition: includes/half.hpp:2725
half_float::erf
half erf(half arg)
Error function.
Definition: includes/half.hpp:3983
HALF_THREAD_LOCAL
#define HALF_THREAD_LOCAL
Definition: includes/half.hpp:258
half_float::detail::binary_t
Tag type for binary construction.
Definition: includes/half.hpp:550
half_float::half::nanh
friend half nanh(const char *)
Get NaN value.
Definition: includes/half.hpp:2932
half_float::half::isinf
friend HALF_CONSTEXPR bool isinf(half)
Check for infinity.
Definition: includes/half.hpp:4395
half_float::half::operator++
half & operator++()
Prefix increment.
Definition: includes/half.hpp:2161
half_float::detail::builtin_signbit
bool builtin_signbit(T arg)
Check sign.
Definition: includes/half.hpp:595
half_float::half::exp
friend half exp(half)
Exponential function.
Definition: includes/half.hpp:2953
half_float::copysign
HALF_CONSTEXPR half copysign(half x, half y)
Take sign.
Definition: includes/half.hpp:4359
half_float::isnan
HALF_CONSTEXPR bool isnan(half arg)
Check for NaN.
Definition: includes/half.hpp:4402
half_float::lround
long lround(half arg)
Nearest integer.
Definition: includes/half.hpp:4119
half_float::half::tan
friend half tan(half)
Tangent function.
Definition: includes/half.hpp:3634
half_float::half::lround
friend long lround(half)
Nearest integer.
Definition: includes/half.hpp:4119
half_float::isfinite
HALF_CONSTEXPR bool isfinite(half arg)
Check if finite number.
Definition: includes/half.hpp:4388
half_float::half::lrint
friend long lrint(half)
Nearest integer using half's internal rounding mode.
Definition: includes/half.hpp:4135
half_float::half::operator=
half & operator=(float rhs)
Assignment operator.
Definition: includes/half.hpp:2096
half_float::half::logb
friend half logb(half)
Extract exponent.
Definition: includes/half.hpp:4282
absl::swap_internal::swap
void swap()
half_float::half::islessgreater
friend HALF_CONSTEXPR bool islessgreater(half, half)
Quiet comarison for less or greater.
Definition: includes/half.hpp:4473
logs
Definition: includes/opentelemetry/logs/event_id.h:13
half_float::half::half
half(float rhs)
Conversion constructor.
Definition: includes/half.hpp:2086
half_float::half::operator+=
half & operator+=(half rhs)
Arithmetic assignment.
Definition: includes/half.hpp:2107
half_float::nanh
half nanh(const char *arg)
Get NaN value.
Definition: includes/half.hpp:2932
half_float::half::floor
friend half floor(half)
Nearest integer not greater than half value.
Definition: includes/half.hpp:4096
half_float::detail::sqrt
uint32 sqrt(uint32 &r, int &exp)
Fixed point square root.
Definition: includes/half.hpp:1497
half_float::pow
half pow(half x, half y)
Power function.
Definition: includes/half.hpp:3444
half_float::cos
half cos(half arg)
Cosine function.
Definition: includes/half.hpp:3606
half_float::half::operator<<
friend std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &, half)
Output operator.
Definition: includes/half.hpp:2707
half_float::detail::errflags
int & errflags()
Internal exception flags.
Definition: includes/half.hpp:637
half_float::log2
half log2(half arg)
Binary logarithm.
Definition: includes/half.hpp:3130
std::numeric_limits< half_float::half >::quiet_NaN
static HALF_CONSTEXPR half_float::half quiet_NaN() HALF_NOTHROW
Quiet NaN.
Definition: includes/half.hpp:2441
FE_UNDERFLOW
#define FE_UNDERFLOW
Definition: includes/half.hpp:441
half_float::detail::half_caster< T, half, R >::cast
static T cast(half arg)
Definition: includes/half.hpp:2327
half_float::half::operator*=
half & operator*=(float rhs)
Arithmetic assignment.
Definition: includes/half.hpp:2146
half_float::tan
half tan(half arg)
Tangent function.
Definition: includes/half.hpp:3634
half_float::detail::exp2_post
unsigned int exp2_post(uint32 m, int exp, bool esign, unsigned int sign=0, unsigned int n=32)
Postprocessing for binary exponential.
Definition: includes/half.hpp:1705
half_float::detail::builtin_isinf
bool builtin_isinf(T arg)
Check for infinity.
Definition: includes/half.hpp:563
half_float::detail::select
HALF_CONSTEXPR_NOERR unsigned int select(unsigned int x, unsigned int HALF_UNUSED_NOERR(y))
Select value or signaling NaN.
Definition: includes/half.hpp:748
half_float::operator*
half operator*(half x, half y)
Multiplication.
Definition: includes/half.hpp:2635
half_float::asinh
half asinh(half arg)
Hyperbolic area sine.
Definition: includes/half.hpp:3897
half_float::detail::hypot_post
unsigned int hypot_post(uint32 r, int exp)
Hypotenuse square root and postprocessing.
Definition: includes/half.hpp:1762
std::numeric_limits< half_float::half >::infinity
static HALF_CONSTEXPR half_float::half infinity() HALF_NOTHROW
Positive infinity.
Definition: includes/half.hpp:2438
half_float::atanh
half atanh(half arg)
Hyperbolic area tangent.
Definition: includes/half.hpp:3950
half_float::half::operator<=
friend HALF_CONSTEXPR_NOERR bool operator<=(half, half)
Comparison for less equal.
Definition: includes/half.hpp:2529
half_float::floor
half floor(half arg)
Nearest integer not greater than half value.
Definition: includes/half.hpp:4096
half_float::half::acosh
friend half acosh(half)
Hyperbolic area cosine.
Definition: includes/half.hpp:3925
half_float::log
half log(half arg)
Natural logarithm.
Definition: includes/half.hpp:3067
half_float::half::isnormal
friend HALF_CONSTEXPR bool isnormal(half)
Check if normal number.
Definition: includes/half.hpp:4409
half_float::log1p
half log1p(half arg)
Natural logarithm plus one.
Definition: includes/half.hpp:3173
HALF_CONSTEXPR
#define HALF_CONSTEXPR
Definition: includes/half.hpp:240
half_float::detail::hyperbolic_args
std::pair< uint32, uint32 > hyperbolic_args(unsigned int abs, int &exp, unsigned int n=32)
Get exponentials for hyperbolic computation.
Definition: includes/half.hpp:1667
half_float::detail::uint16
unsigned short uint16
Unsigned integer of (at least) 16 bits width.
Definition: includes/half.hpp:524
half_float::detail::multiply64
uint32 multiply64(uint32 x, uint32 y)
64-bit multiplication.
Definition: includes/half.hpp:1383
half_float::detail::half_caster< half, half, R >::cast
static half cast(half arg)
Definition: includes/half.hpp:2335
half_float::half::cos
friend half cos(half)
Cosine function.
Definition: includes/half.hpp:3606
half_float::detail::atan2_args
std::pair< uint32, uint32 > atan2_args(unsigned int abs)
Get arguments for atan2 function.
Definition: includes/half.hpp:1644
half_float::ceil
half ceil(half arg)
Nearest integer not less than half value.
Definition: includes/half.hpp:4088
half_float::operator==
HALF_CONSTEXPR_NOERR bool operator==(half x, half y)
Comparison for equality.
Definition: includes/half.hpp:2483
half_float::half::half
HALF_CONSTEXPR half() HALF_NOEXCEPT
Default constructor.
Definition: includes/half.hpp:2081
half_float::detail::binary
HALF_CONSTEXPR_CONST binary_t binary
Tag for binary construction.
Definition: includes/half.hpp:553
half_float::atan
half atan(half arg)
Arc tangent function.
Definition: includes/half.hpp:3725
FP_ILOGBNAN
#define FP_ILOGBNAN
Definition: includes/half.hpp:419
half_float::ldexp
half ldexp(half arg, int exp)
Multiply by power of two.
Definition: includes/half.hpp:4228
FE_OVERFLOW
#define FE_OVERFLOW
Definition: includes/half.hpp:440
half_float::detail::rounded
HALF_CONSTEXPR_NOERR unsigned int rounded(unsigned int value, int g, int s)
Round half-precision number.
Definition: includes/half.hpp:837
half_float::tanh
half tanh(half arg)
Hyperbolic tangent.
Definition: includes/half.hpp:3865
half_float::half::erf
friend half erf(half)
Error function.
Definition: includes/half.hpp:3983
half_float::detail::half2float_impl
float half2float_impl(unsigned int value, float, true_type)
Convert half-precision to IEEE single-precision.
Definition: includes/half.hpp:1113
half_float::lgamma
half lgamma(half arg)
Natural logarithm of gamma function.
Definition: includes/half.hpp:4030
half_float::half::modf
friend half modf(half, half *)
Extract integer and fractional parts.
Definition: includes/half.hpp:4236
half_float::atan2
half atan2(half y, half x)
Arc tangent function.
Definition: includes/half.hpp:3755
std::numeric_limits< half_float::half >::round_error
static HALF_CONSTEXPR half_float::half round_error() HALF_NOTHROW
Maximum rounding error in ULP (units in the last place).
Definition: includes/half.hpp:2434
half_float::operator!=
HALF_CONSTEXPR_NOERR bool operator!=(half x, half y)
Comparison for inequality.
Definition: includes/half.hpp:2494
half_float::log10
half log10(half arg)
Common logarithm.
Definition: includes/half.hpp:3095
half_float::feraiseexcept
int feraiseexcept(int excepts)
Raise exception flags.
Definition: includes/half.hpp:4555
half_float::detail::raise
void raise(int HALF_UNUSED_NOERR(flags), bool HALF_UNUSED_NOERR(cond)=true)
Raise floating-point exception.
Definition: includes/half.hpp:642
half_float::detail::fixed2half
unsigned int fixed2half(uint32 m, int exp=14, unsigned int sign=0, int s=0)
Convert fixed point to half-precision floating-point.
Definition: includes/half.hpp:901
half_float::half::erfc
friend half erfc(half)
Complementary error function.
Definition: includes/half.hpp:4005
half_float::half::nexttoward
friend half nexttoward(half, long double)
Next representable value.
Definition: includes/half.hpp:4335
HALF_NOTHROW
#define HALF_NOTHROW
Definition: includes/half.hpp:251
max
int max(int a, int b)
Compute the component-wise maximum.
Definition: sources/libs/nvmultiobjecttracker/include/modules/cuDCFv2/helper_math.h:60
half_float::detail::f31
Class for 1.31 unsigned floating-point computation.
Definition: includes/half.hpp:1855
half_float::detail::signal
HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int nan)
Signal and silence signaling NaN.
Definition: includes/half.hpp:708
half_float::detail::int2half
unsigned int int2half(T value)
Convert integer to half-precision floating-point.
Definition: includes/half.hpp:1093
half_float::half::ilogb
friend int ilogb(half)
Extract exponent.
Definition: includes/half.hpp:4264
half_float::half::lgamma
friend half lgamma(half)
Natural logarithm of gamma function.
Definition: includes/half.hpp:4030
half_float::tgamma
half tgamma(half arg)
Gamma function.
Definition: includes/half.hpp:4055
half_float::nexttoward
half nexttoward(half from, long double to)
Next representable value.
Definition: includes/half.hpp:4335
half_float::trunc
half trunc(half arg)
Nearest integer not greater in magnitude than half value.
Definition: includes/half.hpp:4104
half_float::half::operator+
friend half operator+(half, half)
Addition.
Definition: includes/half.hpp:2569
half_float::half::trunc
friend half trunc(half)
Nearest integer not greater in magnitude than half value.
Definition: includes/half.hpp:4104
half_float::half::rint
friend half rint(half)
Nearest integer using half's internal rounding mode.
Definition: includes/half.hpp:4127
half_float::fesetexceptflag
int fesetexceptflag(const int *flagp, int excepts)
Restore exception flags.
Definition: includes/half.hpp:4576
half_float::half::atan
friend half atan(half)
Arc tangent function.
Definition: includes/half.hpp:3725
HALF_NOEXCEPT
#define HALF_NOEXCEPT
Definition: includes/half.hpp:250
half_float::half::operator-=
half & operator-=(half rhs)
Arithmetic assignment.
Definition: includes/half.hpp:2114
half_float::detail::exp2
uint32 exp2(uint32 m, unsigned int n=32)
Fixed point binary exponential.
Definition: includes/half.hpp:1521
half_float::detail::atan2
uint32 atan2(uint32 my, uint32 mx, unsigned int n=31)
Fixed point arc tangent.
Definition: includes/half.hpp:1599
half_float::operator<=
HALF_CONSTEXPR_NOERR bool operator<=(half x, half y)
Comparison for less equal.
Definition: includes/half.hpp:2529
half_float::fetestexcept
int fetestexcept(int excepts)
Test exception flags.
Definition: includes/half.hpp:4544
half_float::half::tanh
friend half tanh(half)
Hyperbolic tangent.
Definition: includes/half.hpp:3865
half_float::half::operator--
half & operator--()
Prefix decrement.
Definition: includes/half.hpp:2166
half_float::expm1
half expm1(half arg)
Exponential minus one.
Definition: includes/half.hpp:3014
half_float::isgreaterequal
HALF_CONSTEXPR bool isgreaterequal(half x, half y)
Quiet comparison for greater equal.
Definition: includes/half.hpp:4440
half_float::nextafter
half nextafter(half from, half to)
Next representable value.
Definition: includes/half.hpp:4308
half_float::modf
half modf(half arg, half *iptr)
Extract integer and fractional parts.
Definition: includes/half.hpp:4236
half_float::ilogb
int ilogb(half arg)
Extract exponent.
Definition: includes/half.hpp:4264
half_float::exp
half exp(half arg)
Exponential function.
Definition: includes/half.hpp:2953
half_float::detail::log2_post
unsigned int log2_post(uint32 m, int ilog, int exp, unsigned int sign=0)
Postprocessing for binary logarithm.
Definition: includes/half.hpp:1737
FE_INVALID
#define FE_INVALID
Definition: includes/half.hpp:438
half_float::cosh
half cosh(half arg)
Hyperbolic cosine.
Definition: includes/half.hpp:3838
half_float::half::cbrt
friend half cbrt(half)
Cubic root.
Definition: includes/half.hpp:3281
half_float::acosh
half acosh(half arg)
Hyperbolic area cosine.
Definition: includes/half.hpp:3925
half_float::scalbn
half scalbn(half arg, int exp)
Multiply by power of two.
Definition: includes/half.hpp:4217
half_float::operator<
HALF_CONSTEXPR_NOERR bool operator<(half x, half y)
Comparison for less than.
Definition: includes/half.hpp:2505
half_float::detail::sign_mask
uint32 sign_mask(uint32 arg)
Platform-independent sign mask.
Definition: includes/half.hpp:608
half_float::fethrowexcept
void fethrowexcept(int excepts, const char *msg="")
Throw C++ exceptions based on set exception flags.
Definition: includes/half.hpp:4589
half_float::half::operator--
half operator--(int)
Postfix decrement.
Definition: includes/half.hpp:2176
half_float::detail::log2
uint32 log2(uint32 m, unsigned int n=32)
Fixed point binary logarithm.
Definition: includes/half.hpp:1548
half_float::half::fmod
friend half fmod(half, half)
Remainder of division.
Definition: includes/half.hpp:2760
half_float::half::operator/=
half & operator/=(float rhs)
Arithmetic assignment.
Definition: includes/half.hpp:2152
half_float::islessgreater
HALF_CONSTEXPR bool islessgreater(half x, half y)
Quiet comarison for less or greater.
Definition: includes/half.hpp:4473
std::numeric_limits< half_float::half >::epsilon
static HALF_CONSTEXPR half_float::half epsilon() HALF_NOTHROW
Difference between 1 and next representable value.
Definition: includes/half.hpp:2431
half_float::half::operator>=
friend HALF_CONSTEXPR_NOERR bool operator>=(half, half)
Comparison for greater equal.
Definition: includes/half.hpp:2541
half_float::detail::true_type
bool_type< true > true_type
Definition: includes/half.hpp:488
half_float::fabs
HALF_CONSTEXPR half fabs(half arg)
Absolute value.
Definition: includes/half.hpp:2746
half_float::nearbyint
half nearbyint(half arg)
Nearest integer using half's internal rounding mode.
Definition: includes/half.hpp:4142
half_float
Main namespace for half-precision functionality.
Definition: includes/half.hpp:449
half_float::half::operator*=
half & operator*=(half rhs)
Arithmetic assignment.
Definition: includes/half.hpp:2121
half_float::half::scalbln
friend half scalbln(half, long)
Multiply by power of two.
Definition: includes/half.hpp:4191
half_float::detail::bool_type
Helper for tag dispatching.
Definition: includes/half.hpp:487
half_float::half::acos
friend half acos(half)
Arc cosine function.
Definition: includes/half.hpp:3700
FP_SUBNORMAL
#define FP_SUBNORMAL
Definition: includes/half.hpp:422
half_float::half::log
friend half log(half)
Natural logarithm.
Definition: includes/half.hpp:3067
half_float::operator<<
std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &out, half arg)
Output operator.
Definition: includes/half.hpp:2707
half_float::half::fpclassify
friend HALF_CONSTEXPR int fpclassify(half)
Classify floating-point value.
Definition: includes/half.hpp:4374
half_float::half::fma
friend half fma(half, half, half)
Fused multiply add.
Definition: includes/half.hpp:2826
half_float::detail::overflow
HALF_CONSTEXPR_NOERR unsigned int overflow(unsigned int sign=0)
Half-precision overflow.
Definition: includes/half.hpp:801
half_float::half::sincos
friend void sincos(half, half *, half *)
Compute sine and cosine simultaneously.
Definition: includes/half.hpp:3508
half_float::fpclassify
HALF_CONSTEXPR int fpclassify(half arg)
Classify floating-point value.
Definition: includes/half.hpp:4374
half_float::detail::conditional::type
T type
Definition: includes/half.hpp:483
half_float::half::islessequal
friend HALF_CONSTEXPR bool islessequal(half, half)
Quiet comparison for less equal.
Definition: includes/half.hpp:4462
std::numeric_limits< half_float::half >::denorm_min
static HALF_CONSTEXPR half_float::half denorm_min() HALF_NOTHROW
Smallest positive subnormal value.
Definition: includes/half.hpp:2447
half_float::operator/
half operator/(half x, half y)
Division.
Definition: includes/half.hpp:2668
half_float::scalbln
half scalbln(half arg, long exp)
Multiply by power of two.
Definition: includes/half.hpp:4191
half_float::sqrt
half sqrt(half arg)
Square root.
Definition: includes/half.hpp:3223
min
int min(int a, int b)
Compute the component-wise minimum.
Definition: sources/libs/nvmultiobjecttracker/include/modules/cuDCFv2/helper_math.h:70
half_float::rsqrt
half rsqrt(half arg)
Inverse square root.
Definition: includes/half.hpp:3244
half_float::half_cast
T half_cast(U arg)
Cast to or from half-precision floating-point number.
Definition: includes/half.hpp:4504
half_float::half::remainder
friend half remainder(half, half)
Remainder of division.
Definition: includes/half.hpp:2781
half_float::half::signbit
friend HALF_CONSTEXPR bool signbit(half)
Check sign.
Definition: includes/half.hpp:4416
half_float::half::nextafter
friend half nextafter(half, half)
Next representable value.
Definition: includes/half.hpp:4308
half_float::half::round
friend half round(half)
Nearest integer.
Definition: includes/half.hpp:4112
half_float::detail::mulhi
uint32 mulhi(uint32 x, uint32 y)
upper part of 64-bit multiplication.
Definition: includes/half.hpp:1372
half_float::fmin
HALF_CONSTEXPR_NOERR half fmin(half x, half y)
Minimum of half expressions.
Definition: includes/half.hpp:2907
half_float::half::fmax
friend HALF_CONSTEXPR_NOERR half fmax(half, half)
Maximum of half expressions.
Definition: includes/half.hpp:2895
half_float::detail::half_caster< half, U, R >::cast
static half cast(U arg)
Definition: includes/half.hpp:2315
half_float::operator>
HALF_CONSTEXPR_NOERR bool operator>(half x, half y)
Comparison for greater than.
Definition: includes/half.hpp:2517
HALF_ROUND_STYLE
#define HALF_ROUND_STYLE
Default rounding mode.
Definition: includes/half.hpp:391
half_float::isgreater
HALF_CONSTEXPR bool isgreater(half x, half y)
Quiet comparison for greater than.
Definition: includes/half.hpp:4429
half_float::detail::compsignal
HALF_CONSTEXPR_NOERR bool compsignal(unsigned int x, unsigned int y)
Check and signal for any NaN.
Definition: includes/half.hpp:696
std
Extensions to the C++ standard library.
Definition: includes/opentelemetry/nostd/string_view.h:212
half_float::feclearexcept
int feclearexcept(int excepts)
Clear exception flags.
Definition: includes/half.hpp:4535
std::numeric_limits< half_float::half >::signaling_NaN
static HALF_CONSTEXPR half_float::half signaling_NaN() HALF_NOTHROW
Signaling NaN.
Definition: includes/half.hpp:2444
half_float::detail::f31::operator-
friend f31 operator-(f31 a, f31 b)
Subtraction operator.
Definition: includes/half.hpp:1889
half_float::half::atanh
friend half atanh(half)
Hyperbolic area tangent.
Definition: includes/half.hpp:3950
half_float::isnormal
HALF_CONSTEXPR bool isnormal(half arg)
Check if normal number.
Definition: includes/half.hpp:4409
half_float::half::operator!=
friend HALF_CONSTEXPR_NOERR bool operator!=(half, half)
Comparison for inequality.
Definition: includes/half.hpp:2494
half_float::erfc
half erfc(half arg)
Complementary error function.
Definition: includes/half.hpp:4005
HALF_CONSTEXPR_NOERR
#define HALF_CONSTEXPR_NOERR
Definition: includes/half.hpp:242
half_float::rint
half rint(half arg)
Nearest integer using half's internal rounding mode.
Definition: includes/half.hpp:4127
half_float::frexp
half frexp(half arg, int *exp)
Decompress floating-point number.
Definition: includes/half.hpp:4171
std::numeric_limits< half_float::half >::max
static HALF_CONSTEXPR half_float::half max() HALF_NOTHROW
Largest finite value.
Definition: includes/half.hpp:2428
FP_NORMAL
#define FP_NORMAL
Definition: includes/half.hpp:434
half_float::detail::arithmetic_shift
uint32 arithmetic_shift(uint32 arg, int i)
Platform-independent arithmetic right shift.
Definition: includes/half.hpp:622
FE_INEXACT
#define FE_INEXACT
Definition: includes/half.hpp:442
half_float::half::operator/
friend half operator/(half, half)
Division.
Definition: includes/half.hpp:2668
half_float::half::isfinite
friend HALF_CONSTEXPR bool isfinite(half)
Check if finite number.
Definition: includes/half.hpp:4388
half_float::half::ceil
friend half ceil(half)
Nearest integer not less than half value.
Definition: includes/half.hpp:4088
half_float::detail::f31::operator*
friend f31 operator*(f31 a, f31 b)
Multiplication operator.
Definition: includes/half.hpp:1903
half_float::logb
half logb(half arg)
Extract exponent.
Definition: includes/half.hpp:4282
half_float::isunordered
HALF_CONSTEXPR bool isunordered(half x, half y)
Quiet check if unordered.
Definition: includes/half.hpp:4484
half_float::half::asinh
friend half asinh(half)
Hyperbolic area sine.
Definition: includes/half.hpp:3897
FP_NAN
#define FP_NAN
Definition: includes/half.hpp:428
half_float::detail::integral
unsigned int integral(unsigned int value)
Round half-precision number to nearest integer value.
Definition: includes/half.hpp:866
half_float::detail::int32
long int32
Fastest unsigned integer of (at least) 32 bits width.
Definition: includes/half.hpp:530
half_float::detail::half_caster
Helper class for half casts.
Definition: includes/half.hpp:2052
half_float::half::sinh
friend half sinh(half)
Hyperbolic sine.
Definition: includes/half.hpp:3810
half_float::detail::mod
unsigned int mod(unsigned int x, unsigned int y, int *quo=NULL)
Half precision positive modulus.
Definition: includes/half.hpp:1426
half_float::half::fdim
friend half fdim(half, half)
Positive difference.
Definition: includes/half.hpp:2921
half_float::detail::conditional
Conditional type.
Definition: includes/half.hpp:483
half_float::signbit
HALF_CONSTEXPR bool signbit(half arg)
Check sign.
Definition: includes/half.hpp:4416
half_float::detail::half2float
T half2float(unsigned int value)
Convert half-precision to floating-point.
Definition: includes/half.hpp:1320
half_float::detail::erf
unsigned int erf(unsigned int arg)
Error function and postprocessing.
Definition: includes/half.hpp:1935
half_float::half::frexp
friend half frexp(half, int *)
Decompress floating-point number.
Definition: includes/half.hpp:4171
half_float::detail::invalid
HALF_CONSTEXPR_NOERR unsigned int invalid()
Raise domain error and return NaN.
Definition: includes/half.hpp:760
half_float::half::operator*
friend half operator*(half, half)
Multiplication.
Definition: includes/half.hpp:2635
half_float::half::log10
friend half log10(half)
Common logarithm.
Definition: includes/half.hpp:3095
half_float::half::operator<
friend HALF_CONSTEXPR_NOERR bool operator<(half, half)
Comparison for less than.
Definition: includes/half.hpp:2505
half_float::operator>=
HALF_CONSTEXPR_NOERR bool operator>=(half x, half y)
Comparison for greater equal.
Definition: includes/half.hpp:2541
half_float::half::log2
friend half log2(half)
Binary logarithm.
Definition: includes/half.hpp:3130
half_float::half::asin
friend half asin(half)
Arc sine.
Definition: includes/half.hpp:3671
half_float::half::remquo
friend half remquo(half, half, int *)
Remainder of division.
Definition: includes/half.hpp:2801
half_float::detail::pole
HALF_CONSTEXPR_NOERR unsigned int pole(unsigned int sign=0)
Raise pole error and return infinity.
Definition: includes/half.hpp:772
half_float::half::fmin
friend HALF_CONSTEXPR_NOERR half fmin(half, half)
Minimum of half expressions.
Definition: includes/half.hpp:2907
half_float::half::pow
friend half pow(half, half)
Power function.
Definition: includes/half.hpp:3444
half_float::fmax
HALF_CONSTEXPR_NOERR half fmax(half x, half y)
Maximum of half expressions.
Definition: includes/half.hpp:2895
half_float::half::sin
friend half sin(half)
Sine function.
Definition: includes/half.hpp:3573
half_float::detail::f31::m
uint32 m
mantissa as 1.31.
Definition: includes/half.hpp:1921
half_float::detail::angle_arg
uint32 angle_arg(unsigned int abs, int &k)
Reduce argument for trigonometric functions.
Definition: includes/half.hpp:1621
half_float::half::rsqrt
friend half rsqrt(half)
Inverse square root.
Definition: includes/half.hpp:3244
FE_DIVBYZERO
#define FE_DIVBYZERO
Definition: includes/half.hpp:439
FP_ILOGB0
#define FP_ILOGB0
Definition: includes/half.hpp:416
half_float::half::cosh
friend half cosh(half)
Hyperbolic cosine.
Definition: includes/half.hpp:3838
half_float::detail::f31::operator/
friend f31 operator/(f31 a, f31 b)
Division operator.
Definition: includes/half.hpp:1914
half_float::detail::f31::exp
int exp
exponent.
Definition: includes/half.hpp:1922
half_float::half::operator+=
half & operator+=(float rhs)
Arithmetic assignment.
Definition: includes/half.hpp:2134
std::numeric_limits< half_float::half >::lowest
static HALF_CONSTEXPR half_float::half lowest() HALF_NOTHROW
Smallest finite value.
Definition: includes/half.hpp:2425
half_float::cbrt
half cbrt(half arg)
Cubic root.
Definition: includes/half.hpp:3281
half_float::detail::f31::operator+
friend f31 operator+(f31 a, f31 b)
Addition operator.
Definition: includes/half.hpp:1875
half_float::half::operator>
friend HALF_CONSTEXPR_NOERR bool operator>(half, half)
Comparison for greater than.
Definition: includes/half.hpp:2517
HALF_UNUSED_NOERR
#define HALF_UNUSED_NOERR(name)
Definition: includes/half.hpp:227
half_float::half::operator-=
half & operator-=(float rhs)
Arithmetic assignment.
Definition: includes/half.hpp:2140
half_float::abs
HALF_CONSTEXPR half abs(half arg)
Absolute value.
Definition: includes/half.hpp:2752
half_float::fegetexceptflag
int fegetexceptflag(int *flagp, int excepts)
Save exception flags.
Definition: includes/half.hpp:4565
half_float::half::operator-
friend HALF_CONSTEXPR half operator-(half)
Negation.
Definition: includes/half.hpp:2560
half_float::detail::conditional< false, T, F >::type
F type
Definition: includes/half.hpp:484
half_float::sin
half sin(half arg)
Sine function.
Definition: includes/half.hpp:3573
half_float::half::nearbyint
friend half nearbyint(half)
Nearest integer using half's internal rounding mode.
Definition: includes/half.hpp:4142
half_float::half::exp2
friend half exp2(half)
Binary exponential.
Definition: includes/half.hpp:2988
half_float::detail::bits
Type traits for floating-point bits.
Definition: includes/half.hpp:502
half_float::half::operator/=
half & operator/=(half rhs)
Arithmetic assignment.
Definition: includes/half.hpp:2128
half_float::half::isless
friend HALF_CONSTEXPR bool isless(half, half)
Quiet comparison for less than.
Definition: includes/half.hpp:4451
half_float::half::operator==
friend HALF_CONSTEXPR_NOERR bool operator==(half, half)
Comparison for equality.
Definition: includes/half.hpp:2483
half_float::half::isgreater
friend HALF_CONSTEXPR bool isgreater(half, half)
Quiet comparison for greater than.
Definition: includes/half.hpp:4429
half_float::exp2
half exp2(half arg)
Binary exponential.
Definition: includes/half.hpp:2988