GlobeEngine
Half.h
Go to the documentation of this file.
1 // half - IEEE 754-based half-precision floating point library.
2 //
3 // Copyright (c) 2012-2013 Christian Rau <rauy@users.sourceforge.net>
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
6 // files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
7 // modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
13 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
14 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
15 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16 
17 // Version 1.11.0
18 
21 
22 #ifndef HALF_HALF_HPP
23 #define HALF_HALF_HPP
24 
26 #define HALF_GNUC_VERSION (__GNUC__*100+__GNUC_MINOR__)
27 
28 //check C++11 language features
29 #if defined(__clang__) //clang
30  #if __has_feature(cxx_static_assert) && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
31  #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
32  #endif
33  #if __has_feature(cxx_constexpr) && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
34  #define HALF_ENABLE_CPP11_CONSTEXPR 1
35  #endif
36  #if __has_feature(cxx_noexcept) && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
37  #define HALF_ENABLE_CPP11_NOEXCEPT 1
38  #endif
39  #if __has_feature(cxx_user_literals) && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
40  #define HALF_ENABLE_CPP11_USER_LITERALS 1
41  #endif
42  #if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) && !defined(HALF_ENABLE_CPP11_LONG_LONG)
43  #define HALF_ENABLE_CPP11_LONG_LONG 1
44  #endif
45 /*#elif defined(__INTEL_COMPILER) //Intel C++
46  #if __INTEL_COMPILER >= 1100 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT) ????????
47  #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
48  #endif
49  #if __INTEL_COMPILER >= 1300 && !defined(HALF_ENABLE_CPP11_CONSTEXPR) ????????
50  #define HALF_ENABLE_CPP11_CONSTEXPR 1
51  #endif
52  #if __INTEL_COMPILER >= 1300 && !defined(HALF_ENABLE_CPP11_NOEXCEPT) ????????
53  #define HALF_ENABLE_CPP11_NOEXCEPT 1
54  #endif
55  #if __INTEL_COMPILER >= 1100 && !defined(HALF_ENABLE_CPP11_LONG_LONG) ????????
56  #define HALF_ENABLE_CPP11_LONG_LONG 1
57  #endif*/
58 #elif defined(__GNUC__) //gcc
59  #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
60  #if HALF_GNUC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
61  #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
62  #endif
63  #if HALF_GNUC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
64  #define HALF_ENABLE_CPP11_CONSTEXPR 1
65  #endif
66  #if HALF_GNUC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
67  #define HALF_ENABLE_CPP11_NOEXCEPT 1
68  #endif
69  #if HALF_GNUC_VERSION >= 407 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
70  #define HALF_ENABLE_CPP11_USER_LITERALS 1
71  #endif
72  #if !defined(HALF_ENABLE_CPP11_LONG_LONG)
73  #define HALF_ENABLE_CPP11_LONG_LONG 1
74  #endif
75  #endif
76 #elif defined(_MSC_VER) //Visual C++
77  #if _MSC_VER >= 1600 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
78  #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
79  #endif
80  #if _MSC_VER >= 1310 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
81  #define HALF_ENABLE_CPP11_LONG_LONG 1
82  #endif
83  #define HALF_POP_WARNINGS 1
84  #pragma warning(push)
85  #pragma warning(disable : 4099 4127 4146) //struct vs class, constant in if, negative unsigned
86 #endif
87 
88 //check C++11 library features
89 #include <utility>
90 #if defined(_LIBCPP_VERSION) //libc++
91  #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
92  #ifndef HALF_ENABLE_CPP11_TYPE_TRAITS
93  #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
94  #endif
95  #ifndef HALF_ENABLE_CPP11_CSTDINT
96  #define HALF_ENABLE_CPP11_CSTDINT 1
97  #endif
98  #ifndef HALF_ENABLE_CPP11_CMATH
99  #define HALF_ENABLE_CPP11_CMATH 1
100  #endif
101  #ifndef HALF_ENABLE_CPP11_HASH
102  #define HALF_ENABLE_CPP11_HASH 1
103  #endif
104  #endif
105 #elif defined(__GLIBCXX__) //libstdc++
106  #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
107  #ifdef __clang__
108  #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
109  #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
110  #endif
111  #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CSTDINT)
112  #define HALF_ENABLE_CPP11_CSTDINT 1
113  #endif
114  #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CMATH)
115  #define HALF_ENABLE_CPP11_CMATH 1
116  #endif
117  #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_HASH)
118  #define HALF_ENABLE_CPP11_HASH 1
119  #endif
120  #else
121  #if HALF_GNUC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CSTDINT)
122  #define HALF_ENABLE_CPP11_CSTDINT 1
123  #endif
124  #if HALF_GNUC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CMATH)
125  #define HALF_ENABLE_CPP11_CMATH 1
126  #endif
127  #if HALF_GNUC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_HASH)
128  #define HALF_ENABLE_CPP11_HASH 1
129  #endif
130  #endif
131  #endif
132 #elif defined(_CPPLIB_VER) //Dinkumware/Visual C++
133  #if _CPPLIB_VER >= 520
134  #ifndef HALF_ENABLE_CPP11_TYPE_TRAITS
135  #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
136  #endif
137  #ifndef HALF_ENABLE_CPP11_CSTDINT
138  #define HALF_ENABLE_CPP11_CSTDINT 1
139  #endif
140  #ifndef HALF_ENABLE_CPP11_HASH
141  #define HALF_ENABLE_CPP11_HASH 1
142  #endif
143  #endif
144  #if _CPPLIB_VER >= 610
145  #ifndef HALF_ENABLE_CPP11_CMATH
146  #define HALF_ENABLE_CPP11_CMATH 1
147  #endif
148  #endif
149 #endif
150 #undef HALF_GNUC_VERSION
151 
152 //support constexpr
153 #if HALF_ENABLE_CPP11_CONSTEXPR
154  #define HALF_CONSTEXPR constexpr
155  #define HALF_CONSTEXPR_CONST constexpr
156 #else
157  #define HALF_CONSTEXPR
158  #define HALF_CONSTEXPR_CONST const
159 #endif
160 
161 //support noexcept
162 #if HALF_ENABLE_CPP11_NOEXCEPT
163  #define HALF_NOEXCEPT noexcept
164  #define HALF_NOTHROW noexcept
165 #else
166  #define HALF_NOEXCEPT
167  #define HALF_NOTHROW throw()
168 #endif
169 
170 #include <algorithm>
171 #include <iostream>
172 #include <limits>
173 #include <climits>
174 #include <cmath>
175 #include <cstring>
176 #if HALF_ENABLE_CPP11_TYPE_TRAITS
177  #include <type_traits>
178 #endif
179 #if HALF_ENABLE_CPP11_CSTDINT
180  #include <cstdint>
181 #endif
182 #if HALF_ENABLE_CPP11_HASH
183  #include <functional>
184 #endif
185 
186 
203 #ifndef HALF_ROUND_STYLE
204  #define HALF_ROUND_STYLE -1 // = std::round_indeterminate
205 #endif
206 
212 #ifndef HALF_ROUND_TIES_TO_EVEN
213  #define HALF_ROUND_TIES_TO_EVEN 0 // ties away from zero
214 #endif
215 
219 #define HUGE_VALH std::numeric_limits<half_float::half>::infinity()
220 
225 #define FP_FAST_FMAH 1
226 
227 #ifndef FP_ILOGB0
228  #define FP_ILOGB0 INT_MIN
229 #endif
230 #ifndef FP_ILOGBNAN
231  #define FP_ILOGBNAN INT_MAX
232 #endif
233 #ifndef FP_SUBNORMAL
234  #define FP_SUBNORMAL 0
235 #endif
236 #ifndef FP_ZERO
237  #define FP_ZERO 1
238 #endif
239 #ifndef FP_NAN
240  #define FP_NAN 2
241 #endif
242 #ifndef FP_INFINITE
243  #define FP_INFINITE 3
244 #endif
245 #ifndef FP_NORMAL
246  #define FP_NORMAL 4
247 #endif
248 
249 
252 namespace half_float
253 {
254  class half;
255 
258  namespace detail
259  {
260  #if HALF_ENABLE_CPP11_TYPE_TRAITS
261  template<bool B,typename T,typename F> struct conditional : std::conditional<B,T,F> {};
263 
265  template<bool B> struct bool_type : std::integral_constant<bool,B> {};
266  using std::true_type;
267  using std::false_type;
268 
270  template<typename T> struct is_float : std::is_floating_point<T> {};
271  #else
272  template<bool,typename T,typename> struct conditional { typedef T type; };
274  template<typename T,typename F> struct conditional<false,T,F> { typedef F type; };
275 
277  template<bool> struct bool_type {};
280 
282  template<typename> struct is_float : false_type {};
283  template<typename T> struct is_float<const T> : is_float<T> {};
284  template<typename T> struct is_float<volatile T> : is_float<T> {};
285  template<typename T> struct is_float<const volatile T> : is_float<T> {};
286  template<> struct is_float<float> : true_type {};
287  template<> struct is_float<double> : true_type {};
288  template<> struct is_float<long double> : true_type {};
289  #endif
290 
291  #if HALF_ENABLE_CPP11_CSTDINT
292  typedef std::uint_least16_t uint16;
294 
296  typedef std::uint_least32_t uint32;
297 
299  typedef std::int_fast32_t int17;
300  #else
301  typedef unsigned short uint16;
303 
305  typedef conditional<std::numeric_limits<unsigned int>::digits>=32,unsigned int,unsigned long>::type uint32;
306 
309  #endif
310 
312  struct binary_t {};
313 
316 
319  struct expr
320  {
323  explicit HALF_CONSTEXPR expr(float f) : value_(f) {}
324 
327  HALF_CONSTEXPR operator float() const { return value_; }
328 
329  private:
331  float value_;
332  };
333 
338  template<typename T,typename,typename=void,typename=void> struct enable {};
339  template<typename T> struct enable<T,half,void,void> { typedef T type; };
340  template<typename T> struct enable<T,expr,void,void> { typedef T type; };
341  template<typename T> struct enable<T,half,half,void> { typedef T type; };
342  template<typename T> struct enable<T,half,expr,void> { typedef T type; };
343  template<typename T> struct enable<T,expr,half,void> { typedef T type; };
344  template<typename T> struct enable<T,expr,expr,void> { typedef T type; };
345  template<typename T> struct enable<T,half,half,half> { typedef T type; };
346  template<typename T> struct enable<T,half,half,expr> { typedef T type; };
347  template<typename T> struct enable<T,half,expr,half> { typedef T type; };
348  template<typename T> struct enable<T,half,expr,expr> { typedef T type; };
349  template<typename T> struct enable<T,expr,half,half> { typedef T type; };
350  template<typename T> struct enable<T,expr,half,expr> { typedef T type; };
351  template<typename T> struct enable<T,expr,expr,half> { typedef T type; };
352  template<typename T> struct enable<T,expr,expr,expr> { typedef T type; };
353 
359  template<typename T,typename U> struct result : enable<expr,T,U> {};
360  template<> struct result<half,half> { typedef half type; };
361 
364 
370  template<typename T> bool builtin_isinf(T arg)
371  {
372  #if HALF_ENABLE_CPP11_CMATH
373  return std::isinf(arg);
374  #elif defined(_MSC_VER)
375  return !_finite(static_cast<double>(arg)) && !_isnan(static_cast<double>(arg));
376  #else
377  return arg == std::numeric_limits<T>::infinity() || arg == -std::numeric_limits<T>::infinity();
378  #endif
379  }
380 
386  template<typename T> bool builtin_isnan(T arg)
387  {
388  #if HALF_ENABLE_CPP11_CMATH
389  return std::isnan(arg);
390  #elif defined(_MSC_VER)
391  return _isnan(static_cast<double>(arg)) != 0;
392  #else
393  return arg != arg;
394  #endif
395  }
396 
402  template<typename T> bool builtin_signbit(T arg)
403  {
404  #if HALF_ENABLE_CPP11_CMATH
405  return std::signbit(arg);
406  #else
407  return arg < T() || (arg == T() && T(1)/arg < T());
408  #endif
409  }
410 
414 
420  template<std::float_round_style R> uint16 float2half_impl(float value, true_type)
421  {
422  #if HALF_ENABLE_CPP11_STATIC_ASSERT
423  static_assert(std::numeric_limits<float>::is_iec559, "float to half conversion needs IEEE 754 conformant 'float' type");
424  static_assert(sizeof(uint32)==sizeof(float), "float to half conversion needs unsigned integer type of exactly the size of a 'float'");
425  #endif
426  static const uint16 base_table[512] = {
427  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
428  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
429  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
430  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
431  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
432  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
433  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
434  0x0200, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00,
435  0x4000, 0x4400, 0x4800, 0x4C00, 0x5000, 0x5400, 0x5800, 0x5C00, 0x6000, 0x6400, 0x6800, 0x6C00, 0x7000, 0x7400, 0x7800, 0x7C00,
436  0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
437  0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
438  0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
439  0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
440  0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
441  0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
442  0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
443  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
444  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
445  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
446  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
447  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
448  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
449  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001, 0x8002, 0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100,
450  0x8200, 0x8400, 0x8800, 0x8C00, 0x9000, 0x9400, 0x9800, 0x9C00, 0xA000, 0xA400, 0xA800, 0xAC00, 0xB000, 0xB400, 0xB800, 0xBC00,
451  0xC000, 0xC400, 0xC800, 0xCC00, 0xD000, 0xD400, 0xD800, 0xDC00, 0xE000, 0xE400, 0xE800, 0xEC00, 0xF000, 0xF400, 0xF800, 0xFC00,
452  0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
453  0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
454  0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
455  0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
456  0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
457  0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
458  0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00 };
459  static const unsigned char shift_table[512] = {
460  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,
461  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,
462  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,
463  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,
464  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,
465  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,
466  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,
467  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,
468  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,
469  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,
470  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,
471  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,
472  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,
473  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,
474  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,
475  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 };
476  uint32 bits;// = *reinterpret_cast<uint32*>(&value); //violating strict aliasing!
477  std::memcpy(&bits, &value, sizeof(float));
478  uint16 hbits = base_table[bits>>23] + static_cast<uint16>((bits&0x7FFFFF)>>shift_table[bits>>23]);
479  if(R == std::round_to_nearest)
480  hbits += (((bits&0x7FFFFF)>>(shift_table[bits>>23]-1))|(((bits>>23)&0xFF)==102)) & ((hbits&0x7C00)!=0x7C00)
482  & (((((static_cast<uint32>(1)<<(shift_table[bits>>23]-1))-1)&bits)!=0)|hbits)
483  #endif
484  ;
485  else if(R == std::round_toward_zero)
486  hbits -= ((hbits&0x7FFF)==0x7C00) & ~shift_table[bits>>23];
487  else if(R == std::round_toward_infinity)
488  hbits += ((((bits&0x7FFFFF&((static_cast<uint32>(1)<<(shift_table[bits>>23]))-1))!=0)|(((bits>>23)<=102)&
489  ((bits>>23)!=0)))&(hbits<0x7C00)) - ((hbits==0xFC00)&((bits>>23)!=511));
490  else if(R == std::round_toward_neg_infinity)
491  hbits += ((((bits&0x7FFFFF&((static_cast<uint32>(1)<<(shift_table[bits>>23]))-1))!=0)|(((bits>>23)<=358)&
492  ((bits>>23)!=256)))&(hbits<0xFC00)&(hbits>>15)) - ((hbits==0x7C00)&((bits>>23)!=255));
493  return hbits;
494  }
495 
499  template<std::float_round_style R> uint16 float2half_impl(float value, false_type)
500  {
501  uint16 hbits = builtin_signbit(value) << 15;
502  if(value == 0.0f)
503  return hbits;
504  if(builtin_isnan(value))
505  return hbits | 0x7FFF;
506  if(builtin_isinf(value))
507  return hbits | 0x7C00;
508  int exp;
509  std::frexp(value, &exp);
510  if(exp > 16)
511  {
512  if(R == std::round_toward_zero)
513  return hbits | 0x7BFF;
514  else if(R == std::round_toward_infinity)
515  return hbits | 0x7C00 - (hbits>>15);
516  else if(R == std::round_toward_neg_infinity)
517  return hbits | 0x7BFF + (hbits>>15);
518  return hbits | 0x7C00;
519  }
520  if(exp < -13)
521  value = std::ldexp(value, 24);
522  else
523  {
524  value = std::ldexp(value, 11-exp);
525  hbits |= ((exp+14)<<10);
526  }
527  int ival = static_cast<int>(value);
528  hbits |= static_cast<uint16>(std::abs(ival)&0x3FF);
529  if(R == std::round_to_nearest)
530  {
531  float diff = std::abs(value-static_cast<float>(ival));
532  #if HALF_ROUND_TIES_TO_EVEN
533  hbits += (diff>0.5f) | ((diff==0.5f)&hbits);
534  #else
535  hbits += diff >= 0.5f;
536  #endif
537  }
538  else if(R == std::round_toward_infinity)
539  hbits += value > static_cast<float>(ival);
540  else if(R == std::round_toward_neg_infinity)
541  hbits += value < static_cast<float>(ival);
542  return hbits;
543  }
544 
548  template<std::float_round_style R> uint16 float2half(float value)
549  {
550  return float2half_impl<R>(value, bool_type<std::numeric_limits<float>::is_iec559&&sizeof(uint32)==sizeof(float)>());
551  }
552 
559  template<std::float_round_style R,bool S,typename T> uint16 int2half_impl(T value)
560  {
561  if(S)
562  value = -value;
563  uint16 bits = S << 15;
564  if(value > 65504)
565  {
566  if(R == std::round_toward_infinity)
567  bits |= 0x7C00 - S;
568  else if(R == std::round_toward_neg_infinity)
569  bits |= 0x7BFF + S;
570  else
571  bits |= 0x7BFF + (R!=std::round_toward_zero);
572  }
573  else if(value)
574  {
575  unsigned int m = value, exp = 25;
576  for(; m<0x400; m<<=1,--exp) ;
577  for(; m>0x7FF; m>>=1,++exp) ;
578  bits |= (exp<<10) | (m&0x3FF);
579  if(exp > 25)
580  {
581  if(R == std::round_to_nearest)
582  bits += (value>>(exp-26)) & 1
583  #if HALF_ROUND_TIES_TO_EVEN
584  & (((((1<<(exp-26))-1)&value)!=0)|bits)
585  #endif
586  ;
587  else if(R == std::round_toward_infinity)
588  bits += ((value&((1<<(exp-25))-1))!=0) & !S;
589  else if(R == std::round_toward_neg_infinity)
590  bits += ((value&((1<<(exp-25))-1))!=0) & S;
591  }
592  }
593  return bits;
594  }
595 
601  template<std::float_round_style R,typename T> uint16 int2half(T value)
602  {
603  return (value<0) ? int2half_impl<R,true>(value) : int2half_impl<R,false>(value);
604  }
605 
610  inline float half2float_impl(uint16 value, true_type)
611  {
612  #if HALF_ENABLE_CPP11_STATIC_ASSERT
613  static_assert(std::numeric_limits<float>::is_iec559, "half to float conversion needs IEEE 754 conformant 'float' type");
614  static_assert(sizeof(uint32)==sizeof(float), "half to float conversion needs unsigned integer type of exactly the size of a 'float'");
615  #endif
616  static const uint32 mantissa_table[2048] = {
617  0x00000000, 0x33800000, 0x34000000, 0x34400000, 0x34800000, 0x34A00000, 0x34C00000, 0x34E00000, 0x35000000, 0x35100000, 0x35200000, 0x35300000, 0x35400000, 0x35500000, 0x35600000, 0x35700000,
618  0x35800000, 0x35880000, 0x35900000, 0x35980000, 0x35A00000, 0x35A80000, 0x35B00000, 0x35B80000, 0x35C00000, 0x35C80000, 0x35D00000, 0x35D80000, 0x35E00000, 0x35E80000, 0x35F00000, 0x35F80000,
619  0x36000000, 0x36040000, 0x36080000, 0x360C0000, 0x36100000, 0x36140000, 0x36180000, 0x361C0000, 0x36200000, 0x36240000, 0x36280000, 0x362C0000, 0x36300000, 0x36340000, 0x36380000, 0x363C0000,
620  0x36400000, 0x36440000, 0x36480000, 0x364C0000, 0x36500000, 0x36540000, 0x36580000, 0x365C0000, 0x36600000, 0x36640000, 0x36680000, 0x366C0000, 0x36700000, 0x36740000, 0x36780000, 0x367C0000,
621  0x36800000, 0x36820000, 0x36840000, 0x36860000, 0x36880000, 0x368A0000, 0x368C0000, 0x368E0000, 0x36900000, 0x36920000, 0x36940000, 0x36960000, 0x36980000, 0x369A0000, 0x369C0000, 0x369E0000,
622  0x36A00000, 0x36A20000, 0x36A40000, 0x36A60000, 0x36A80000, 0x36AA0000, 0x36AC0000, 0x36AE0000, 0x36B00000, 0x36B20000, 0x36B40000, 0x36B60000, 0x36B80000, 0x36BA0000, 0x36BC0000, 0x36BE0000,
623  0x36C00000, 0x36C20000, 0x36C40000, 0x36C60000, 0x36C80000, 0x36CA0000, 0x36CC0000, 0x36CE0000, 0x36D00000, 0x36D20000, 0x36D40000, 0x36D60000, 0x36D80000, 0x36DA0000, 0x36DC0000, 0x36DE0000,
624  0x36E00000, 0x36E20000, 0x36E40000, 0x36E60000, 0x36E80000, 0x36EA0000, 0x36EC0000, 0x36EE0000, 0x36F00000, 0x36F20000, 0x36F40000, 0x36F60000, 0x36F80000, 0x36FA0000, 0x36FC0000, 0x36FE0000,
625  0x37000000, 0x37010000, 0x37020000, 0x37030000, 0x37040000, 0x37050000, 0x37060000, 0x37070000, 0x37080000, 0x37090000, 0x370A0000, 0x370B0000, 0x370C0000, 0x370D0000, 0x370E0000, 0x370F0000,
626  0x37100000, 0x37110000, 0x37120000, 0x37130000, 0x37140000, 0x37150000, 0x37160000, 0x37170000, 0x37180000, 0x37190000, 0x371A0000, 0x371B0000, 0x371C0000, 0x371D0000, 0x371E0000, 0x371F0000,
627  0x37200000, 0x37210000, 0x37220000, 0x37230000, 0x37240000, 0x37250000, 0x37260000, 0x37270000, 0x37280000, 0x37290000, 0x372A0000, 0x372B0000, 0x372C0000, 0x372D0000, 0x372E0000, 0x372F0000,
628  0x37300000, 0x37310000, 0x37320000, 0x37330000, 0x37340000, 0x37350000, 0x37360000, 0x37370000, 0x37380000, 0x37390000, 0x373A0000, 0x373B0000, 0x373C0000, 0x373D0000, 0x373E0000, 0x373F0000,
629  0x37400000, 0x37410000, 0x37420000, 0x37430000, 0x37440000, 0x37450000, 0x37460000, 0x37470000, 0x37480000, 0x37490000, 0x374A0000, 0x374B0000, 0x374C0000, 0x374D0000, 0x374E0000, 0x374F0000,
630  0x37500000, 0x37510000, 0x37520000, 0x37530000, 0x37540000, 0x37550000, 0x37560000, 0x37570000, 0x37580000, 0x37590000, 0x375A0000, 0x375B0000, 0x375C0000, 0x375D0000, 0x375E0000, 0x375F0000,
631  0x37600000, 0x37610000, 0x37620000, 0x37630000, 0x37640000, 0x37650000, 0x37660000, 0x37670000, 0x37680000, 0x37690000, 0x376A0000, 0x376B0000, 0x376C0000, 0x376D0000, 0x376E0000, 0x376F0000,
632  0x37700000, 0x37710000, 0x37720000, 0x37730000, 0x37740000, 0x37750000, 0x37760000, 0x37770000, 0x37780000, 0x37790000, 0x377A0000, 0x377B0000, 0x377C0000, 0x377D0000, 0x377E0000, 0x377F0000,
633  0x37800000, 0x37808000, 0x37810000, 0x37818000, 0x37820000, 0x37828000, 0x37830000, 0x37838000, 0x37840000, 0x37848000, 0x37850000, 0x37858000, 0x37860000, 0x37868000, 0x37870000, 0x37878000,
634  0x37880000, 0x37888000, 0x37890000, 0x37898000, 0x378A0000, 0x378A8000, 0x378B0000, 0x378B8000, 0x378C0000, 0x378C8000, 0x378D0000, 0x378D8000, 0x378E0000, 0x378E8000, 0x378F0000, 0x378F8000,
635  0x37900000, 0x37908000, 0x37910000, 0x37918000, 0x37920000, 0x37928000, 0x37930000, 0x37938000, 0x37940000, 0x37948000, 0x37950000, 0x37958000, 0x37960000, 0x37968000, 0x37970000, 0x37978000,
636  0x37980000, 0x37988000, 0x37990000, 0x37998000, 0x379A0000, 0x379A8000, 0x379B0000, 0x379B8000, 0x379C0000, 0x379C8000, 0x379D0000, 0x379D8000, 0x379E0000, 0x379E8000, 0x379F0000, 0x379F8000,
637  0x37A00000, 0x37A08000, 0x37A10000, 0x37A18000, 0x37A20000, 0x37A28000, 0x37A30000, 0x37A38000, 0x37A40000, 0x37A48000, 0x37A50000, 0x37A58000, 0x37A60000, 0x37A68000, 0x37A70000, 0x37A78000,
638  0x37A80000, 0x37A88000, 0x37A90000, 0x37A98000, 0x37AA0000, 0x37AA8000, 0x37AB0000, 0x37AB8000, 0x37AC0000, 0x37AC8000, 0x37AD0000, 0x37AD8000, 0x37AE0000, 0x37AE8000, 0x37AF0000, 0x37AF8000,
639  0x37B00000, 0x37B08000, 0x37B10000, 0x37B18000, 0x37B20000, 0x37B28000, 0x37B30000, 0x37B38000, 0x37B40000, 0x37B48000, 0x37B50000, 0x37B58000, 0x37B60000, 0x37B68000, 0x37B70000, 0x37B78000,
640  0x37B80000, 0x37B88000, 0x37B90000, 0x37B98000, 0x37BA0000, 0x37BA8000, 0x37BB0000, 0x37BB8000, 0x37BC0000, 0x37BC8000, 0x37BD0000, 0x37BD8000, 0x37BE0000, 0x37BE8000, 0x37BF0000, 0x37BF8000,
641  0x37C00000, 0x37C08000, 0x37C10000, 0x37C18000, 0x37C20000, 0x37C28000, 0x37C30000, 0x37C38000, 0x37C40000, 0x37C48000, 0x37C50000, 0x37C58000, 0x37C60000, 0x37C68000, 0x37C70000, 0x37C78000,
642  0x37C80000, 0x37C88000, 0x37C90000, 0x37C98000, 0x37CA0000, 0x37CA8000, 0x37CB0000, 0x37CB8000, 0x37CC0000, 0x37CC8000, 0x37CD0000, 0x37CD8000, 0x37CE0000, 0x37CE8000, 0x37CF0000, 0x37CF8000,
643  0x37D00000, 0x37D08000, 0x37D10000, 0x37D18000, 0x37D20000, 0x37D28000, 0x37D30000, 0x37D38000, 0x37D40000, 0x37D48000, 0x37D50000, 0x37D58000, 0x37D60000, 0x37D68000, 0x37D70000, 0x37D78000,
644  0x37D80000, 0x37D88000, 0x37D90000, 0x37D98000, 0x37DA0000, 0x37DA8000, 0x37DB0000, 0x37DB8000, 0x37DC0000, 0x37DC8000, 0x37DD0000, 0x37DD8000, 0x37DE0000, 0x37DE8000, 0x37DF0000, 0x37DF8000,
645  0x37E00000, 0x37E08000, 0x37E10000, 0x37E18000, 0x37E20000, 0x37E28000, 0x37E30000, 0x37E38000, 0x37E40000, 0x37E48000, 0x37E50000, 0x37E58000, 0x37E60000, 0x37E68000, 0x37E70000, 0x37E78000,
646  0x37E80000, 0x37E88000, 0x37E90000, 0x37E98000, 0x37EA0000, 0x37EA8000, 0x37EB0000, 0x37EB8000, 0x37EC0000, 0x37EC8000, 0x37ED0000, 0x37ED8000, 0x37EE0000, 0x37EE8000, 0x37EF0000, 0x37EF8000,
647  0x37F00000, 0x37F08000, 0x37F10000, 0x37F18000, 0x37F20000, 0x37F28000, 0x37F30000, 0x37F38000, 0x37F40000, 0x37F48000, 0x37F50000, 0x37F58000, 0x37F60000, 0x37F68000, 0x37F70000, 0x37F78000,
648  0x37F80000, 0x37F88000, 0x37F90000, 0x37F98000, 0x37FA0000, 0x37FA8000, 0x37FB0000, 0x37FB8000, 0x37FC0000, 0x37FC8000, 0x37FD0000, 0x37FD8000, 0x37FE0000, 0x37FE8000, 0x37FF0000, 0x37FF8000,
649  0x38000000, 0x38004000, 0x38008000, 0x3800C000, 0x38010000, 0x38014000, 0x38018000, 0x3801C000, 0x38020000, 0x38024000, 0x38028000, 0x3802C000, 0x38030000, 0x38034000, 0x38038000, 0x3803C000,
650  0x38040000, 0x38044000, 0x38048000, 0x3804C000, 0x38050000, 0x38054000, 0x38058000, 0x3805C000, 0x38060000, 0x38064000, 0x38068000, 0x3806C000, 0x38070000, 0x38074000, 0x38078000, 0x3807C000,
651  0x38080000, 0x38084000, 0x38088000, 0x3808C000, 0x38090000, 0x38094000, 0x38098000, 0x3809C000, 0x380A0000, 0x380A4000, 0x380A8000, 0x380AC000, 0x380B0000, 0x380B4000, 0x380B8000, 0x380BC000,
652  0x380C0000, 0x380C4000, 0x380C8000, 0x380CC000, 0x380D0000, 0x380D4000, 0x380D8000, 0x380DC000, 0x380E0000, 0x380E4000, 0x380E8000, 0x380EC000, 0x380F0000, 0x380F4000, 0x380F8000, 0x380FC000,
653  0x38100000, 0x38104000, 0x38108000, 0x3810C000, 0x38110000, 0x38114000, 0x38118000, 0x3811C000, 0x38120000, 0x38124000, 0x38128000, 0x3812C000, 0x38130000, 0x38134000, 0x38138000, 0x3813C000,
654  0x38140000, 0x38144000, 0x38148000, 0x3814C000, 0x38150000, 0x38154000, 0x38158000, 0x3815C000, 0x38160000, 0x38164000, 0x38168000, 0x3816C000, 0x38170000, 0x38174000, 0x38178000, 0x3817C000,
655  0x38180000, 0x38184000, 0x38188000, 0x3818C000, 0x38190000, 0x38194000, 0x38198000, 0x3819C000, 0x381A0000, 0x381A4000, 0x381A8000, 0x381AC000, 0x381B0000, 0x381B4000, 0x381B8000, 0x381BC000,
656  0x381C0000, 0x381C4000, 0x381C8000, 0x381CC000, 0x381D0000, 0x381D4000, 0x381D8000, 0x381DC000, 0x381E0000, 0x381E4000, 0x381E8000, 0x381EC000, 0x381F0000, 0x381F4000, 0x381F8000, 0x381FC000,
657  0x38200000, 0x38204000, 0x38208000, 0x3820C000, 0x38210000, 0x38214000, 0x38218000, 0x3821C000, 0x38220000, 0x38224000, 0x38228000, 0x3822C000, 0x38230000, 0x38234000, 0x38238000, 0x3823C000,
658  0x38240000, 0x38244000, 0x38248000, 0x3824C000, 0x38250000, 0x38254000, 0x38258000, 0x3825C000, 0x38260000, 0x38264000, 0x38268000, 0x3826C000, 0x38270000, 0x38274000, 0x38278000, 0x3827C000,
659  0x38280000, 0x38284000, 0x38288000, 0x3828C000, 0x38290000, 0x38294000, 0x38298000, 0x3829C000, 0x382A0000, 0x382A4000, 0x382A8000, 0x382AC000, 0x382B0000, 0x382B4000, 0x382B8000, 0x382BC000,
660  0x382C0000, 0x382C4000, 0x382C8000, 0x382CC000, 0x382D0000, 0x382D4000, 0x382D8000, 0x382DC000, 0x382E0000, 0x382E4000, 0x382E8000, 0x382EC000, 0x382F0000, 0x382F4000, 0x382F8000, 0x382FC000,
661  0x38300000, 0x38304000, 0x38308000, 0x3830C000, 0x38310000, 0x38314000, 0x38318000, 0x3831C000, 0x38320000, 0x38324000, 0x38328000, 0x3832C000, 0x38330000, 0x38334000, 0x38338000, 0x3833C000,
662  0x38340000, 0x38344000, 0x38348000, 0x3834C000, 0x38350000, 0x38354000, 0x38358000, 0x3835C000, 0x38360000, 0x38364000, 0x38368000, 0x3836C000, 0x38370000, 0x38374000, 0x38378000, 0x3837C000,
663  0x38380000, 0x38384000, 0x38388000, 0x3838C000, 0x38390000, 0x38394000, 0x38398000, 0x3839C000, 0x383A0000, 0x383A4000, 0x383A8000, 0x383AC000, 0x383B0000, 0x383B4000, 0x383B8000, 0x383BC000,
664  0x383C0000, 0x383C4000, 0x383C8000, 0x383CC000, 0x383D0000, 0x383D4000, 0x383D8000, 0x383DC000, 0x383E0000, 0x383E4000, 0x383E8000, 0x383EC000, 0x383F0000, 0x383F4000, 0x383F8000, 0x383FC000,
665  0x38400000, 0x38404000, 0x38408000, 0x3840C000, 0x38410000, 0x38414000, 0x38418000, 0x3841C000, 0x38420000, 0x38424000, 0x38428000, 0x3842C000, 0x38430000, 0x38434000, 0x38438000, 0x3843C000,
666  0x38440000, 0x38444000, 0x38448000, 0x3844C000, 0x38450000, 0x38454000, 0x38458000, 0x3845C000, 0x38460000, 0x38464000, 0x38468000, 0x3846C000, 0x38470000, 0x38474000, 0x38478000, 0x3847C000,
667  0x38480000, 0x38484000, 0x38488000, 0x3848C000, 0x38490000, 0x38494000, 0x38498000, 0x3849C000, 0x384A0000, 0x384A4000, 0x384A8000, 0x384AC000, 0x384B0000, 0x384B4000, 0x384B8000, 0x384BC000,
668  0x384C0000, 0x384C4000, 0x384C8000, 0x384CC000, 0x384D0000, 0x384D4000, 0x384D8000, 0x384DC000, 0x384E0000, 0x384E4000, 0x384E8000, 0x384EC000, 0x384F0000, 0x384F4000, 0x384F8000, 0x384FC000,
669  0x38500000, 0x38504000, 0x38508000, 0x3850C000, 0x38510000, 0x38514000, 0x38518000, 0x3851C000, 0x38520000, 0x38524000, 0x38528000, 0x3852C000, 0x38530000, 0x38534000, 0x38538000, 0x3853C000,
670  0x38540000, 0x38544000, 0x38548000, 0x3854C000, 0x38550000, 0x38554000, 0x38558000, 0x3855C000, 0x38560000, 0x38564000, 0x38568000, 0x3856C000, 0x38570000, 0x38574000, 0x38578000, 0x3857C000,
671  0x38580000, 0x38584000, 0x38588000, 0x3858C000, 0x38590000, 0x38594000, 0x38598000, 0x3859C000, 0x385A0000, 0x385A4000, 0x385A8000, 0x385AC000, 0x385B0000, 0x385B4000, 0x385B8000, 0x385BC000,
672  0x385C0000, 0x385C4000, 0x385C8000, 0x385CC000, 0x385D0000, 0x385D4000, 0x385D8000, 0x385DC000, 0x385E0000, 0x385E4000, 0x385E8000, 0x385EC000, 0x385F0000, 0x385F4000, 0x385F8000, 0x385FC000,
673  0x38600000, 0x38604000, 0x38608000, 0x3860C000, 0x38610000, 0x38614000, 0x38618000, 0x3861C000, 0x38620000, 0x38624000, 0x38628000, 0x3862C000, 0x38630000, 0x38634000, 0x38638000, 0x3863C000,
674  0x38640000, 0x38644000, 0x38648000, 0x3864C000, 0x38650000, 0x38654000, 0x38658000, 0x3865C000, 0x38660000, 0x38664000, 0x38668000, 0x3866C000, 0x38670000, 0x38674000, 0x38678000, 0x3867C000,
675  0x38680000, 0x38684000, 0x38688000, 0x3868C000, 0x38690000, 0x38694000, 0x38698000, 0x3869C000, 0x386A0000, 0x386A4000, 0x386A8000, 0x386AC000, 0x386B0000, 0x386B4000, 0x386B8000, 0x386BC000,
676  0x386C0000, 0x386C4000, 0x386C8000, 0x386CC000, 0x386D0000, 0x386D4000, 0x386D8000, 0x386DC000, 0x386E0000, 0x386E4000, 0x386E8000, 0x386EC000, 0x386F0000, 0x386F4000, 0x386F8000, 0x386FC000,
677  0x38700000, 0x38704000, 0x38708000, 0x3870C000, 0x38710000, 0x38714000, 0x38718000, 0x3871C000, 0x38720000, 0x38724000, 0x38728000, 0x3872C000, 0x38730000, 0x38734000, 0x38738000, 0x3873C000,
678  0x38740000, 0x38744000, 0x38748000, 0x3874C000, 0x38750000, 0x38754000, 0x38758000, 0x3875C000, 0x38760000, 0x38764000, 0x38768000, 0x3876C000, 0x38770000, 0x38774000, 0x38778000, 0x3877C000,
679  0x38780000, 0x38784000, 0x38788000, 0x3878C000, 0x38790000, 0x38794000, 0x38798000, 0x3879C000, 0x387A0000, 0x387A4000, 0x387A8000, 0x387AC000, 0x387B0000, 0x387B4000, 0x387B8000, 0x387BC000,
680  0x387C0000, 0x387C4000, 0x387C8000, 0x387CC000, 0x387D0000, 0x387D4000, 0x387D8000, 0x387DC000, 0x387E0000, 0x387E4000, 0x387E8000, 0x387EC000, 0x387F0000, 0x387F4000, 0x387F8000, 0x387FC000,
681  0x38000000, 0x38002000, 0x38004000, 0x38006000, 0x38008000, 0x3800A000, 0x3800C000, 0x3800E000, 0x38010000, 0x38012000, 0x38014000, 0x38016000, 0x38018000, 0x3801A000, 0x3801C000, 0x3801E000,
682  0x38020000, 0x38022000, 0x38024000, 0x38026000, 0x38028000, 0x3802A000, 0x3802C000, 0x3802E000, 0x38030000, 0x38032000, 0x38034000, 0x38036000, 0x38038000, 0x3803A000, 0x3803C000, 0x3803E000,
683  0x38040000, 0x38042000, 0x38044000, 0x38046000, 0x38048000, 0x3804A000, 0x3804C000, 0x3804E000, 0x38050000, 0x38052000, 0x38054000, 0x38056000, 0x38058000, 0x3805A000, 0x3805C000, 0x3805E000,
684  0x38060000, 0x38062000, 0x38064000, 0x38066000, 0x38068000, 0x3806A000, 0x3806C000, 0x3806E000, 0x38070000, 0x38072000, 0x38074000, 0x38076000, 0x38078000, 0x3807A000, 0x3807C000, 0x3807E000,
685  0x38080000, 0x38082000, 0x38084000, 0x38086000, 0x38088000, 0x3808A000, 0x3808C000, 0x3808E000, 0x38090000, 0x38092000, 0x38094000, 0x38096000, 0x38098000, 0x3809A000, 0x3809C000, 0x3809E000,
686  0x380A0000, 0x380A2000, 0x380A4000, 0x380A6000, 0x380A8000, 0x380AA000, 0x380AC000, 0x380AE000, 0x380B0000, 0x380B2000, 0x380B4000, 0x380B6000, 0x380B8000, 0x380BA000, 0x380BC000, 0x380BE000,
687  0x380C0000, 0x380C2000, 0x380C4000, 0x380C6000, 0x380C8000, 0x380CA000, 0x380CC000, 0x380CE000, 0x380D0000, 0x380D2000, 0x380D4000, 0x380D6000, 0x380D8000, 0x380DA000, 0x380DC000, 0x380DE000,
688  0x380E0000, 0x380E2000, 0x380E4000, 0x380E6000, 0x380E8000, 0x380EA000, 0x380EC000, 0x380EE000, 0x380F0000, 0x380F2000, 0x380F4000, 0x380F6000, 0x380F8000, 0x380FA000, 0x380FC000, 0x380FE000,
689  0x38100000, 0x38102000, 0x38104000, 0x38106000, 0x38108000, 0x3810A000, 0x3810C000, 0x3810E000, 0x38110000, 0x38112000, 0x38114000, 0x38116000, 0x38118000, 0x3811A000, 0x3811C000, 0x3811E000,
690  0x38120000, 0x38122000, 0x38124000, 0x38126000, 0x38128000, 0x3812A000, 0x3812C000, 0x3812E000, 0x38130000, 0x38132000, 0x38134000, 0x38136000, 0x38138000, 0x3813A000, 0x3813C000, 0x3813E000,
691  0x38140000, 0x38142000, 0x38144000, 0x38146000, 0x38148000, 0x3814A000, 0x3814C000, 0x3814E000, 0x38150000, 0x38152000, 0x38154000, 0x38156000, 0x38158000, 0x3815A000, 0x3815C000, 0x3815E000,
692  0x38160000, 0x38162000, 0x38164000, 0x38166000, 0x38168000, 0x3816A000, 0x3816C000, 0x3816E000, 0x38170000, 0x38172000, 0x38174000, 0x38176000, 0x38178000, 0x3817A000, 0x3817C000, 0x3817E000,
693  0x38180000, 0x38182000, 0x38184000, 0x38186000, 0x38188000, 0x3818A000, 0x3818C000, 0x3818E000, 0x38190000, 0x38192000, 0x38194000, 0x38196000, 0x38198000, 0x3819A000, 0x3819C000, 0x3819E000,
694  0x381A0000, 0x381A2000, 0x381A4000, 0x381A6000, 0x381A8000, 0x381AA000, 0x381AC000, 0x381AE000, 0x381B0000, 0x381B2000, 0x381B4000, 0x381B6000, 0x381B8000, 0x381BA000, 0x381BC000, 0x381BE000,
695  0x381C0000, 0x381C2000, 0x381C4000, 0x381C6000, 0x381C8000, 0x381CA000, 0x381CC000, 0x381CE000, 0x381D0000, 0x381D2000, 0x381D4000, 0x381D6000, 0x381D8000, 0x381DA000, 0x381DC000, 0x381DE000,
696  0x381E0000, 0x381E2000, 0x381E4000, 0x381E6000, 0x381E8000, 0x381EA000, 0x381EC000, 0x381EE000, 0x381F0000, 0x381F2000, 0x381F4000, 0x381F6000, 0x381F8000, 0x381FA000, 0x381FC000, 0x381FE000,
697  0x38200000, 0x38202000, 0x38204000, 0x38206000, 0x38208000, 0x3820A000, 0x3820C000, 0x3820E000, 0x38210000, 0x38212000, 0x38214000, 0x38216000, 0x38218000, 0x3821A000, 0x3821C000, 0x3821E000,
698  0x38220000, 0x38222000, 0x38224000, 0x38226000, 0x38228000, 0x3822A000, 0x3822C000, 0x3822E000, 0x38230000, 0x38232000, 0x38234000, 0x38236000, 0x38238000, 0x3823A000, 0x3823C000, 0x3823E000,
699  0x38240000, 0x38242000, 0x38244000, 0x38246000, 0x38248000, 0x3824A000, 0x3824C000, 0x3824E000, 0x38250000, 0x38252000, 0x38254000, 0x38256000, 0x38258000, 0x3825A000, 0x3825C000, 0x3825E000,
700  0x38260000, 0x38262000, 0x38264000, 0x38266000, 0x38268000, 0x3826A000, 0x3826C000, 0x3826E000, 0x38270000, 0x38272000, 0x38274000, 0x38276000, 0x38278000, 0x3827A000, 0x3827C000, 0x3827E000,
701  0x38280000, 0x38282000, 0x38284000, 0x38286000, 0x38288000, 0x3828A000, 0x3828C000, 0x3828E000, 0x38290000, 0x38292000, 0x38294000, 0x38296000, 0x38298000, 0x3829A000, 0x3829C000, 0x3829E000,
702  0x382A0000, 0x382A2000, 0x382A4000, 0x382A6000, 0x382A8000, 0x382AA000, 0x382AC000, 0x382AE000, 0x382B0000, 0x382B2000, 0x382B4000, 0x382B6000, 0x382B8000, 0x382BA000, 0x382BC000, 0x382BE000,
703  0x382C0000, 0x382C2000, 0x382C4000, 0x382C6000, 0x382C8000, 0x382CA000, 0x382CC000, 0x382CE000, 0x382D0000, 0x382D2000, 0x382D4000, 0x382D6000, 0x382D8000, 0x382DA000, 0x382DC000, 0x382DE000,
704  0x382E0000, 0x382E2000, 0x382E4000, 0x382E6000, 0x382E8000, 0x382EA000, 0x382EC000, 0x382EE000, 0x382F0000, 0x382F2000, 0x382F4000, 0x382F6000, 0x382F8000, 0x382FA000, 0x382FC000, 0x382FE000,
705  0x38300000, 0x38302000, 0x38304000, 0x38306000, 0x38308000, 0x3830A000, 0x3830C000, 0x3830E000, 0x38310000, 0x38312000, 0x38314000, 0x38316000, 0x38318000, 0x3831A000, 0x3831C000, 0x3831E000,
706  0x38320000, 0x38322000, 0x38324000, 0x38326000, 0x38328000, 0x3832A000, 0x3832C000, 0x3832E000, 0x38330000, 0x38332000, 0x38334000, 0x38336000, 0x38338000, 0x3833A000, 0x3833C000, 0x3833E000,
707  0x38340000, 0x38342000, 0x38344000, 0x38346000, 0x38348000, 0x3834A000, 0x3834C000, 0x3834E000, 0x38350000, 0x38352000, 0x38354000, 0x38356000, 0x38358000, 0x3835A000, 0x3835C000, 0x3835E000,
708  0x38360000, 0x38362000, 0x38364000, 0x38366000, 0x38368000, 0x3836A000, 0x3836C000, 0x3836E000, 0x38370000, 0x38372000, 0x38374000, 0x38376000, 0x38378000, 0x3837A000, 0x3837C000, 0x3837E000,
709  0x38380000, 0x38382000, 0x38384000, 0x38386000, 0x38388000, 0x3838A000, 0x3838C000, 0x3838E000, 0x38390000, 0x38392000, 0x38394000, 0x38396000, 0x38398000, 0x3839A000, 0x3839C000, 0x3839E000,
710  0x383A0000, 0x383A2000, 0x383A4000, 0x383A6000, 0x383A8000, 0x383AA000, 0x383AC000, 0x383AE000, 0x383B0000, 0x383B2000, 0x383B4000, 0x383B6000, 0x383B8000, 0x383BA000, 0x383BC000, 0x383BE000,
711  0x383C0000, 0x383C2000, 0x383C4000, 0x383C6000, 0x383C8000, 0x383CA000, 0x383CC000, 0x383CE000, 0x383D0000, 0x383D2000, 0x383D4000, 0x383D6000, 0x383D8000, 0x383DA000, 0x383DC000, 0x383DE000,
712  0x383E0000, 0x383E2000, 0x383E4000, 0x383E6000, 0x383E8000, 0x383EA000, 0x383EC000, 0x383EE000, 0x383F0000, 0x383F2000, 0x383F4000, 0x383F6000, 0x383F8000, 0x383FA000, 0x383FC000, 0x383FE000,
713  0x38400000, 0x38402000, 0x38404000, 0x38406000, 0x38408000, 0x3840A000, 0x3840C000, 0x3840E000, 0x38410000, 0x38412000, 0x38414000, 0x38416000, 0x38418000, 0x3841A000, 0x3841C000, 0x3841E000,
714  0x38420000, 0x38422000, 0x38424000, 0x38426000, 0x38428000, 0x3842A000, 0x3842C000, 0x3842E000, 0x38430000, 0x38432000, 0x38434000, 0x38436000, 0x38438000, 0x3843A000, 0x3843C000, 0x3843E000,
715  0x38440000, 0x38442000, 0x38444000, 0x38446000, 0x38448000, 0x3844A000, 0x3844C000, 0x3844E000, 0x38450000, 0x38452000, 0x38454000, 0x38456000, 0x38458000, 0x3845A000, 0x3845C000, 0x3845E000,
716  0x38460000, 0x38462000, 0x38464000, 0x38466000, 0x38468000, 0x3846A000, 0x3846C000, 0x3846E000, 0x38470000, 0x38472000, 0x38474000, 0x38476000, 0x38478000, 0x3847A000, 0x3847C000, 0x3847E000,
717  0x38480000, 0x38482000, 0x38484000, 0x38486000, 0x38488000, 0x3848A000, 0x3848C000, 0x3848E000, 0x38490000, 0x38492000, 0x38494000, 0x38496000, 0x38498000, 0x3849A000, 0x3849C000, 0x3849E000,
718  0x384A0000, 0x384A2000, 0x384A4000, 0x384A6000, 0x384A8000, 0x384AA000, 0x384AC000, 0x384AE000, 0x384B0000, 0x384B2000, 0x384B4000, 0x384B6000, 0x384B8000, 0x384BA000, 0x384BC000, 0x384BE000,
719  0x384C0000, 0x384C2000, 0x384C4000, 0x384C6000, 0x384C8000, 0x384CA000, 0x384CC000, 0x384CE000, 0x384D0000, 0x384D2000, 0x384D4000, 0x384D6000, 0x384D8000, 0x384DA000, 0x384DC000, 0x384DE000,
720  0x384E0000, 0x384E2000, 0x384E4000, 0x384E6000, 0x384E8000, 0x384EA000, 0x384EC000, 0x384EE000, 0x384F0000, 0x384F2000, 0x384F4000, 0x384F6000, 0x384F8000, 0x384FA000, 0x384FC000, 0x384FE000,
721  0x38500000, 0x38502000, 0x38504000, 0x38506000, 0x38508000, 0x3850A000, 0x3850C000, 0x3850E000, 0x38510000, 0x38512000, 0x38514000, 0x38516000, 0x38518000, 0x3851A000, 0x3851C000, 0x3851E000,
722  0x38520000, 0x38522000, 0x38524000, 0x38526000, 0x38528000, 0x3852A000, 0x3852C000, 0x3852E000, 0x38530000, 0x38532000, 0x38534000, 0x38536000, 0x38538000, 0x3853A000, 0x3853C000, 0x3853E000,
723  0x38540000, 0x38542000, 0x38544000, 0x38546000, 0x38548000, 0x3854A000, 0x3854C000, 0x3854E000, 0x38550000, 0x38552000, 0x38554000, 0x38556000, 0x38558000, 0x3855A000, 0x3855C000, 0x3855E000,
724  0x38560000, 0x38562000, 0x38564000, 0x38566000, 0x38568000, 0x3856A000, 0x3856C000, 0x3856E000, 0x38570000, 0x38572000, 0x38574000, 0x38576000, 0x38578000, 0x3857A000, 0x3857C000, 0x3857E000,
725  0x38580000, 0x38582000, 0x38584000, 0x38586000, 0x38588000, 0x3858A000, 0x3858C000, 0x3858E000, 0x38590000, 0x38592000, 0x38594000, 0x38596000, 0x38598000, 0x3859A000, 0x3859C000, 0x3859E000,
726  0x385A0000, 0x385A2000, 0x385A4000, 0x385A6000, 0x385A8000, 0x385AA000, 0x385AC000, 0x385AE000, 0x385B0000, 0x385B2000, 0x385B4000, 0x385B6000, 0x385B8000, 0x385BA000, 0x385BC000, 0x385BE000,
727  0x385C0000, 0x385C2000, 0x385C4000, 0x385C6000, 0x385C8000, 0x385CA000, 0x385CC000, 0x385CE000, 0x385D0000, 0x385D2000, 0x385D4000, 0x385D6000, 0x385D8000, 0x385DA000, 0x385DC000, 0x385DE000,
728  0x385E0000, 0x385E2000, 0x385E4000, 0x385E6000, 0x385E8000, 0x385EA000, 0x385EC000, 0x385EE000, 0x385F0000, 0x385F2000, 0x385F4000, 0x385F6000, 0x385F8000, 0x385FA000, 0x385FC000, 0x385FE000,
729  0x38600000, 0x38602000, 0x38604000, 0x38606000, 0x38608000, 0x3860A000, 0x3860C000, 0x3860E000, 0x38610000, 0x38612000, 0x38614000, 0x38616000, 0x38618000, 0x3861A000, 0x3861C000, 0x3861E000,
730  0x38620000, 0x38622000, 0x38624000, 0x38626000, 0x38628000, 0x3862A000, 0x3862C000, 0x3862E000, 0x38630000, 0x38632000, 0x38634000, 0x38636000, 0x38638000, 0x3863A000, 0x3863C000, 0x3863E000,
731  0x38640000, 0x38642000, 0x38644000, 0x38646000, 0x38648000, 0x3864A000, 0x3864C000, 0x3864E000, 0x38650000, 0x38652000, 0x38654000, 0x38656000, 0x38658000, 0x3865A000, 0x3865C000, 0x3865E000,
732  0x38660000, 0x38662000, 0x38664000, 0x38666000, 0x38668000, 0x3866A000, 0x3866C000, 0x3866E000, 0x38670000, 0x38672000, 0x38674000, 0x38676000, 0x38678000, 0x3867A000, 0x3867C000, 0x3867E000,
733  0x38680000, 0x38682000, 0x38684000, 0x38686000, 0x38688000, 0x3868A000, 0x3868C000, 0x3868E000, 0x38690000, 0x38692000, 0x38694000, 0x38696000, 0x38698000, 0x3869A000, 0x3869C000, 0x3869E000,
734  0x386A0000, 0x386A2000, 0x386A4000, 0x386A6000, 0x386A8000, 0x386AA000, 0x386AC000, 0x386AE000, 0x386B0000, 0x386B2000, 0x386B4000, 0x386B6000, 0x386B8000, 0x386BA000, 0x386BC000, 0x386BE000,
735  0x386C0000, 0x386C2000, 0x386C4000, 0x386C6000, 0x386C8000, 0x386CA000, 0x386CC000, 0x386CE000, 0x386D0000, 0x386D2000, 0x386D4000, 0x386D6000, 0x386D8000, 0x386DA000, 0x386DC000, 0x386DE000,
736  0x386E0000, 0x386E2000, 0x386E4000, 0x386E6000, 0x386E8000, 0x386EA000, 0x386EC000, 0x386EE000, 0x386F0000, 0x386F2000, 0x386F4000, 0x386F6000, 0x386F8000, 0x386FA000, 0x386FC000, 0x386FE000,
737  0x38700000, 0x38702000, 0x38704000, 0x38706000, 0x38708000, 0x3870A000, 0x3870C000, 0x3870E000, 0x38710000, 0x38712000, 0x38714000, 0x38716000, 0x38718000, 0x3871A000, 0x3871C000, 0x3871E000,
738  0x38720000, 0x38722000, 0x38724000, 0x38726000, 0x38728000, 0x3872A000, 0x3872C000, 0x3872E000, 0x38730000, 0x38732000, 0x38734000, 0x38736000, 0x38738000, 0x3873A000, 0x3873C000, 0x3873E000,
739  0x38740000, 0x38742000, 0x38744000, 0x38746000, 0x38748000, 0x3874A000, 0x3874C000, 0x3874E000, 0x38750000, 0x38752000, 0x38754000, 0x38756000, 0x38758000, 0x3875A000, 0x3875C000, 0x3875E000,
740  0x38760000, 0x38762000, 0x38764000, 0x38766000, 0x38768000, 0x3876A000, 0x3876C000, 0x3876E000, 0x38770000, 0x38772000, 0x38774000, 0x38776000, 0x38778000, 0x3877A000, 0x3877C000, 0x3877E000,
741  0x38780000, 0x38782000, 0x38784000, 0x38786000, 0x38788000, 0x3878A000, 0x3878C000, 0x3878E000, 0x38790000, 0x38792000, 0x38794000, 0x38796000, 0x38798000, 0x3879A000, 0x3879C000, 0x3879E000,
742  0x387A0000, 0x387A2000, 0x387A4000, 0x387A6000, 0x387A8000, 0x387AA000, 0x387AC000, 0x387AE000, 0x387B0000, 0x387B2000, 0x387B4000, 0x387B6000, 0x387B8000, 0x387BA000, 0x387BC000, 0x387BE000,
743  0x387C0000, 0x387C2000, 0x387C4000, 0x387C6000, 0x387C8000, 0x387CA000, 0x387CC000, 0x387CE000, 0x387D0000, 0x387D2000, 0x387D4000, 0x387D6000, 0x387D8000, 0x387DA000, 0x387DC000, 0x387DE000,
744  0x387E0000, 0x387E2000, 0x387E4000, 0x387E6000, 0x387E8000, 0x387EA000, 0x387EC000, 0x387EE000, 0x387F0000, 0x387F2000, 0x387F4000, 0x387F6000, 0x387F8000, 0x387FA000, 0x387FC000, 0x387FE000 };
745  static const uint32 exponent_table[64] = {
746  0x00000000, 0x00800000, 0x01000000, 0x01800000, 0x02000000, 0x02800000, 0x03000000, 0x03800000, 0x04000000, 0x04800000, 0x05000000, 0x05800000, 0x06000000, 0x06800000, 0x07000000, 0x07800000,
747  0x08000000, 0x08800000, 0x09000000, 0x09800000, 0x0A000000, 0x0A800000, 0x0B000000, 0x0B800000, 0x0C000000, 0x0C800000, 0x0D000000, 0x0D800000, 0x0E000000, 0x0E800000, 0x0F000000, 0x47800000,
748  0x80000000, 0x80800000, 0x81000000, 0x81800000, 0x82000000, 0x82800000, 0x83000000, 0x83800000, 0x84000000, 0x84800000, 0x85000000, 0x85800000, 0x86000000, 0x86800000, 0x87000000, 0x87800000,
749  0x88000000, 0x88800000, 0x89000000, 0x89800000, 0x8A000000, 0x8A800000, 0x8B000000, 0x8B800000, 0x8C000000, 0x8C800000, 0x8D000000, 0x8D800000, 0x8E000000, 0x8E800000, 0x8F000000, 0xC7800000 };
750  static const unsigned short offset_table[64] = {
751  0, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
752  0, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024 };
753  uint32 bits = mantissa_table[offset_table[value>>10]+(value&0x3FF)] + exponent_table[value>>10];
754 // uint32 bits = mantissa_table[(((value&0x7C00)!=0)<<10)+(value&0x3FF)] + exponent_table[value>>10];
755 // return *reinterpret_cast<float*>(&bits); //violating strict aliasing!
756  float out;
757  std::memcpy(&out, &bits, sizeof(float));
758  return out;
759  }
760 
764  inline float half2float_impl(uint16 value, false_type)
765  {
766  float out;
767  int abs = value & 0x7FFF;
768  if(abs > 0x7C00)
769  out = std::numeric_limits<float>::has_quiet_NaN ? std::numeric_limits<float>::quiet_NaN() : 0.0f;
770  else if(abs == 0x7C00)
771  out = std::numeric_limits<float>::has_infinity ? std::numeric_limits<float>::infinity() : std::numeric_limits<float>::max();
772  else if(abs > 0x3FF)
773  out = std::ldexp(static_cast<float>((value&0x3FF)|0x400), (abs>>10)-25);
774  else
775  out = std::ldexp(static_cast<float>(abs), -24);
776  return (value&0x8000) ? -out : out;
777  }
778 
782  inline float half2float(uint16 value)
783  {
784  return half2float_impl(value, bool_type<std::numeric_limits<float>::is_iec559&&sizeof(uint32)==sizeof(float)>());
785  }
786 
793  template<std::float_round_style R,bool E,typename T> T half2int_impl(uint16 value)
794  {
795  unsigned int e = value & 0x7FFF;
796  if(e >= 0x7C00)
797  return (value&0x8000) ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max();
798  if(e < 0x3800)
799  {
800  if(R == std::round_toward_infinity)
801  return T(~(value>>15)&(e!=0));
802  else if(R == std::round_toward_neg_infinity)
803  return -T(value>0x8000);
804  return T();
805  }
806  int17 m = (value&0x3FF) | 0x400;
807  e >>= 10;
808  if(e < 25)
809  {
810  if(R == std::round_indeterminate || R == std::round_toward_zero)
811  m >>= 25 - e;
812  else
813  {
814  if(R == std::round_to_nearest)
815  m += (1<<(24-e)) - (~(m>>(25-e))&E);
816  else if(R == std::round_toward_infinity)
817  m += ((value>>15)-1) & ((1<<(25-e))-1U);
818  else if(R == std::round_toward_neg_infinity)
819  m += -(value>>15) & ((1<<(25-e))-1U);
820  m >>= 25 - e;
821  }
822  }
823  else
824  m <<= e - 25;
825 // if(std::numeric_limits<T>::digits < 16)
826 // return std::min(std::max(m, static_cast<int17>(std::numeric_limits<T>::min())), static_cast<int17>(std::numeric_limits<T>::max()));
827  return static_cast<T>((value&0x8000) ? -m : m);
828  }
829 
835  template<std::float_round_style R,typename T> T half2int(uint16 value) { return half2int_impl<R,HALF_ROUND_TIES_TO_EVEN,T>(value); }
836 
841  template<typename T> T half2int_up(uint16 value) { return half2int_impl<std::round_to_nearest,0,T>(value); }
842 
848  template<std::float_round_style R,bool E> uint16 round_half_impl(uint16 value)
849  {
850  unsigned int e = value & 0x7FFF;
851  uint16 result = value;
852  if(e < 0x3C00)
853  {
854  result &= 0x8000;
855  if(R == std::round_to_nearest)
856  result |= 0x3C00U & -(e>=(0x3800+E));
857  else if(R == std::round_toward_infinity)
858  result |= 0x3C00U & -(~(value>>15)&(e!=0));
859  else if(R == std::round_toward_neg_infinity)
860  result |= 0x3C00U & -(value>0x8000);
861  }
862  else if(e < 0x6400)
863  {
864  e = 25 - (e>>10);
865  unsigned int mask = (1<<e) - 1;
866  if(R == std::round_to_nearest)
867  result += (1<<(e-1)) - (~(result>>e)&E);
868  else if(R == std::round_toward_infinity)
869  result += mask & ((value>>15)-1);
870  else if(R == std::round_toward_neg_infinity)
871  result += mask & -(value>>15);
872  result &= ~mask;
873  }
874  return result;
875  }
876 
881  template<std::float_round_style R> uint16 round_half(uint16 value) { return round_half_impl<R,HALF_ROUND_TIES_TO_EVEN>(value); }
882 
886  inline uint16 round_half_up(uint16 value) { return round_half_impl<std::round_to_nearest,0>(value); }
888 
889  struct functions;
890  template<typename> struct unary_specialized;
891  template<typename,typename> struct binary_specialized;
892  template<typename,typename,std::float_round_style> struct half_caster;
893  }
894 
915  class half
916  {
917  friend struct detail::functions;
920  template<typename,typename,std::float_round_style> friend struct detail::half_caster;
921  friend class std::numeric_limits<half>;
922  #if HALF_ENABLE_CPP11_HASH
923  friend struct std::hash<half>;
924  #endif
925 
926  public:
930  HALF_CONSTEXPR half() : data_() {}
931 
935  half(detail::expr rhs) : data_(detail::float2half<round_style>(rhs)) {}
936 
939  explicit half(float rhs) : data_(detail::float2half<round_style>(rhs)) {}
940 
943  operator float() const { return detail::half2float(data_); }
944 
949  half& operator=(detail::expr rhs) { return *this = static_cast<float>(rhs); }
950 
955  template<typename T> typename detail::enable<half&,T>::type operator+=(T rhs) { return *this += static_cast<float>(rhs); }
956 
961  template<typename T> typename detail::enable<half&,T>::type operator-=(T rhs) { return *this -= static_cast<float>(rhs); }
962 
967  template<typename T> typename detail::enable<half&,T>::type operator*=(T rhs) { return *this *= static_cast<float>(rhs); }
968 
973  template<typename T> typename detail::enable<half&,T>::type operator/=(T rhs) { return *this /= static_cast<float>(rhs); }
974 
978  half& operator=(float rhs) { data_ = detail::float2half<round_style>(rhs); return *this; }
979 
983  half& operator+=(float rhs) { data_ = detail::float2half<round_style>(detail::half2float(data_)+rhs); return *this; }
984 
988  half& operator-=(float rhs) { data_ = detail::float2half<round_style>(detail::half2float(data_)-rhs); return *this; }
989 
993  half& operator*=(float rhs) { data_ = detail::float2half<round_style>(detail::half2float(data_)*rhs); return *this; }
994 
998  half& operator/=(float rhs) { data_ = detail::float2half<round_style>(detail::half2float(data_)/rhs); return *this; }
999 
1002  half& operator++() { return *this += 1.0f; }
1003 
1006  half& operator--() { return *this -= 1.0f; }
1007 
1010  half operator++(int) { half out(*this); ++*this; return out; }
1011 
1014  half operator--(int) { half out(*this); --*this; return out; }
1015 
1016  private:
1018  static const std::float_round_style round_style = (std::float_round_style)(HALF_ROUND_STYLE);
1019 
1022  HALF_CONSTEXPR half(detail::binary_t, detail::uint16 bits) : data_(bits) {}
1023 
1025  detail::uint16 data_;
1026  };
1027 
1028 #if HALF_ENABLE_CPP11_USER_LITERALS
1029  namespace literal
1036  {
1042  inline half operator "" _h(long double value) { return half(static_cast<float>(value)); }
1043  }
1044 #endif
1045 
1046  namespace detail
1047  {
1049  struct functions
1050  {
1055  static expr plus(float x, float y) { return expr(x+y); }
1056 
1061  static expr minus(float x, float y) { return expr(x-y); }
1062 
1067  static expr multiplies(float x, float y) { return expr(x*y); }
1068 
1073  static expr divides(float x, float y) { return expr(x/y); }
1074 
1079  template<typename charT,typename traits> static std::basic_ostream<charT,traits>& write(std::basic_ostream<charT,traits> &out, float arg) { return out << arg; }
1080 
1085  template<typename charT,typename traits> static std::basic_istream<charT,traits>& read(std::basic_istream<charT,traits> &in, half &arg)
1086  {
1087  float f;
1088  if(in >> f)
1089  arg = f;
1090  return in;
1091  }
1092 
1097  static expr fmod(float x, float y) { return expr(std::fmod(x, y)); }
1098 
1103  static expr remainder(float x, float y)
1104  {
1105  #if HALF_ENABLE_CPP11_CMATH
1106  return expr(std::remainder(x, y));
1107  #else
1108  if(builtin_isnan(x) || builtin_isnan(y))
1109  return expr(std::numeric_limits<float>::quiet_NaN());
1110  float ax = std::fabs(x), ay = std::fabs(y);
1111  if(ax >= 65536.0f || ay < std::ldexp(1.0f, -24))
1112  return expr(std::numeric_limits<float>::quiet_NaN());
1113  if(ay >= 65536.0f)
1114  return expr(x);
1115  if(ax == ay)
1116  return expr(builtin_signbit(x) ? -0.0f : 0.0f);
1117  ax = std::fmod(ax, ay+ay);
1118  float y2 = 0.5f * ay;
1119  if(ax > y2)
1120  {
1121  ax -= ay;
1122  if(ax >= y2)
1123  ax -= ay;
1124  }
1125  return expr(builtin_signbit(x) ? -ax : ax);
1126  #endif
1127  }
1128 
1134  static expr remquo(float x, float y, int *quo)
1135  {
1136  #if HALF_ENABLE_CPP11_CMATH
1137  return expr(std::remquo(x, y, quo));
1138  #else
1139  if(builtin_isnan(x) || builtin_isnan(y))
1140  return expr(std::numeric_limits<float>::quiet_NaN());
1141  bool sign = builtin_signbit(x), qsign = static_cast<bool>(sign^builtin_signbit(y));
1142  float ax = std::fabs(x), ay = std::fabs(y);
1143  if(ax >= 65536.0f || ay < std::ldexp(1.0f, -24))
1144  return expr(std::numeric_limits<float>::quiet_NaN());
1145  if(ay >= 65536.0f)
1146  return expr(x);
1147  if(ax == ay)
1148  return *quo = qsign ? -1 : 1, expr(sign ? -0.0f : 0.0f);
1149  ax = std::fmod(ax, 8.0f*ay);
1150  int cquo = 0;
1151  if(ax >= 4.0f * ay)
1152  {
1153  ax -= 4.0f * ay;
1154  cquo += 4;
1155  }
1156  if(ax >= 2.0f * ay)
1157  {
1158  ax -= 2.0f * ay;
1159  cquo += 2;
1160  }
1161  float y2 = 0.5f * ay;
1162  if(ax > y2)
1163  {
1164  ax -= ay;
1165  ++cquo;
1166  if(ax >= y2)
1167  {
1168  ax -= ay;
1169  ++cquo;
1170  }
1171  }
1172  return *quo = qsign ? -cquo : cquo, expr(sign ? -ax : ax);
1173  #endif
1174  }
1175 
1180  static expr fdim(float x, float y)
1181  {
1182  #if HALF_ENABLE_CPP11_CMATH
1183  return expr(std::fdim(x, y));
1184  #else
1185  return expr((x<=y) ? 0.0f : (x-y));
1186  #endif
1187  }
1188 
1194  static expr fma(float x, float y, float z)
1195  {
1196  #if HALF_ENABLE_CPP11_CMATH && defined(FP_FAST_FMAF)
1197  return expr(std::fma(x, y, z));
1198  #else
1199  return expr(x*y+z);
1200  #endif
1201  }
1202 
1205  static half nanh(const char*) { return half(binary, 0x7FFF); }
1206 
1210  static expr exp(float arg) { return expr(std::exp(arg)); }
1211 
1215  static expr expm1(float arg)
1216  {
1217  #if HALF_ENABLE_CPP11_CMATH
1218  return expr(std::expm1(arg));
1219  #else
1220  return expr(static_cast<float>(std::exp(static_cast<double>(arg))-1.0));
1221  #endif
1222  }
1223 
1227  static expr exp2(float arg)
1228  {
1229  #if HALF_ENABLE_CPP11_CMATH
1230  return expr(std::exp2(arg));
1231  #else
1232  return expr(static_cast<float>(std::exp(arg*0.69314718055994530941723212145818)));
1233  #endif
1234  }
1235 
1239  static expr log(float arg) { return expr(std::log(arg)); }
1240 
1244  static expr log10(float arg) { return expr(std::log10(arg)); }
1245 
1249  static expr log1p(float arg)
1250  {
1251  #if HALF_ENABLE_CPP11_CMATH
1252  return expr(std::log1p(arg));
1253  #else
1254  return expr(static_cast<float>(std::log(1.0+arg)));
1255  #endif
1256  }
1257 
1261  static expr log2(float arg)
1262  {
1263  #if HALF_ENABLE_CPP11_CMATH
1264  return expr(std::log2(arg));
1265  #else
1266  return expr(static_cast<float>(std::log(static_cast<double>(arg))*1.4426950408889634073599246810019));
1267  #endif
1268  }
1269 
1273  static expr sqrt(float arg) { return expr(std::sqrt(arg)); }
1274 
1278  static expr cbrt(float arg)
1279  {
1280  #if HALF_ENABLE_CPP11_CMATH
1281  return expr(std::cbrt(arg));
1282  #else
1283  if(builtin_isnan(arg) || builtin_isinf(arg))
1284  return expr(arg);
1285  return expr(builtin_signbit(arg) ? -static_cast<float>(std::pow(std::fabs(static_cast<double>(arg)), 1.0/3.0)) :
1286  static_cast<float>(std::pow(static_cast<double>(arg), 1.0/3.0)));
1287  #endif
1288  }
1289 
1294  static expr hypot(float x, float y)
1295  {
1296  #if HALF_ENABLE_CPP11_CMATH
1297  return expr(std::hypot(x, y));
1298  #else
1299  return expr((builtin_isinf(x) || builtin_isinf(y)) ? std::numeric_limits<float>::infinity() :
1300  static_cast<float>(std::sqrt(static_cast<double>(x)*x+static_cast<double>(y)*y)));
1301  #endif
1302  }
1303 
1308  static expr pow(float base, float exp) { return expr(std::pow(base, exp)); }
1309 
1313  static expr sin(float arg) { return expr(std::sin(arg)); }
1314 
1318  static expr cos(float arg) { return expr(std::cos(arg)); }
1319 
1323  static expr tan(float arg) { return expr(std::tan(arg)); }
1324 
1328  static expr asin(float arg) { return expr(std::asin(arg)); }
1329 
1333  static expr acos(float arg) { return expr(std::acos(arg)); }
1334 
1338  static expr atan(float arg) { return expr(std::atan(arg)); }
1339 
1344  static expr atan2(float x, float y) { return expr(std::atan2(x, y)); }
1345 
1349  static expr sinh(float arg) { return expr(std::sinh(arg)); }
1350 
1354  static expr cosh(float arg) { return expr(std::cosh(arg)); }
1355 
1359  static expr tanh(float arg) { return expr(std::tanh(arg)); }
1360 
1364  static expr asinh(float arg)
1365  {
1366  #if HALF_ENABLE_CPP11_CMATH
1367  return expr(std::asinh(arg));
1368  #else
1369  return expr((arg==-std::numeric_limits<float>::infinity()) ? arg : static_cast<float>(std::log(arg+std::sqrt(arg*arg+1.0))));
1370  #endif
1371  }
1372 
1376  static expr acosh(float arg)
1377  {
1378  #if HALF_ENABLE_CPP11_CMATH
1379  return expr(std::acosh(arg));
1380  #else
1381  return expr((arg<-1.0f) ? std::numeric_limits<float>::quiet_NaN() : static_cast<float>(std::log(arg+std::sqrt(arg*arg-1.0))));
1382  #endif
1383  }
1384 
1388  static expr atanh(float arg)
1389  {
1390  #if HALF_ENABLE_CPP11_CMATH
1391  return expr(std::atanh(arg));
1392  #else
1393  return expr(static_cast<float>(0.5*std::log((1.0+arg)/(1.0-arg))));
1394  #endif
1395  }
1396 
1400  static expr erf(float arg)
1401  {
1402  #if HALF_ENABLE_CPP11_CMATH
1403  return expr(std::erf(arg));
1404  #else
1405  return expr(static_cast<float>(erf(static_cast<double>(arg))));
1406  #endif
1407  }
1408 
1412  static expr erfc(float arg)
1413  {
1414  #if HALF_ENABLE_CPP11_CMATH
1415  return expr(std::erfc(arg));
1416  #else
1417  return expr(static_cast<float>(1.0-erf(static_cast<double>(arg))));
1418  #endif
1419  }
1420 
1424  static expr lgamma(float arg)
1425  {
1426  #if HALF_ENABLE_CPP11_CMATH
1427  return expr(std::lgamma(arg));
1428  #else
1429  if(builtin_isinf(arg))
1430  return expr(std::numeric_limits<float>::infinity());
1431  double z = static_cast<double>(arg);
1432  if(z < 0)
1433  {
1434  double i, f = std::modf(-z, &i);
1435  if(f == 0.0)
1436  return expr(std::numeric_limits<float>::infinity());
1437  return expr(static_cast<float>(1.1447298858494001741434273513531-std::log(std::abs(std::sin(3.1415926535897932384626433832795*f)))-lgamma(1.0-z)));
1438  }
1439 // if(z < 8.0)
1440  return expr(static_cast<float>(lgamma(static_cast<double>(arg))));
1441  return expr(static_cast<float>(0.5*(1.8378770664093454835606594728112-std::log(z))+z*(std::log(z+1.0/(12.0*z-1.0/(10.0*z)-1.0))-1.0)));
1442  #endif
1443  }
1444 
1448  static expr tgamma(float arg)
1449  {
1450  #if HALF_ENABLE_CPP11_CMATH
1451  return expr(std::tgamma(arg));
1452  #else
1453  double z = static_cast<double>(arg);
1454  if(z == 0.0)
1455  return builtin_signbit(z) ? expr(-std::numeric_limits<float>::infinity()) : expr(std::numeric_limits<float>::infinity());
1456  if(z < 0.0)
1457  {
1458  double i, f = std::modf(-z, &i);
1459  if(f == 0.0)
1460  return expr(std::numeric_limits<float>::quiet_NaN());
1461  double sign = (std::fmod(i, 2.0)==0.0) ? -1.0 : 1.0;
1462  return expr(static_cast<float>(sign*3.1415926535897932384626433832795/(std::sin(3.1415926535897932384626433832795*f)*std::exp(lgamma(1.0-z)))));
1463  }
1464  if(builtin_isinf(arg))
1465  return expr(arg);
1466 // if(arg < 8.0f)
1467  return expr(static_cast<float>(std::exp(lgamma(z))));
1468  return expr(static_cast<float>(std::sqrt(6.283185307179586476925286766559/z)*std::pow(0.36787944117144232159552377016146*(z+1.0/(12.0*z-1.0/(10.0*z))), z)));
1469  #endif
1470  }
1471 
1475  static half floor(half arg) { return half(binary, round_half<std::round_toward_neg_infinity>(arg.data_)); }
1476 
1480  static half ceil(half arg) { return half(binary, round_half<std::round_toward_infinity>(arg.data_)); }
1481 
1485  static half trunc(half arg) { return half(binary, round_half<std::round_toward_zero>(arg.data_)); }
1486 
1490  static half round(half arg) { return half(binary, round_half_up(arg.data_)); }
1491 
1495  static long lround(half arg) { return detail::half2int_up<long>(arg.data_); }
1496 
1500  static half rint(half arg) { return half(binary, round_half<half::round_style>(arg.data_)); }
1501 
1505  static long lrint(half arg) { return detail::half2int<half::round_style,long>(arg.data_); }
1506 
1507  #if HALF_ENABLE_CPP11_LONG_LONG
1508  static long long llround(half arg) { return detail::half2int_up<long long>(arg.data_); }
1512 
1516  static long long llrint(half arg) { return detail::half2int<half::round_style,long long>(arg.data_); }
1517  #endif
1518 
1523  static half frexp(half arg, int *exp)
1524  {
1525  unsigned int m = arg.data_ & 0x7FFF;
1526  if(m >= 0x7C00 || !m)
1527  return *exp = 0, arg;
1528  int e = m >> 10;
1529  if(!e)
1530  for(m<<=1; m<0x400; m<<=1,--e) ;
1531  return *exp = e-14, half(binary, static_cast<uint16>((arg.data_&0x8000)|0x3800|(m&0x3FF)));
1532  }
1533 
1538  static half modf(half arg, half *iptr)
1539  {
1540  unsigned int e = arg.data_ & 0x7C00;
1541  if(e > 0x6000)
1542  return *iptr = arg, (e==0x7C00&&(arg.data_&0x3FF)) ? arg : half(binary, arg.data_&0x8000);
1543  if(e < 0x3C00)
1544  return iptr->data_ = arg.data_ & 0x8000, arg;
1545  e >>= 10;
1546  unsigned int mask = (1<<(25-e)) - 1, m = arg.data_ & mask;
1547  iptr->data_ = arg.data_ & ~mask;
1548  if(!m)
1549  return half(binary, arg.data_&0x8000);
1550  for(; m<0x400; m<<=1,--e) ;
1551  return half(binary, static_cast<uint16>((arg.data_&0x8000)|(e<<10)|(m&0x3FF)));
1552  }
1553 
1558  static half scalbln(half arg, long exp)
1559  {
1560  long e = arg.data_ & 0x7C00;
1561  if(e == 0x7C00)
1562  return arg;
1563  unsigned int m = arg.data_ & 0x3FF;
1564  if(e >>= 10)
1565  m |= 0x400;
1566  else
1567  {
1568  if(!m)
1569  return arg;
1570  for(m<<=1; m<0x400; m<<=1,--e) ;
1571  }
1572  e += exp;
1573  uint16 value = arg.data_ & 0x8000;
1574  if(e > 30)
1575  {
1576  if(half::round_style == std::round_toward_zero)
1577  value |= 0x7BFF;
1578  else if(half::round_style == std::round_toward_infinity)
1579  value |= 0x7C00 - (value>>15);
1580  else if(half::round_style == std::round_toward_neg_infinity)
1581  value |= 0x7BFF + (value>>15);
1582  else
1583  value |= 0x7C00;
1584  }
1585  else if(e > 0)
1586  value |= (e<<10) | (m&0x3FF);
1587  else if(e > -11)
1588  {
1589  if(half::round_style == std::round_to_nearest)
1590  {
1591  m += 1 << -e;
1592  #if HALF_ROUND_TIES_TO_EVEN
1593  m -= (m>>(1-e)) & 1;
1594  #endif
1595  }
1596  else if(half::round_style == std::round_toward_infinity)
1597  m += ((value>>15)-1) & ((1<<(1-e))-1U);
1598  else if(half::round_style == std::round_toward_neg_infinity)
1599  m += -(value>>15) & ((1<<(1-e))-1U);
1600  value |= m >> (1-e);
1601  }
1602  else if(half::round_style == std::round_toward_infinity)
1603  value |= ((value>>15)-1) & 1;
1604  else if(half::round_style == std::round_toward_neg_infinity)
1605  value |= value >> 15;
1606  return half(binary, value);
1607  }
1608 
1612  static int ilogb(half arg)
1613  {
1614  int exp = arg.data_ & 0x7FFF;
1615  if(!exp)
1616  return FP_ILOGB0;
1617  if(exp < 0x7C00)
1618  {
1619  if(!(exp>>=10))
1620  for(unsigned int m=(arg.data_&0x3FF); m<0x200; m<<=1,--exp) ;
1621  return exp - 15;
1622  }
1623  if(exp > 0x7C00)
1624  return FP_ILOGBNAN;
1625  return INT_MAX;
1626  }
1627 
1631  static half logb(half arg)
1632  {
1633  int exp = arg.data_ & 0x7FFF;
1634  if(!exp)
1635  return half(binary, 0xFC00);
1636  if(exp < 0x7C00)
1637  {
1638  if(!(exp>>=10))
1639  for(unsigned int m=(arg.data_&0x3FF); m<0x200; m<<=1,--exp) ;
1640  return half(static_cast<float>(exp-15));
1641  }
1642  if(exp > 0x7C00)
1643  return arg;
1644  return half(binary, 0x7C00);
1645  }
1646 
1651  static half nextafter(half from, half to)
1652  {
1653  uint16 fabs = from.data_ & 0x7FFF, tabs = to.data_ & 0x7FFF;
1654  if(fabs > 0x7C00)
1655  return from;
1656  if(tabs > 0x7C00 || from.data_ == to.data_ || !(fabs|tabs))
1657  return to;
1658  if(!fabs)
1659  return half(binary, (to.data_&0x8000)+1);
1660  bool lt = (signbit(from) ? (static_cast<int17>(0x8000)-from.data_) : static_cast<int17>(from.data_)) <
1661  (signbit(to) ? (static_cast<int17>(0x8000)-to.data_) : static_cast<int17>(to.data_));
1662  return half(binary, from.data_+(((from.data_>>15)^static_cast<uint16>(lt))<<1)-1);
1663  }
1664 
1669  static half nexttoward(half from, long double to)
1670  {
1671  if(isnan(from))
1672  return from;
1673  long double lfrom = static_cast<long double>(from);
1674  if(builtin_isnan(to) || lfrom == to)
1675  return half(static_cast<float>(to));
1676  if(!(from.data_&0x7FFF))
1677  return half(binary, (static_cast<detail::uint16>(builtin_signbit(to))<<15)+1);
1678  return half(binary, from.data_+(((from.data_>>15)^static_cast<uint16>(lfrom<to))<<1)-1);
1679  }
1680 
1685  static half copysign(half x, half y) { return half(binary, x.data_^((x.data_^y.data_)&0x8000)); }
1686 
1691  static int fpclassify(half arg)
1692  {
1693  unsigned int abs = arg.data_ & 0x7FFF;
1694  if(abs > 0x7C00)
1695  return FP_NAN;
1696  if(abs == 0x7C00)
1697  return FP_INFINITE;
1698  if(abs > 0x3FF)
1699  return FP_NORMAL;
1700  return abs ? FP_SUBNORMAL : FP_ZERO;
1701  }
1702 
1707  static bool isfinite(half arg) { return (arg.data_&0x7C00) != 0x7C00; }
1708 
1713  static bool isinf(half arg) { return (arg.data_&0x7FFF) == 0x7C00; }
1714 
1719  static bool isnan(half arg) { return (arg.data_&0x7FFF) > 0x7C00; }
1720 
1725  static bool isnormal(half arg) { return ((arg.data_&0x7C00)!=0) & ((arg.data_&0x7C00)!=0x7C00); }
1726 
1731  static bool signbit(half arg) { return (arg.data_&0x8000) != 0; }
1732 
1738  static bool isequal(half x, half y) { return (x.data_==y.data_ || !((x.data_|y.data_)&0x7FFF)) && !isnan(x); }
1739 
1745  static bool isnotequal(half x, half y) { return (x.data_!=y.data_ && ((x.data_|y.data_)&0x7FFF)) || isnan(x); }
1746 
1752  static bool isgreater(half x, half y) { return !isnan(x) && !isnan(y) && ((signbit(x) ? (static_cast<int17>(0x8000)-x.data_) :
1753  static_cast<int17>(x.data_)) > (signbit(y) ? (static_cast<int17>(0x8000)-y.data_) : static_cast<int17>(y.data_))); }
1754 
1760  static bool isgreaterequal(half x, half y) { return !isnan(x) && !isnan(y) && ((signbit(x) ? (static_cast<int17>(0x8000)-x.data_) :
1761  static_cast<int17>(x.data_)) >= (signbit(y) ? (static_cast<int17>(0x8000)-y.data_) : static_cast<int17>(y.data_))); }
1762 
1768  static bool isless(half x, half y) { return !isnan(x) && !isnan(y) && ((signbit(x) ? (static_cast<int17>(0x8000)-x.data_) :
1769  static_cast<int17>(x.data_)) < (signbit(y) ? (static_cast<int17>(0x8000)-y.data_) : static_cast<int17>(y.data_))); }
1770 
1776  static bool islessequal(half x, half y) { return !isnan(x) && !isnan(y) && ((signbit(x) ? (static_cast<int17>(0x8000)-x.data_) :
1777  static_cast<int17>(x.data_)) <= (signbit(y) ? (static_cast<int17>(0x8000)-y.data_) : static_cast<int17>(y.data_))); }
1778 
1784  static bool islessgreater(half x, half y)
1785  {
1786  if(isnan(x) || isnan(y))
1787  return false;
1788  int17 a = signbit(x) ? (static_cast<int17>(0x8000)-x.data_) : static_cast<int17>(x.data_);
1789  int17 b = signbit(y) ? (static_cast<int17>(0x8000)-y.data_) : static_cast<int17>(y.data_);
1790  return a < b || a > b;
1791  }
1792 
1798  static bool isunordered(half x, half y) { return isnan(x) || isnan(y); }
1799 
1800  private:
1801  static double erf(double arg)
1802  {
1803  if(builtin_isinf(arg))
1804  return (arg<0.0) ? -1.0 : 1.0;
1805  double x2 = static_cast<double>(arg) * static_cast<double>(arg), ax2 = 0.147 * x2;
1806  double value = std::sqrt(1.0-std::exp(-x2*(1.2732395447351626861510701069801+ax2)/(1.0+ax2)));
1807  return builtin_signbit(arg) ? -value : value;
1808  }
1809 
1810  static double lgamma(double arg)
1811  {
1812  double v = 1.0;
1813  for(; arg<8.0; ++arg) v *= arg;
1814  double w = 1.0 / (arg * arg);
1815  return (((((((-0.02955065359477124183006535947712*w+0.00641025641025641025641025641026)*w+
1816  -0.00191752691752691752691752691753)*w+8.4175084175084175084175084175084e-4)*w+
1817  -5.952380952380952380952380952381e-4)*w+7.9365079365079365079365079365079e-4)*w+
1818  -0.00277777777777777777777777777778)*w+0.08333333333333333333333333333333)/arg +
1819  0.91893853320467274178032973640562 - std::log(v) - arg + (arg-0.5) * std::log(arg);
1820  }
1821  };
1822 
1825  template<typename T> struct unary_specialized
1826  {
1830  static HALF_CONSTEXPR half negate(half arg) { return half(binary, arg.data_^0x8000); }
1831 
1835  static half fabs(half arg) { return half(binary, arg.data_&0x7FFF); }
1836  };
1837  template<> struct unary_specialized<expr>
1838  {
1839  static HALF_CONSTEXPR expr negate(float arg) { return expr(-arg); }
1840  static expr fabs(float arg) { return expr(std::fabs(arg)); }
1841  };
1842 
1846  template<typename T,typename U> struct binary_specialized
1847  {
1852  static expr fmin(float x, float y)
1853  {
1854  #if HALF_ENABLE_CPP11_CMATH
1855  return expr(std::fmin(x, y));
1856  #else
1857  if(builtin_isnan(x))
1858  return expr(y);
1859  if(builtin_isnan(y))
1860  return expr(x);
1861  return expr(std::min(x, y));
1862  #endif
1863  }
1864 
1869  static expr fmax(float x, float y)
1870  {
1871  #if HALF_ENABLE_CPP11_CMATH
1872  return expr(std::fmax(x, y));
1873  #else
1874  if(builtin_isnan(x))
1875  return expr(y);
1876  if(builtin_isnan(y))
1877  return expr(x);
1878  return expr(std::max(x, y));
1879  #endif
1880  }
1881  };
1882  template<> struct binary_specialized<half,half>
1883  {
1884  static half fmin(half x, half y)
1885  {
1886  if(functions::isnan(x))
1887  return y;
1888  if(functions::isnan(y))
1889  return x;
1890  return ((functions::signbit(x) ? (static_cast<int17>(0x8000)-x.data_) : static_cast<int17>(x.data_)) >
1891  (functions::signbit(y) ? (static_cast<int17>(0x8000)-y.data_) : static_cast<int17>(y.data_))) ? y : x;
1892  }
1893  static half fmax(half x, half y)
1894  {
1895  if(functions::isnan(x))
1896  return y;
1897  if(functions::isnan(y))
1898  return x;
1899  return ((functions::signbit(x) ? (static_cast<int17>(0x8000)-x.data_) : static_cast<int17>(x.data_)) <
1900  (functions::signbit(y) ? (static_cast<int17>(0x8000)-y.data_) : static_cast<int17>(y.data_))) ? y : x;
1901  }
1902  };
1903 
1910  template<typename T,typename U,std::float_round_style R=(std::float_round_style)(HALF_ROUND_STYLE)> struct half_caster {};
1911  template<typename U,std::float_round_style R> struct half_caster<half,U,R>
1912  {
1913  #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
1914  static_assert(std::is_arithmetic<U>::value, "half_cast from non-arithmetic type unsupported");
1915  #endif
1916 
1917  typedef half type;
1918  static half cast(U arg) { return cast_impl(arg, is_float<U>()); };
1919 
1920  private:
1921  static half cast_impl(U arg, true_type) { return half(binary, float2half<R>(static_cast<float>(arg))); }
1922  static half cast_impl(U arg, false_type) { return half(binary, int2half<R>(arg)); }
1923  };
1924  template<typename T,std::float_round_style R> struct half_caster<T,half,R>
1925  {
1926  #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
1927  static_assert(std::is_arithmetic<T>::value, "half_cast to non-arithmetic type unsupported");
1928  #endif
1929 
1930  typedef T type;
1931  template<typename U> static T cast(U arg) { return cast_impl(arg, is_float<T>()); }
1932 
1933  private:
1934  static T cast_impl(float arg, true_type) { return static_cast<T>(arg); }
1935  static T cast_impl(half arg, false_type) { return half2int<R,T>(arg.data_); }
1936  };
1937  template<typename T,std::float_round_style R> struct half_caster<T,expr,R> : public half_caster<T,half,R> {};
1938  template<std::float_round_style R> struct half_caster<half,half,R>
1939  {
1940  typedef half type;
1941  static half cast(half arg) { return arg; }
1942  };
1943  template<std::float_round_style R> struct half_caster<half,expr,R> : public half_caster<half,half,R> {};
1944 
1947 
1953  template<typename T,typename U> typename enable<bool,T,U>::type operator==(T x, U y) { return functions::isequal(x, y); }
1954 
1960  template<typename T,typename U> typename enable<bool,T,U>::type operator!=(T x, U y) { return functions::isnotequal(x, y); }
1961 
1967  template<typename T,typename U> typename enable<bool,T,U>::type operator<(T x, U y) { return functions::isless(x, y); }
1968 
1974  template<typename T,typename U> typename enable<bool,T,U>::type operator>(T x, U y) { return functions::isgreater(x, y); }
1975 
1981  template<typename T,typename U> typename enable<bool,T,U>::type operator<=(T x, U y) { return functions::islessequal(x, y); }
1982 
1988  template<typename T,typename U> typename enable<bool,T,U>::type operator>=(T x, U y) { return functions::isgreaterequal(x, y); }
1989 
1993 
1998  template<typename T,typename U> typename enable<expr,T,U>::type operator+(T x, U y) { return functions::plus(x, y); }
1999 
2004  template<typename T,typename U> typename enable<expr,T,U>::type operator-(T x, U y) { return functions::minus(x, y); }
2005 
2010  template<typename T,typename U> typename enable<expr,T,U>::type operator*(T x, U y) { return functions::multiplies(x, y); }
2011 
2016  template<typename T,typename U> typename enable<expr,T,U>::type operator/(T x, U y) { return functions::divides(x, y); }
2017 
2021  template<typename T> HALF_CONSTEXPR typename enable<T,T>::type operator+(T arg) { return arg; }
2022 
2026  template<typename T> HALF_CONSTEXPR typename enable<T,T>::type operator-(T arg) { return unary_specialized<T>::negate(arg); }
2027 
2031 
2036  template<typename T,typename charT,typename traits> typename enable<std::basic_ostream<charT,traits>&,T>::type
2037  operator<<(std::basic_ostream<charT,traits> &out, T arg) { return functions::write(out, arg); }
2038 
2043  template<typename charT,typename traits> std::basic_istream<charT,traits>&
2044  operator>>(std::basic_istream<charT,traits> &in, half &arg) { return functions::read(in, arg); }
2045 
2049 
2053 // template<typename T> typename enable<T,T>::type abs(T arg) { return unary_specialized<T>::fabs(arg); }
2054  inline half abs(half arg) { return unary_specialized<half>::fabs(arg); }
2055  inline expr abs(expr arg) { return unary_specialized<expr>::fabs(arg); }
2056 
2060 // template<typename T> typename enable<T,T>::type fabs(T arg) { return unary_specialized<T>::fabs(arg); }
2061  inline half fabs(half arg) { return unary_specialized<half>::fabs(arg); }
2062  inline expr fabs(expr arg) { return unary_specialized<expr>::fabs(arg); }
2063 
2068 // template<typename T,typename U> typename enable<expr,T,U>::type fmod(T x, U y) { return functions::fmod(x, y); }
2069  inline expr fmod(half x, half y) { return functions::fmod(x, y); }
2070  inline expr fmod(half x, expr y) { return functions::fmod(x, y); }
2071  inline expr fmod(expr x, half y) { return functions::fmod(x, y); }
2072  inline expr fmod(expr x, expr y) { return functions::fmod(x, y); }
2073 
2078 // template<typename T,typename U> typename enable<expr,T,U>::type remainder(T x, U y) { return functions::remainder(x, y); }
2079  inline expr remainder(half x, half y) { return functions::remainder(x, y); }
2080  inline expr remainder(half x, expr y) { return functions::remainder(x, y); }
2081  inline expr remainder(expr x, half y) { return functions::remainder(x, y); }
2082  inline expr remainder(expr x, expr y) { return functions::remainder(x, y); }
2083 
2089 // template<typename T,typename U> typename enable<expr,T,U>::type remquo(T x, U y, int *quo) { return functions::remquo(x, y, quo); }
2090  inline expr remquo(half x, half y, int *quo) { return functions::remquo(x, y, quo); }
2091  inline expr remquo(half x, expr y, int *quo) { return functions::remquo(x, y, quo); }
2092  inline expr remquo(expr x, half y, int *quo) { return functions::remquo(x, y, quo); }
2093  inline expr remquo(expr x, expr y, int *quo) { return functions::remquo(x, y, quo); }
2094 
2100 // template<typename T,typename U,typename V> typename enable<expr,T,U,V>::type fma(T x, U y, V z) { return functions::fma(x, y, z); }
2101  inline expr fma(half x, half y, half z) { return functions::fma(x, y, z); }
2102  inline expr fma(half x, half y, expr z) { return functions::fma(x, y, z); }
2103  inline expr fma(half x, expr y, half z) { return functions::fma(x, y, z); }
2104  inline expr fma(half x, expr y, expr z) { return functions::fma(x, y, z); }
2105  inline expr fma(expr x, half y, half z) { return functions::fma(x, y, z); }
2106  inline expr fma(expr x, half y, expr z) { return functions::fma(x, y, z); }
2107  inline expr fma(expr x, expr y, half z) { return functions::fma(x, y, z); }
2108  inline expr fma(expr x, expr y, expr z) { return functions::fma(x, y, z); }
2109 
2114 // template<typename T,typename U> typename result<T,U>::type fmax(T x, U y) { return binary_specialized<T,U>::fmax(x, y); }
2115  inline half fmax(half x, half y) { return binary_specialized<half,half>::fmax(x, y); }
2116  inline expr fmax(half x, expr y) { return binary_specialized<half,expr>::fmax(x, y); }
2117  inline expr fmax(expr x, half y) { return binary_specialized<expr,half>::fmax(x, y); }
2118  inline expr fmax(expr x, expr y) { return binary_specialized<expr,expr>::fmax(x, y); }
2119 
2124 // template<typename T,typename U> typename result<T,U>::type fmin(T x, U y) { return binary_specialized<T,U>::fmin(x, y); }
2125  inline half fmin(half x, half y) { return binary_specialized<half,half>::fmin(x, y); }
2126  inline expr fmin(half x, expr y) { return binary_specialized<half,expr>::fmin(x, y); }
2127  inline expr fmin(expr x, half y) { return binary_specialized<expr,half>::fmin(x, y); }
2128  inline expr fmin(expr x, expr y) { return binary_specialized<expr,expr>::fmin(x, y); }
2129 
2134 // template<typename T,typename U> typename enable<expr,T,U>::type fdim(T x, U y) { return functions::fdim(x, y); }
2135  inline expr fdim(half x, half y) { return functions::fdim(x, y); }
2136  inline expr fdim(half x, expr y) { return functions::fdim(x, y); }
2137  inline expr fdim(expr x, half y) { return functions::fdim(x, y); }
2138  inline expr fdim(expr x, expr y) { return functions::fdim(x, y); }
2139 
2143  inline half nanh(const char *arg) { return functions::nanh(arg); }
2144 
2148 
2152 // template<typename T> typename enable<expr,T>::type exp(T arg) { return functions::exp(arg); }
2153  inline expr exp(half arg) { return functions::exp(arg); }
2154  inline expr exp(expr arg) { return functions::exp(arg); }
2155 
2159 // template<typename T> typename enable<expr,T>::type expm1(T arg) { return functions::expm1(arg); }
2160  inline expr expm1(half arg) { return functions::expm1(arg); }
2161  inline expr expm1(expr arg) { return functions::expm1(arg); }
2162 
2166 // template<typename T> typename enable<expr,T>::type exp2(T arg) { return functions::exp2(arg); }
2167  inline expr exp2(half arg) { return functions::exp2(arg); }
2168  inline expr exp2(expr arg) { return functions::exp2(arg); }
2169 
2173 // template<typename T> typename enable<expr,T>::type log(T arg) { return functions::log(arg); }
2174  inline expr log(half arg) { return functions::log(arg); }
2175  inline expr log(expr arg) { return functions::log(arg); }
2176 
2180 // template<typename T> typename enable<expr,T>::type log10(T arg) { return functions::log10(arg); }
2181  inline expr log10(half arg) { return functions::log10(arg); }
2182  inline expr log10(expr arg) { return functions::log10(arg); }
2183 
2187 // template<typename T> typename enable<expr,T>::type log1p(T arg) { return functions::log1p(arg); }
2188  inline expr log1p(half arg) { return functions::log1p(arg); }
2189  inline expr log1p(expr arg) { return functions::log1p(arg); }
2190 
2194 // template<typename T> typename enable<expr,T>::type log2(T arg) { return functions::log2(arg); }
2195  inline expr log2(half arg) { return functions::log2(arg); }
2196  inline expr log2(expr arg) { return functions::log2(arg); }
2197 
2201 
2205 // template<typename T> typename enable<expr,T>::type sqrt(T arg) { return functions::sqrt(arg); }
2206  inline expr sqrt(half arg) { return functions::sqrt(arg); }
2207  inline expr sqrt(expr arg) { return functions::sqrt(arg); }
2208 
2212 // template<typename T> typename enable<expr,T>::type cbrt(T arg) { return functions::cbrt(arg); }
2213  inline expr cbrt(half arg) { return functions::cbrt(arg); }
2214  inline expr cbrt(expr arg) { return functions::cbrt(arg); }
2215 
2220 // template<typename T,typename U> typename enable<expr,T,U>::type hypot(T x, U y) { return functions::hypot(x, y); }
2221  inline expr hypot(half x, half y) { return functions::hypot(x, y); }
2222  inline expr hypot(half x, expr y) { return functions::hypot(x, y); }
2223  inline expr hypot(expr x, half y) { return functions::hypot(x, y); }
2224  inline expr hypot(expr x, expr y) { return functions::hypot(x, y); }
2225 
2230 // template<typename T,typename U> typename enable<expr,T,U>::type pow(T base, U exp) { return functions::pow(base, exp); }
2231  inline expr pow(half base, half exp) { return functions::pow(base, exp); }
2232  inline expr pow(half base, expr exp) { return functions::pow(base, exp); }
2233  inline expr pow(expr base, half exp) { return functions::pow(base, exp); }
2234  inline expr pow(expr base, expr exp) { return functions::pow(base, exp); }
2235 
2239 
2243 // template<typename T> typename enable<expr,T>::type sin(T arg) { return functions::sin(arg); }
2244  inline expr sin(half arg) { return functions::sin(arg); }
2245  inline expr sin(expr arg) { return functions::sin(arg); }
2246 
2250 // template<typename T> typename enable<expr,T>::type cos(T arg) { return functions::cos(arg); }
2251  inline expr cos(half arg) { return functions::cos(arg); }
2252  inline expr cos(expr arg) { return functions::cos(arg); }
2253 
2257 // template<typename T> typename enable<expr,T>::type tan(T arg) { return functions::tan(arg); }
2258  inline expr tan(half arg) { return functions::tan(arg); }
2259  inline expr tan(expr arg) { return functions::tan(arg); }
2260 
2264 // template<typename T> typename enable<expr,T>::type asin(T arg) { return functions::asin(arg); }
2265  inline expr asin(half arg) { return functions::asin(arg); }
2266  inline expr asin(expr arg) { return functions::asin(arg); }
2267 
2271 // template<typename T> typename enable<expr,T>::type acos(T arg) { return functions::acos(arg); }
2272  inline expr acos(half arg) { return functions::acos(arg); }
2273  inline expr acos(expr arg) { return functions::acos(arg); }
2274 
2278 // template<typename T> typename enable<expr,T>::type atan(T arg) { return functions::atan(arg); }
2279  inline expr atan(half arg) { return functions::atan(arg); }
2280  inline expr atan(expr arg) { return functions::atan(arg); }
2281 
2286 // template<typename T,typename U> typename enable<expr,T,U>::type atan2(T x, U y) { return functions::atan2(x, y); }
2287  inline expr atan2(half x, half y) { return functions::atan2(x, y); }
2288  inline expr atan2(half x, expr y) { return functions::atan2(x, y); }
2289  inline expr atan2(expr x, half y) { return functions::atan2(x, y); }
2290  inline expr atan2(expr x, expr y) { return functions::atan2(x, y); }
2291 
2295 
2299 // template<typename T> typename enable<expr,T>::type sinh(T arg) { return functions::sinh(arg); }
2300  inline expr sinh(half arg) { return functions::sinh(arg); }
2301  inline expr sinh(expr arg) { return functions::sinh(arg); }
2302 
2306 // template<typename T> typename enable<expr,T>::type cosh(T arg) { return functions::cosh(arg); }
2307  inline expr cosh(half arg) { return functions::cosh(arg); }
2308  inline expr cosh(expr arg) { return functions::cosh(arg); }
2309 
2313 // template<typename T> typename enable<expr,T>::type tanh(T arg) { return functions::tanh(arg); }
2314  inline expr tanh(half arg) { return functions::tanh(arg); }
2315  inline expr tanh(expr arg) { return functions::tanh(arg); }
2316 
2320 // template<typename T> typename enable<expr,T>::type asinh(T arg) { return functions::asinh(arg); }
2321  inline expr asinh(half arg) { return functions::asinh(arg); }
2322  inline expr asinh(expr arg) { return functions::asinh(arg); }
2323 
2327 // template<typename T> typename enable<expr,T>::type acosh(T arg) { return functions::acosh(arg); }
2328  inline expr acosh(half arg) { return functions::acosh(arg); }
2329  inline expr acosh(expr arg) { return functions::acosh(arg); }
2330 
2334 // template<typename T> typename enable<expr,T>::type atanh(T arg) { return functions::atanh(arg); }
2335  inline expr atanh(half arg) { return functions::atanh(arg); }
2336  inline expr atanh(expr arg) { return functions::atanh(arg); }
2337 
2341 
2345 // template<typename T> typename enable<expr,T>::type erf(T arg) { return functions::erf(arg); }
2346  inline expr erf(half arg) { return functions::erf(arg); }
2347  inline expr erf(expr arg) { return functions::erf(arg); }
2348 
2352 // template<typename T> typename enable<expr,T>::type erfc(T arg) { return functions::erfc(arg); }
2353  inline expr erfc(half arg) { return functions::erfc(arg); }
2354  inline expr erfc(expr arg) { return functions::erfc(arg); }
2355 
2359 // template<typename T> typename enable<expr,T>::type lgamma(T arg) { return functions::lgamma(arg); }
2360  inline expr lgamma(half arg) { return functions::lgamma(arg); }
2361  inline expr lgamma(expr arg) { return functions::lgamma(arg); }
2362 
2366 // template<typename T> typename enable<expr,T>::type tgamma(T arg) { return functions::tgamma(arg); }
2367  inline expr tgamma(half arg) { return functions::tgamma(arg); }
2368  inline expr tgamma(expr arg) { return functions::tgamma(arg); }
2369 
2373 
2377 // template<typename T> typename enable<half,T>::type ceil(T arg) { return functions::ceil(arg); }
2378  inline half ceil(half arg) { return functions::ceil(arg); }
2379  inline half ceil(expr arg) { return functions::ceil(arg); }
2380 
2384 // template<typename T> typename enable<half,T>::type floor(T arg) { return functions::floor(arg); }
2385  inline half floor(half arg) { return functions::floor(arg); }
2386  inline half floor(expr arg) { return functions::floor(arg); }
2387 
2391 // template<typename T> typename enable<half,T>::type trunc(T arg) { return functions::trunc(arg); }
2392  inline half trunc(half arg) { return functions::trunc(arg); }
2393  inline half trunc(expr arg) { return functions::trunc(arg); }
2394 
2398 // template<typename T> typename enable<half,T>::type round(T arg) { return functions::round(arg); }
2399  inline half round(half arg) { return functions::round(arg); }
2400  inline half round(expr arg) { return functions::round(arg); }
2401 
2405 // template<typename T> typename enable<long,T>::type lround(T arg) { return functions::lround(arg); }
2406  inline long lround(half arg) { return functions::lround(arg); }
2407  inline long lround(expr arg) { return functions::lround(arg); }
2408 
2412 // template<typename T> typename enable<half,T>::type nearbyint(T arg) { return functions::nearbyint(arg); }
2413  inline half nearbyint(half arg) { return functions::rint(arg); }
2414  inline half nearbyint(expr arg) { return functions::rint(arg); }
2415 
2419 // template<typename T> typename enable<half,T>::type rint(T arg) { return functions::rint(arg); }
2420  inline half rint(half arg) { return functions::rint(arg); }
2421  inline half rint(expr arg) { return functions::rint(arg); }
2422 
2426 // template<typename T> typename enable<long,T>::type lrint(T arg) { return functions::lrint(arg); }
2427  inline long lrint(half arg) { return functions::lrint(arg); }
2428  inline long lrint(expr arg) { return functions::lrint(arg); }
2429  #if HALF_ENABLE_CPP11_LONG_LONG
2430 // template<typename T> typename enable<long long,T>::type llround(T arg) { return functions::llround(arg); }
2434  inline long long llround(half arg) { return functions::llround(arg); }
2435  inline long long llround(expr arg) { return functions::llround(arg); }
2436 
2440 // template<typename T> typename enable<long long,T>::type llrint(T arg) { return functions::llrint(arg); }
2441  inline long long llrint(half arg) { return functions::llrint(arg); }
2442  inline long long llrint(expr arg) { return functions::llrint(arg); }
2443  #endif
2444 
2448 
2453 // template<typename T> typename enable<half,T>::type frexp(T arg, int *exp) { return functions::frexp(arg, exp); }
2454  inline half frexp(half arg, int *exp) { return functions::frexp(arg, exp); }
2455  inline half frexp(expr arg, int *exp) { return functions::frexp(arg, exp); }
2456 
2461 // template<typename T> typename enable<half,T>::type ldexp(T arg, int exp) { return functions::scalbln(arg, exp); }
2462  inline half ldexp(half arg, int exp) { return functions::scalbln(arg, exp); }
2463  inline half ldexp(expr arg, int exp) { return functions::scalbln(arg, exp); }
2464 
2469 // template<typename T> typename enable<half,T>::type modf(T arg, half *iptr) { return functions::modf(arg, iptr); }
2470  inline half modf(half arg, half *iptr) { return functions::modf(arg, iptr); }
2471  inline half modf(expr arg, half *iptr) { return functions::modf(arg, iptr); }
2472 
2477 // template<typename T> typename enable<half,T>::type scalbn(T arg, int exp) { return functions::scalbln(arg, exp); }
2478  inline half scalbn(half arg, int exp) { return functions::scalbln(arg, exp); }
2479  inline half scalbn(expr arg, int exp) { return functions::scalbln(arg, exp); }
2480 
2485 // template<typename T> typename enable<half,T>::type scalbln(T arg, long exp) { return functions::scalbln(arg, exp); }
2486  inline half scalbln(half arg, long exp) { return functions::scalbln(arg, exp); }
2487  inline half scalbln(expr arg, long exp) { return functions::scalbln(arg, exp); }
2488 
2495 // template<typename T> typename enable<int,T>::type ilogb(T arg) { return functions::ilogb(arg); }
2496  inline int ilogb(half arg) { return functions::ilogb(arg); }
2497  inline int ilogb(expr arg) { return functions::ilogb(arg); }
2498 
2502 // template<typename T> typename enable<half,T>::type logb(T arg) { return functions::logb(arg); }
2503  inline half logb(half arg) { return functions::logb(arg); }
2504  inline half logb(expr arg) { return functions::logb(arg); }
2505 
2510 // template<typename T,typename U> typename enable<half,T,U>::type nextafter(T from, U to) { return functions::nextafter(from, to); }
2511  inline half nextafter(half from, half to) { return functions::nextafter(from, to); }
2512  inline half nextafter(half from, expr to) { return functions::nextafter(from, to); }
2513  inline half nextafter(expr from, half to) { return functions::nextafter(from, to); }
2514  inline half nextafter(expr from, expr to) { return functions::nextafter(from, to); }
2515 
2520 // template<typename T> typename enable<half,T>::type nexttoward(T from, long double to) { return functions::nexttoward(from, to); }
2521  inline half nexttoward(half from, long double to) { return functions::nexttoward(from, to); }
2522  inline half nexttoward(expr from, long double to) { return functions::nexttoward(from, to); }
2523 
2528 // template<typename T,typename U> typename enable<half,T,U>::type copysign(T x, U y) { return functions::copysign(x, y); }
2529  inline half copysign(half x, half y) { return functions::copysign(x, y); }
2530  inline half copysign(half x, expr y) { return functions::copysign(x, y); }
2531  inline half copysign(expr x, half y) { return functions::copysign(x, y); }
2532  inline half copysign(expr x, expr y) { return functions::copysign(x, y); }
2533 
2537 
2538 
2546 // template<typename T> typename enable<int,T>::type fpclassify(T arg) { return functions::fpclassify(arg); }
2547  inline int fpclassify(half arg) { return functions::fpclassify(arg); }
2548  inline int fpclassify(expr arg) { return functions::fpclassify(arg); }
2549 
2554 // template<typename T> typename enable<bool,T>::type isfinite(T arg) { return functions::isfinite(arg); }
2555  inline bool isfinite(half arg) { return functions::isfinite(arg); }
2556  inline bool isfinite(expr arg) { return functions::isfinite(arg); }
2557 
2562 // template<typename T> typename enable<bool,T>::type isinf(T arg) { return functions::isinf(arg); }
2563  inline bool isinf(half arg) { return functions::isinf(arg); }
2564  inline bool isinf(expr arg) { return functions::isinf(arg); }
2565 
2570 // template<typename T> typename enable<bool,T>::type isnan(T arg) { return functions::isnan(arg); }
2571  inline bool isnan(half arg) { return functions::isnan(arg); }
2572  inline bool isnan(expr arg) { return functions::isnan(arg); }
2573 
2578 // template<typename T> typename enable<bool,T>::type isnormal(T arg) { return functions::isnormal(arg); }
2579  inline bool isnormal(half arg) { return functions::isnormal(arg); }
2580  inline bool isnormal(expr arg) { return functions::isnormal(arg); }
2581 
2586 // template<typename T> typename enable<bool,T>::type signbit(T arg) { return functions::signbit(arg); }
2587  inline bool signbit(half arg) { return functions::signbit(arg); }
2588  inline bool signbit(expr arg) { return functions::signbit(arg); }
2589 
2593 
2599 // template<typename T,typename U> typename enable<bool,T,U>::type isgreater(T x, U y) { return functions::isgreater(x, y); }
2600  inline bool isgreater(half x, half y) { return functions::isgreater(x, y); }
2601  inline bool isgreater(half x, expr y) { return functions::isgreater(x, y); }
2602  inline bool isgreater(expr x, half y) { return functions::isgreater(x, y); }
2603  inline bool isgreater(expr x, expr y) { return functions::isgreater(x, y); }
2604 
2610 // template<typename T,typename U> typename enable<bool,T,U>::type isgreaterequal(T x, U y) { return functions::isgreaterequal(x, y); }
2611  inline bool isgreaterequal(half x, half y) { return functions::isgreaterequal(x, y); }
2612  inline bool isgreaterequal(half x, expr y) { return functions::isgreaterequal(x, y); }
2613  inline bool isgreaterequal(expr x, half y) { return functions::isgreaterequal(x, y); }
2614  inline bool isgreaterequal(expr x, expr y) { return functions::isgreaterequal(x, y); }
2615 
2621 // template<typename T,typename U> typename enable<bool,T,U>::type isless(T x, U y) { return functions::isless(x, y); }
2622  inline bool isless(half x, half y) { return functions::isless(x, y); }
2623  inline bool isless(half x, expr y) { return functions::isless(x, y); }
2624  inline bool isless(expr x, half y) { return functions::isless(x, y); }
2625  inline bool isless(expr x, expr y) { return functions::isless(x, y); }
2626 
2632 // template<typename T,typename U> typename enable<bool,T,U>::type islessequal(T x, U y) { return functions::islessequal(x, y); }
2633  inline bool islessequal(half x, half y) { return functions::islessequal(x, y); }
2634  inline bool islessequal(half x, expr y) { return functions::islessequal(x, y); }
2635  inline bool islessequal(expr x, half y) { return functions::islessequal(x, y); }
2636  inline bool islessequal(expr x, expr y) { return functions::islessequal(x, y); }
2637 
2643 // template<typename T,typename U> typename enable<bool,T,U>::type islessgreater(T x, U y) { return functions::islessgreater(x, y); }
2644  inline bool islessgreater(half x, half y) { return functions::islessgreater(x, y); }
2645  inline bool islessgreater(half x, expr y) { return functions::islessgreater(x, y); }
2646  inline bool islessgreater(expr x, half y) { return functions::islessgreater(x, y); }
2647  inline bool islessgreater(expr x, expr y) { return functions::islessgreater(x, y); }
2648 
2654 // template<typename T,typename U> typename enable<bool,T,U>::type isunordered(T x, U y) { return functions::isunordered(x, y); }
2655  inline bool isunordered(half x, half y) { return functions::isunordered(x, y); }
2656  inline bool isunordered(half x, expr y) { return functions::isunordered(x, y); }
2657  inline bool isunordered(expr x, half y) { return functions::isunordered(x, y); }
2658  inline bool isunordered(expr x, expr y) { return functions::isunordered(x, y); }
2659 
2662 
2677  template<typename T,typename U> typename half_caster<T,U>::type half_cast(U arg) { return half_caster<T,U>::cast(arg); }
2678 
2694  template<typename T,std::float_round_style R,typename U> typename half_caster<T,U,R>::type half_cast(U arg)
2695  { return half_caster<T,U,R>::cast(arg); }
2697  }
2698 
2699  using detail::operator==;
2700  using detail::operator!=;
2701  using detail::operator<;
2702  using detail::operator>;
2703  using detail::operator<=;
2704  using detail::operator>=;
2705  using detail::operator+;
2706  using detail::operator-;
2707  using detail::operator*;
2708  using detail::operator/;
2709  using detail::operator<<;
2710  using detail::operator>>;
2711 
2712  using detail::abs;
2713  using detail::fabs;
2714  using detail::fmod;
2715  using detail::remainder;
2716  using detail::remquo;
2717  using detail::fma;
2718  using detail::fmax;
2719  using detail::fmin;
2720  using detail::fdim;
2721  using detail::nanh;
2722  using detail::exp;
2723  using detail::expm1;
2724  using detail::exp2;
2725  using detail::log;
2726  using detail::log10;
2727  using detail::log1p;
2728  using detail::log2;
2729  using detail::sqrt;
2730  using detail::cbrt;
2731  using detail::hypot;
2732  using detail::pow;
2733  using detail::sin;
2734  using detail::cos;
2735  using detail::tan;
2736  using detail::asin;
2737  using detail::acos;
2738  using detail::atan;
2739  using detail::atan2;
2740  using detail::sinh;
2741  using detail::cosh;
2742  using detail::tanh;
2743  using detail::asinh;
2744  using detail::acosh;
2745  using detail::atanh;
2746  using detail::erf;
2747  using detail::erfc;
2748  using detail::lgamma;
2749  using detail::tgamma;
2750  using detail::ceil;
2751  using detail::floor;
2752  using detail::trunc;
2753  using detail::round;
2754  using detail::lround;
2755  using detail::nearbyint;
2756  using detail::rint;
2757  using detail::lrint;
2758 #if HALF_ENABLE_CPP11_LONG_LONG
2759  using detail::llround;
2760  using detail::llrint;
2761 #endif
2762  using detail::frexp;
2763  using detail::ldexp;
2764  using detail::modf;
2765  using detail::scalbn;
2766  using detail::scalbln;
2767  using detail::ilogb;
2768  using detail::logb;
2769  using detail::nextafter;
2770  using detail::nexttoward;
2771  using detail::copysign;
2772  using detail::fpclassify;
2773  using detail::isfinite;
2774  using detail::isinf;
2775  using detail::isnan;
2776  using detail::isnormal;
2777  using detail::signbit;
2778  using detail::isgreater;
2779  using detail::isgreaterequal;
2780  using detail::isless;
2781  using detail::islessequal;
2782  using detail::islessgreater;
2783  using detail::isunordered;
2784 
2785  using detail::half_cast;
2786 }
2787 
2788 
2790 namespace std
2791 {
2795  template<> class numeric_limits<half_float::half> : public numeric_limits<float>
2796  {
2797  public:
2799  static HALF_CONSTEXPR_CONST bool is_signed = true;
2800 
2802  static HALF_CONSTEXPR_CONST bool is_exact = false;
2803 
2805  static HALF_CONSTEXPR_CONST bool is_modulo = false;
2806 
2808  static HALF_CONSTEXPR_CONST bool is_iec559 = true;
2809 
2811  static HALF_CONSTEXPR_CONST bool has_infinity = true;
2812 
2814  static HALF_CONSTEXPR_CONST bool has_quiet_NaN = true;
2815 
2817  static HALF_CONSTEXPR_CONST float_denorm_style has_denorm = denorm_present;
2818 
2823  static HALF_CONSTEXPR_CONST float_round_style round_style = (std::numeric_limits<float>::round_style==
2824  half_float::half::round_style) ? half_float::half::round_style : round_indeterminate;
2825 
2827  static HALF_CONSTEXPR_CONST int digits = 11;
2828 
2830  static HALF_CONSTEXPR_CONST int digits10 = 3;
2831 
2833  static HALF_CONSTEXPR_CONST int max_digits10 = 5;
2834 
2836  static HALF_CONSTEXPR_CONST int radix = 2;
2837 
2839  static HALF_CONSTEXPR_CONST int min_exponent = -13;
2840 
2842  static HALF_CONSTEXPR_CONST int min_exponent10 = -4;
2843 
2845  static HALF_CONSTEXPR_CONST int max_exponent = 16;
2846 
2848  static HALF_CONSTEXPR_CONST int max_exponent10 = 4;
2849 
2852 
2855 
2858 
2861 
2864  { return half_float::half(half_float::detail::binary, (round_style==std::round_to_nearest) ? 0x3800 : 0x3C00); }
2865 
2868 
2871 
2874 
2877  };
2878 
2879 #if HALF_ENABLE_CPP11_HASH
2880  template<> struct hash<half_float::half> //: unary_function<half_float::half,size_t>
2883  {
2885  typedef half_float::half argument_type;
2886 
2888  typedef size_t result_type;
2889 
2893  result_type operator()(argument_type arg) const
2894  { return hash<half_float::detail::uint16>()(static_cast<unsigned int>(arg.data_)&-(arg.data_!=0x8000)); }
2895  };
2896 #endif
2897 }
2898 
2899 
2900 #undef HALF_CONSTEXPR
2901 #undef HALF_CONSTEXPR_CONST
2902 #undef HALF_NOEXCEPT
2903 #undef HALF_NOTHROW
2904 #ifdef HALF_POP_WARNINGS
2905  #pragma warning(pop)
2906  #undef HALF_POP_WARNINGS
2907 #endif
2908 
2909 #endif
half rint(half arg)
Definition: Half.h:2420
expr atan(expr arg)
Definition: Half.h:2280
expr erfc(half arg)
Definition: Half.h:2353
#define FP_SUBNORMAL
Definition: Half.h:234
expr atanh(expr arg)
Definition: Half.h:2336
static expr pow(float base, float exp)
Definition: Half.h:1308
expr asinh(expr arg)
Definition: Half.h:2322
static half rint(half arg)
Definition: Half.h:1500
Definition: Half.h:319
static HALF_CONSTEXPR half_float::half quiet_NaN() HALF_NOTHROW
Quiet NaN.
Definition: Half.h:2870
bool isinf(half arg)
Definition: Half.h:2563
static int ilogb(half arg)
Definition: Half.h:1612
#define FP_NAN
Definition: Half.h:240
half nextafter(half from, half to)
Definition: Half.h:2511
expr asin(expr arg)
Definition: Half.h:2266
std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &in, half &arg)
Definition: Half.h:2044
#define HALF_NOTHROW
Definition: Half.h:167
static expr atan2(float x, float y)
Definition: Half.h:1344
expr tgamma(half arg)
Definition: Half.h:2367
Definition: Half.h:338
expr atan2(half x, half y)
Definition: Half.h:2287
static half ceil(half arg)
Definition: Half.h:1480
static expr remainder(float x, float y)
Definition: Half.h:1103
static expr asinh(float arg)
Definition: Half.h:1364
T type
Definition: Half.h:273
static expr remquo(float x, float y, int *quo)
Definition: Half.h:1134
long lround(half arg)
Definition: Half.h:2406
expr sinh(half arg)
Definition: Half.h:2300
T half2int_impl(uint16 value)
Definition: Half.h:793
static half trunc(half arg)
Definition: Half.h:1485
static bool isnormal(half arg)
Definition: Half.h:1725
uint16 int2half(T value)
Definition: Half.h:601
static half round(half arg)
Definition: Half.h:1490
expr asinh(half arg)
Definition: Half.h:2321
expr cbrt(half arg)
Definition: Half.h:2213
expr pow(half base, half exp)
Definition: Half.h:2231
#define HALF_ROUND_STYLE
Definition: Half.h:204
expr acos(expr arg)
Definition: Half.h:2273
#define FP_ILOGB0
Definition: Half.h:228
half_caster< T, U >::type half_cast(U arg)
Definition: Half.h:2677
static HALF_CONSTEXPR half_float::half max() HALF_NOTHROW
Largest finite value.
Definition: Half.h:2857
half trunc(half arg)
Definition: Half.h:2392
expr expm1(half arg)
Definition: Half.h:2160
uint16 int2half_impl(T value)
Definition: Half.h:559
static long lrint(half arg)
Definition: Half.h:1505
uint16 float2half(float value)
Definition: Half.h:548
expr fdim(half x, half y)
Definition: Half.h:2135
Definition: Half.h:915
half(detail::expr rhs)
Definition: Half.h:935
static expr tan(float arg)
Definition: Half.h:1323
half & operator=(float rhs)
Definition: Half.h:978
expr sqrt(expr arg)
Definition: Half.h:2207
expr erf(expr arg)
Definition: Half.h:2347
half(float rhs)
Definition: Half.h:939
half copysign(half x, half y)
Definition: Half.h:2529
expr acosh(half arg)
Definition: Half.h:2328
half nanh(const char *arg)
Definition: Half.h:2143
expr atanh(half arg)
Definition: Half.h:2335
expr tan(expr arg)
Definition: Half.h:2259
static bool islessequal(half x, half y)
Definition: Half.h:1776
half ldexp(half arg, int exp)
Definition: Half.h:2462
bool isless(half x, half y)
Definition: Half.h:2622
expr tanh(half arg)
Definition: Half.h:2314
half fmax(half x, half y)
Definition: Half.h:2115
enable< bool, T, U >::type operator>=(T x, U y)
Definition: Half.h:1988
static expr log1p(float arg)
Definition: Half.h:1249
detail::enable< half &, T >::type operator-=(T rhs)
Definition: Half.h:961
expr tanh(expr arg)
Definition: Half.h:2315
expr fabs(expr arg)
Definition: Half.h:2062
Extensions to the C++ standard library.
Definition: Half.h:2790
expr exp2(expr arg)
Definition: Half.h:2168
static bool isfinite(half arg)
Definition: Half.h:1707
expr sin(half arg)
Definition: Half.h:2244
expr fma(half x, half y, half z)
Definition: Half.h:2101
bool signbit(expr arg)
Definition: Half.h:2588
static half fmin(half x, half y)
Definition: Half.h:1884
unsigned int
Definition: Half.h:305
expr fma(expr x, expr y, expr z)
Definition: Half.h:2108
half nexttoward(half from, long double to)
Definition: Half.h:2521
T half2int_up(uint16 value)
Definition: Half.h:841
static expr cbrt(float arg)
Definition: Half.h:1278
static HALF_CONSTEXPR half_float::half epsilon() HALF_NOTHROW
Difference between one and next representable value.
Definition: Half.h:2860
expr expm1(expr arg)
Definition: Half.h:2161
enable< expr, T, U >::type operator*(T x, U y)
Definition: Half.h:2010
static std::basic_istream< charT, traits > & read(std::basic_istream< charT, traits > &in, half &arg)
Definition: Half.h:1085
#define HALF_ROUND_TIES_TO_EVEN
Definition: Half.h:213
static half floor(half arg)
Definition: Half.h:1475
static half nanh(const char *)
Definition: Half.h:1205
half scalbn(half arg, int exp)
Definition: Half.h:2478
expr sin(expr arg)
Definition: Half.h:2245
half ceil(half arg)
Definition: Half.h:2378
static half frexp(half arg, int *exp)
Definition: Half.h:1523
detail::enable< half &, T >::type operator+=(T rhs)
Definition: Half.h:955
half fabs(half arg)
Definition: Half.h:2061
half & operator=(detail::expr rhs)
Definition: Half.h:949
long const char const char const char const char *typedef void(CALL_CONVENTION *func_type_com_asprise_ocr_stop)(long long)
Definition: asprise_ocr_api.h:201
static expr exp2(float arg)
Definition: Half.h:1227
half frexp(expr arg, int *exp)
Definition: Half.h:2455
static half fabs(half arg)
Definition: Half.h:1835
bool builtin_signbit(T arg)
Definition: Half.h:402
static long lround(half arg)
Definition: Half.h:1495
expr tan(half arg)
Definition: Half.h:2258
static bool isinf(half arg)
Definition: Half.h:1713
half nearbyint(half arg)
Definition: Half.h:2413
expr acos(half arg)
Definition: Half.h:2272
static expr acosh(float arg)
Definition: Half.h:1376
expr fmod(expr x, expr y)
Definition: Half.h:2072
half & operator-=(float rhs)
Definition: Half.h:988
static bool isnotequal(half x, half y)
Definition: Half.h:1745
bool isnan(expr arg)
Definition: Half.h:2572
half type
Definition: Half.h:360
bool isgreaterequal(half x, half y)
Definition: Half.h:2611
half & operator/=(float rhs)
Definition: Half.h:998
static expr expm1(float arg)
Definition: Half.h:1215
Tag type for binary construction.
Definition: Half.h:312
expr erf(half arg)
Definition: Half.h:2346
static expr log2(float arg)
Definition: Half.h:1261
static expr fmin(float x, float y)
Definition: Half.h:1852
static HALF_CONSTEXPR half_float::half signaling_NaN() HALF_NOTHROW
Signalling NaN.
Definition: Half.h:2873
expr exp(half arg)
Definition: Half.h:2153
expr atan(half arg)
Definition: Half.h:2279
expr pow(expr base, expr exp)
Definition: Half.h:2234
float half2float_impl(uint16 value, true_type)
Definition: Half.h:610
expr abs(expr arg)
Definition: Half.h:2055
uint16 round_half_up(uint16 value)
Definition: Half.h:886
float half2float(uint16 value)
Definition: Half.h:782
#define FP_NORMAL
Definition: Half.h:246
HALF_CONSTEXPR expr(float f)
Definition: Half.h:323
expr cos(expr arg)
Definition: Half.h:2252
expr cbrt(expr arg)
Definition: Half.h:2214
expr log(half arg)
Definition: Half.h:2174
static expr tgamma(float arg)
Definition: Half.h:1448
static half nextafter(half from, half to)
Definition: Half.h:1651
static std::basic_ostream< charT, traits > & write(std::basic_ostream< charT, traits > &out, float arg)
Definition: Half.h:1079
long lrint(half arg)
Definition: Half.h:2427
expr fmin(expr x, expr y)
Definition: Half.h:2128
static expr hypot(float x, float y)
Definition: Half.h:1294
half & operator++()
Definition: Half.h:1002
unsigned short uint16
Unsigned integer of (at least) 16 bits width.
Definition: Half.h:302
enable< bool, T, U >::type operator<=(T x, U y)
Definition: Half.h:1981
int fpclassify(half arg)
Definition: Half.h:2547
HALF_CONSTEXPR_CONST binary_t binary
Tag for binary construction.
Definition: Half.h:315
static expr fdim(float x, float y)
Definition: Half.h:1180
uint16 round_half_impl(uint16 value)
Definition: Half.h:848
half logb(half arg)
Definition: Half.h:2503
static expr tanh(float arg)
Definition: Half.h:1359
bool builtin_isinf(T arg)
Definition: Half.h:370
expr fdim(expr x, expr y)
Definition: Half.h:2138
static half cast(U arg)
Definition: Half.h:1918
bool isnan(half arg)
Definition: Half.h:2571
static expr cosh(float arg)
Definition: Half.h:1354
static expr fabs(float arg)
Definition: Half.h:1840
static bool isgreater(half x, half y)
Definition: Half.h:1752
expr erfc(expr arg)
Definition: Half.h:2354
bool isgreater(half x, half y)
Definition: Half.h:2600
half modf(expr arg, half *iptr)
Definition: Half.h:2471
#define HALF_CONSTEXPR
Definition: Half.h:157
static HALF_CONSTEXPR half_float::half round_error() HALF_NOTHROW
Maximum rounding error.
Definition: Half.h:2863
expr remainder(expr x, expr y)
Definition: Half.h:2082
half operator--(int)
Definition: Half.h:1014
half abs(half arg)
Definition: Half.h:2054
Definition: Half.h:892
static expr fmax(float x, float y)
Definition: Half.h:1869
static HALF_CONSTEXPR expr negate(float arg)
Definition: Half.h:1839
half scalbln(half arg, long exp)
Definition: Half.h:2486
expr lgamma(expr arg)
Definition: Half.h:2361
Helper for tag dispatching.
Definition: Half.h:277
static HALF_CONSTEXPR half_float::half min() HALF_NOTHROW
Smallest positive normal value.
Definition: Half.h:2851
expr acosh(expr arg)
Definition: Half.h:2329
bool builtin_isnan(T arg)
Definition: Half.h:386
expr sinh(expr arg)
Definition: Half.h:2301
#define FP_ILOGBNAN
Definition: Half.h:231
expr cosh(half arg)
Definition: Half.h:2307
HALF_CONSTEXPR half()
Definition: Half.h:930
static expr sqrt(float arg)
Definition: Half.h:1273
expr log1p(half arg)
Definition: Half.h:2188
static expr lgamma(float arg)
Definition: Half.h:1424
half round(half arg)
Definition: Half.h:2399
expr log10(expr arg)
Definition: Half.h:2182
static expr fmod(float x, float y)
Definition: Half.h:1097
expr fmod(half x, half y)
Definition: Half.h:2069
expr tgamma(expr arg)
Definition: Half.h:2368
bool_type< false > false_type
Definition: Half.h:279
bool_type< true > true_type
Definition: Half.h:278
static expr fma(float x, float y, float z)
Definition: Half.h:1194
long::type int17
Definition: Half.h:308
static expr atan(float arg)
Definition: Half.h:1338
static expr erfc(float arg)
Definition: Half.h:1412
bool islessequal(half x, half y)
Definition: Half.h:2633
static expr multiplies(float x, float y)
Definition: Half.h:1067
bool isunordered(half x, half y)
Definition: Half.h:2655
half & operator*=(float rhs)
Definition: Half.h:993
static half nexttoward(half from, long double to)
Definition: Half.h:1669
static bool isequal(half x, half y)
Definition: Half.h:1738
static expr sin(float arg)
Definition: Half.h:1313
static expr log10(float arg)
Definition: Half.h:1244
Definition: Half.h:252
expr cos(half arg)
Definition: Half.h:2251
static HALF_CONSTEXPR half_float::half denorm_min() HALF_NOTHROW
Smallest positive subnormal value.
Definition: Half.h:2876
half operator++(int)
Definition: Half.h:1010
bool isfinite(half arg)
Definition: Half.h:2555
static bool isunordered(half x, half y)
Definition: Half.h:1798
T half2int(uint16 value)
Definition: Half.h:835
static expr erf(float arg)
Definition: Half.h:1400
static HALF_CONSTEXPR half_float::half lowest() HALF_NOTHROW
Smallest finite value.
Definition: Half.h:2854
bool isnormal(half arg)
Definition: Half.h:2579
static expr atanh(float arg)
Definition: Half.h:1388
static HALF_CONSTEXPR half_float::half infinity() HALF_NOTHROW
Positive infinity.
Definition: Half.h:2867
static expr acos(float arg)
Definition: Half.h:1333
half fmin(half x, half y)
Definition: Half.h:2125
static expr log(float arg)
Definition: Half.h:1239
Definition: Half.h:359
static HALF_CONSTEXPR half negate(half arg)
Definition: Half.h:1830
expr log1p(expr arg)
Definition: Half.h:2189
#define FP_INFINITE
Definition: Half.h:243
expr log2(expr arg)
Definition: Half.h:2196
#define HALF_CONSTEXPR_CONST
Definition: Half.h:158
static expr exp(float arg)
Definition: Half.h:1210
static expr cos(float arg)
Definition: Half.h:1318
bool signbit(half arg)
Definition: Half.h:2587
#define FP_ZERO
Definition: Half.h:237
enable< bool, T, U >::type operator>(T x, U y)
Definition: Half.h:1974
half & operator--()
Definition: Half.h:1006
expr hypot(half x, half y)
Definition: Half.h:2221
expr asin(half arg)
Definition: Half.h:2265
uint16 float2half_impl(float value, true_type)
Definition: Half.h:420
expr log(expr arg)
Definition: Half.h:2175
static int fpclassify(half arg)
Definition: Half.h:1691
detail::enable< half &, T >::type operator*=(T rhs)
Definition: Half.h:967
half ldexp(expr arg, int exp)
Definition: Half.h:2463
expr remquo(expr x, expr y, int *quo)
Definition: Half.h:2093
static bool isless(half x, half y)
Definition: Half.h:1768
static half logb(half arg)
Definition: Half.h:1631
static expr minus(float x, float y)
Definition: Half.h:1061
enable< bool, T, U >::type operator<(T x, U y)
Definition: Half.h:1967
unsigned unsigned long::type uint32
Definition: Half.h:305
static expr divides(float x, float y)
Definition: Half.h:1073
enable< expr, T, U >::type operator/(T x, U y)
Definition: Half.h:2016
bool islessgreater(half x, half y)
Definition: Half.h:2644
bool isinf(expr arg)
Definition: Half.h:2564
expr cosh(expr arg)
Definition: Half.h:2308
static expr asin(float arg)
Definition: Half.h:1328
static bool islessgreater(half x, half y)
Definition: Half.h:1784
enable< bool, T, U >::type operator==(T x, U y)
Definition: Half.h:1953
Conditional type.
Definition: Half.h:273
static half copysign(half x, half y)
Definition: Half.h:1685
enable< expr, T, U >::type operator+(T x, U y)
Definition: Half.h:1998
expr lgamma(half arg)
Definition: Half.h:2360
static bool isgreaterequal(half x, half y)
Definition: Half.h:1760
expr sqrt(half arg)
Definition: Half.h:2206
static half cast(half arg)
Definition: Half.h:1941
half modf(half arg, half *iptr)
Definition: Half.h:2470
half & operator+=(float rhs)
Definition: Half.h:983
static half fmax(half x, half y)
Definition: Half.h:1893
static expr plus(float x, float y)
Definition: Half.h:1055
detail::enable< half &, T >::type operator/=(T rhs)
Definition: Half.h:973
long long(CALL_CONVENTION *func_type_com_asprise_ocr_start)(const char *
Definition: asprise_ocr_api.h:200
static half modf(half arg, half *iptr)
Definition: Half.h:1538
static expr sinh(float arg)
Definition: Half.h:1349
half floor(half arg)
Definition: Half.h:2385
static T cast(U arg)
Definition: Half.h:1931
static bool signbit(half arg)
Definition: Half.h:1731
expr fmax(expr x, expr y)
Definition: Half.h:2118
half frexp(half arg, int *exp)
Definition: Half.h:2454
expr exp(expr arg)
Definition: Half.h:2154
int ilogb(half arg)
Definition: Half.h:2496
Type traits for floating point types.
Definition: Half.h:282
expr hypot(expr x, expr y)
Definition: Half.h:2224
static half scalbln(half arg, long exp)
Definition: Half.h:1558
Wrapper implementing unspecialized half-precision functions.
Definition: Half.h:1049
expr atan2(expr x, expr y)
Definition: Half.h:2290
expr remainder(half x, half y)
Definition: Half.h:2079
static bool isnan(half arg)
Definition: Half.h:1719
uint16 round_half(uint16 value)
Definition: Half.h:881
enable< bool, T, U >::type operator!=(T x, U y)
Definition: Half.h:1960
enable< expr, T, U >::type operator-(T x, U y)
Definition: Half.h:2004
expr exp2(half arg)
Definition: Half.h:2167
expr remquo(half x, half y, int *quo)
Definition: Half.h:2090
expr log10(half arg)
Definition: Half.h:2181
expr log2(half arg)
Definition: Half.h:2195