GADGET-4
half.hpp
Go to the documentation of this file.
1 
7 // half - IEEE 754-based half-precision floating point library.
8 //
9 // Copyright (c) 2012-2017 Christian Rau <rauy@users.sourceforge.net>
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
12 // files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
13 // modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
14 // Software is furnished to do so, subject to the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
19 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 
23 // Version 1.12.0
24 
25 #ifndef HALF_HALF_HPP
26 #define HALF_HALF_HPP
27 
29 #define HALF_GNUC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
30 
31 // check C++11 language features
32 #if defined(__clang__) // clang
33 #if __has_feature(cxx_static_assert) && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
34 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
35 #endif
36 #if __has_feature(cxx_constexpr) && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
37 #define HALF_ENABLE_CPP11_CONSTEXPR 1
38 #endif
39 #if __has_feature(cxx_noexcept) && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
40 #define HALF_ENABLE_CPP11_NOEXCEPT 1
41 #endif
42 #if __has_feature(cxx_user_literals) && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
43 #define HALF_ENABLE_CPP11_USER_LITERALS 1
44 #endif
45 #if(defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) && !defined(HALF_ENABLE_CPP11_LONG_LONG)
46 #define HALF_ENABLE_CPP11_LONG_LONG 1
47 #endif
48 /*#elif defined(__INTEL_COMPILER) //Intel C++
49  #if __INTEL_COMPILER >= 1100 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT) ????????
50  #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
51  #endif
52  #if __INTEL_COMPILER >= 1300 && !defined(HALF_ENABLE_CPP11_CONSTEXPR) ????????
53  #define HALF_ENABLE_CPP11_CONSTEXPR 1
54  #endif
55  #if __INTEL_COMPILER >= 1300 && !defined(HALF_ENABLE_CPP11_NOEXCEPT) ????????
56  #define HALF_ENABLE_CPP11_NOEXCEPT 1
57  #endif
58  #if __INTEL_COMPILER >= 1100 && !defined(HALF_ENABLE_CPP11_LONG_LONG) ????????
59  #define HALF_ENABLE_CPP11_LONG_LONG 1
60  #endif*/
61 #elif defined(__GNUC__) // gcc
62 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
63 #if HALF_GNUC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
64 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
65 #endif
66 #if HALF_GNUC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
67 #define HALF_ENABLE_CPP11_CONSTEXPR 1
68 #endif
69 #if HALF_GNUC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
70 #define HALF_ENABLE_CPP11_NOEXCEPT 1
71 #endif
72 #if HALF_GNUC_VERSION >= 407 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
73 #define HALF_ENABLE_CPP11_USER_LITERALS 1
74 #endif
75 #if !defined(HALF_ENABLE_CPP11_LONG_LONG)
76 #define HALF_ENABLE_CPP11_LONG_LONG 1
77 #endif
78 #endif
79 #elif defined(_MSC_VER) // Visual C++
80 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
81 #define HALF_ENABLE_CPP11_CONSTEXPR 1
82 #endif
83 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
84 #define HALF_ENABLE_CPP11_NOEXCEPT 1
85 #endif
86 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
87 #define HALF_ENABLE_CPP11_USER_LITERALS 1
88 #endif
89 #if _MSC_VER >= 1600 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
90 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
91 #endif
92 #if _MSC_VER >= 1310 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
93 #define HALF_ENABLE_CPP11_LONG_LONG 1
94 #endif
95 #define HALF_POP_WARNINGS 1
96 #pragma warning(push)
97 #pragma warning(disable : 4099 4127 4146) // struct vs class, constant in if, negative unsigned
98 #endif
99 
100 // check C++11 library features
101 #include <utility>
102 #if defined(_LIBCPP_VERSION) // libc++
103 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
104 #ifndef HALF_ENABLE_CPP11_TYPE_TRAITS
105 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
106 #endif
107 #ifndef HALF_ENABLE_CPP11_CSTDINT
108 #define HALF_ENABLE_CPP11_CSTDINT 1
109 #endif
110 #ifndef HALF_ENABLE_CPP11_CMATH
111 #define HALF_ENABLE_CPP11_CMATH 1
112 #endif
113 #ifndef HALF_ENABLE_CPP11_HASH
114 #define HALF_ENABLE_CPP11_HASH 1
115 #endif
116 #endif
117 #elif defined(__GLIBCXX__) // libstdc++
118 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
119 #ifdef __clang__
120 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
121 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
122 #endif
123 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CSTDINT)
124 #define HALF_ENABLE_CPP11_CSTDINT 1
125 #endif
126 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CMATH)
127 #define HALF_ENABLE_CPP11_CMATH 1
128 #endif
129 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_HASH)
130 #define HALF_ENABLE_CPP11_HASH 1
131 #endif
132 #else
133 #if HALF_GNUC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CSTDINT)
134 #define HALF_ENABLE_CPP11_CSTDINT 1
135 #endif
136 #if HALF_GNUC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CMATH)
137 #define HALF_ENABLE_CPP11_CMATH 1
138 #endif
139 #if HALF_GNUC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_HASH)
140 #define HALF_ENABLE_CPP11_HASH 1
141 #endif
142 #endif
143 #endif
144 #elif defined(_CPPLIB_VER) // Dinkumware/Visual C++
145 #if _CPPLIB_VER >= 520
146 #ifndef HALF_ENABLE_CPP11_TYPE_TRAITS
147 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
148 #endif
149 #ifndef HALF_ENABLE_CPP11_CSTDINT
150 #define HALF_ENABLE_CPP11_CSTDINT 1
151 #endif
152 #ifndef HALF_ENABLE_CPP11_HASH
153 #define HALF_ENABLE_CPP11_HASH 1
154 #endif
155 #endif
156 #if _CPPLIB_VER >= 610
157 #ifndef HALF_ENABLE_CPP11_CMATH
158 #define HALF_ENABLE_CPP11_CMATH 1
159 #endif
160 #endif
161 #endif
162 #undef HALF_GNUC_VERSION
163 
164 // support constexpr
165 #if HALF_ENABLE_CPP11_CONSTEXPR
166 #define HALF_CONSTEXPR constexpr
167 #define HALF_CONSTEXPR_CONST constexpr
168 #else
169 #define HALF_CONSTEXPR
170 #define HALF_CONSTEXPR_CONST const
171 #endif
172 
173 // support noexcept
174 #if HALF_ENABLE_CPP11_NOEXCEPT
175 #define HALF_NOEXCEPT noexcept
176 #define HALF_NOTHROW noexcept
177 #else
178 #define HALF_NOEXCEPT
179 #define HALF_NOTHROW throw()
180 #endif
181 
182 #include <algorithm>
183 #include <climits>
184 #include <cmath>
185 #include <cstring>
186 #include <iostream>
187 #include <limits>
188 #if HALF_ENABLE_CPP11_TYPE_TRAITS
189 #include <type_traits>
190 #endif
191 #if HALF_ENABLE_CPP11_CSTDINT
192 #include <cstdint>
193 #endif
194 #if HALF_ENABLE_CPP11_HASH
195 #include <functional>
196 #endif
197 
214 #ifndef HALF_ROUND_STYLE
215 #define HALF_ROUND_STYLE -1 // = std::round_indeterminate
216 #endif
217 
223 #ifndef HALF_ROUND_TIES_TO_EVEN
224 #define HALF_ROUND_TIES_TO_EVEN 0 // ties away from zero
225 #endif
226 
230 #define HUGE_VALH std::numeric_limits<half_float::half>::infinity()
231 
236 #define FP_FAST_FMAH 1
237 
238 #ifndef FP_ILOGB0
239 #define FP_ILOGB0 INT_MIN
240 #endif
241 #ifndef FP_ILOGBNAN
242 #define FP_ILOGBNAN INT_MAX
243 #endif
244 #ifndef FP_SUBNORMAL
245 #define FP_SUBNORMAL 0
246 #endif
247 #ifndef FP_ZERO
248 #define FP_ZERO 1
249 #endif
250 #ifndef FP_NAN
251 #define FP_NAN 2
252 #endif
253 #ifndef FP_INFINITE
254 #define FP_INFINITE 3
255 #endif
256 #ifndef FP_NORMAL
257 #define FP_NORMAL 4
258 #endif
259 
262 namespace half_float
263 {
264 class half;
265 
266 #if HALF_ENABLE_CPP11_USER_LITERALS
273 namespace literal
274 {
275 half operator""_h(long double);
276 }
277 #endif
278 
281 namespace detail
282 {
283 #if HALF_ENABLE_CPP11_TYPE_TRAITS
285 template <bool B, typename T, typename F>
286 struct conditional : std::conditional<B, T, F>
287 {
288 };
289 
291 template <bool B>
292 struct bool_type : std::integral_constant<bool, B>
293 {
294 };
295 using std::false_type;
296 using std::true_type;
297 
299 template <typename T>
300 struct is_float : std::is_floating_point<T>
301 {
302 };
303 #else
305 template <bool, typename T, typename>
307 {
308  typedef T type;
309 };
310 template <typename T, typename F>
311 struct conditional<false, T, F>
312 {
313  typedef F type;
314 };
315 
317 template <bool>
318 struct bool_type
319 {
320 };
323 
325 template <typename>
327 {
328 };
329 template <typename T>
330 struct is_float<const T> : is_float<T>
331 {
332 };
333 template <typename T>
334 struct is_float<volatile T> : is_float<T>
335 {
336 };
337 template <typename T>
338 struct is_float<const volatile T> : is_float<T>
339 {
340 };
341 template <>
342 struct is_float<float> : true_type
343 {
344 };
345 template <>
346 struct is_float<double> : true_type
347 {
348 };
349 template <>
350 struct is_float<long double> : true_type
351 {
352 };
353 #endif
354 
356 template <typename T>
357 struct bits
358 {
359  typedef unsigned char type;
360 };
361 template <typename T>
362 struct bits<const T> : bits<T>
363 {
364 };
365 template <typename T>
366 struct bits<volatile T> : bits<T>
367 {
368 };
369 template <typename T>
370 struct bits<const volatile T> : bits<T>
371 {
372 };
373 
374 #if HALF_ENABLE_CPP11_CSTDINT
376 typedef std::uint_least16_t uint16;
377 
379 template <>
380 struct bits<float>
381 {
382  typedef std::uint_least32_t type;
383 };
384 
386 template <>
387 struct bits<double>
388 {
389  typedef std::uint_least64_t type;
390 };
391 #else
393 typedef unsigned short uint16;
394 
396 template <>
397 struct bits<float> : conditional<std::numeric_limits<unsigned int>::digits >= 32, unsigned int, unsigned long>
398 {
399 };
400 
401 #if HALF_ENABLE_CPP11_LONG_LONG
403 template <>
404 struct bits<double> : conditional<std::numeric_limits<unsigned long>::digits >= 64, unsigned long, unsigned long long>
405 {
406 };
407 #else
409 template <>
410 struct bits<double>
411 {
412  typedef unsigned long type;
413 };
414 #endif
415 #endif
416 
418 struct binary_t
419 {
420 };
421 
424 
427 struct expr
428 {
431  explicit HALF_CONSTEXPR expr(float f) HALF_NOEXCEPT : value_(f) {}
432 
435  HALF_CONSTEXPR operator float() const HALF_NOEXCEPT { return value_; }
436 
437  private:
439  float value_;
440 };
441 
446 template <typename T, typename, typename = void, typename = void>
447 struct enable
448 {
449 };
450 template <typename T>
451 struct enable<T, half, void, void>
452 {
453  typedef T type;
454 };
455 template <typename T>
456 struct enable<T, expr, void, void>
457 {
458  typedef T type;
459 };
460 template <typename T>
461 struct enable<T, half, half, void>
462 {
463  typedef T type;
464 };
465 template <typename T>
466 struct enable<T, half, expr, void>
467 {
468  typedef T type;
469 };
470 template <typename T>
471 struct enable<T, expr, half, void>
472 {
473  typedef T type;
474 };
475 template <typename T>
476 struct enable<T, expr, expr, void>
477 {
478  typedef T type;
479 };
480 template <typename T>
481 struct enable<T, half, half, half>
482 {
483  typedef T type;
484 };
485 template <typename T>
486 struct enable<T, half, half, expr>
487 {
488  typedef T type;
489 };
490 template <typename T>
491 struct enable<T, half, expr, half>
492 {
493  typedef T type;
494 };
495 template <typename T>
496 struct enable<T, half, expr, expr>
497 {
498  typedef T type;
499 };
500 template <typename T>
501 struct enable<T, expr, half, half>
502 {
503  typedef T type;
504 };
505 template <typename T>
506 struct enable<T, expr, half, expr>
507 {
508  typedef T type;
509 };
510 template <typename T>
511 struct enable<T, expr, expr, half>
512 {
513  typedef T type;
514 };
515 template <typename T>
516 struct enable<T, expr, expr, expr>
517 {
518  typedef T type;
519 };
520 
526 template <typename T, typename U>
527 struct result : enable<expr, T, U>
528 {
529 };
530 template <>
531 struct result<half, half>
532 {
533  typedef half type;
534 };
535 
538 
544 template <typename T>
545 bool builtin_isinf(T arg)
546 {
547 #if HALF_ENABLE_CPP11_CMATH
548  return std::isinf(arg);
549 #elif defined(_MSC_VER)
550  return !::_finite(static_cast<double>(arg)) && !::_isnan(static_cast<double>(arg));
551 #else
552  return arg == std::numeric_limits<T>::infinity() || arg == -std::numeric_limits<T>::infinity();
553 #endif
554 }
555 
561 template <typename T>
562 bool builtin_isnan(T arg)
563 {
564 #if HALF_ENABLE_CPP11_CMATH
565  return std::isnan(arg);
566 #elif defined(_MSC_VER)
567  return ::_isnan(static_cast<double>(arg)) != 0;
568 #else
569  return arg != arg;
570 #endif
571 }
572 
578 template <typename T>
579 bool builtin_signbit(T arg)
580 {
581 #if HALF_ENABLE_CPP11_CMATH
582  return std::signbit(arg);
583 #else
584  return arg < T() || (arg == T() && T(1) / arg < T());
585 #endif
586 }
587 
591 
597 template <std::float_round_style R>
598 uint16 float2half_impl(float value, true_type)
599 {
600  typedef bits<float>::type uint32;
601  uint32 bits; // = *reinterpret_cast<uint32*>(&value); //violating strict aliasing!
602  std::memcpy(&bits, &value, sizeof(float));
603  /* uint16 hbits = (bits>>16) & 0x8000;
604  bits &= 0x7FFFFFFF;
605  int exp = bits >> 23;
606  if(exp == 255)
607  return hbits | 0x7C00 | (0x3FF&-static_cast<unsigned>((bits&0x7FFFFF)!=0));
608  if(exp > 142)
609  {
610  if(R == std::round_toward_infinity)
611  return hbits | 0x7C00 - (hbits>>15);
612  if(R == std::round_toward_neg_infinity)
613  return hbits | 0x7BFF + (hbits>>15);
614  return hbits | 0x7BFF + (R!=std::round_toward_zero);
615  }
616  int g, s;
617  if(exp > 112)
618  {
619  g = (bits>>12) & 1;
620  s = (bits&0xFFF) != 0;
621  hbits |= ((exp-112)<<10) | ((bits>>13)&0x3FF);
622  }
623  else if(exp > 101)
624  {
625  int i = 125 - exp;
626  bits = (bits&0x7FFFFF) | 0x800000;
627  g = (bits>>i) & 1;
628  s = (bits&((1L<<i)-1)) != 0;
629  hbits |= bits >> (i+1);
630  }
631  else
632  {
633  g = 0;
634  s = bits != 0;
635  }
636  if(R == std::round_to_nearest)
637  #if HALF_ROUND_TIES_TO_EVEN
638  hbits += g & (s|hbits);
639  #else
640  hbits += g;
641  #endif
642  else if(R == std::round_toward_infinity)
643  hbits += ~(hbits>>15) & (s|g);
644  else if(R == std::round_toward_neg_infinity)
645  hbits += (hbits>>15) & (g|s);
646  */
647  static const uint16 base_table[512] = {
648  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
649  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
650  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
651  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
652  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
653  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
654  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
655  0x0200, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00,
656  0x4000, 0x4400, 0x4800, 0x4C00, 0x5000, 0x5400, 0x5800, 0x5C00, 0x6000, 0x6400, 0x6800, 0x6C00, 0x7000, 0x7400, 0x7800, 0x7C00,
657  0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
658  0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
659  0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
660  0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
661  0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
662  0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
663  0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
664  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
665  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
666  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
667  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
668  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
669  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
670  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001, 0x8002, 0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100,
671  0x8200, 0x8400, 0x8800, 0x8C00, 0x9000, 0x9400, 0x9800, 0x9C00, 0xA000, 0xA400, 0xA800, 0xAC00, 0xB000, 0xB400, 0xB800, 0xBC00,
672  0xC000, 0xC400, 0xC800, 0xCC00, 0xD000, 0xD400, 0xD800, 0xDC00, 0xE000, 0xE400, 0xE800, 0xEC00, 0xF000, 0xF400, 0xF800, 0xFC00,
673  0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
674  0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
675  0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
676  0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
677  0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
678  0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
679  0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00};
680  static const unsigned char shift_table[512] = {
681  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,
682  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,
683  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,
684  24, 24, 24, 24, 24, 24, 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,
685  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,
686  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,
687  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,
688  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,
689  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,
690  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,
691  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,
692  24, 24, 24, 24, 24, 24, 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,
693  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,
694  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,
695  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,
696  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};
697  uint16 hbits = base_table[bits >> 23] + static_cast<uint16>((bits & 0x7FFFFF) >> shift_table[bits >> 23]);
698  if(R == std::round_to_nearest)
699  hbits += (((bits & 0x7FFFFF) >> (shift_table[bits >> 23] - 1)) | (((bits >> 23) & 0xFF) == 102)) & ((hbits & 0x7C00) != 0x7C00)
701  & (((((static_cast<uint32>(1) << (shift_table[bits >> 23] - 1)) - 1) & bits) != 0) | hbits)
702 #endif
703  ;
704  else if(R == std::round_toward_zero)
705  hbits -= ((hbits & 0x7FFF) == 0x7C00) & ~shift_table[bits >> 23];
706  else if(R == std::round_toward_infinity)
707  hbits += ((((bits & 0x7FFFFF & ((static_cast<uint32>(1) << (shift_table[bits >> 23])) - 1)) != 0) |
708  (((bits >> 23) <= 102) & ((bits >> 23) != 0))) &
709  (hbits < 0x7C00)) -
710  ((hbits == 0xFC00) & ((bits >> 23) != 511));
711  else if(R == std::round_toward_neg_infinity)
712  hbits += ((((bits & 0x7FFFFF & ((static_cast<uint32>(1) << (shift_table[bits >> 23])) - 1)) != 0) |
713  (((bits >> 23) <= 358) & ((bits >> 23) != 256))) &
714  (hbits < 0xFC00) & (hbits >> 15)) -
715  ((hbits == 0x7C00) & ((bits >> 23) != 255));
716  return hbits;
717 }
718 
723 template <std::float_round_style R>
724 uint16 float2half_impl(double value, true_type)
725 {
726  typedef bits<float>::type uint32;
727  typedef bits<double>::type uint64;
728  uint64 bits; // = *reinterpret_cast<uint64*>(&value); //violating strict aliasing!
729  std::memcpy(&bits, &value, sizeof(double));
730  uint32 hi = bits >> 32, lo = bits & 0xFFFFFFFF;
731  uint16 hbits = (hi >> 16) & 0x8000;
732  hi &= 0x7FFFFFFF;
733  int exp = hi >> 20;
734  if(exp == 2047)
735  return hbits | 0x7C00 | (0x3FF & -static_cast<unsigned>((bits & 0xFFFFFFFFFFFFF) != 0));
736  if(exp > 1038)
737  {
738  if(R == std::round_toward_infinity)
739  return hbits | 0x7C00 - (hbits >> 15);
740  if(R == std::round_toward_neg_infinity)
741  return hbits | 0x7BFF + (hbits >> 15);
742  return hbits | 0x7BFF + (R != std::round_toward_zero);
743  }
744  int g, s = lo != 0;
745  if(exp > 1008)
746  {
747  g = (hi >> 9) & 1;
748  s |= (hi & 0x1FF) != 0;
749  hbits |= ((exp - 1008) << 10) | ((hi >> 10) & 0x3FF);
750  }
751  else if(exp > 997)
752  {
753  int i = 1018 - exp;
754  hi = (hi & 0xFFFFF) | 0x100000;
755  g = (hi >> i) & 1;
756  s |= (hi & ((1L << i) - 1)) != 0;
757  hbits |= hi >> (i + 1);
758  }
759  else
760  {
761  g = 0;
762  s |= hi != 0;
763  }
764  if(R == std::round_to_nearest)
765 #if HALF_ROUND_TIES_TO_EVEN
766  hbits += g & (s | hbits);
767 #else
768  hbits += g;
769 #endif
770  else if(R == std::round_toward_infinity)
771  hbits += ~(hbits >> 15) & (s | g);
772  else if(R == std::round_toward_neg_infinity)
773  hbits += (hbits >> 15) & (g | s);
774  return hbits;
775 }
776 
782 template <std::float_round_style R, typename T>
783 uint16 float2half_impl(T value, ...)
784 {
785  uint16 hbits = static_cast<unsigned>(builtin_signbit(value)) << 15;
786  if(value == T())
787  return hbits;
788  if(builtin_isnan(value))
789  return hbits | 0x7FFF;
790  if(builtin_isinf(value))
791  return hbits | 0x7C00;
792  int exp;
793  std::frexp(value, &exp);
794  if(exp > 16)
795  {
796  if(R == std::round_toward_infinity)
797  return hbits | (0x7C00 - (hbits >> 15));
798  else if(R == std::round_toward_neg_infinity)
799  return hbits | (0x7BFF + (hbits >> 15));
800  return hbits | (0x7BFF + (R != std::round_toward_zero));
801  }
802  if(exp < -13)
803  value = std::ldexp(value, 24);
804  else
805  {
806  value = std::ldexp(value, 11 - exp);
807  hbits |= ((exp + 13) << 10);
808  }
809  T ival, frac = std::modf(value, &ival);
810  hbits += static_cast<uint16>(std::abs(static_cast<int>(ival)));
811  if(R == std::round_to_nearest)
812  {
813  frac = std::abs(frac);
814 #if HALF_ROUND_TIES_TO_EVEN
815  hbits += (frac > T(0.5)) | ((frac == T(0.5)) & hbits);
816 #else
817  hbits += frac >= T(0.5);
818 #endif
819  }
820  else if(R == std::round_toward_infinity)
821  hbits += frac > T();
822  else if(R == std::round_toward_neg_infinity)
823  hbits += frac < T();
824  return hbits;
825 }
826 
832 template <std::float_round_style R, typename T>
833 uint16 float2half(T value)
834 {
835  return float2half_impl<R>(value, bool_type < std::numeric_limits<T>::is_iec559 && sizeof(typename bits<T>::type) == sizeof(T) > ());
836 }
837 
844 template <std::float_round_style R, bool S, typename T>
845 uint16 int2half_impl(T value)
846 {
847 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
848  static_assert(std::is_integral<T>::value, "int to half conversion only supports builtin integer types");
849 #endif
850  if(S)
851  value = -value;
852  uint16 bits = S << 15;
853  if(value > 0xFFFF)
854  {
855  if(R == std::round_toward_infinity)
856  bits |= 0x7C00 - S;
857  else if(R == std::round_toward_neg_infinity)
858  bits |= 0x7BFF + S;
859  else
860  bits |= 0x7BFF + (R != std::round_toward_zero);
861  }
862  else if(value)
863  {
864  unsigned int m = value, exp = 24;
865  for(; m < 0x400; m <<= 1, --exp)
866  ;
867  for(; m > 0x7FF; m >>= 1, ++exp)
868  ;
869  bits |= (exp << 10) + m;
870  if(exp > 24)
871  {
872  if(R == std::round_to_nearest)
873  bits += (value >> (exp - 25)) & 1
874 #if HALF_ROUND_TIES_TO_EVEN
875  & (((((1 << (exp - 25)) - 1) & value) != 0) | bits)
876 #endif
877  ;
878  else if(R == std::round_toward_infinity)
879  bits += ((value & ((1 << (exp - 24)) - 1)) != 0) & !S;
880  else if(R == std::round_toward_neg_infinity)
881  bits += ((value & ((1 << (exp - 24)) - 1)) != 0) & S;
882  }
883  }
884  return bits;
885 }
886 
892 template <std::float_round_style R, typename T>
893 uint16 int2half(T value)
894 {
895  return (value < 0) ? int2half_impl<R, true>(value) : int2half_impl<R, false>(value);
896 }
897 
902 inline float half2float_impl(uint16 value, float, true_type)
903 {
904  typedef bits<float>::type uint32;
905  /* uint32 bits = static_cast<uint32>(value&0x8000) << 16;
906  int abs = value & 0x7FFF;
907  if(abs)
908  {
909  bits |= 0x38000000 << static_cast<unsigned>(abs>=0x7C00);
910  for(; abs<0x400; abs<<=1,bits-=0x800000) ;
911  bits += static_cast<uint32>(abs) << 13;
912  }
913  */
914  static const uint32 mantissa_table[2048] = {
915  0x00000000, 0x33800000, 0x34000000, 0x34400000, 0x34800000, 0x34A00000, 0x34C00000, 0x34E00000, 0x35000000, 0x35100000,
916  0x35200000, 0x35300000, 0x35400000, 0x35500000, 0x35600000, 0x35700000, 0x35800000, 0x35880000, 0x35900000, 0x35980000,
917  0x35A00000, 0x35A80000, 0x35B00000, 0x35B80000, 0x35C00000, 0x35C80000, 0x35D00000, 0x35D80000, 0x35E00000, 0x35E80000,
918  0x35F00000, 0x35F80000, 0x36000000, 0x36040000, 0x36080000, 0x360C0000, 0x36100000, 0x36140000, 0x36180000, 0x361C0000,
919  0x36200000, 0x36240000, 0x36280000, 0x362C0000, 0x36300000, 0x36340000, 0x36380000, 0x363C0000, 0x36400000, 0x36440000,
920  0x36480000, 0x364C0000, 0x36500000, 0x36540000, 0x36580000, 0x365C0000, 0x36600000, 0x36640000, 0x36680000, 0x366C0000,
921  0x36700000, 0x36740000, 0x36780000, 0x367C0000, 0x36800000, 0x36820000, 0x36840000, 0x36860000, 0x36880000, 0x368A0000,
922  0x368C0000, 0x368E0000, 0x36900000, 0x36920000, 0x36940000, 0x36960000, 0x36980000, 0x369A0000, 0x369C0000, 0x369E0000,
923  0x36A00000, 0x36A20000, 0x36A40000, 0x36A60000, 0x36A80000, 0x36AA0000, 0x36AC0000, 0x36AE0000, 0x36B00000, 0x36B20000,
924  0x36B40000, 0x36B60000, 0x36B80000, 0x36BA0000, 0x36BC0000, 0x36BE0000, 0x36C00000, 0x36C20000, 0x36C40000, 0x36C60000,
925  0x36C80000, 0x36CA0000, 0x36CC0000, 0x36CE0000, 0x36D00000, 0x36D20000, 0x36D40000, 0x36D60000, 0x36D80000, 0x36DA0000,
926  0x36DC0000, 0x36DE0000, 0x36E00000, 0x36E20000, 0x36E40000, 0x36E60000, 0x36E80000, 0x36EA0000, 0x36EC0000, 0x36EE0000,
927  0x36F00000, 0x36F20000, 0x36F40000, 0x36F60000, 0x36F80000, 0x36FA0000, 0x36FC0000, 0x36FE0000, 0x37000000, 0x37010000,
928  0x37020000, 0x37030000, 0x37040000, 0x37050000, 0x37060000, 0x37070000, 0x37080000, 0x37090000, 0x370A0000, 0x370B0000,
929  0x370C0000, 0x370D0000, 0x370E0000, 0x370F0000, 0x37100000, 0x37110000, 0x37120000, 0x37130000, 0x37140000, 0x37150000,
930  0x37160000, 0x37170000, 0x37180000, 0x37190000, 0x371A0000, 0x371B0000, 0x371C0000, 0x371D0000, 0x371E0000, 0x371F0000,
931  0x37200000, 0x37210000, 0x37220000, 0x37230000, 0x37240000, 0x37250000, 0x37260000, 0x37270000, 0x37280000, 0x37290000,
932  0x372A0000, 0x372B0000, 0x372C0000, 0x372D0000, 0x372E0000, 0x372F0000, 0x37300000, 0x37310000, 0x37320000, 0x37330000,
933  0x37340000, 0x37350000, 0x37360000, 0x37370000, 0x37380000, 0x37390000, 0x373A0000, 0x373B0000, 0x373C0000, 0x373D0000,
934  0x373E0000, 0x373F0000, 0x37400000, 0x37410000, 0x37420000, 0x37430000, 0x37440000, 0x37450000, 0x37460000, 0x37470000,
935  0x37480000, 0x37490000, 0x374A0000, 0x374B0000, 0x374C0000, 0x374D0000, 0x374E0000, 0x374F0000, 0x37500000, 0x37510000,
936  0x37520000, 0x37530000, 0x37540000, 0x37550000, 0x37560000, 0x37570000, 0x37580000, 0x37590000, 0x375A0000, 0x375B0000,
937  0x375C0000, 0x375D0000, 0x375E0000, 0x375F0000, 0x37600000, 0x37610000, 0x37620000, 0x37630000, 0x37640000, 0x37650000,
938  0x37660000, 0x37670000, 0x37680000, 0x37690000, 0x376A0000, 0x376B0000, 0x376C0000, 0x376D0000, 0x376E0000, 0x376F0000,
939  0x37700000, 0x37710000, 0x37720000, 0x37730000, 0x37740000, 0x37750000, 0x37760000, 0x37770000, 0x37780000, 0x37790000,
940  0x377A0000, 0x377B0000, 0x377C0000, 0x377D0000, 0x377E0000, 0x377F0000, 0x37800000, 0x37808000, 0x37810000, 0x37818000,
941  0x37820000, 0x37828000, 0x37830000, 0x37838000, 0x37840000, 0x37848000, 0x37850000, 0x37858000, 0x37860000, 0x37868000,
942  0x37870000, 0x37878000, 0x37880000, 0x37888000, 0x37890000, 0x37898000, 0x378A0000, 0x378A8000, 0x378B0000, 0x378B8000,
943  0x378C0000, 0x378C8000, 0x378D0000, 0x378D8000, 0x378E0000, 0x378E8000, 0x378F0000, 0x378F8000, 0x37900000, 0x37908000,
944  0x37910000, 0x37918000, 0x37920000, 0x37928000, 0x37930000, 0x37938000, 0x37940000, 0x37948000, 0x37950000, 0x37958000,
945  0x37960000, 0x37968000, 0x37970000, 0x37978000, 0x37980000, 0x37988000, 0x37990000, 0x37998000, 0x379A0000, 0x379A8000,
946  0x379B0000, 0x379B8000, 0x379C0000, 0x379C8000, 0x379D0000, 0x379D8000, 0x379E0000, 0x379E8000, 0x379F0000, 0x379F8000,
947  0x37A00000, 0x37A08000, 0x37A10000, 0x37A18000, 0x37A20000, 0x37A28000, 0x37A30000, 0x37A38000, 0x37A40000, 0x37A48000,
948  0x37A50000, 0x37A58000, 0x37A60000, 0x37A68000, 0x37A70000, 0x37A78000, 0x37A80000, 0x37A88000, 0x37A90000, 0x37A98000,
949  0x37AA0000, 0x37AA8000, 0x37AB0000, 0x37AB8000, 0x37AC0000, 0x37AC8000, 0x37AD0000, 0x37AD8000, 0x37AE0000, 0x37AE8000,
950  0x37AF0000, 0x37AF8000, 0x37B00000, 0x37B08000, 0x37B10000, 0x37B18000, 0x37B20000, 0x37B28000, 0x37B30000, 0x37B38000,
951  0x37B40000, 0x37B48000, 0x37B50000, 0x37B58000, 0x37B60000, 0x37B68000, 0x37B70000, 0x37B78000, 0x37B80000, 0x37B88000,
952  0x37B90000, 0x37B98000, 0x37BA0000, 0x37BA8000, 0x37BB0000, 0x37BB8000, 0x37BC0000, 0x37BC8000, 0x37BD0000, 0x37BD8000,
953  0x37BE0000, 0x37BE8000, 0x37BF0000, 0x37BF8000, 0x37C00000, 0x37C08000, 0x37C10000, 0x37C18000, 0x37C20000, 0x37C28000,
954  0x37C30000, 0x37C38000, 0x37C40000, 0x37C48000, 0x37C50000, 0x37C58000, 0x37C60000, 0x37C68000, 0x37C70000, 0x37C78000,
955  0x37C80000, 0x37C88000, 0x37C90000, 0x37C98000, 0x37CA0000, 0x37CA8000, 0x37CB0000, 0x37CB8000, 0x37CC0000, 0x37CC8000,
956  0x37CD0000, 0x37CD8000, 0x37CE0000, 0x37CE8000, 0x37CF0000, 0x37CF8000, 0x37D00000, 0x37D08000, 0x37D10000, 0x37D18000,
957  0x37D20000, 0x37D28000, 0x37D30000, 0x37D38000, 0x37D40000, 0x37D48000, 0x37D50000, 0x37D58000, 0x37D60000, 0x37D68000,
958  0x37D70000, 0x37D78000, 0x37D80000, 0x37D88000, 0x37D90000, 0x37D98000, 0x37DA0000, 0x37DA8000, 0x37DB0000, 0x37DB8000,
959  0x37DC0000, 0x37DC8000, 0x37DD0000, 0x37DD8000, 0x37DE0000, 0x37DE8000, 0x37DF0000, 0x37DF8000, 0x37E00000, 0x37E08000,
960  0x37E10000, 0x37E18000, 0x37E20000, 0x37E28000, 0x37E30000, 0x37E38000, 0x37E40000, 0x37E48000, 0x37E50000, 0x37E58000,
961  0x37E60000, 0x37E68000, 0x37E70000, 0x37E78000, 0x37E80000, 0x37E88000, 0x37E90000, 0x37E98000, 0x37EA0000, 0x37EA8000,
962  0x37EB0000, 0x37EB8000, 0x37EC0000, 0x37EC8000, 0x37ED0000, 0x37ED8000, 0x37EE0000, 0x37EE8000, 0x37EF0000, 0x37EF8000,
963  0x37F00000, 0x37F08000, 0x37F10000, 0x37F18000, 0x37F20000, 0x37F28000, 0x37F30000, 0x37F38000, 0x37F40000, 0x37F48000,
964  0x37F50000, 0x37F58000, 0x37F60000, 0x37F68000, 0x37F70000, 0x37F78000, 0x37F80000, 0x37F88000, 0x37F90000, 0x37F98000,
965  0x37FA0000, 0x37FA8000, 0x37FB0000, 0x37FB8000, 0x37FC0000, 0x37FC8000, 0x37FD0000, 0x37FD8000, 0x37FE0000, 0x37FE8000,
966  0x37FF0000, 0x37FF8000, 0x38000000, 0x38004000, 0x38008000, 0x3800C000, 0x38010000, 0x38014000, 0x38018000, 0x3801C000,
967  0x38020000, 0x38024000, 0x38028000, 0x3802C000, 0x38030000, 0x38034000, 0x38038000, 0x3803C000, 0x38040000, 0x38044000,
968  0x38048000, 0x3804C000, 0x38050000, 0x38054000, 0x38058000, 0x3805C000, 0x38060000, 0x38064000, 0x38068000, 0x3806C000,
969  0x38070000, 0x38074000, 0x38078000, 0x3807C000, 0x38080000, 0x38084000, 0x38088000, 0x3808C000, 0x38090000, 0x38094000,
970  0x38098000, 0x3809C000, 0x380A0000, 0x380A4000, 0x380A8000, 0x380AC000, 0x380B0000, 0x380B4000, 0x380B8000, 0x380BC000,
971  0x380C0000, 0x380C4000, 0x380C8000, 0x380CC000, 0x380D0000, 0x380D4000, 0x380D8000, 0x380DC000, 0x380E0000, 0x380E4000,
972  0x380E8000, 0x380EC000, 0x380F0000, 0x380F4000, 0x380F8000, 0x380FC000, 0x38100000, 0x38104000, 0x38108000, 0x3810C000,
973  0x38110000, 0x38114000, 0x38118000, 0x3811C000, 0x38120000, 0x38124000, 0x38128000, 0x3812C000, 0x38130000, 0x38134000,
974  0x38138000, 0x3813C000, 0x38140000, 0x38144000, 0x38148000, 0x3814C000, 0x38150000, 0x38154000, 0x38158000, 0x3815C000,
975  0x38160000, 0x38164000, 0x38168000, 0x3816C000, 0x38170000, 0x38174000, 0x38178000, 0x3817C000, 0x38180000, 0x38184000,
976  0x38188000, 0x3818C000, 0x38190000, 0x38194000, 0x38198000, 0x3819C000, 0x381A0000, 0x381A4000, 0x381A8000, 0x381AC000,
977  0x381B0000, 0x381B4000, 0x381B8000, 0x381BC000, 0x381C0000, 0x381C4000, 0x381C8000, 0x381CC000, 0x381D0000, 0x381D4000,
978  0x381D8000, 0x381DC000, 0x381E0000, 0x381E4000, 0x381E8000, 0x381EC000, 0x381F0000, 0x381F4000, 0x381F8000, 0x381FC000,
979  0x38200000, 0x38204000, 0x38208000, 0x3820C000, 0x38210000, 0x38214000, 0x38218000, 0x3821C000, 0x38220000, 0x38224000,
980  0x38228000, 0x3822C000, 0x38230000, 0x38234000, 0x38238000, 0x3823C000, 0x38240000, 0x38244000, 0x38248000, 0x3824C000,
981  0x38250000, 0x38254000, 0x38258000, 0x3825C000, 0x38260000, 0x38264000, 0x38268000, 0x3826C000, 0x38270000, 0x38274000,
982  0x38278000, 0x3827C000, 0x38280000, 0x38284000, 0x38288000, 0x3828C000, 0x38290000, 0x38294000, 0x38298000, 0x3829C000,
983  0x382A0000, 0x382A4000, 0x382A8000, 0x382AC000, 0x382B0000, 0x382B4000, 0x382B8000, 0x382BC000, 0x382C0000, 0x382C4000,
984  0x382C8000, 0x382CC000, 0x382D0000, 0x382D4000, 0x382D8000, 0x382DC000, 0x382E0000, 0x382E4000, 0x382E8000, 0x382EC000,
985  0x382F0000, 0x382F4000, 0x382F8000, 0x382FC000, 0x38300000, 0x38304000, 0x38308000, 0x3830C000, 0x38310000, 0x38314000,
986  0x38318000, 0x3831C000, 0x38320000, 0x38324000, 0x38328000, 0x3832C000, 0x38330000, 0x38334000, 0x38338000, 0x3833C000,
987  0x38340000, 0x38344000, 0x38348000, 0x3834C000, 0x38350000, 0x38354000, 0x38358000, 0x3835C000, 0x38360000, 0x38364000,
988  0x38368000, 0x3836C000, 0x38370000, 0x38374000, 0x38378000, 0x3837C000, 0x38380000, 0x38384000, 0x38388000, 0x3838C000,
989  0x38390000, 0x38394000, 0x38398000, 0x3839C000, 0x383A0000, 0x383A4000, 0x383A8000, 0x383AC000, 0x383B0000, 0x383B4000,
990  0x383B8000, 0x383BC000, 0x383C0000, 0x383C4000, 0x383C8000, 0x383CC000, 0x383D0000, 0x383D4000, 0x383D8000, 0x383DC000,
991  0x383E0000, 0x383E4000, 0x383E8000, 0x383EC000, 0x383F0000, 0x383F4000, 0x383F8000, 0x383FC000, 0x38400000, 0x38404000,
992  0x38408000, 0x3840C000, 0x38410000, 0x38414000, 0x38418000, 0x3841C000, 0x38420000, 0x38424000, 0x38428000, 0x3842C000,
993  0x38430000, 0x38434000, 0x38438000, 0x3843C000, 0x38440000, 0x38444000, 0x38448000, 0x3844C000, 0x38450000, 0x38454000,
994  0x38458000, 0x3845C000, 0x38460000, 0x38464000, 0x38468000, 0x3846C000, 0x38470000, 0x38474000, 0x38478000, 0x3847C000,
995  0x38480000, 0x38484000, 0x38488000, 0x3848C000, 0x38490000, 0x38494000, 0x38498000, 0x3849C000, 0x384A0000, 0x384A4000,
996  0x384A8000, 0x384AC000, 0x384B0000, 0x384B4000, 0x384B8000, 0x384BC000, 0x384C0000, 0x384C4000, 0x384C8000, 0x384CC000,
997  0x384D0000, 0x384D4000, 0x384D8000, 0x384DC000, 0x384E0000, 0x384E4000, 0x384E8000, 0x384EC000, 0x384F0000, 0x384F4000,
998  0x384F8000, 0x384FC000, 0x38500000, 0x38504000, 0x38508000, 0x3850C000, 0x38510000, 0x38514000, 0x38518000, 0x3851C000,
999  0x38520000, 0x38524000, 0x38528000, 0x3852C000, 0x38530000, 0x38534000, 0x38538000, 0x3853C000, 0x38540000, 0x38544000,
1000  0x38548000, 0x3854C000, 0x38550000, 0x38554000, 0x38558000, 0x3855C000, 0x38560000, 0x38564000, 0x38568000, 0x3856C000,
1001  0x38570000, 0x38574000, 0x38578000, 0x3857C000, 0x38580000, 0x38584000, 0x38588000, 0x3858C000, 0x38590000, 0x38594000,
1002  0x38598000, 0x3859C000, 0x385A0000, 0x385A4000, 0x385A8000, 0x385AC000, 0x385B0000, 0x385B4000, 0x385B8000, 0x385BC000,
1003  0x385C0000, 0x385C4000, 0x385C8000, 0x385CC000, 0x385D0000, 0x385D4000, 0x385D8000, 0x385DC000, 0x385E0000, 0x385E4000,
1004  0x385E8000, 0x385EC000, 0x385F0000, 0x385F4000, 0x385F8000, 0x385FC000, 0x38600000, 0x38604000, 0x38608000, 0x3860C000,
1005  0x38610000, 0x38614000, 0x38618000, 0x3861C000, 0x38620000, 0x38624000, 0x38628000, 0x3862C000, 0x38630000, 0x38634000,
1006  0x38638000, 0x3863C000, 0x38640000, 0x38644000, 0x38648000, 0x3864C000, 0x38650000, 0x38654000, 0x38658000, 0x3865C000,
1007  0x38660000, 0x38664000, 0x38668000, 0x3866C000, 0x38670000, 0x38674000, 0x38678000, 0x3867C000, 0x38680000, 0x38684000,
1008  0x38688000, 0x3868C000, 0x38690000, 0x38694000, 0x38698000, 0x3869C000, 0x386A0000, 0x386A4000, 0x386A8000, 0x386AC000,
1009  0x386B0000, 0x386B4000, 0x386B8000, 0x386BC000, 0x386C0000, 0x386C4000, 0x386C8000, 0x386CC000, 0x386D0000, 0x386D4000,
1010  0x386D8000, 0x386DC000, 0x386E0000, 0x386E4000, 0x386E8000, 0x386EC000, 0x386F0000, 0x386F4000, 0x386F8000, 0x386FC000,
1011  0x38700000, 0x38704000, 0x38708000, 0x3870C000, 0x38710000, 0x38714000, 0x38718000, 0x3871C000, 0x38720000, 0x38724000,
1012  0x38728000, 0x3872C000, 0x38730000, 0x38734000, 0x38738000, 0x3873C000, 0x38740000, 0x38744000, 0x38748000, 0x3874C000,
1013  0x38750000, 0x38754000, 0x38758000, 0x3875C000, 0x38760000, 0x38764000, 0x38768000, 0x3876C000, 0x38770000, 0x38774000,
1014  0x38778000, 0x3877C000, 0x38780000, 0x38784000, 0x38788000, 0x3878C000, 0x38790000, 0x38794000, 0x38798000, 0x3879C000,
1015  0x387A0000, 0x387A4000, 0x387A8000, 0x387AC000, 0x387B0000, 0x387B4000, 0x387B8000, 0x387BC000, 0x387C0000, 0x387C4000,
1016  0x387C8000, 0x387CC000, 0x387D0000, 0x387D4000, 0x387D8000, 0x387DC000, 0x387E0000, 0x387E4000, 0x387E8000, 0x387EC000,
1017  0x387F0000, 0x387F4000, 0x387F8000, 0x387FC000, 0x38000000, 0x38002000, 0x38004000, 0x38006000, 0x38008000, 0x3800A000,
1018  0x3800C000, 0x3800E000, 0x38010000, 0x38012000, 0x38014000, 0x38016000, 0x38018000, 0x3801A000, 0x3801C000, 0x3801E000,
1019  0x38020000, 0x38022000, 0x38024000, 0x38026000, 0x38028000, 0x3802A000, 0x3802C000, 0x3802E000, 0x38030000, 0x38032000,
1020  0x38034000, 0x38036000, 0x38038000, 0x3803A000, 0x3803C000, 0x3803E000, 0x38040000, 0x38042000, 0x38044000, 0x38046000,
1021  0x38048000, 0x3804A000, 0x3804C000, 0x3804E000, 0x38050000, 0x38052000, 0x38054000, 0x38056000, 0x38058000, 0x3805A000,
1022  0x3805C000, 0x3805E000, 0x38060000, 0x38062000, 0x38064000, 0x38066000, 0x38068000, 0x3806A000, 0x3806C000, 0x3806E000,
1023  0x38070000, 0x38072000, 0x38074000, 0x38076000, 0x38078000, 0x3807A000, 0x3807C000, 0x3807E000, 0x38080000, 0x38082000,
1024  0x38084000, 0x38086000, 0x38088000, 0x3808A000, 0x3808C000, 0x3808E000, 0x38090000, 0x38092000, 0x38094000, 0x38096000,
1025  0x38098000, 0x3809A000, 0x3809C000, 0x3809E000, 0x380A0000, 0x380A2000, 0x380A4000, 0x380A6000, 0x380A8000, 0x380AA000,
1026  0x380AC000, 0x380AE000, 0x380B0000, 0x380B2000, 0x380B4000, 0x380B6000, 0x380B8000, 0x380BA000, 0x380BC000, 0x380BE000,
1027  0x380C0000, 0x380C2000, 0x380C4000, 0x380C6000, 0x380C8000, 0x380CA000, 0x380CC000, 0x380CE000, 0x380D0000, 0x380D2000,
1028  0x380D4000, 0x380D6000, 0x380D8000, 0x380DA000, 0x380DC000, 0x380DE000, 0x380E0000, 0x380E2000, 0x380E4000, 0x380E6000,
1029  0x380E8000, 0x380EA000, 0x380EC000, 0x380EE000, 0x380F0000, 0x380F2000, 0x380F4000, 0x380F6000, 0x380F8000, 0x380FA000,
1030  0x380FC000, 0x380FE000, 0x38100000, 0x38102000, 0x38104000, 0x38106000, 0x38108000, 0x3810A000, 0x3810C000, 0x3810E000,
1031  0x38110000, 0x38112000, 0x38114000, 0x38116000, 0x38118000, 0x3811A000, 0x3811C000, 0x3811E000, 0x38120000, 0x38122000,
1032  0x38124000, 0x38126000, 0x38128000, 0x3812A000, 0x3812C000, 0x3812E000, 0x38130000, 0x38132000, 0x38134000, 0x38136000,
1033  0x38138000, 0x3813A000, 0x3813C000, 0x3813E000, 0x38140000, 0x38142000, 0x38144000, 0x38146000, 0x38148000, 0x3814A000,
1034  0x3814C000, 0x3814E000, 0x38150000, 0x38152000, 0x38154000, 0x38156000, 0x38158000, 0x3815A000, 0x3815C000, 0x3815E000,
1035  0x38160000, 0x38162000, 0x38164000, 0x38166000, 0x38168000, 0x3816A000, 0x3816C000, 0x3816E000, 0x38170000, 0x38172000,
1036  0x38174000, 0x38176000, 0x38178000, 0x3817A000, 0x3817C000, 0x3817E000, 0x38180000, 0x38182000, 0x38184000, 0x38186000,
1037  0x38188000, 0x3818A000, 0x3818C000, 0x3818E000, 0x38190000, 0x38192000, 0x38194000, 0x38196000, 0x38198000, 0x3819A000,
1038  0x3819C000, 0x3819E000, 0x381A0000, 0x381A2000, 0x381A4000, 0x381A6000, 0x381A8000, 0x381AA000, 0x381AC000, 0x381AE000,
1039  0x381B0000, 0x381B2000, 0x381B4000, 0x381B6000, 0x381B8000, 0x381BA000, 0x381BC000, 0x381BE000, 0x381C0000, 0x381C2000,
1040  0x381C4000, 0x381C6000, 0x381C8000, 0x381CA000, 0x381CC000, 0x381CE000, 0x381D0000, 0x381D2000, 0x381D4000, 0x381D6000,
1041  0x381D8000, 0x381DA000, 0x381DC000, 0x381DE000, 0x381E0000, 0x381E2000, 0x381E4000, 0x381E6000, 0x381E8000, 0x381EA000,
1042  0x381EC000, 0x381EE000, 0x381F0000, 0x381F2000, 0x381F4000, 0x381F6000, 0x381F8000, 0x381FA000, 0x381FC000, 0x381FE000,
1043  0x38200000, 0x38202000, 0x38204000, 0x38206000, 0x38208000, 0x3820A000, 0x3820C000, 0x3820E000, 0x38210000, 0x38212000,
1044  0x38214000, 0x38216000, 0x38218000, 0x3821A000, 0x3821C000, 0x3821E000, 0x38220000, 0x38222000, 0x38224000, 0x38226000,
1045  0x38228000, 0x3822A000, 0x3822C000, 0x3822E000, 0x38230000, 0x38232000, 0x38234000, 0x38236000, 0x38238000, 0x3823A000,
1046  0x3823C000, 0x3823E000, 0x38240000, 0x38242000, 0x38244000, 0x38246000, 0x38248000, 0x3824A000, 0x3824C000, 0x3824E000,
1047  0x38250000, 0x38252000, 0x38254000, 0x38256000, 0x38258000, 0x3825A000, 0x3825C000, 0x3825E000, 0x38260000, 0x38262000,
1048  0x38264000, 0x38266000, 0x38268000, 0x3826A000, 0x3826C000, 0x3826E000, 0x38270000, 0x38272000, 0x38274000, 0x38276000,
1049  0x38278000, 0x3827A000, 0x3827C000, 0x3827E000, 0x38280000, 0x38282000, 0x38284000, 0x38286000, 0x38288000, 0x3828A000,
1050  0x3828C000, 0x3828E000, 0x38290000, 0x38292000, 0x38294000, 0x38296000, 0x38298000, 0x3829A000, 0x3829C000, 0x3829E000,
1051  0x382A0000, 0x382A2000, 0x382A4000, 0x382A6000, 0x382A8000, 0x382AA000, 0x382AC000, 0x382AE000, 0x382B0000, 0x382B2000,
1052  0x382B4000, 0x382B6000, 0x382B8000, 0x382BA000, 0x382BC000, 0x382BE000, 0x382C0000, 0x382C2000, 0x382C4000, 0x382C6000,
1053  0x382C8000, 0x382CA000, 0x382CC000, 0x382CE000, 0x382D0000, 0x382D2000, 0x382D4000, 0x382D6000, 0x382D8000, 0x382DA000,
1054  0x382DC000, 0x382DE000, 0x382E0000, 0x382E2000, 0x382E4000, 0x382E6000, 0x382E8000, 0x382EA000, 0x382EC000, 0x382EE000,
1055  0x382F0000, 0x382F2000, 0x382F4000, 0x382F6000, 0x382F8000, 0x382FA000, 0x382FC000, 0x382FE000, 0x38300000, 0x38302000,
1056  0x38304000, 0x38306000, 0x38308000, 0x3830A000, 0x3830C000, 0x3830E000, 0x38310000, 0x38312000, 0x38314000, 0x38316000,
1057  0x38318000, 0x3831A000, 0x3831C000, 0x3831E000, 0x38320000, 0x38322000, 0x38324000, 0x38326000, 0x38328000, 0x3832A000,
1058  0x3832C000, 0x3832E000, 0x38330000, 0x38332000, 0x38334000, 0x38336000, 0x38338000, 0x3833A000, 0x3833C000, 0x3833E000,
1059  0x38340000, 0x38342000, 0x38344000, 0x38346000, 0x38348000, 0x3834A000, 0x3834C000, 0x3834E000, 0x38350000, 0x38352000,
1060  0x38354000, 0x38356000, 0x38358000, 0x3835A000, 0x3835C000, 0x3835E000, 0x38360000, 0x38362000, 0x38364000, 0x38366000,
1061  0x38368000, 0x3836A000, 0x3836C000, 0x3836E000, 0x38370000, 0x38372000, 0x38374000, 0x38376000, 0x38378000, 0x3837A000,
1062  0x3837C000, 0x3837E000, 0x38380000, 0x38382000, 0x38384000, 0x38386000, 0x38388000, 0x3838A000, 0x3838C000, 0x3838E000,
1063  0x38390000, 0x38392000, 0x38394000, 0x38396000, 0x38398000, 0x3839A000, 0x3839C000, 0x3839E000, 0x383A0000, 0x383A2000,
1064  0x383A4000, 0x383A6000, 0x383A8000, 0x383AA000, 0x383AC000, 0x383AE000, 0x383B0000, 0x383B2000, 0x383B4000, 0x383B6000,
1065  0x383B8000, 0x383BA000, 0x383BC000, 0x383BE000, 0x383C0000, 0x383C2000, 0x383C4000, 0x383C6000, 0x383C8000, 0x383CA000,
1066  0x383CC000, 0x383CE000, 0x383D0000, 0x383D2000, 0x383D4000, 0x383D6000, 0x383D8000, 0x383DA000, 0x383DC000, 0x383DE000,
1067  0x383E0000, 0x383E2000, 0x383E4000, 0x383E6000, 0x383E8000, 0x383EA000, 0x383EC000, 0x383EE000, 0x383F0000, 0x383F2000,
1068  0x383F4000, 0x383F6000, 0x383F8000, 0x383FA000, 0x383FC000, 0x383FE000, 0x38400000, 0x38402000, 0x38404000, 0x38406000,
1069  0x38408000, 0x3840A000, 0x3840C000, 0x3840E000, 0x38410000, 0x38412000, 0x38414000, 0x38416000, 0x38418000, 0x3841A000,
1070  0x3841C000, 0x3841E000, 0x38420000, 0x38422000, 0x38424000, 0x38426000, 0x38428000, 0x3842A000, 0x3842C000, 0x3842E000,
1071  0x38430000, 0x38432000, 0x38434000, 0x38436000, 0x38438000, 0x3843A000, 0x3843C000, 0x3843E000, 0x38440000, 0x38442000,
1072  0x38444000, 0x38446000, 0x38448000, 0x3844A000, 0x3844C000, 0x3844E000, 0x38450000, 0x38452000, 0x38454000, 0x38456000,
1073  0x38458000, 0x3845A000, 0x3845C000, 0x3845E000, 0x38460000, 0x38462000, 0x38464000, 0x38466000, 0x38468000, 0x3846A000,
1074  0x3846C000, 0x3846E000, 0x38470000, 0x38472000, 0x38474000, 0x38476000, 0x38478000, 0x3847A000, 0x3847C000, 0x3847E000,
1075  0x38480000, 0x38482000, 0x38484000, 0x38486000, 0x38488000, 0x3848A000, 0x3848C000, 0x3848E000, 0x38490000, 0x38492000,
1076  0x38494000, 0x38496000, 0x38498000, 0x3849A000, 0x3849C000, 0x3849E000, 0x384A0000, 0x384A2000, 0x384A4000, 0x384A6000,
1077  0x384A8000, 0x384AA000, 0x384AC000, 0x384AE000, 0x384B0000, 0x384B2000, 0x384B4000, 0x384B6000, 0x384B8000, 0x384BA000,
1078  0x384BC000, 0x384BE000, 0x384C0000, 0x384C2000, 0x384C4000, 0x384C6000, 0x384C8000, 0x384CA000, 0x384CC000, 0x384CE000,
1079  0x384D0000, 0x384D2000, 0x384D4000, 0x384D6000, 0x384D8000, 0x384DA000, 0x384DC000, 0x384DE000, 0x384E0000, 0x384E2000,
1080  0x384E4000, 0x384E6000, 0x384E8000, 0x384EA000, 0x384EC000, 0x384EE000, 0x384F0000, 0x384F2000, 0x384F4000, 0x384F6000,
1081  0x384F8000, 0x384FA000, 0x384FC000, 0x384FE000, 0x38500000, 0x38502000, 0x38504000, 0x38506000, 0x38508000, 0x3850A000,
1082  0x3850C000, 0x3850E000, 0x38510000, 0x38512000, 0x38514000, 0x38516000, 0x38518000, 0x3851A000, 0x3851C000, 0x3851E000,
1083  0x38520000, 0x38522000, 0x38524000, 0x38526000, 0x38528000, 0x3852A000, 0x3852C000, 0x3852E000, 0x38530000, 0x38532000,
1084  0x38534000, 0x38536000, 0x38538000, 0x3853A000, 0x3853C000, 0x3853E000, 0x38540000, 0x38542000, 0x38544000, 0x38546000,
1085  0x38548000, 0x3854A000, 0x3854C000, 0x3854E000, 0x38550000, 0x38552000, 0x38554000, 0x38556000, 0x38558000, 0x3855A000,
1086  0x3855C000, 0x3855E000, 0x38560000, 0x38562000, 0x38564000, 0x38566000, 0x38568000, 0x3856A000, 0x3856C000, 0x3856E000,
1087  0x38570000, 0x38572000, 0x38574000, 0x38576000, 0x38578000, 0x3857A000, 0x3857C000, 0x3857E000, 0x38580000, 0x38582000,
1088  0x38584000, 0x38586000, 0x38588000, 0x3858A000, 0x3858C000, 0x3858E000, 0x38590000, 0x38592000, 0x38594000, 0x38596000,
1089  0x38598000, 0x3859A000, 0x3859C000, 0x3859E000, 0x385A0000, 0x385A2000, 0x385A4000, 0x385A6000, 0x385A8000, 0x385AA000,
1090  0x385AC000, 0x385AE000, 0x385B0000, 0x385B2000, 0x385B4000, 0x385B6000, 0x385B8000, 0x385BA000, 0x385BC000, 0x385BE000,
1091  0x385C0000, 0x385C2000, 0x385C4000, 0x385C6000, 0x385C8000, 0x385CA000, 0x385CC000, 0x385CE000, 0x385D0000, 0x385D2000,
1092  0x385D4000, 0x385D6000, 0x385D8000, 0x385DA000, 0x385DC000, 0x385DE000, 0x385E0000, 0x385E2000, 0x385E4000, 0x385E6000,
1093  0x385E8000, 0x385EA000, 0x385EC000, 0x385EE000, 0x385F0000, 0x385F2000, 0x385F4000, 0x385F6000, 0x385F8000, 0x385FA000,
1094  0x385FC000, 0x385FE000, 0x38600000, 0x38602000, 0x38604000, 0x38606000, 0x38608000, 0x3860A000, 0x3860C000, 0x3860E000,
1095  0x38610000, 0x38612000, 0x38614000, 0x38616000, 0x38618000, 0x3861A000, 0x3861C000, 0x3861E000, 0x38620000, 0x38622000,
1096  0x38624000, 0x38626000, 0x38628000, 0x3862A000, 0x3862C000, 0x3862E000, 0x38630000, 0x38632000, 0x38634000, 0x38636000,
1097  0x38638000, 0x3863A000, 0x3863C000, 0x3863E000, 0x38640000, 0x38642000, 0x38644000, 0x38646000, 0x38648000, 0x3864A000,
1098  0x3864C000, 0x3864E000, 0x38650000, 0x38652000, 0x38654000, 0x38656000, 0x38658000, 0x3865A000, 0x3865C000, 0x3865E000,
1099  0x38660000, 0x38662000, 0x38664000, 0x38666000, 0x38668000, 0x3866A000, 0x3866C000, 0x3866E000, 0x38670000, 0x38672000,
1100  0x38674000, 0x38676000, 0x38678000, 0x3867A000, 0x3867C000, 0x3867E000, 0x38680000, 0x38682000, 0x38684000, 0x38686000,
1101  0x38688000, 0x3868A000, 0x3868C000, 0x3868E000, 0x38690000, 0x38692000, 0x38694000, 0x38696000, 0x38698000, 0x3869A000,
1102  0x3869C000, 0x3869E000, 0x386A0000, 0x386A2000, 0x386A4000, 0x386A6000, 0x386A8000, 0x386AA000, 0x386AC000, 0x386AE000,
1103  0x386B0000, 0x386B2000, 0x386B4000, 0x386B6000, 0x386B8000, 0x386BA000, 0x386BC000, 0x386BE000, 0x386C0000, 0x386C2000,
1104  0x386C4000, 0x386C6000, 0x386C8000, 0x386CA000, 0x386CC000, 0x386CE000, 0x386D0000, 0x386D2000, 0x386D4000, 0x386D6000,
1105  0x386D8000, 0x386DA000, 0x386DC000, 0x386DE000, 0x386E0000, 0x386E2000, 0x386E4000, 0x386E6000, 0x386E8000, 0x386EA000,
1106  0x386EC000, 0x386EE000, 0x386F0000, 0x386F2000, 0x386F4000, 0x386F6000, 0x386F8000, 0x386FA000, 0x386FC000, 0x386FE000,
1107  0x38700000, 0x38702000, 0x38704000, 0x38706000, 0x38708000, 0x3870A000, 0x3870C000, 0x3870E000, 0x38710000, 0x38712000,
1108  0x38714000, 0x38716000, 0x38718000, 0x3871A000, 0x3871C000, 0x3871E000, 0x38720000, 0x38722000, 0x38724000, 0x38726000,
1109  0x38728000, 0x3872A000, 0x3872C000, 0x3872E000, 0x38730000, 0x38732000, 0x38734000, 0x38736000, 0x38738000, 0x3873A000,
1110  0x3873C000, 0x3873E000, 0x38740000, 0x38742000, 0x38744000, 0x38746000, 0x38748000, 0x3874A000, 0x3874C000, 0x3874E000,
1111  0x38750000, 0x38752000, 0x38754000, 0x38756000, 0x38758000, 0x3875A000, 0x3875C000, 0x3875E000, 0x38760000, 0x38762000,
1112  0x38764000, 0x38766000, 0x38768000, 0x3876A000, 0x3876C000, 0x3876E000, 0x38770000, 0x38772000, 0x38774000, 0x38776000,
1113  0x38778000, 0x3877A000, 0x3877C000, 0x3877E000, 0x38780000, 0x38782000, 0x38784000, 0x38786000, 0x38788000, 0x3878A000,
1114  0x3878C000, 0x3878E000, 0x38790000, 0x38792000, 0x38794000, 0x38796000, 0x38798000, 0x3879A000, 0x3879C000, 0x3879E000,
1115  0x387A0000, 0x387A2000, 0x387A4000, 0x387A6000, 0x387A8000, 0x387AA000, 0x387AC000, 0x387AE000, 0x387B0000, 0x387B2000,
1116  0x387B4000, 0x387B6000, 0x387B8000, 0x387BA000, 0x387BC000, 0x387BE000, 0x387C0000, 0x387C2000, 0x387C4000, 0x387C6000,
1117  0x387C8000, 0x387CA000, 0x387CC000, 0x387CE000, 0x387D0000, 0x387D2000, 0x387D4000, 0x387D6000, 0x387D8000, 0x387DA000,
1118  0x387DC000, 0x387DE000, 0x387E0000, 0x387E2000, 0x387E4000, 0x387E6000, 0x387E8000, 0x387EA000, 0x387EC000, 0x387EE000,
1119  0x387F0000, 0x387F2000, 0x387F4000, 0x387F6000, 0x387F8000, 0x387FA000, 0x387FC000, 0x387FE000};
1120  static const uint32 exponent_table[64] = {
1121  0x00000000, 0x00800000, 0x01000000, 0x01800000, 0x02000000, 0x02800000, 0x03000000, 0x03800000, 0x04000000, 0x04800000,
1122  0x05000000, 0x05800000, 0x06000000, 0x06800000, 0x07000000, 0x07800000, 0x08000000, 0x08800000, 0x09000000, 0x09800000,
1123  0x0A000000, 0x0A800000, 0x0B000000, 0x0B800000, 0x0C000000, 0x0C800000, 0x0D000000, 0x0D800000, 0x0E000000, 0x0E800000,
1124  0x0F000000, 0x47800000, 0x80000000, 0x80800000, 0x81000000, 0x81800000, 0x82000000, 0x82800000, 0x83000000, 0x83800000,
1125  0x84000000, 0x84800000, 0x85000000, 0x85800000, 0x86000000, 0x86800000, 0x87000000, 0x87800000, 0x88000000, 0x88800000,
1126  0x89000000, 0x89800000, 0x8A000000, 0x8A800000, 0x8B000000, 0x8B800000, 0x8C000000, 0x8C800000, 0x8D000000, 0x8D800000,
1127  0x8E000000, 0x8E800000, 0x8F000000, 0xC7800000};
1128  static const unsigned short offset_table[64] = {0, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1129  1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1130  1024, 1024, 1024, 1024, 1024, 1024, 0, 1024, 1024, 1024, 1024, 1024, 1024,
1131  1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1132  1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024};
1133  uint32 bits = mantissa_table[offset_table[value >> 10] + (value & 0x3FF)] + exponent_table[value >> 10];
1134  // return *reinterpret_cast<float*>(&bits); //violating strict aliasing!
1135  float out;
1136  std::memcpy(&out, &bits, sizeof(float));
1137  return out;
1138 }
1139 
1143 inline double half2float_impl(uint16 value, double, true_type)
1145  typedef bits<float>::type uint32;
1146  typedef bits<double>::type uint64;
1147  uint32 hi = static_cast<uint32>(value & 0x8000) << 16;
1148  int abs = value & 0x7FFF;
1149  if(abs)
1150  {
1151  hi |= 0x3F000000 << static_cast<unsigned>(abs >= 0x7C00);
1152  for(; abs < 0x400; abs <<= 1, hi -= 0x100000)
1153  ;
1154  hi += static_cast<uint32>(abs) << 10;
1155  }
1156  uint64 bits = static_cast<uint64>(hi) << 32;
1157  // return *reinterpret_cast<double*>(&bits); //violating strict aliasing!
1158  double out;
1159  std::memcpy(&out, &bits, sizeof(double));
1160  return out;
1161 }
1162 
1167 template <typename T>
1168 T half2float_impl(uint16 value, T, ...)
1170  T out;
1171  int abs = value & 0x7FFF;
1172  if(abs > 0x7C00)
1173  out = std::numeric_limits<T>::has_quiet_NaN ? std::numeric_limits<T>::quiet_NaN() : T();
1174  else if(abs == 0x7C00)
1175  out = std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : std::numeric_limits<T>::max();
1176  else if(abs > 0x3FF)
1177  out = std::ldexp(static_cast<T>((abs & 0x3FF) | 0x400), (abs >> 10) - 25);
1178  else
1179  out = std::ldexp(static_cast<T>(abs), -24);
1180  return (value & 0x8000) ? -out : out;
1181 }
1182 
1187 template <typename T>
1188 T half2float(uint16 value)
1190  return half2float_impl(value, T(),
1191  bool_type < std::numeric_limits<T>::is_iec559 && sizeof(typename bits<T>::type) == sizeof(T) > ());
1192 }
1193 
1200 template <std::float_round_style R, bool E, typename T>
1201 T half2int_impl(uint16 value)
1203 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
1204  static_assert(std::is_integral<T>::value, "half to int conversion only supports builtin integer types");
1205 #endif
1206  unsigned int e = value & 0x7FFF;
1207  if(e >= 0x7C00)
1208  return (value & 0x8000) ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max();
1209  if(e < 0x3800)
1210  {
1211  if(R == std::round_toward_infinity)
1212  return T(~(value >> 15) & (e != 0));
1213  else if(R == std::round_toward_neg_infinity)
1214  return -T(value > 0x8000);
1215  return T();
1216  }
1217  unsigned int m = (value & 0x3FF) | 0x400;
1218  e >>= 10;
1219  if(e < 25)
1220  {
1221  if(R == std::round_to_nearest)
1222  m += (1 << (24 - e)) - (~(m >> (25 - e)) & E);
1223  else if(R == std::round_toward_infinity)
1224  m += ((value >> 15) - 1) & ((1 << (25 - e)) - 1U);
1225  else if(R == std::round_toward_neg_infinity)
1226  m += -(value >> 15) & ((1 << (25 - e)) - 1U);
1227  m >>= 25 - e;
1228  }
1229  else
1230  m <<= e - 25;
1231  return (value & 0x8000) ? -static_cast<T>(m) : static_cast<T>(m);
1232 }
1233 
1239 template <std::float_round_style R, typename T>
1240 T half2int(uint16 value)
1242  return half2int_impl<R, HALF_ROUND_TIES_TO_EVEN, T>(value);
1243 }
1244 
1249 template <typename T>
1250 T half2int_up(uint16 value)
1252  return half2int_impl<std::round_to_nearest, 0, T>(value);
1253 }
1254 
1260 template <std::float_round_style R, bool E>
1263  unsigned int e = value & 0x7FFF;
1264  uint16 result = value;
1265  if(e < 0x3C00)
1266  {
1267  result &= 0x8000;
1268  if(R == std::round_to_nearest)
1269  result |= 0x3C00U & -(e >= (0x3800 + E));
1270  else if(R == std::round_toward_infinity)
1271  result |= 0x3C00U & -(~(value >> 15) & (e != 0));
1272  else if(R == std::round_toward_neg_infinity)
1273  result |= 0x3C00U & -(value > 0x8000);
1274  }
1275  else if(e < 0x6400)
1276  {
1277  e = 25 - (e >> 10);
1278  unsigned int mask = (1 << e) - 1;
1279  if(R == std::round_to_nearest)
1280  result += (1 << (e - 1)) - (~(result >> e) & E);
1281  else if(R == std::round_toward_infinity)
1282  result += mask & ((value >> 15) - 1);
1283  else if(R == std::round_toward_neg_infinity)
1284  result += mask & -(value >> 15);
1285  result &= ~mask;
1286  }
1287  return result;
1288 }
1289 
1294 template <std::float_round_style R>
1295 uint16 round_half(uint16 value)
1297  return round_half_impl<R, HALF_ROUND_TIES_TO_EVEN>(value);
1298 }
1299 
1303 inline uint16 round_half_up(uint16 value) { return round_half_impl<std::round_to_nearest, 0>(value); }
1305 
1306 struct functions;
1307 template <typename>
1308 struct unary_specialized;
1309 template <typename, typename>
1310 struct binary_specialized;
1311 template <typename, typename, std::float_round_style>
1312 struct half_caster;
1313 } // namespace detail
1314 
1335 class half
1336 {
1337  friend struct detail::functions;
1338  friend struct detail::unary_specialized<half>;
1339  friend struct detail::binary_specialized<half, half>;
1340  template <typename, typename, std::float_round_style>
1341  friend struct detail::half_caster;
1342  friend class std::numeric_limits<half>;
1343 #if HALF_ENABLE_CPP11_HASH
1344  friend struct std::hash<half>;
1345 #endif
1346 #if HALF_ENABLE_CPP11_USER_LITERALS
1347  friend half literal::operator""_h(long double);
1348 #endif
1349 
1350  public:
1355 
1359  half(detail::expr rhs) : data_(detail::float2half<round_style>(static_cast<float>(rhs))) {}
1360 
1363  explicit half(float rhs) : data_(detail::float2half<round_style>(rhs)) {}
1364 
1367  operator float() const { return detail::half2float<float>(data_); }
1368 
1373  half &operator=(detail::expr rhs) { return *this = static_cast<float>(rhs); }
1374 
1379  template <typename T>
1381  {
1382  return *this += static_cast<float>(rhs);
1383  }
1384 
1389  template <typename T>
1391  {
1392  return *this -= static_cast<float>(rhs);
1393  }
1394 
1399  template <typename T>
1401  {
1402  return *this *= static_cast<float>(rhs);
1403  }
1404 
1409  template <typename T>
1411  {
1412  return *this /= static_cast<float>(rhs);
1413  }
1414 
1418  half &operator=(float rhs)
1419  {
1420  data_ = detail::float2half<round_style>(rhs);
1421  return *this;
1422  }
1423 
1427  half &operator+=(float rhs)
1428  {
1429  data_ = detail::float2half<round_style>(detail::half2float<float>(data_) + rhs);
1430  return *this;
1431  }
1432 
1436  half &operator-=(float rhs)
1437  {
1438  data_ = detail::float2half<round_style>(detail::half2float<float>(data_) - rhs);
1439  return *this;
1440  }
1441 
1445  half &operator*=(float rhs)
1446  {
1447  data_ = detail::float2half<round_style>(detail::half2float<float>(data_) * rhs);
1448  return *this;
1449  }
1450 
1454  half &operator/=(float rhs)
1455  {
1456  data_ = detail::float2half<round_style>(detail::half2float<float>(data_) / rhs);
1457  return *this;
1458  }
1459 
1462  half &operator++() { return *this += 1.0f; }
1463 
1466  half &operator--() { return *this -= 1.0f; }
1467 
1471  {
1472  half out(*this);
1473  ++*this;
1474  return out;
1475  }
1476 
1480  {
1481  half out(*this);
1482  --*this;
1483  return out;
1484  }
1485 
1486  private:
1488  static const std::float_round_style round_style = (std::float_round_style)(HALF_ROUND_STYLE);
1489 
1493 
1495  detail::uint16 data_;
1496 };
1497 
1498 #if HALF_ENABLE_CPP11_USER_LITERALS
1499 namespace literal
1500 {
1506 inline half operator""_h(long double value) { return half(detail::binary, detail::float2half<half::round_style>(value)); }
1507 } // namespace literal
1508 #endif
1509 
1510 namespace detail
1511 {
1514 {
1519  static expr plus(float x, float y) { return expr(x + y); }
1520 
1525  static expr minus(float x, float y) { return expr(x - y); }
1526 
1531  static expr multiplies(float x, float y) { return expr(x * y); }
1532 
1537  static expr divides(float x, float y) { return expr(x / y); }
1538 
1543  template <typename charT, typename traits>
1544  static std::basic_ostream<charT, traits> &write(std::basic_ostream<charT, traits> &out, float arg)
1545  {
1546  return out << arg;
1547  }
1548 
1553  template <typename charT, typename traits>
1554  static std::basic_istream<charT, traits> &read(std::basic_istream<charT, traits> &in, half &arg)
1555  {
1556  float f;
1557  if(in >> f)
1558  arg = f;
1559  return in;
1560  }
1561 
1566  static expr fmod(float x, float y) { return expr(std::fmod(x, y)); }
1567 
1572  static expr remainder(float x, float y)
1573  {
1574 #if HALF_ENABLE_CPP11_CMATH
1575  return expr(std::remainder(x, y));
1576 #else
1577  if(builtin_isnan(x) || builtin_isnan(y))
1578  return expr(std::numeric_limits<float>::quiet_NaN());
1579  float ax = std::fabs(x), ay = std::fabs(y);
1580  if(ax >= 65536.0f || ay < std::ldexp(1.0f, -24))
1581  return expr(std::numeric_limits<float>::quiet_NaN());
1582  if(ay >= 65536.0f)
1583  return expr(x);
1584  if(ax == ay)
1585  return expr(builtin_signbit(x) ? -0.0f : 0.0f);
1586  ax = std::fmod(ax, ay + ay);
1587  float y2 = 0.5f * ay;
1588  if(ax > y2)
1589  {
1590  ax -= ay;
1591  if(ax >= y2)
1592  ax -= ay;
1593  }
1594  return expr(builtin_signbit(x) ? -ax : ax);
1595 #endif
1596  }
1597 
1603  static expr remquo(float x, float y, int *quo)
1604  {
1605 #if HALF_ENABLE_CPP11_CMATH
1606  return expr(std::remquo(x, y, quo));
1607 #else
1608  if(builtin_isnan(x) || builtin_isnan(y))
1609  return expr(std::numeric_limits<float>::quiet_NaN());
1610  bool sign = builtin_signbit(x), qsign = static_cast<bool>(sign ^ builtin_signbit(y));
1611  float ax = std::fabs(x), ay = std::fabs(y);
1612  if(ax >= 65536.0f || ay < std::ldexp(1.0f, -24))
1613  return expr(std::numeric_limits<float>::quiet_NaN());
1614  if(ay >= 65536.0f)
1615  return expr(x);
1616  if(ax == ay)
1617  return *quo = qsign ? -1 : 1, expr(sign ? -0.0f : 0.0f);
1618  ax = std::fmod(ax, 8.0f * ay);
1619  int cquo = 0;
1620  if(ax >= 4.0f * ay)
1621  {
1622  ax -= 4.0f * ay;
1623  cquo += 4;
1624  }
1625  if(ax >= 2.0f * ay)
1626  {
1627  ax -= 2.0f * ay;
1628  cquo += 2;
1629  }
1630  float y2 = 0.5f * ay;
1631  if(ax > y2)
1632  {
1633  ax -= ay;
1634  ++cquo;
1635  if(ax >= y2)
1636  {
1637  ax -= ay;
1638  ++cquo;
1639  }
1640  }
1641  return *quo = qsign ? -cquo : cquo, expr(sign ? -ax : ax);
1642 #endif
1643  }
1644 
1649  static expr fdim(float x, float y)
1650  {
1651 #if HALF_ENABLE_CPP11_CMATH
1652  return expr(std::fdim(x, y));
1653 #else
1654  return expr((x <= y) ? 0.0f : (x - y));
1655 #endif
1656  }
1657 
1663  static expr fma(float x, float y, float z)
1664  {
1665 #if HALF_ENABLE_CPP11_CMATH && defined(FP_FAST_FMAF)
1666  return expr(std::fma(x, y, z));
1667 #else
1668  return expr(x * y + z);
1669 #endif
1670  }
1671 
1674  static half nanh() { return half(binary, 0x7FFF); }
1675 
1679  static expr exp(float arg) { return expr(std::exp(arg)); }
1680 
1684  static expr expm1(float arg)
1685  {
1686 #if HALF_ENABLE_CPP11_CMATH
1687  return expr(std::expm1(arg));
1688 #else
1689  return expr(static_cast<float>(std::exp(static_cast<double>(arg)) - 1.0));
1690 #endif
1691  }
1692 
1696  static expr exp2(float arg)
1697  {
1698 #if HALF_ENABLE_CPP11_CMATH
1699  return expr(std::exp2(arg));
1700 #else
1701  return expr(static_cast<float>(std::exp(arg * 0.69314718055994530941723212145818)));
1702 #endif
1703  }
1704 
1708  static expr log(float arg) { return expr(std::log(arg)); }
1709 
1713  static expr log10(float arg) { return expr(std::log10(arg)); }
1714 
1718  static expr log1p(float arg)
1719  {
1720 #if HALF_ENABLE_CPP11_CMATH
1721  return expr(std::log1p(arg));
1722 #else
1723  return expr(static_cast<float>(std::log(1.0 + arg)));
1724 #endif
1725  }
1726 
1730  static expr log2(float arg)
1731  {
1732 #if HALF_ENABLE_CPP11_CMATH
1733  return expr(std::log2(arg));
1734 #else
1735  return expr(static_cast<float>(std::log(static_cast<double>(arg)) * 1.4426950408889634073599246810019));
1736 #endif
1737  }
1738 
1742  static expr sqrt(float arg) { return expr(std::sqrt(arg)); }
1743 
1747  static expr cbrt(float arg)
1748  {
1749 #if HALF_ENABLE_CPP11_CMATH
1750  return expr(std::cbrt(arg));
1751 #else
1752  if(builtin_isnan(arg) || builtin_isinf(arg))
1753  return expr(arg);
1754  return expr(builtin_signbit(arg) ? -static_cast<float>(std::pow(-static_cast<double>(arg), 1.0 / 3.0))
1755  : static_cast<float>(std::pow(static_cast<double>(arg), 1.0 / 3.0)));
1756 #endif
1757  }
1758 
1763  static expr hypot(float x, float y)
1764  {
1765 #if HALF_ENABLE_CPP11_CMATH
1766  return expr(std::hypot(x, y));
1767 #else
1768  return expr((builtin_isinf(x) || builtin_isinf(y))
1769  ? std::numeric_limits<float>::infinity()
1770  : static_cast<float>(std::sqrt(static_cast<double>(x) * x + static_cast<double>(y) * y)));
1771 #endif
1772  }
1773 
1778  static expr pow(float base, float exp) { return expr(std::pow(base, exp)); }
1779 
1783  static expr sin(float arg) { return expr(std::sin(arg)); }
1784 
1788  static expr cos(float arg) { return expr(std::cos(arg)); }
1789 
1793  static expr tan(float arg) { return expr(std::tan(arg)); }
1794 
1798  static expr asin(float arg) { return expr(std::asin(arg)); }
1799 
1803  static expr acos(float arg) { return expr(std::acos(arg)); }
1804 
1808  static expr atan(float arg) { return expr(std::atan(arg)); }
1809 
1814  static expr atan2(float x, float y) { return expr(std::atan2(x, y)); }
1815 
1819  static expr sinh(float arg) { return expr(std::sinh(arg)); }
1820 
1824  static expr cosh(float arg) { return expr(std::cosh(arg)); }
1825 
1829  static expr tanh(float arg) { return expr(std::tanh(arg)); }
1830 
1834  static expr asinh(float arg)
1835  {
1836 #if HALF_ENABLE_CPP11_CMATH
1837  return expr(std::asinh(arg));
1838 #else
1839  return expr((arg == -std::numeric_limits<float>::infinity()) ? arg
1840  : static_cast<float>(std::log(arg + std::sqrt(arg * arg + 1.0))));
1841 #endif
1842  }
1843 
1847  static expr acosh(float arg)
1848  {
1849 #if HALF_ENABLE_CPP11_CMATH
1850  return expr(std::acosh(arg));
1851 #else
1852  return expr((arg < -1.0f) ? std::numeric_limits<float>::quiet_NaN()
1853  : static_cast<float>(std::log(arg + std::sqrt(arg * arg - 1.0))));
1854 #endif
1855  }
1856 
1860  static expr atanh(float arg)
1861  {
1862 #if HALF_ENABLE_CPP11_CMATH
1863  return expr(std::atanh(arg));
1864 #else
1865  return expr(static_cast<float>(0.5 * std::log((1.0 + arg) / (1.0 - arg))));
1866 #endif
1867  }
1868 
1872  static expr erf(float arg)
1873  {
1874 #if HALF_ENABLE_CPP11_CMATH
1875  return expr(std::erf(arg));
1876 #else
1877  return expr(static_cast<float>(erf(static_cast<double>(arg))));
1878 #endif
1879  }
1880 
1884  static expr erfc(float arg)
1885  {
1886 #if HALF_ENABLE_CPP11_CMATH
1887  return expr(std::erfc(arg));
1888 #else
1889  return expr(static_cast<float>(1.0 - erf(static_cast<double>(arg))));
1890 #endif
1891  }
1892 
1896  static expr lgamma(float arg)
1897  {
1898 #if HALF_ENABLE_CPP11_CMATH
1899  return expr(std::lgamma(arg));
1900 #else
1901  if(builtin_isinf(arg))
1902  return expr(std::numeric_limits<float>::infinity());
1903  if(arg < 0.0f)
1904  {
1905  float i, f = std::modf(-arg, &i);
1906  if(f == 0.0f)
1907  return expr(std::numeric_limits<float>::infinity());
1908  return expr(static_cast<float>(1.1447298858494001741434273513531 -
1909  std::log(std::abs(std::sin(3.1415926535897932384626433832795 * f))) - lgamma(1.0 - arg)));
1910  }
1911  return expr(static_cast<float>(lgamma(static_cast<double>(arg))));
1912 #endif
1913  }
1914 
1918  static expr tgamma(float arg)
1919  {
1920 #if HALF_ENABLE_CPP11_CMATH
1921  return expr(std::tgamma(arg));
1922 #else
1923  if(arg == 0.0f)
1924  return builtin_signbit(arg) ? expr(-std::numeric_limits<float>::infinity()) : expr(std::numeric_limits<float>::infinity());
1925  if(arg < 0.0f)
1926  {
1927  float i, f = std::modf(-arg, &i);
1928  if(f == 0.0f)
1929  return expr(std::numeric_limits<float>::quiet_NaN());
1930  double value =
1931  3.1415926535897932384626433832795 / (std::sin(3.1415926535897932384626433832795 * f) * std::exp(lgamma(1.0 - arg)));
1932  return expr(static_cast<float>((std::fmod(i, 2.0f) == 0.0f) ? -value : value));
1933  }
1934  if(builtin_isinf(arg))
1935  return expr(arg);
1936  return expr(static_cast<float>(std::exp(lgamma(static_cast<double>(arg)))));
1937 #endif
1938  }
1939 
1943  static half floor(half arg) { return half(binary, round_half<std::round_toward_neg_infinity>(arg.data_)); }
1944 
1948  static half ceil(half arg) { return half(binary, round_half<std::round_toward_infinity>(arg.data_)); }
1949 
1953  static half trunc(half arg) { return half(binary, round_half<std::round_toward_zero>(arg.data_)); }
1954 
1958  static half round(half arg) { return half(binary, round_half_up(arg.data_)); }
1959 
1963  static long lround(half arg) { return detail::half2int_up<long>(arg.data_); }
1964 
1968  static half rint(half arg) { return half(binary, round_half<half::round_style>(arg.data_)); }
1969 
1973  static long lrint(half arg) { return detail::half2int<half::round_style, long>(arg.data_); }
1974 
1975 #if HALF_ENABLE_CPP11_LONG_LONG
1979  static long long llround(half arg) { return detail::half2int_up<long long>(arg.data_); }
1980 
1984  static long long llrint(half arg) { return detail::half2int<half::round_style, long long>(arg.data_); }
1985 #endif
1986 
1991  static half frexp(half arg, int *exp)
1992  {
1993  int m = arg.data_ & 0x7FFF, e = -14;
1994  if(m >= 0x7C00 || !m)
1995  return *exp = 0, arg;
1996  for(; m < 0x400; m <<= 1, --e)
1997  ;
1998  return *exp = e + (m >> 10), half(binary, (arg.data_ & 0x8000) | 0x3800 | (m & 0x3FF));
1999  }
2000 
2005  static half modf(half arg, half *iptr)
2006  {
2007  unsigned int e = arg.data_ & 0x7FFF;
2008  if(e >= 0x6400)
2009  return *iptr = arg, half(binary, arg.data_ & (0x8000U | -(e > 0x7C00)));
2010  if(e < 0x3C00)
2011  return iptr->data_ = arg.data_ & 0x8000, arg;
2012  e >>= 10;
2013  unsigned int mask = (1 << (25 - e)) - 1, m = arg.data_ & mask;
2014  iptr->data_ = arg.data_ & ~mask;
2015  if(!m)
2016  return half(binary, arg.data_ & 0x8000);
2017  for(; m < 0x400; m <<= 1, --e)
2018  ;
2019  return half(binary, static_cast<uint16>((arg.data_ & 0x8000) | (e << 10) | (m & 0x3FF)));
2020  }
2021 
2026  static half scalbln(half arg, long exp)
2027  {
2028  unsigned int m = arg.data_ & 0x7FFF;
2029  if(m >= 0x7C00 || !m)
2030  return arg;
2031  for(; m < 0x400; m <<= 1, --exp)
2032  ;
2033  exp += m >> 10;
2034  uint16 value = arg.data_ & 0x8000;
2035  if(exp > 30)
2036  {
2037  if(half::round_style == std::round_toward_zero)
2038  value |= 0x7BFF;
2039  else if(half::round_style == std::round_toward_infinity)
2040  value |= 0x7C00 - (value >> 15);
2041  else if(half::round_style == std::round_toward_neg_infinity)
2042  value |= 0x7BFF + (value >> 15);
2043  else
2044  value |= 0x7C00;
2045  }
2046  else if(exp > 0)
2047  value |= (exp << 10) | (m & 0x3FF);
2048  else if(exp > -11)
2049  {
2050  m = (m & 0x3FF) | 0x400;
2051  if(half::round_style == std::round_to_nearest)
2052  {
2053  m += 1 << -exp;
2054 #if HALF_ROUND_TIES_TO_EVEN
2055  m -= (m >> (1 - exp)) & 1;
2056 #endif
2057  }
2058  else if(half::round_style == std::round_toward_infinity)
2059  m += ((value >> 15) - 1) & ((1 << (1 - exp)) - 1U);
2060  else if(half::round_style == std::round_toward_neg_infinity)
2061  m += -(value >> 15) & ((1 << (1 - exp)) - 1U);
2062  value |= m >> (1 - exp);
2063  }
2064  else if(half::round_style == std::round_toward_infinity)
2065  value -= (value >> 15) - 1;
2066  else if(half::round_style == std::round_toward_neg_infinity)
2067  value += value >> 15;
2068  return half(binary, value);
2069  }
2070 
2074  static int ilogb(half arg)
2075  {
2076  int abs = arg.data_ & 0x7FFF;
2077  if(!abs)
2078  return FP_ILOGB0;
2079  if(abs < 0x7C00)
2080  {
2081  int exp = (abs >> 10) - 15;
2082  if(abs < 0x400)
2083  for(; abs < 0x200; abs <<= 1, --exp)
2084  ;
2085  return exp;
2086  }
2087  if(abs > 0x7C00)
2088  return FP_ILOGBNAN;
2089  return INT_MAX;
2090  }
2091 
2095  static half logb(half arg)
2096  {
2097  int abs = arg.data_ & 0x7FFF;
2098  if(!abs)
2099  return half(binary, 0xFC00);
2100  if(abs < 0x7C00)
2101  {
2102  int exp = (abs >> 10) - 15;
2103  if(abs < 0x400)
2104  for(; abs < 0x200; abs <<= 1, --exp)
2105  ;
2106  uint16 bits = (exp < 0) << 15;
2107  if(exp)
2108  {
2109  unsigned int m = std::abs(exp) << 6, e = 18;
2110  for(; m < 0x400; m <<= 1, --e)
2111  ;
2112  bits |= (e << 10) + m;
2113  }
2114  return half(binary, bits);
2115  }
2116  if(abs > 0x7C00)
2117  return arg;
2118  return half(binary, 0x7C00);
2119  }
2120 
2125  static half nextafter(half from, half to)
2126  {
2127  uint16 fabs = from.data_ & 0x7FFF, tabs = to.data_ & 0x7FFF;
2128  if(fabs > 0x7C00)
2129  return from;
2130  if(tabs > 0x7C00 || from.data_ == to.data_ || !(fabs | tabs))
2131  return to;
2132  if(!fabs)
2133  return half(binary, (to.data_ & 0x8000) + 1);
2134  bool lt = ((fabs == from.data_) ? static_cast<int>(fabs) : -static_cast<int>(fabs)) <
2135  ((tabs == to.data_) ? static_cast<int>(tabs) : -static_cast<int>(tabs));
2136  return half(binary, from.data_ + (((from.data_ >> 15) ^ static_cast<unsigned>(lt)) << 1) - 1);
2137  }
2138 
2143  static half nexttoward(half from, long double to)
2144  {
2145  if(isnan(from))
2146  return from;
2147  long double lfrom = static_cast<long double>(from);
2148  if(builtin_isnan(to) || lfrom == to)
2149  return half(static_cast<float>(to));
2150  if(!(from.data_ & 0x7FFF))
2151  return half(binary, (static_cast<detail::uint16>(builtin_signbit(to)) << 15) + 1);
2152  return half(binary, from.data_ + (((from.data_ >> 15) ^ static_cast<unsigned>(lfrom < to)) << 1) - 1);
2153  }
2154 
2159  static half copysign(half x, half y) { return half(binary, x.data_ ^ ((x.data_ ^ y.data_) & 0x8000)); }
2160 
2165  static int fpclassify(half arg)
2166  {
2167  unsigned int abs = arg.data_ & 0x7FFF;
2168  return abs ? ((abs > 0x3FF) ? ((abs >= 0x7C00) ? ((abs > 0x7C00) ? FP_NAN : FP_INFINITE) : FP_NORMAL) : FP_SUBNORMAL) : FP_ZERO;
2169  }
2170 
2175  static bool isfinite(half arg) { return (arg.data_ & 0x7C00) != 0x7C00; }
2176 
2181  static bool isinf(half arg) { return (arg.data_ & 0x7FFF) == 0x7C00; }
2182 
2187  static bool isnan(half arg) { return (arg.data_ & 0x7FFF) > 0x7C00; }
2188 
2193  static bool isnormal(half arg) { return ((arg.data_ & 0x7C00) != 0) & ((arg.data_ & 0x7C00) != 0x7C00); }
2194 
2199  static bool signbit(half arg) { return (arg.data_ & 0x8000) != 0; }
2200 
2206  static bool isequal(half x, half y) { return (x.data_ == y.data_ || !((x.data_ | y.data_) & 0x7FFF)) && !isnan(x); }
2207 
2213  static bool isnotequal(half x, half y) { return (x.data_ != y.data_ && ((x.data_ | y.data_) & 0x7FFF)) || isnan(x); }
2214 
2220  static bool isgreater(half x, half y)
2221  {
2222  int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF;
2223  return xabs <= 0x7C00 && yabs <= 0x7C00 && (((xabs == x.data_) ? xabs : -xabs) > ((yabs == y.data_) ? yabs : -yabs));
2224  }
2225 
2231  static bool isgreaterequal(half x, half y)
2232  {
2233  int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF;
2234  return xabs <= 0x7C00 && yabs <= 0x7C00 && (((xabs == x.data_) ? xabs : -xabs) >= ((yabs == y.data_) ? yabs : -yabs));
2235  }
2236 
2242  static bool isless(half x, half y)
2243  {
2244  int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF;
2245  return xabs <= 0x7C00 && yabs <= 0x7C00 && (((xabs == x.data_) ? xabs : -xabs) < ((yabs == y.data_) ? yabs : -yabs));
2246  }
2247 
2253  static bool islessequal(half x, half y)
2254  {
2255  int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF;
2256  return xabs <= 0x7C00 && yabs <= 0x7C00 && (((xabs == x.data_) ? xabs : -xabs) <= ((yabs == y.data_) ? yabs : -yabs));
2257  }
2258 
2264  static bool islessgreater(half x, half y)
2265  {
2266  int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF;
2267  if(xabs > 0x7C00 || yabs > 0x7C00)
2268  return false;
2269  int a = (xabs == x.data_) ? xabs : -xabs, b = (yabs == y.data_) ? yabs : -yabs;
2270  return a < b || a > b;
2271  }
2272 
2278  static bool isunordered(half x, half y) { return isnan(x) || isnan(y); }
2279 
2280  private:
2281  static double erf(double arg)
2282  {
2283  if(builtin_isinf(arg))
2284  return (arg < 0.0) ? -1.0 : 1.0;
2285  double x2 = arg * arg, ax2 = 0.147 * x2,
2286  value = std::sqrt(1.0 - std::exp(-x2 * (1.2732395447351626861510701069801 + ax2) / (1.0 + ax2)));
2287  return builtin_signbit(arg) ? -value : value;
2288  }
2289 
2290  static double lgamma(double arg)
2291  {
2292  double v = 1.0;
2293  for(; arg < 8.0; ++arg)
2294  v *= arg;
2295  double w = 1.0 / (arg * arg);
2296  return (((((((-0.02955065359477124183006535947712 * w + 0.00641025641025641025641025641026) * w +
2297  -0.00191752691752691752691752691753) *
2298  w +
2299  8.4175084175084175084175084175084e-4) *
2300  w +
2301  -5.952380952380952380952380952381e-4) *
2302  w +
2303  7.9365079365079365079365079365079e-4) *
2304  w +
2305  -0.00277777777777777777777777777778) *
2306  w +
2307  0.08333333333333333333333333333333) /
2308  arg +
2309  0.91893853320467274178032973640562 - std::log(v) - arg + (arg - 0.5) * std::log(arg);
2310  }
2311 };
2312 
2315 template <typename T>
2317 {
2321  static HALF_CONSTEXPR half negate(half arg) { return half(binary, arg.data_ ^ 0x8000); }
2322 
2326  static half fabs(half arg) { return half(binary, arg.data_ & 0x7FFF); }
2327 };
2328 template <>
2330 {
2331  static HALF_CONSTEXPR expr negate(float arg) { return expr(-arg); }
2332  static expr fabs(float arg) { return expr(std::fabs(arg)); }
2333 };
2334 
2338 template <typename T, typename U>
2340 {
2345  static expr fmin(float x, float y)
2346  {
2347 #if HALF_ENABLE_CPP11_CMATH
2348  return expr(std::fmin(x, y));
2349 #else
2350  if(builtin_isnan(x))
2351  return expr(y);
2352  if(builtin_isnan(y))
2353  return expr(x);
2354  return expr(std::min(x, y));
2355 #endif
2356  }
2357 
2362  static expr fmax(float x, float y)
2363  {
2364 #if HALF_ENABLE_CPP11_CMATH
2365  return expr(std::fmax(x, y));
2366 #else
2367  if(builtin_isnan(x))
2368  return expr(y);
2369  if(builtin_isnan(y))
2370  return expr(x);
2371  return expr(std::max(x, y));
2372 #endif
2373  }
2374 };
2375 template <>
2377 {
2378  static half fmin(half x, half y)
2379  {
2380  int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF;
2381  if(xabs > 0x7C00)
2382  return y;
2383  if(yabs > 0x7C00)
2384  return x;
2385  return (((xabs == x.data_) ? xabs : -xabs) > ((yabs == y.data_) ? yabs : -yabs)) ? y : x;
2386  }
2387  static half fmax(half x, half y)
2388  {
2389  int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF;
2390  if(xabs > 0x7C00)
2391  return y;
2392  if(yabs > 0x7C00)
2393  return x;
2394  return (((xabs == x.data_) ? xabs : -xabs) < ((yabs == y.data_) ? yabs : -yabs)) ? y : x;
2395  }
2396 };
2397 
2404 template <typename T, typename U, std::float_round_style R = (std::float_round_style)(HALF_ROUND_STYLE)>
2406 {
2407 };
2408 template <typename U, std::float_round_style R>
2409 struct half_caster<half, U, R>
2410 {
2411 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
2412  static_assert(std::is_arithmetic<U>::value, "half_cast from non-arithmetic type unsupported");
2413 #endif
2414 
2415  static half cast(U arg) { return cast_impl(arg, is_float<U>()); };
2416 
2417  private:
2418  static half cast_impl(U arg, true_type) { return half(binary, float2half<R>(arg)); }
2419  static half cast_impl(U arg, false_type) { return half(binary, int2half<R>(arg)); }
2420 };
2421 template <typename T, std::float_round_style R>
2422 struct half_caster<T, half, R>
2423 {
2424 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
2425  static_assert(std::is_arithmetic<T>::value, "half_cast to non-arithmetic type unsupported");
2426 #endif
2427 
2428  static T cast(half arg) { return cast_impl(arg, is_float<T>()); }
2429 
2430  private:
2431  static T cast_impl(half arg, true_type) { return half2float<T>(arg.data_); }
2432  static T cast_impl(half arg, false_type) { return half2int<R, T>(arg.data_); }
2433 };
2434 template <typename T, std::float_round_style R>
2435 struct half_caster<T, expr, R>
2436 {
2437 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
2438  static_assert(std::is_arithmetic<T>::value, "half_cast to non-arithmetic type unsupported");
2439 #endif
2440 
2441  static T cast(expr arg) { return cast_impl(arg, is_float<T>()); }
2442 
2443  private:
2444  static T cast_impl(float arg, true_type) { return static_cast<T>(arg); }
2445  static T cast_impl(half arg, false_type) { return half2int<R, T>(arg.data_); }
2446 };
2447 template <std::float_round_style R>
2448 struct half_caster<half, half, R>
2449 {
2450  static half cast(half arg) { return arg; }
2451 };
2452 template <std::float_round_style R>
2453 struct half_caster<half, expr, R> : half_caster<half, half, R>
2454 {
2455 };
2456 
2459 
2465 template <typename T, typename U>
2467 {
2468  return functions::isequal(x, y);
2469 }
2470 
2476 template <typename T, typename U>
2478 {
2479  return functions::isnotequal(x, y);
2480 }
2481 
2487 template <typename T, typename U>
2489 {
2490  return functions::isless(x, y);
2491 }
2492 
2498 template <typename T, typename U>
2500 {
2501  return functions::isgreater(x, y);
2502 }
2503 
2509 template <typename T, typename U>
2511 {
2512  return functions::islessequal(x, y);
2513 }
2514 
2520 template <typename T, typename U>
2522 {
2523  return functions::isgreaterequal(x, y);
2524 }
2525 
2529 
2534 template <typename T, typename U>
2536 {
2537  return functions::plus(x, y);
2538 }
2539 
2544 template <typename T, typename U>
2546 {
2547  return functions::minus(x, y);
2548 }
2549 
2554 template <typename T, typename U>
2556 {
2557  return functions::multiplies(x, y);
2558 }
2559 
2564 template <typename T, typename U>
2566 {
2567  return functions::divides(x, y);
2568 }
2569 
2573 template <typename T>
2575 {
2576  return arg;
2577 }
2578 
2582 template <typename T>
2584 {
2585  return unary_specialized<T>::negate(arg);
2586 }
2587 
2591 
2596 template <typename T, typename charT, typename traits>
2597 typename enable<std::basic_ostream<charT, traits> &, T>::type operator<<(std::basic_ostream<charT, traits> &out, T arg)
2598 {
2599  return functions::write(out, arg);
2600 }
2601 
2606 template <typename charT, typename traits>
2607 std::basic_istream<charT, traits> &operator>>(std::basic_istream<charT, traits> &in, half &arg)
2608 {
2609  return functions::read(in, arg);
2610 }
2611 
2615 
2619 // template<typename T> typename enable<T,T>::type abs(T arg) { return unary_specialized<T>::fabs(arg); }
2620 inline half abs(half arg) { return unary_specialized<half>::fabs(arg); }
2621 inline expr abs(expr arg) { return unary_specialized<expr>::fabs(arg); }
2622 
2626 // template<typename T> typename enable<T,T>::type fabs(T arg) { return unary_specialized<T>::fabs(arg); }
2627 inline half fabs(half arg) { return unary_specialized<half>::fabs(arg); }
2628 inline expr fabs(expr arg) { return unary_specialized<expr>::fabs(arg); }
2629 
2634 // template<typename T,typename U> typename enable<expr,T,U>::type fmod(T x, U y) { return functions::fmod(x, y); }
2635 inline expr fmod(half x, half y) { return functions::fmod(x, y); }
2636 inline expr fmod(half x, expr y) { return functions::fmod(x, y); }
2637 inline expr fmod(expr x, half y) { return functions::fmod(x, y); }
2638 inline expr fmod(expr x, expr y) { return functions::fmod(x, y); }
2639 
2644 // template<typename T,typename U> typename enable<expr,T,U>::type remainder(T x, U y) { return functions::remainder(x,
2645 // y);
2646 //}
2647 inline expr remainder(half x, half y) { return functions::remainder(x, y); }
2648 inline expr remainder(half x, expr y) { return functions::remainder(x, y); }
2649 inline expr remainder(expr x, half y) { return functions::remainder(x, y); }
2650 inline expr remainder(expr x, expr y) { return functions::remainder(x, y); }
2651 
2657 // template<typename T,typename U> typename enable<expr,T,U>::type remquo(T x, U y, int *quo) { return
2658 // functions::remquo(x, y, quo); }
2659 inline expr remquo(half x, half y, int *quo) { return functions::remquo(x, y, quo); }
2660 inline expr remquo(half x, expr y, int *quo) { return functions::remquo(x, y, quo); }
2661 inline expr remquo(expr x, half y, int *quo) { return functions::remquo(x, y, quo); }
2662 inline expr remquo(expr x, expr y, int *quo) { return functions::remquo(x, y, quo); }
2663 
2669 // template<typename T,typename U,typename V> typename enable<expr,T,U,V>::type fma(T x, U y, V z) { return
2670 // functions::fma(x, y, z); }
2671 inline expr fma(half x, half y, half z) { return functions::fma(x, y, z); }
2672 inline expr fma(half x, half y, expr z) { return functions::fma(x, y, z); }
2673 inline expr fma(half x, expr y, half z) { return functions::fma(x, y, z); }
2674 inline expr fma(half x, expr y, expr z) { return functions::fma(x, y, z); }
2675 inline expr fma(expr x, half y, half z) { return functions::fma(x, y, z); }
2676 inline expr fma(expr x, half y, expr z) { return functions::fma(x, y, z); }
2677 inline expr fma(expr x, expr y, half z) { return functions::fma(x, y, z); }
2678 inline expr fma(expr x, expr y, expr z) { return functions::fma(x, y, z); }
2679 
2684 // template<typename T,typename U> typename result<T,U>::type fmax(T x, U y) { return binary_specialized<T,U>::fmax(x, y);
2685 //}
2690 
2695 // template<typename T,typename U> typename result<T,U>::type fmin(T x, U y) { return binary_specialized<T,U>::fmin(x, y);
2696 //}
2701 
2706 // template<typename T,typename U> typename enable<expr,T,U>::type fdim(T x, U y) { return functions::fdim(x, y); }
2707 inline expr fdim(half x, half y) { return functions::fdim(x, y); }
2708 inline expr fdim(half x, expr y) { return functions::fdim(x, y); }
2709 inline expr fdim(expr x, half y) { return functions::fdim(x, y); }
2710 inline expr fdim(expr x, expr y) { return functions::fdim(x, y); }
2711 
2714 inline half nanh(const char *) { return functions::nanh(); }
2715 
2719 
2723 // template<typename T> typename enable<expr,T>::type exp(T arg) { return functions::exp(arg); }
2724 inline expr exp(half arg) { return functions::exp(arg); }
2725 inline expr exp(expr arg) { return functions::exp(arg); }
2726 
2730 // template<typename T> typename enable<expr,T>::type expm1(T arg) { return functions::expm1(arg); }
2731 inline expr expm1(half arg) { return functions::expm1(arg); }
2732 inline expr expm1(expr arg) { return functions::expm1(arg); }
2733 
2737 // template<typename T> typename enable<expr,T>::type exp2(T arg) { return functions::exp2(arg); }
2738 inline expr exp2(half arg) { return functions::exp2(arg); }
2739 inline expr exp2(expr arg) { return functions::exp2(arg); }
2740 
2744 // template<typename T> typename enable<expr,T>::type log(T arg) { return functions::log(arg); }
2745 inline expr log(half arg) { return functions::log(arg); }
2746 inline expr log(expr arg) { return functions::log(arg); }
2747 
2751 // template<typename T> typename enable<expr,T>::type log10(T arg) { return functions::log10(arg); }
2752 inline expr log10(half arg) { return functions::log10(arg); }
2753 inline expr log10(expr arg) { return functions::log10(arg); }
2754 
2758 // template<typename T> typename enable<expr,T>::type log1p(T arg) { return functions::log1p(arg); }
2759 inline expr log1p(half arg) { return functions::log1p(arg); }
2760 inline expr log1p(expr arg) { return functions::log1p(arg); }
2761 
2765 // template<typename T> typename enable<expr,T>::type log2(T arg) { return functions::log2(arg); }
2766 inline expr log2(half arg) { return functions::log2(arg); }
2767 inline expr log2(expr arg) { return functions::log2(arg); }
2768 
2772 
2776 // template<typename T> typename enable<expr,T>::type sqrt(T arg) { return functions::sqrt(arg); }
2777 inline expr sqrt(half arg) { return functions::sqrt(arg); }
2778 inline expr sqrt(expr arg) { return functions::sqrt(arg); }
2779 
2783 // template<typename T> typename enable<expr,T>::type cbrt(T arg) { return functions::cbrt(arg); }
2784 inline expr cbrt(half arg) { return functions::cbrt(arg); }
2785 inline expr cbrt(expr arg) { return functions::cbrt(arg); }
2786 
2791 // template<typename T,typename U> typename enable<expr,T,U>::type hypot(T x, U y) { return functions::hypot(x, y); }
2792 inline expr hypot(half x, half y) { return functions::hypot(x, y); }
2793 inline expr hypot(half x, expr y) { return functions::hypot(x, y); }
2794 inline expr hypot(expr x, half y) { return functions::hypot(x, y); }
2795 inline expr hypot(expr x, expr y) { return functions::hypot(x, y); }
2796 
2801 // template<typename T,typename U> typename enable<expr,T,U>::type pow(T base, U exp) { return functions::pow(base, exp);
2802 //}
2803 inline expr pow(half base, half exp) { return functions::pow(base, exp); }
2804 inline expr pow(half base, expr exp) { return functions::pow(base, exp); }
2805 inline expr pow(expr base, half exp) { return functions::pow(base, exp); }
2806 inline expr pow(expr base, expr exp) { return functions::pow(base, exp); }
2807 
2811 
2815 // template<typename T> typename enable<expr,T>::type sin(T arg) { return functions::sin(arg); }
2816 inline expr sin(half arg) { return functions::sin(arg); }
2817 inline expr sin(expr arg) { return functions::sin(arg); }
2818 
2822 // template<typename T> typename enable<expr,T>::type cos(T arg) { return functions::cos(arg); }
2823 inline expr cos(half arg) { return functions::cos(arg); }
2824 inline expr cos(expr arg) { return functions::cos(arg); }
2825 
2829 // template<typename T> typename enable<expr,T>::type tan(T arg) { return functions::tan(arg); }
2830 inline expr tan(half arg) { return functions::tan(arg); }
2831 inline expr tan(expr arg) { return functions::tan(arg); }
2832 
2836 // template<typename T> typename enable<expr,T>::type asin(T arg) { return functions::asin(arg); }
2837 inline expr asin(half arg) { return functions::asin(arg); }
2838 inline expr asin(expr arg) { return functions::asin(arg); }
2839 
2843 // template<typename T> typename enable<expr,T>::type acos(T arg) { return functions::acos(arg); }
2844 inline expr acos(half arg) { return functions::acos(arg); }
2845 inline expr acos(expr arg) { return functions::acos(arg); }
2846 
2850 // template<typename T> typename enable<expr,T>::type atan(T arg) { return functions::atan(arg); }
2851 inline expr atan(half arg) { return functions::atan(arg); }
2852 inline expr atan(expr arg) { return functions::atan(arg); }
2853 
2858 // template<typename T,typename U> typename enable<expr,T,U>::type atan2(T x, U y) { return functions::atan2(x, y); }
2859 inline expr atan2(half x, half y) { return functions::atan2(x, y); }
2860 inline expr atan2(half x, expr y) { return functions::atan2(x, y); }
2861 inline expr atan2(expr x, half y) { return functions::atan2(x, y); }
2862 inline expr atan2(expr x, expr y) { return functions::atan2(x, y); }
2863 
2867 
2871 // template<typename T> typename enable<expr,T>::type sinh(T arg) { return functions::sinh(arg); }
2872 inline expr sinh(half arg) { return functions::sinh(arg); }
2873 inline expr sinh(expr arg) { return functions::sinh(arg); }
2874 
2878 // template<typename T> typename enable<expr,T>::type cosh(T arg) { return functions::cosh(arg); }
2879 inline expr cosh(half arg) { return functions::cosh(arg); }
2880 inline expr cosh(expr arg) { return functions::cosh(arg); }
2881 
2885 // template<typename T> typename enable<expr,T>::type tanh(T arg) { return functions::tanh(arg); }
2886 inline expr tanh(half arg) { return functions::tanh(arg); }
2887 inline expr tanh(expr arg) { return functions::tanh(arg); }
2888 
2892 // template<typename T> typename enable<expr,T>::type asinh(T arg) { return functions::asinh(arg); }
2893 inline expr asinh(half arg) { return functions::asinh(arg); }
2894 inline expr asinh(expr arg) { return functions::asinh(arg); }
2895 
2899 // template<typename T> typename enable<expr,T>::type acosh(T arg) { return functions::acosh(arg); }
2900 inline expr acosh(half arg) { return functions::acosh(arg); }
2901 inline expr acosh(expr arg) { return functions::acosh(arg); }
2902 
2906 // template<typename T> typename enable<expr,T>::type atanh(T arg) { return functions::atanh(arg); }
2907 inline expr atanh(half arg) { return functions::atanh(arg); }
2908 inline expr atanh(expr arg) { return functions::atanh(arg); }
2909 
2913 
2917 // template<typename T> typename enable<expr,T>::type erf(T arg) { return functions::erf(arg); }
2918 inline expr erf(half arg) { return functions::erf(arg); }
2919 inline expr erf(expr arg) { return functions::erf(arg); }
2920 
2924 // template<typename T> typename enable<expr,T>::type erfc(T arg) { return functions::erfc(arg); }
2925 inline expr erfc(half arg) { return functions::erfc(arg); }
2926 inline expr erfc(expr arg) { return functions::erfc(arg); }
2927 
2931 // template<typename T> typename enable<expr,T>::type lgamma(T arg) { return functions::lgamma(arg); }
2932 inline expr lgamma(half arg) { return functions::lgamma(arg); }
2933 inline expr lgamma(expr arg) { return functions::lgamma(arg); }
2934 
2938 // template<typename T> typename enable<expr,T>::type tgamma(T arg) { return functions::tgamma(arg); }
2939 inline expr tgamma(half arg) { return functions::tgamma(arg); }
2940 inline expr tgamma(expr arg) { return functions::tgamma(arg); }
2941 
2945 
2949 // template<typename T> typename enable<half,T>::type ceil(T arg) { return functions::ceil(arg); }
2950 inline half ceil(half arg) { return functions::ceil(arg); }
2951 inline half ceil(expr arg) { return functions::ceil(arg); }
2952 
2956 // template<typename T> typename enable<half,T>::type floor(T arg) { return functions::floor(arg); }
2957 inline half floor(half arg) { return functions::floor(arg); }
2958 inline half floor(expr arg) { return functions::floor(arg); }
2959 
2963 // template<typename T> typename enable<half,T>::type trunc(T arg) { return functions::trunc(arg); }
2964 inline half trunc(half arg) { return functions::trunc(arg); }
2965 inline half trunc(expr arg) { return functions::trunc(arg); }
2966 
2970 // template<typename T> typename enable<half,T>::type round(T arg) { return functions::round(arg); }
2971 inline half round(half arg) { return functions::round(arg); }
2972 inline half round(expr arg) { return functions::round(arg); }
2973 
2977 // template<typename T> typename enable<long,T>::type lround(T arg) { return functions::lround(arg); }
2978 inline long lround(half arg) { return functions::lround(arg); }
2979 inline long lround(expr arg) { return functions::lround(arg); }
2980 
2984 // template<typename T> typename enable<half,T>::type nearbyint(T arg) { return functions::nearbyint(arg); }
2985 inline half nearbyint(half arg) { return functions::rint(arg); }
2986 inline half nearbyint(expr arg) { return functions::rint(arg); }
2987 
2991 // template<typename T> typename enable<half,T>::type rint(T arg) { return functions::rint(arg); }
2992 inline half rint(half arg) { return functions::rint(arg); }
2993 inline half rint(expr arg) { return functions::rint(arg); }
2994 
2998 // template<typename T> typename enable<long,T>::type lrint(T arg) { return functions::lrint(arg); }
2999 inline long lrint(half arg) { return functions::lrint(arg); }
3000 inline long lrint(expr arg) { return functions::lrint(arg); }
3001 #if HALF_ENABLE_CPP11_LONG_LONG
3005 // template<typename T> typename enable<long long,T>::type llround(T arg) { return functions::llround(arg); }
3006 inline long long llround(half arg) { return functions::llround(arg); }
3007 inline long long llround(expr arg) { return functions::llround(arg); }
3008 
3012 // template<typename T> typename enable<long long,T>::type llrint(T arg) { return functions::llrint(arg); }
3013 inline long long llrint(half arg) { return functions::llrint(arg); }
3014 inline long long llrint(expr arg) { return functions::llrint(arg); }
3015 #endif
3016 
3020 
3025 // template<typename T> typename enable<half,T>::type frexp(T arg, int *exp) { return functions::frexp(arg, exp); }
3026 inline half frexp(half arg, int *exp) { return functions::frexp(arg, exp); }
3027 inline half frexp(expr arg, int *exp) { return functions::frexp(arg, exp); }
3028 
3033 // template<typename T> typename enable<half,T>::type ldexp(T arg, int exp) { return functions::scalbln(arg, exp); }
3034 inline half ldexp(half arg, int exp) { return functions::scalbln(arg, exp); }
3035 inline half ldexp(expr arg, int exp) { return functions::scalbln(arg, exp); }
3036 
3041 // template<typename T> typename enable<half,T>::type modf(T arg, half *iptr) { return functions::modf(arg, iptr); }
3042 inline half modf(half arg, half *iptr) { return functions::modf(arg, iptr); }
3043 inline half modf(expr arg, half *iptr) { return functions::modf(arg, iptr); }
3044 
3049 // template<typename T> typename enable<half,T>::type scalbn(T arg, int exp) { return functions::scalbln(arg, exp); }
3050 inline half scalbn(half arg, int exp) { return functions::scalbln(arg, exp); }
3051 inline half scalbn(expr arg, int exp) { return functions::scalbln(arg, exp); }
3052 
3057 // template<typename T> typename enable<half,T>::type scalbln(T arg, long exp) { return functions::scalbln(arg, exp); }
3058 inline half scalbln(half arg, long exp) { return functions::scalbln(arg, exp); }
3059 inline half scalbln(expr arg, long exp) { return functions::scalbln(arg, exp); }
3060 
3067 // template<typename T> typename enable<int,T>::type ilogb(T arg) { return functions::ilogb(arg); }
3068 inline int ilogb(half arg) { return functions::ilogb(arg); }
3069 inline int ilogb(expr arg) { return functions::ilogb(arg); }
3070 
3074 // template<typename T> typename enable<half,T>::type logb(T arg) { return functions::logb(arg); }
3075 inline half logb(half arg) { return functions::logb(arg); }
3076 inline half logb(expr arg) { return functions::logb(arg); }
3077 
3082 // template<typename T,typename U> typename enable<half,T,U>::type nextafter(T from, U to) { return
3083 // functions::nextafter(from, to); }
3084 inline half nextafter(half from, half to) { return functions::nextafter(from, to); }
3085 inline half nextafter(half from, expr to) { return functions::nextafter(from, to); }
3086 inline half nextafter(expr from, half to) { return functions::nextafter(from, to); }
3087 inline half nextafter(expr from, expr to) { return functions::nextafter(from, to); }
3088 
3093 // template<typename T> typename enable<half,T>::type nexttoward(T from, long double to) { return
3094 // functions::nexttoward(from, to); }
3095 inline half nexttoward(half from, long double to) { return functions::nexttoward(from, to); }
3096 inline half nexttoward(expr from, long double to) { return functions::nexttoward(from, to); }
3097 
3102 // template<typename T,typename U> typename enable<half,T,U>::type copysign(T x, U y) { return functions::copysign(x, y);
3103 //}
3104 inline half copysign(half x, half y) { return functions::copysign(x, y); }
3105 inline half copysign(half x, expr y) { return functions::copysign(x, y); }
3106 inline half copysign(expr x, half y) { return functions::copysign(x, y); }
3107 inline half copysign(expr x, expr y) { return functions::copysign(x, y); }
3108 
3112 
3120 // template<typename T> typename enable<int,T>::type fpclassify(T arg) { return functions::fpclassify(arg); }
3121 inline int fpclassify(half arg) { return functions::fpclassify(arg); }
3122 inline int fpclassify(expr arg) { return functions::fpclassify(arg); }
3123 
3128 // template<typename T> typename enable<bool,T>::type isfinite(T arg) { return functions::isfinite(arg); }
3129 inline bool isfinite(half arg) { return functions::isfinite(arg); }
3130 inline bool isfinite(expr arg) { return functions::isfinite(arg); }
3131 
3136 // template<typename T> typename enable<bool,T>::type isinf(T arg) { return functions::isinf(arg); }
3137 inline bool isinf(half arg) { return functions::isinf(arg); }
3138 inline bool isinf(expr arg) { return functions::isinf(arg); }
3139 
3144 // template<typename T> typename enable<bool,T>::type isnan(T arg) { return functions::isnan(arg); }
3145 inline bool isnan(half arg) { return functions::isnan(arg); }
3146 inline bool isnan(expr arg) { return functions::isnan(arg); }
3147 
3152 // template<typename T> typename enable<bool,T>::type isnormal(T arg) { return functions::isnormal(arg); }
3153 inline bool isnormal(half arg) { return functions::isnormal(arg); }
3154 inline bool isnormal(expr arg) { return functions::isnormal(arg); }
3155 
3160 // template<typename T> typename enable<bool,T>::type signbit(T arg) { return functions::signbit(arg); }
3161 inline bool signbit(half arg) { return functions::signbit(arg); }
3162 inline bool signbit(expr arg) { return functions::signbit(arg); }
3163 
3167 
3173 // template<typename T,typename U> typename enable<bool,T,U>::type isgreater(T x, U y) { return functions::isgreater(x,
3174 // y);
3175 //}
3176 inline bool isgreater(half x, half y) { return functions::isgreater(x, y); }
3177 inline bool isgreater(half x, expr y) { return functions::isgreater(x, y); }
3178 inline bool isgreater(expr x, half y) { return functions::isgreater(x, y); }
3179 inline bool isgreater(expr x, expr y) { return functions::isgreater(x, y); }
3180 
3186 // template<typename T,typename U> typename enable<bool,T,U>::type isgreaterequal(T x, U y) { return
3187 // functions::isgreaterequal(x, y); }
3188 inline bool isgreaterequal(half x, half y) { return functions::isgreaterequal(x, y); }
3189 inline bool isgreaterequal(half x, expr y) { return functions::isgreaterequal(x, y); }
3190 inline bool isgreaterequal(expr x, half y) { return functions::isgreaterequal(x, y); }
3191 inline bool isgreaterequal(expr x, expr y) { return functions::isgreaterequal(x, y); }
3192 
3198 // template<typename T,typename U> typename enable<bool,T,U>::type isless(T x, U y) { return functions::isless(x, y); }
3199 inline bool isless(half x, half y) { return functions::isless(x, y); }
3200 inline bool isless(half x, expr y) { return functions::isless(x, y); }
3201 inline bool isless(expr x, half y) { return functions::isless(x, y); }
3202 inline bool isless(expr x, expr y) { return functions::isless(x, y); }
3203 
3209 // template<typename T,typename U> typename enable<bool,T,U>::type islessequal(T x, U y) { return
3210 // functions::islessequal(x, y); }
3211 inline bool islessequal(half x, half y) { return functions::islessequal(x, y); }
3212 inline bool islessequal(half x, expr y) { return functions::islessequal(x, y); }
3213 inline bool islessequal(expr x, half y) { return functions::islessequal(x, y); }
3214 inline bool islessequal(expr x, expr y) { return functions::islessequal(x, y); }
3215 
3221 // template<typename T,typename U> typename enable<bool,T,U>::type islessgreater(T x, U y) { return
3222 // functions::islessgreater(x, y); }
3223 inline bool islessgreater(half x, half y) { return functions::islessgreater(x, y); }
3224 inline bool islessgreater(half x, expr y) { return functions::islessgreater(x, y); }
3225 inline bool islessgreater(expr x, half y) { return functions::islessgreater(x, y); }
3226 inline bool islessgreater(expr x, expr y) { return functions::islessgreater(x, y); }
3227 
3233 // template<typename T,typename U> typename enable<bool,T,U>::type isunordered(T x, U y) { return
3234 // functions::isunordered(x, y); }
3235 inline bool isunordered(half x, half y) { return functions::isunordered(x, y); }
3236 inline bool isunordered(half x, expr y) { return functions::isunordered(x, y); }
3237 inline bool isunordered(expr x, half y) { return functions::isunordered(x, y); }
3238 inline bool isunordered(expr x, expr y) { return functions::isunordered(x, y); }
3239 
3242 
3255 template <typename T, typename U>
3256 T half_cast(U arg)
3257 {
3258  return half_caster<T, U>::cast(arg);
3259 }
3260 
3273 template <typename T, std::float_round_style R, typename U>
3274 T half_cast(U arg)
3275 {
3276  return half_caster<T, U, R>::cast(arg);
3277 }
3279 } // namespace detail
3280 
3281 using detail::operator==;
3282 using detail::operator!=;
3283 using detail::operator<;
3284 using detail::operator>;
3285 using detail::operator<=;
3286 using detail::operator>=;
3287 using detail::operator+;
3288 using detail::operator-;
3289 using detail::operator*;
3290 using detail::operator/;
3291 using detail::operator<<;
3292 using detail::operator>>;
3293 
3294 using detail::abs;
3295 using detail::acos;
3296 using detail::acosh;
3297 using detail::asin;
3298 using detail::asinh;
3299 using detail::atan;
3300 using detail::atan2;
3301 using detail::atanh;
3302 using detail::cbrt;
3303 using detail::ceil;
3304 using detail::cos;
3305 using detail::cosh;
3306 using detail::erf;
3307 using detail::erfc;
3308 using detail::exp;
3309 using detail::exp2;
3310 using detail::expm1;
3311 using detail::fabs;
3312 using detail::fdim;
3313 using detail::floor;
3314 using detail::fma;
3315 using detail::fmax;
3316 using detail::fmin;
3317 using detail::fmod;
3318 using detail::hypot;
3319 using detail::lgamma;
3320 using detail::log;
3321 using detail::log10;
3322 using detail::log1p;
3323 using detail::log2;
3324 using detail::lrint;
3325 using detail::lround;
3326 using detail::nanh;
3327 using detail::nearbyint;
3328 using detail::pow;
3329 using detail::remainder;
3330 using detail::remquo;
3331 using detail::rint;
3332 using detail::round;
3333 using detail::sin;
3334 using detail::sinh;
3335 using detail::sqrt;
3336 using detail::tan;
3337 using detail::tanh;
3338 using detail::tgamma;
3339 using detail::trunc;
3340 #if HALF_ENABLE_CPP11_LONG_LONG
3341 using detail::llrint;
3342 using detail::llround;
3343 #endif
3344 using detail::copysign;
3345 using detail::fpclassify;
3346 using detail::frexp;
3347 using detail::ilogb;
3348 using detail::isfinite;
3349 using detail::isgreater;
3351 using detail::isinf;
3352 using detail::isless;
3353 using detail::islessequal;
3354 using detail::islessgreater;
3355 using detail::isnan;
3356 using detail::isnormal;
3357 using detail::isunordered;
3358 using detail::ldexp;
3359 using detail::logb;
3360 using detail::modf;
3361 using detail::nextafter;
3362 using detail::nexttoward;
3363 using detail::scalbln;
3364 using detail::scalbn;
3365 using detail::signbit;
3366 
3367 using detail::half_cast;
3368 } // namespace half_float
3369 
3371 namespace std
3372 {
3376 template <>
3377 class numeric_limits<half_float::half> : public numeric_limits<float>
3378 {
3379  public:
3381  static HALF_CONSTEXPR_CONST bool is_signed = true;
3382 
3384  static HALF_CONSTEXPR_CONST bool is_exact = false;
3385 
3387  static HALF_CONSTEXPR_CONST bool is_modulo = false;
3388 
3390  static HALF_CONSTEXPR_CONST bool is_iec559 = true;
3391 
3393  static HALF_CONSTEXPR_CONST bool has_infinity = true;
3394 
3396  static HALF_CONSTEXPR_CONST bool has_quiet_NaN = true;
3397 
3399  static HALF_CONSTEXPR_CONST float_denorm_style has_denorm = denorm_present;
3400 
3406  static HALF_CONSTEXPR_CONST float_round_style round_style =
3407  (std::numeric_limits<float>::round_style == half_float::half::round_style) ? half_float::half::round_style : round_indeterminate;
3408 
3410  static HALF_CONSTEXPR_CONST int digits = 11;
3411 
3413  static HALF_CONSTEXPR_CONST int digits10 = 3;
3414 
3416  static HALF_CONSTEXPR_CONST int max_digits10 = 5;
3417 
3419  static HALF_CONSTEXPR_CONST int radix = 2;
3420 
3422  static HALF_CONSTEXPR_CONST int min_exponent = -13;
3423 
3425  static HALF_CONSTEXPR_CONST int min_exponent10 = -4;
3426 
3428  static HALF_CONSTEXPR_CONST int max_exponent = 16;
3429 
3431  static HALF_CONSTEXPR_CONST int max_exponent10 = 4;
3432 
3435 
3438 
3441 
3444 
3447  {
3448  return half_float::half(half_float::detail::binary, (round_style == std::round_to_nearest) ? 0x3800 : 0x3C00);
3449  }
3450 
3453 
3456 
3459 
3462 };
3463 
3464 #if HALF_ENABLE_CPP11_HASH
3467 template <>
3468 struct hash<half_float::half> //: unary_function<half_float::half,size_t>
3469 {
3471  typedef half_float::half argument_type;
3472 
3474  typedef size_t result_type;
3475 
3479  result_type operator()(argument_type arg) const
3480  {
3481  return hash<half_float::detail::uint16>()(static_cast<unsigned>(arg.data_) & -(arg.data_ != 0x8000));
3482  }
3483 };
3484 #endif
3485 } // namespace std
3486 
3487 #undef HALF_CONSTEXPR
3488 #undef HALF_CONSTEXPR_CONST
3489 #undef HALF_NOEXCEPT
3490 #undef HALF_NOTHROW
3491 #ifdef HALF_POP_WARNINGS
3492 #pragma warning(pop)
3493 #undef HALF_POP_WARNINGS
3494 #endif
3495 
3496 #endif
half & operator/=(float rhs)
Definition: half.hpp:1454
half(detail::expr rhs)
Definition: half.hpp:1359
HALF_CONSTEXPR half() HALF_NOEXCEPT
Definition: half.hpp:1354
detail::enable< half &, T >::type operator*=(T rhs)
Definition: half.hpp:1400
half operator++(int)
Definition: half.hpp:1470
half & operator-=(float rhs)
Definition: half.hpp:1436
detail::enable< half &, T >::type operator-=(T rhs)
Definition: half.hpp:1390
half & operator=(detail::expr rhs)
Definition: half.hpp:1373
half & operator+=(float rhs)
Definition: half.hpp:1427
half & operator++()
Definition: half.hpp:1462
detail::enable< half &, T >::type operator+=(T rhs)
Definition: half.hpp:1380
detail::enable< half &, T >::type operator/=(T rhs)
Definition: half.hpp:1410
half & operator=(float rhs)
Definition: half.hpp:1418
half & operator*=(float rhs)
Definition: half.hpp:1445
half(float rhs)
Definition: half.hpp:1363
half operator--(int)
Definition: half.hpp:1479
half & operator--()
Definition: half.hpp:1466
static HALF_CONSTEXPR half_float::half epsilon() HALF_NOTHROW
Difference between one and next representable value.
Definition: half.hpp:3443
static HALF_CONSTEXPR half_float::half max() HALF_NOTHROW
Largest finite value.
Definition: half.hpp:3440
static HALF_CONSTEXPR half_float::half lowest() HALF_NOTHROW
Smallest finite value.
Definition: half.hpp:3437
static HALF_CONSTEXPR half_float::half signaling_NaN() HALF_NOTHROW
Signalling NaN.
Definition: half.hpp:3458
static HALF_CONSTEXPR half_float::half min() HALF_NOTHROW
Smallest positive normal value.
Definition: half.hpp:3434
static HALF_CONSTEXPR half_float::half round_error() HALF_NOTHROW
Maximum rounding error.
Definition: half.hpp:3446
static HALF_CONSTEXPR half_float::half infinity() HALF_NOTHROW
Positive infinity.
Definition: half.hpp:3452
static HALF_CONSTEXPR half_float::half denorm_min() HALF_NOTHROW
Smallest positive subnormal value.
Definition: half.hpp:3461
static HALF_CONSTEXPR half_float::half quiet_NaN() HALF_NOTHROW
Quiet NaN.
Definition: half.hpp:3455
#define FP_ILOGBNAN
Definition: half.hpp:242
#define HALF_NOEXCEPT
Definition: half.hpp:178
#define FP_NAN
Definition: half.hpp:251
#define FP_ZERO
Definition: half.hpp:248
#define FP_INFINITE
Definition: half.hpp:254
#define HALF_CONSTEXPR_CONST
Definition: half.hpp:170
#define HALF_NOTHROW
Definition: half.hpp:179
#define FP_ILOGB0
Definition: half.hpp:239
#define HALF_ROUND_TIES_TO_EVEN
Definition: half.hpp:224
#define FP_NORMAL
Definition: half.hpp:257
#define HALF_CONSTEXPR
Definition: half.hpp:169
#define FP_SUBNORMAL
Definition: half.hpp:245
#define HALF_ROUND_STYLE
Definition: half.hpp:215
expr tan(half arg)
Definition: half.hpp:2830
unsigned short uint16
Unsigned integer of (at least) 16 bits width.
Definition: half.hpp:393
expr tanh(half arg)
Definition: half.hpp:2886
bool isinf(expr arg)
Definition: half.hpp:3138
expr fdim(half x, half y)
Definition: half.hpp:2707
expr exp(expr arg)
Definition: half.hpp:2725
expr cbrt(expr arg)
Definition: half.hpp:2785
bool builtin_signbit(T arg)
Definition: half.hpp:580
enable< bool, T, U >::type operator<(T x, U y)
Definition: half.hpp:2488
expr acos(half arg)
Definition: half.hpp:2844
T half2int_up(uint16 value)
Definition: half.hpp:1251
expr asinh(expr arg)
Definition: half.hpp:2894
bool islessgreater(half x, half y)
Definition: half.hpp:3223
float half2float_impl(uint16 value, float, true_type)
Definition: half.hpp:903
bool builtin_isnan(T arg)
Definition: half.hpp:563
expr exp(half arg)
Definition: half.hpp:2724
expr tgamma(half arg)
Definition: half.hpp:2939
half rint(half arg)
Definition: half.hpp:2992
half abs(half arg)
Definition: half.hpp:2620
expr fma(half x, half y, half z)
Definition: half.hpp:2671
expr fmax(expr x, expr y)
Definition: half.hpp:2689
expr remainder(expr x, expr y)
Definition: half.hpp:2650
T half_cast(U arg)
Definition: half.hpp:3256
uint16 float2half(T value)
Definition: half.hpp:834
uint16 float2half_impl(float value, true_type)
Definition: half.hpp:599
int fpclassify(half arg)
Definition: half.hpp:3121
expr acos(expr arg)
Definition: half.hpp:2845
HALF_CONSTEXPR_CONST binary_t binary
Tag for binary construction.
Definition: half.hpp:424
expr hypot(half x, half y)
Definition: half.hpp:2792
bool isless(half x, half y)
Definition: half.hpp:3199
expr pow(expr base, expr exp)
Definition: half.hpp:2806
expr cos(half arg)
Definition: half.hpp:2823
expr sin(half arg)
Definition: half.hpp:2816
expr fmod(expr x, expr y)
Definition: half.hpp:2638
expr log1p(expr arg)
Definition: half.hpp:2760
enable< expr, T, U >::type operator-(T x, U y)
Definition: half.hpp:2545
half ldexp(half arg, int exp)
Definition: half.hpp:3034
half fmax(half x, half y)
Definition: half.hpp:2686
enable< std::basic_ostream< charT, traits > &, T >::type operator<<(std::basic_ostream< charT, traits > &out, T arg)
Definition: half.hpp:2597
expr cosh(half arg)
Definition: half.hpp:2879
expr atanh(half arg)
Definition: half.hpp:2907
expr tan(expr arg)
Definition: half.hpp:2831
expr atan2(expr x, expr y)
Definition: half.hpp:2862
expr sin(expr arg)
Definition: half.hpp:2817
expr tanh(expr arg)
Definition: half.hpp:2887
half modf(half arg, half *iptr)
Definition: half.hpp:3042
enable< expr, T, U >::type operator+(T x, U y)
Definition: half.hpp:2535
bool_type< true > true_type
Definition: half.hpp:321
expr exp2(half arg)
Definition: half.hpp:2738
std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &in, half &arg)
Definition: half.hpp:2607
enable< bool, T, U >::type operator<=(T x, U y)
Definition: half.hpp:2510
expr cosh(expr arg)
Definition: half.hpp:2880
expr atan(half arg)
Definition: half.hpp:2851
half fabs(half arg)
Definition: half.hpp:2627
uint16 int2half(T value)
Definition: half.hpp:894
expr abs(expr arg)
Definition: half.hpp:2621
expr acosh(expr arg)
Definition: half.hpp:2901
T half2int(uint16 value)
Definition: half.hpp:1241
half ldexp(expr arg, int exp)
Definition: half.hpp:3035
expr cos(expr arg)
Definition: half.hpp:2824
expr expm1(half arg)
Definition: half.hpp:2731
expr lgamma(half arg)
Definition: half.hpp:2932
uint16 int2half_impl(T value)
Definition: half.hpp:846
expr atan2(half x, half y)
Definition: half.hpp:2859
half modf(expr arg, half *iptr)
Definition: half.hpp:3043
half ceil(half arg)
Definition: half.hpp:2950
expr log(expr arg)
Definition: half.hpp:2746
expr fma(expr x, expr y, expr z)
Definition: half.hpp:2678
bool signbit(half arg)
Definition: half.hpp:3161
bool isinf(half arg)
Definition: half.hpp:3137
expr log2(expr arg)
Definition: half.hpp:2767
enable< expr, T, U >::type operator*(T x, U y)
Definition: half.hpp:2555
enable< expr, T, U >::type operator/(T x, U y)
Definition: half.hpp:2565
bool isnormal(half arg)
Definition: half.hpp:3153
bool isnan(expr arg)
Definition: half.hpp:3146
enable< bool, T, U >::type operator>(T x, U y)
Definition: half.hpp:2499
expr erf(half arg)
Definition: half.hpp:2918
half scalbln(half arg, long exp)
Definition: half.hpp:3058
expr fmod(half x, half y)
Definition: half.hpp:2635
bool isgreaterequal(half x, half y)
Definition: half.hpp:3188
T half2int_impl(uint16 value)
Definition: half.hpp:1202
expr log10(expr arg)
Definition: half.hpp:2753
bool isfinite(half arg)
Definition: half.hpp:3129
expr erfc(expr arg)
Definition: half.hpp:2926
half logb(half arg)
Definition: half.hpp:3075
half fmin(half x, half y)
Definition: half.hpp:2697
bool isunordered(half x, half y)
Definition: half.hpp:3235
half nearbyint(half arg)
Definition: half.hpp:2985
long lrint(half arg)
Definition: half.hpp:2999
enable< bool, T, U >::type operator>=(T x, U y)
Definition: half.hpp:2521
expr lgamma(expr arg)
Definition: half.hpp:2933
expr sinh(half arg)
Definition: half.hpp:2872
expr asinh(half arg)
Definition: half.hpp:2893
expr tgamma(expr arg)
Definition: half.hpp:2940
expr log1p(half arg)
Definition: half.hpp:2759
T half2float(uint16 value)
Definition: half.hpp:1189
expr exp2(expr arg)
Definition: half.hpp:2739
expr log(half arg)
Definition: half.hpp:2745
expr remquo(half x, half y, int *quo)
Definition: half.hpp:2659
expr sqrt(expr arg)
Definition: half.hpp:2778
uint16 round_half_up(uint16 value)
Definition: half.hpp:1304
expr acosh(half arg)
Definition: half.hpp:2900
expr erf(expr arg)
Definition: half.hpp:2919
uint16 round_half_impl(uint16 value)
Definition: half.hpp:1262
expr remainder(half x, half y)
Definition: half.hpp:2647
half frexp(expr arg, int *exp)
Definition: half.hpp:3027
expr sinh(expr arg)
Definition: half.hpp:2873
expr atan(expr arg)
Definition: half.hpp:2852
half nextafter(half from, half to)
Definition: half.hpp:3084
expr fdim(expr x, expr y)
Definition: half.hpp:2710
long lround(half arg)
Definition: half.hpp:2978
bool islessequal(half x, half y)
Definition: half.hpp:3211
half frexp(half arg, int *exp)
Definition: half.hpp:3026
bool isgreater(half x, half y)
Definition: half.hpp:3176
expr atanh(expr arg)
Definition: half.hpp:2908
expr log2(half arg)
Definition: half.hpp:2766
bool signbit(expr arg)
Definition: half.hpp:3162
bool isnan(half arg)
Definition: half.hpp:3145
half copysign(half x, half y)
Definition: half.hpp:3104
expr cbrt(half arg)
Definition: half.hpp:2784
int ilogb(half arg)
Definition: half.hpp:3068
bool_type< false > false_type
Definition: half.hpp:322
enable< bool, T, U >::type operator==(T x, U y)
Definition: half.hpp:2466
half trunc(half arg)
Definition: half.hpp:2964
half floor(half arg)
Definition: half.hpp:2957
expr hypot(expr x, expr y)
Definition: half.hpp:2795
uint16 round_half(uint16 value)
Definition: half.hpp:1296
expr log10(half arg)
Definition: half.hpp:2752
expr asin(half arg)
Definition: half.hpp:2837
expr fmin(expr x, expr y)
Definition: half.hpp:2700
enable< bool, T, U >::type operator!=(T x, U y)
Definition: half.hpp:2477
expr pow(half base, half exp)
Definition: half.hpp:2803
expr erfc(half arg)
Definition: half.hpp:2925
expr asin(expr arg)
Definition: half.hpp:2838
half round(half arg)
Definition: half.hpp:2971
bool builtin_isinf(T arg)
Definition: half.hpp:546
expr remquo(expr x, expr y, int *quo)
Definition: half.hpp:2662
half nexttoward(half from, long double to)
Definition: half.hpp:3095
expr fabs(expr arg)
Definition: half.hpp:2628
expr sqrt(half arg)
Definition: half.hpp:2777
half nanh(const char *)
Definition: half.hpp:2714
half scalbn(half arg, int exp)
Definition: half.hpp:3050
expr expm1(expr arg)
Definition: half.hpp:2732
static expr fmax(float x, float y)
Definition: half.hpp:2362
static expr fmin(float x, float y)
Definition: half.hpp:2345
Tag type for binary construction.
Definition: half.hpp:420
Type traits for floating point bits.
Definition: half.hpp:358
unsigned char type
Definition: half.hpp:359
Helper for tag dispatching.
Definition: half.hpp:319
Conditional type.
Definition: half.hpp:307
HALF_CONSTEXPR expr(float f) HALF_NOEXCEPT
Definition: half.hpp:432
Wrapper implementing unspecialized half-precision functions.
Definition: half.hpp:1514
static bool isequal(half x, half y)
Definition: half.hpp:2206
static half trunc(half arg)
Definition: half.hpp:1953
static expr remainder(float x, float y)
Definition: half.hpp:1572
static expr atan2(float x, float y)
Definition: half.hpp:1814
static bool isnotequal(half x, half y)
Definition: half.hpp:2213
static half modf(half arg, half *iptr)
Definition: half.hpp:2005
static expr fmod(float x, float y)
Definition: half.hpp:1566
static expr acosh(float arg)
Definition: half.hpp:1847
static expr minus(float x, float y)
Definition: half.hpp:1525
static bool isfinite(half arg)
Definition: half.hpp:2175
static std::basic_ostream< charT, traits > & write(std::basic_ostream< charT, traits > &out, float arg)
Definition: half.hpp:1544
static expr log2(float arg)
Definition: half.hpp:1730
static bool isgreaterequal(half x, half y)
Definition: half.hpp:2231
static half copysign(half x, half y)
Definition: half.hpp:2159
static bool isnan(half arg)
Definition: half.hpp:2187
static expr log10(float arg)
Definition: half.hpp:1713
static expr erfc(float arg)
Definition: half.hpp:1884
static expr log1p(float arg)
Definition: half.hpp:1718
static expr expm1(float arg)
Definition: half.hpp:1684
static expr divides(float x, float y)
Definition: half.hpp:1537
static expr asin(float arg)
Definition: half.hpp:1798
static int fpclassify(half arg)
Definition: half.hpp:2165
static half logb(half arg)
Definition: half.hpp:2095
static expr sqrt(float arg)
Definition: half.hpp:1742
static bool isless(half x, half y)
Definition: half.hpp:2242
static expr exp(float arg)
Definition: half.hpp:1679
static half nextafter(half from, half to)
Definition: half.hpp:2125
static expr cbrt(float arg)
Definition: half.hpp:1747
static expr cosh(float arg)
Definition: half.hpp:1824
static bool islessequal(half x, half y)
Definition: half.hpp:2253
static expr exp2(float arg)
Definition: half.hpp:1696
static expr tanh(float arg)
Definition: half.hpp:1829
static half ceil(half arg)
Definition: half.hpp:1948
static expr tgamma(float arg)
Definition: half.hpp:1918
static half scalbln(half arg, long exp)
Definition: half.hpp:2026
static bool isgreater(half x, half y)
Definition: half.hpp:2220
static expr plus(float x, float y)
Definition: half.hpp:1519
static expr tan(float arg)
Definition: half.hpp:1793
static expr pow(float base, float exp)
Definition: half.hpp:1778
static bool isunordered(half x, half y)
Definition: half.hpp:2278
static expr asinh(float arg)
Definition: half.hpp:1834
static expr atanh(float arg)
Definition: half.hpp:1860
static long lround(half arg)
Definition: half.hpp:1963
static bool signbit(half arg)
Definition: half.hpp:2199
static expr acos(float arg)
Definition: half.hpp:1803
static expr sin(float arg)
Definition: half.hpp:1783
static expr remquo(float x, float y, int *quo)
Definition: half.hpp:1603
static expr multiplies(float x, float y)
Definition: half.hpp:1531
static bool islessgreater(half x, half y)
Definition: half.hpp:2264
static half round(half arg)
Definition: half.hpp:1958
static expr log(float arg)
Definition: half.hpp:1708
static half floor(half arg)
Definition: half.hpp:1943
static int ilogb(half arg)
Definition: half.hpp:2074
static bool isnormal(half arg)
Definition: half.hpp:2193
static half frexp(half arg, int *exp)
Definition: half.hpp:1991
static expr fdim(float x, float y)
Definition: half.hpp:1649
static expr hypot(float x, float y)
Definition: half.hpp:1763
static expr lgamma(float arg)
Definition: half.hpp:1896
static long lrint(half arg)
Definition: half.hpp:1973
static expr sinh(float arg)
Definition: half.hpp:1819
static half nexttoward(half from, long double to)
Definition: half.hpp:2143
static expr atan(float arg)
Definition: half.hpp:1808
static bool isinf(half arg)
Definition: half.hpp:2181
static expr cos(float arg)
Definition: half.hpp:1788
static std::basic_istream< charT, traits > & read(std::basic_istream< charT, traits > &in, half &arg)
Definition: half.hpp:1554
static expr erf(float arg)
Definition: half.hpp:1872
static half rint(half arg)
Definition: half.hpp:1968
static expr fma(float x, float y, float z)
Definition: half.hpp:1663
Type traits for floating point types.
Definition: half.hpp:327
static HALF_CONSTEXPR expr negate(float arg)
Definition: half.hpp:2331
static HALF_CONSTEXPR half negate(half arg)
Definition: half.hpp:2321
static half fabs(half arg)
Definition: half.hpp:2326