xref: /aosp_15_r20/external/armnn/third-party/half/half.hpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 // half - IEEE 754-based half-precision floating point library.
2 //
3 // Copyright (c) 2012-2017 Christian Rau <[email protected]>
4 //
5 // SPDX-License-Identifier: MIT
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
8 // files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
9 // modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
10 // Software is furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
15 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
17 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 
19 // Version 1.12.0
20 
21 /// \file
22 /// Main header file for half precision functionality.
23 
24 #ifndef HALF_HALF_HPP
25 #define HALF_HALF_HPP
26 
27 /// Combined gcc version number.
28 #define HALF_GNUC_VERSION (__GNUC__*100+__GNUC_MINOR__)
29 
30 //check C++11 language features
31 #if defined(__clang__)										//clang
32 	#if __has_feature(cxx_static_assert) && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
33 		#define HALF_ENABLE_CPP11_STATIC_ASSERT 1
34 	#endif
35 	#if __has_feature(cxx_constexpr) && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
36 		#define HALF_ENABLE_CPP11_CONSTEXPR 1
37 	#endif
38 	#if __has_feature(cxx_noexcept) && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
39 		#define HALF_ENABLE_CPP11_NOEXCEPT 1
40 	#endif
41 	#if __has_feature(cxx_user_literals) && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
42 		#define HALF_ENABLE_CPP11_USER_LITERALS 1
43 	#endif
44 	#if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) && !defined(HALF_ENABLE_CPP11_LONG_LONG)
45 		#define HALF_ENABLE_CPP11_LONG_LONG 1
46 	#endif
47 /*#elif defined(__INTEL_COMPILER)								//Intel C++
48 	#if __INTEL_COMPILER >= 1100 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)		????????
49 		#define HALF_ENABLE_CPP11_STATIC_ASSERT 1
50 	#endif
51 	#if __INTEL_COMPILER >= 1300 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)			????????
52 		#define HALF_ENABLE_CPP11_CONSTEXPR 1
53 	#endif
54 	#if __INTEL_COMPILER >= 1300 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)			????????
55 		#define HALF_ENABLE_CPP11_NOEXCEPT 1
56 	#endif
57 	#if __INTEL_COMPILER >= 1100 && !defined(HALF_ENABLE_CPP11_LONG_LONG)			????????
58 		#define HALF_ENABLE_CPP11_LONG_LONG 1
59 	#endif*/
60 #elif defined(__GNUC__)										//gcc
61 	#if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
62 		#if HALF_GNUC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
63 			#define HALF_ENABLE_CPP11_STATIC_ASSERT 1
64 		#endif
65 		#if HALF_GNUC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
66 			#define HALF_ENABLE_CPP11_CONSTEXPR 1
67 		#endif
68 		#if HALF_GNUC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
69 			#define HALF_ENABLE_CPP11_NOEXCEPT 1
70 		#endif
71 		#if HALF_GNUC_VERSION >= 407 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
72 			#define HALF_ENABLE_CPP11_USER_LITERALS 1
73 		#endif
74 		#if !defined(HALF_ENABLE_CPP11_LONG_LONG)
75 			#define HALF_ENABLE_CPP11_LONG_LONG 1
76 		#endif
77 	#endif
78 #elif defined(_MSC_VER)										//Visual C++
79 	#if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
80 		#define HALF_ENABLE_CPP11_CONSTEXPR 1
81 	#endif
82 	#if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
83 		#define HALF_ENABLE_CPP11_NOEXCEPT 1
84 	#endif
85 	#if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
86 		#define HALF_ENABLE_CPP11_USER_LITERALS 1
87 	#endif
88 	#if _MSC_VER >= 1600 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
89 		#define HALF_ENABLE_CPP11_STATIC_ASSERT 1
90 	#endif
91 	#if _MSC_VER >= 1310 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
92 		#define HALF_ENABLE_CPP11_LONG_LONG 1
93 	#endif
94 	#define HALF_POP_WARNINGS 1
95 	#pragma warning(push)
96 	#pragma warning(disable : 4099 4127 4146)	//struct vs class, constant in if, negative unsigned
97 #endif
98 
99 //check C++11 library features
100 #include <utility>
101 #if defined(_LIBCPP_VERSION)								//libc++
102 	#if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
103 		#ifndef HALF_ENABLE_CPP11_TYPE_TRAITS
104 			#define HALF_ENABLE_CPP11_TYPE_TRAITS 1
105 		#endif
106 		#ifndef HALF_ENABLE_CPP11_CSTDINT
107 			#define HALF_ENABLE_CPP11_CSTDINT 1
108 		#endif
109 		#ifndef HALF_ENABLE_CPP11_CMATH
110 			#define HALF_ENABLE_CPP11_CMATH 1
111 		#endif
112 		#ifndef HALF_ENABLE_CPP11_HASH
113 			#define HALF_ENABLE_CPP11_HASH 1
114 		#endif
115 	#endif
116 #elif defined(__GLIBCXX__)									//libstdc++
117 	#if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
118 		#ifdef __clang__
119 			#if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
120 				#define HALF_ENABLE_CPP11_TYPE_TRAITS 1
121 			#endif
122 			#if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CSTDINT)
123 				#define HALF_ENABLE_CPP11_CSTDINT 1
124 			#endif
125 			#if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CMATH)
126 				#define HALF_ENABLE_CPP11_CMATH 1
127 			#endif
128 			#if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_HASH)
129 				#define HALF_ENABLE_CPP11_HASH 1
130 			#endif
131 		#else
132 			#if HALF_GNUC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CSTDINT)
133 				#define HALF_ENABLE_CPP11_CSTDINT 1
134 			#endif
135 			#if HALF_GNUC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CMATH)
136 				#define HALF_ENABLE_CPP11_CMATH 1
137 			#endif
138 			#if HALF_GNUC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_HASH)
139 				#define HALF_ENABLE_CPP11_HASH 1
140 			#endif
141 		#endif
142 	#endif
143 #elif defined(_CPPLIB_VER)									//Dinkumware/Visual C++
144 	#if _CPPLIB_VER >= 520
145 		#ifndef HALF_ENABLE_CPP11_TYPE_TRAITS
146 			#define HALF_ENABLE_CPP11_TYPE_TRAITS 1
147 		#endif
148 		#ifndef HALF_ENABLE_CPP11_CSTDINT
149 			#define HALF_ENABLE_CPP11_CSTDINT 1
150 		#endif
151 		#ifndef HALF_ENABLE_CPP11_HASH
152 			#define HALF_ENABLE_CPP11_HASH 1
153 		#endif
154 	#endif
155 	#if _CPPLIB_VER >= 610
156 		#ifndef HALF_ENABLE_CPP11_CMATH
157 			#define HALF_ENABLE_CPP11_CMATH 1
158 		#endif
159 	#endif
160 #endif
161 #undef HALF_GNUC_VERSION
162 
163 //support constexpr
164 #if HALF_ENABLE_CPP11_CONSTEXPR
165 	#define HALF_CONSTEXPR			constexpr
166 	#define HALF_CONSTEXPR_CONST	constexpr
167 #else
168 	#define HALF_CONSTEXPR
169 	#define HALF_CONSTEXPR_CONST	const
170 #endif
171 
172 //support noexcept
173 #if HALF_ENABLE_CPP11_NOEXCEPT
174 	#define HALF_NOEXCEPT	noexcept
175 	#define HALF_NOTHROW	noexcept
176 #else
177 	#define HALF_NOEXCEPT
178 	#define HALF_NOTHROW	throw()
179 #endif
180 
181 #include <algorithm>
182 #include <iostream>
183 #include <limits>
184 #include <climits>
185 #include <cmath>
186 #include <cstring>
187 #include <cstdlib>
188 #if HALF_ENABLE_CPP11_TYPE_TRAITS
189 	#include <type_traits>
190 #endif
191 #if HALF_ENABLE_CPP11_CSTDINT
192 	#include <cstdint>
193 #endif
194 #if HALF_ENABLE_CPP11_HASH
195 	#include <functional>
196 #endif
197 
198 
199 /// Default rounding mode.
200 /// This specifies the rounding mode used for all conversions between [half](\ref half_float::half)s and `float`s as well as
201 /// for the half_cast() if not specifying a rounding mode explicitly. It can be redefined (before including half.hpp) to one
202 /// of the standard rounding modes using their respective constants or the equivalent values of `std::float_round_style`:
203 ///
204 /// `std::float_round_style`         | value | rounding
205 /// ---------------------------------|-------|-------------------------
206 /// `std::round_indeterminate`       | -1    | fastest (default)
207 /// `std::round_toward_zero`         | 0     | toward zero
208 /// `std::round_to_nearest`          | 1     | to nearest
209 /// `std::round_toward_infinity`     | 2     | toward positive infinity
210 /// `std::round_toward_neg_infinity` | 3     | toward negative infinity
211 ///
212 /// By default this is set to `-1` (`std::round_indeterminate`), which uses truncation (round toward zero, but with overflows
213 /// set to infinity) and is the fastest rounding mode possible. It can even be set to `std::numeric_limits<float>::round_style`
214 /// to synchronize the rounding mode with that of the underlying single-precision implementation.
215 #ifndef HALF_ROUND_STYLE
216 	#define HALF_ROUND_STYLE	-1			// = std::round_indeterminate
217 #endif
218 
219 /// Tie-breaking behaviour for round to nearest.
220 /// This specifies if ties in round to nearest should be resolved by rounding to the nearest even value. By default this is
221 /// defined to `0` resulting in the faster but slightly more biased behaviour of rounding away from zero in half-way cases (and
222 /// thus equal to the round() function), but can be redefined to `1` (before including half.hpp) if more IEEE-conformant
223 /// behaviour is needed.
224 #ifndef HALF_ROUND_TIES_TO_EVEN
225 	#define HALF_ROUND_TIES_TO_EVEN	0		// ties away from zero
226 #endif
227 
228 /// Value signaling overflow.
229 /// In correspondence with `HUGE_VAL[F|L]` from `<cmath>` this symbol expands to a positive value signaling the overflow of an
230 /// operation, in particular it just evaluates to positive infinity.
231 #define HUGE_VALH	std::numeric_limits<half_float::half>::infinity()
232 
233 /// Fast half-precision fma function.
234 /// This symbol is only defined if the fma() function generally executes as fast as, or faster than, a separate
235 /// half-precision multiplication followed by an addition. Due to the internal single-precision implementation of all
236 /// arithmetic operations, this is in fact always the case.
237 #define FP_FAST_FMAH	1
238 
239 #ifndef FP_ILOGB0
240 	#define FP_ILOGB0		INT_MIN
241 #endif
242 #ifndef FP_ILOGBNAN
243 	#define FP_ILOGBNAN		INT_MAX
244 #endif
245 #ifndef FP_SUBNORMAL
246 	#define FP_SUBNORMAL	0
247 #endif
248 #ifndef FP_ZERO
249 	#define FP_ZERO			1
250 #endif
251 #ifndef FP_NAN
252 	#define FP_NAN			2
253 #endif
254 #ifndef FP_INFINITE
255 	#define FP_INFINITE		3
256 #endif
257 #ifndef FP_NORMAL
258 	#define FP_NORMAL		4
259 #endif
260 
261 
262 /// Main namespace for half precision functionality.
263 /// This namespace contains all the functionality provided by the library.
264 namespace half_float
265 {
266 	class half;
267 
268 #if HALF_ENABLE_CPP11_USER_LITERALS
269 	/// Library-defined half-precision literals.
270 	/// Import this namespace to enable half-precision floating point literals:
271 	/// ~~~~{.cpp}
272 	/// using namespace half_float::literal;
273 	/// half_float::half = 4.2_h;
274 	/// ~~~~
275 	namespace literal
276 	{
277 		half operator""_h(long double);
278 	}
279 #endif
280 
281 	/// \internal
282 	/// \brief Implementation details.
283 	namespace detail
284 	{
285 	#if HALF_ENABLE_CPP11_TYPE_TRAITS
286 		/// Conditional type.
287 		template<bool B,typename T,typename F> struct conditional : std::conditional<B,T,F> {};
288 
289 		/// Helper for tag dispatching.
290 		template<bool B> struct bool_type : std::integral_constant<bool,B> {};
291 		using std::true_type;
292 		using std::false_type;
293 
294 		/// Type traits for floating point types.
295 		template<typename T> struct is_float : std::is_floating_point<T> {};
296 	#else
297 		/// Conditional type.
298 		template<bool,typename T,typename> struct conditional { typedef T type; };
299 		template<typename T,typename F> struct conditional<false,T,F> { typedef F type; };
300 
301 		/// Helper for tag dispatching.
302 		template<bool> struct bool_type {};
303 		typedef bool_type<true> true_type;
304 		typedef bool_type<false> false_type;
305 
306 		/// Type traits for floating point types.
307 		template<typename> struct is_float : false_type {};
308 		template<typename T> struct is_float<const T> : is_float<T> {};
309 		template<typename T> struct is_float<volatile T> : is_float<T> {};
310 		template<typename T> struct is_float<const volatile T> : is_float<T> {};
311 		template<> struct is_float<float> : true_type {};
312 		template<> struct is_float<double> : true_type {};
313 		template<> struct is_float<long double> : true_type {};
314 	#endif
315 
316 		/// Type traits for floating point bits.
317 		template<typename T> struct bits { typedef unsigned char type; };
318 		template<typename T> struct bits<const T> : bits<T> {};
319 		template<typename T> struct bits<volatile T> : bits<T> {};
320 		template<typename T> struct bits<const volatile T> : bits<T> {};
321 
322 	#if HALF_ENABLE_CPP11_CSTDINT
323 		/// Unsigned integer of (at least) 16 bits width.
324 		typedef std::uint_least16_t uint16;
325 
326 		/// Unsigned integer of (at least) 32 bits width.
327 		template<> struct bits<float> { typedef std::uint_least32_t type; };
328 
329 		/// Unsigned integer of (at least) 64 bits width.
330 		template<> struct bits<double> { typedef std::uint_least64_t type; };
331 	#else
332 		/// Unsigned integer of (at least) 16 bits width.
333 		typedef unsigned short uint16;
334 
335 		/// Unsigned integer of (at least) 32 bits width.
336 		template<> struct bits<float> : conditional<std::numeric_limits<unsigned int>::digits>=32,unsigned int,unsigned long> {};
337 
338 		#if HALF_ENABLE_CPP11_LONG_LONG
339 			/// Unsigned integer of (at least) 64 bits width.
340 			template<> struct bits<double> : conditional<std::numeric_limits<unsigned long>::digits>=64,unsigned long,unsigned long long> {};
341 		#else
342 			/// Unsigned integer of (at least) 64 bits width.
343 			template<> struct bits<double> { typedef unsigned long type; };
344 		#endif
345 	#endif
346 
347 		/// Tag type for binary construction.
348 		struct binary_t {};
349 
350 		/// Tag for binary construction.
351 		HALF_CONSTEXPR_CONST binary_t binary = binary_t();
352 
353 		/// Temporary half-precision expression.
354 		/// This class represents a half-precision expression which just stores a single-precision value internally.
355 		struct expr
356 		{
357 			/// Conversion constructor.
358 			/// \param f single-precision value to convert
exprhalf_float::detail::expr359 			explicit HALF_CONSTEXPR expr(float f) HALF_NOEXCEPT : value_(f) {}
360 
361 			/// Conversion to single-precision.
362 			/// \return single precision value representing expression value
operator floathalf_float::detail::expr363 			HALF_CONSTEXPR operator float() const HALF_NOEXCEPT { return value_; }
364 
365 		private:
366 			/// Internal expression value stored in single-precision.
367 			float value_;
368 		};
369 
370 		/// SFINAE helper for generic half-precision functions.
371 		/// This class template has to be specialized for each valid combination of argument types to provide a corresponding
372 		/// `type` member equivalent to \a T.
373 		/// \tparam T type to return
374 		template<typename T,typename,typename=void,typename=void> struct enable {};
375 		template<typename T> struct enable<T,half,void,void> { typedef T type; };
376 		template<typename T> struct enable<T,expr,void,void> { typedef T type; };
377 		template<typename T> struct enable<T,half,half,void> { typedef T type; };
378 		template<typename T> struct enable<T,half,expr,void> { typedef T type; };
379 		template<typename T> struct enable<T,expr,half,void> { typedef T type; };
380 		template<typename T> struct enable<T,expr,expr,void> { typedef T type; };
381 		template<typename T> struct enable<T,half,half,half> { typedef T type; };
382 		template<typename T> struct enable<T,half,half,expr> { typedef T type; };
383 		template<typename T> struct enable<T,half,expr,half> { typedef T type; };
384 		template<typename T> struct enable<T,half,expr,expr> { typedef T type; };
385 		template<typename T> struct enable<T,expr,half,half> { typedef T type; };
386 		template<typename T> struct enable<T,expr,half,expr> { typedef T type; };
387 		template<typename T> struct enable<T,expr,expr,half> { typedef T type; };
388 		template<typename T> struct enable<T,expr,expr,expr> { typedef T type; };
389 
390 		/// Return type for specialized generic 2-argument half-precision functions.
391 		/// This class template has to be specialized for each valid combination of argument types to provide a corresponding
392 		/// `type` member denoting the appropriate return type.
393 		/// \tparam T first argument type
394 		/// \tparam U first argument type
395 		template<typename T,typename U> struct result : enable<expr,T,U> {};
396 		template<> struct result<half,half> { typedef half type; };
397 
398 		/// \name Classification helpers
399 		/// \{
400 
401 		/// Check for infinity.
402 		/// \tparam T argument type (builtin floating point type)
403 		/// \param arg value to query
404 		/// \retval true if infinity
405 		/// \retval false else
builtin_isinf(T arg)406 		template<typename T> bool builtin_isinf(T arg)
407 		{
408 		#if HALF_ENABLE_CPP11_CMATH
409 			return std::isinf(arg);
410 		#elif defined(_MSC_VER)
411 			return !::_finite(static_cast<double>(arg)) && !::_isnan(static_cast<double>(arg));
412 		#else
413 			return arg == std::numeric_limits<T>::infinity() || arg == -std::numeric_limits<T>::infinity();
414 		#endif
415 		}
416 
417 		/// Check for NaN.
418 		/// \tparam T argument type (builtin floating point type)
419 		/// \param arg value to query
420 		/// \retval true if not a number
421 		/// \retval false else
builtin_isnan(T arg)422 		template<typename T> bool builtin_isnan(T arg)
423 		{
424 		#if HALF_ENABLE_CPP11_CMATH
425 			return std::isnan(arg);
426 		#elif defined(_MSC_VER)
427 			return ::_isnan(static_cast<double>(arg)) != 0;
428 		#else
429 			return arg != arg;
430 		#endif
431 		}
432 
433 		/// Check sign.
434 		/// \tparam T argument type (builtin floating point type)
435 		/// \param arg value to query
436 		/// \retval true if signbit set
437 		/// \retval false else
builtin_signbit(T arg)438 		template<typename T> bool builtin_signbit(T arg)
439 		{
440 		#if HALF_ENABLE_CPP11_CMATH
441 			return std::signbit(arg);
442 		#else
443 			return arg < T() || (arg == T() && T(1)/arg < T());
444 		#endif
445 		}
446 
447 		/// \}
448 		/// \name Conversion
449 		/// \{
450 
451 		/// Convert IEEE single-precision to half-precision.
452 		/// Credit for this goes to [Jeroen van der Zijp](ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf).
453 		/// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding
454 		/// \param value single-precision value
455 		/// \return binary representation of half-precision value
float2half_impl(float value,true_type)456 		template<std::float_round_style R> uint16 float2half_impl(float value, true_type)
457 		{
458 			typedef bits<float>::type uint32;
459 			uint32 bits;// = *reinterpret_cast<uint32*>(&value);		//violating strict aliasing!
460 			std::memcpy(&bits, &value, sizeof(float));
461 /*			uint16 hbits = (bits>>16) & 0x8000;
462 			bits &= 0x7FFFFFFF;
463 			int exp = bits >> 23;
464 			if(exp == 255)
465 				return hbits | 0x7C00 | (0x3FF&-static_cast<unsigned>((bits&0x7FFFFF)!=0));
466 			if(exp > 142)
467 			{
468 				if(R == std::round_toward_infinity)
469 					return hbits | 0x7C00 - (hbits>>15);
470 				if(R == std::round_toward_neg_infinity)
471 					return hbits | 0x7BFF + (hbits>>15);
472 				return hbits | 0x7BFF + (R!=std::round_toward_zero);
473 			}
474 			int g, s;
475 			if(exp > 112)
476 			{
477 				g = (bits>>12) & 1;
478 				s = (bits&0xFFF) != 0;
479 				hbits |= ((exp-112)<<10) | ((bits>>13)&0x3FF);
480 			}
481 			else if(exp > 101)
482 			{
483 				int i = 125 - exp;
484 				bits = (bits&0x7FFFFF) | 0x800000;
485 				g = (bits>>i) & 1;
486 				s = (bits&((1L<<i)-1)) != 0;
487 				hbits |= bits >> (i+1);
488 			}
489 			else
490 			{
491 				g = 0;
492 				s = bits != 0;
493 			}
494 			if(R == std::round_to_nearest)
495 				#if HALF_ROUND_TIES_TO_EVEN
496 					hbits += g & (s|hbits);
497 				#else
498 					hbits += g;
499 				#endif
500 			else if(R == std::round_toward_infinity)
501 				hbits += ~(hbits>>15) & (s|g);
502 			else if(R == std::round_toward_neg_infinity)
503 				hbits += (hbits>>15) & (g|s);
504 */			static const uint16 base_table[512] = {
505 				0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
506 				0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
507 				0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
508 				0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
509 				0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
510 				0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
511 				0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
512 				0x0200, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00,
513 				0x4000, 0x4400, 0x4800, 0x4C00, 0x5000, 0x5400, 0x5800, 0x5C00, 0x6000, 0x6400, 0x6800, 0x6C00, 0x7000, 0x7400, 0x7800, 0x7C00,
514 				0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
515 				0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
516 				0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
517 				0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
518 				0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
519 				0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
520 				0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00,
521 				0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
522 				0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
523 				0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
524 				0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
525 				0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
526 				0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
527 				0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001, 0x8002, 0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100,
528 				0x8200, 0x8400, 0x8800, 0x8C00, 0x9000, 0x9400, 0x9800, 0x9C00, 0xA000, 0xA400, 0xA800, 0xAC00, 0xB000, 0xB400, 0xB800, 0xBC00,
529 				0xC000, 0xC400, 0xC800, 0xCC00, 0xD000, 0xD400, 0xD800, 0xDC00, 0xE000, 0xE400, 0xE800, 0xEC00, 0xF000, 0xF400, 0xF800, 0xFC00,
530 				0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
531 				0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
532 				0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
533 				0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
534 				0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
535 				0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00,
536 				0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00 };
537 			static const unsigned char shift_table[512] = {
538 				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,
539 				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,
540 				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,
541 				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,
542 				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,
543 				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,
544 				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,
545 				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,
546 				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,
547 				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,
548 				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,
549 				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,
550 				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,
551 				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,
552 				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,
553 				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 };
554 			uint16 hbits = base_table[bits>>23] + static_cast<uint16>((bits&0x7FFFFF)>>shift_table[bits>>23]);
555 			if(R == std::round_to_nearest)
556 				hbits += (((bits&0x7FFFFF)>>(shift_table[bits>>23]-1))|(((bits>>23)&0xFF)==102)) & ((hbits&0x7C00)!=0x7C00)
557 				#if HALF_ROUND_TIES_TO_EVEN
558 					& (((((static_cast<uint32>(1)<<(shift_table[bits>>23]-1))-1)&bits)!=0)|hbits)
559 				#endif
560 				;
561 			else if(R == std::round_toward_zero)
562 				hbits -= ((hbits&0x7FFF)==0x7C00) & ~shift_table[bits>>23];
563 			else if(R == std::round_toward_infinity)
564 				hbits += ((((bits&0x7FFFFF&((static_cast<uint32>(1)<<(shift_table[bits>>23]))-1))!=0)|(((bits>>23)<=102)&
565 					((bits>>23)!=0)))&(hbits<0x7C00)) - ((hbits==0xFC00)&((bits>>23)!=511));
566 			else if(R == std::round_toward_neg_infinity)
567 				hbits += ((((bits&0x7FFFFF&((static_cast<uint32>(1)<<(shift_table[bits>>23]))-1))!=0)|(((bits>>23)<=358)&
568 					((bits>>23)!=256)))&(hbits<0xFC00)&(hbits>>15)) - ((hbits==0x7C00)&((bits>>23)!=255));
569 			return hbits;
570 		}
571 
572 		/// Convert IEEE double-precision to half-precision.
573 		/// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding
574 		/// \param value double-precision value
575 		/// \return binary representation of half-precision value
float2half_impl(double value,true_type)576 		template<std::float_round_style R> uint16 float2half_impl(double value, true_type)
577 		{
578 			typedef bits<float>::type uint32;
579 			typedef bits<double>::type uint64;
580 			uint64 bits;// = *reinterpret_cast<uint64*>(&value);		//violating strict aliasing!
581 			std::memcpy(&bits, &value, sizeof(double));
582 			uint32 hi = bits >> 32, lo = bits & 0xFFFFFFFF;
583 			uint16 hbits = (hi>>16) & 0x8000;
584 			hi &= 0x7FFFFFFF;
585 			int exp = hi >> 20;
586 			if(exp == 2047)
587 				return hbits | 0x7C00 | (0x3FF&-static_cast<unsigned>((bits&0xFFFFFFFFFFFFF)!=0));
588 			if(exp > 1038)
589 			{
590 				if(R == std::round_toward_infinity)
591 					return hbits | 0x7C00 - (hbits>>15);
592 				if(R == std::round_toward_neg_infinity)
593 					return hbits | 0x7BFF + (hbits>>15);
594 				return hbits | 0x7BFF + (R!=std::round_toward_zero);
595 			}
596 			int g, s = lo != 0;
597 			if(exp > 1008)
598 			{
599 				g = (hi>>9) & 1;
600 				s |= (hi&0x1FF) != 0;
601 				hbits |= ((exp-1008)<<10) | ((hi>>10)&0x3FF);
602 			}
603 			else if(exp > 997)
604 			{
605 				int i = 1018 - exp;
606 				hi = (hi&0xFFFFF) | 0x100000;
607 				g = (hi>>i) & 1;
608 				s |= (hi&((1L<<i)-1)) != 0;
609 				hbits |= hi >> (i+1);
610 			}
611 			else
612 			{
613 				g = 0;
614 				s |= hi != 0;
615 			}
616 			if(R == std::round_to_nearest)
617 				#if HALF_ROUND_TIES_TO_EVEN
618 					hbits += g & (s|hbits);
619 				#else
620 					hbits += g;
621 				#endif
622 			else if(R == std::round_toward_infinity)
623 				hbits += ~(hbits>>15) & (s|g);
624 			else if(R == std::round_toward_neg_infinity)
625 				hbits += (hbits>>15) & (g|s);
626 			return hbits;
627 		}
628 
629 		/// Convert non-IEEE floating point to half-precision.
630 		/// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding
631 		/// \tparam T source type (builtin floating point type)
632 		/// \param value floating point value
633 		/// \return binary representation of half-precision value
float2half_impl(T value,...)634 		template<std::float_round_style R,typename T> uint16 float2half_impl(T value, ...)
635 		{
636 			uint16 hbits = static_cast<unsigned>(builtin_signbit(value)) << 15;
637 			if(value == T())
638 				return hbits;
639 			if(builtin_isnan(value))
640 				return hbits | 0x7FFF;
641 			if(builtin_isinf(value))
642 				return hbits | 0x7C00;
643 			int exp;
644 			std::frexp(value, &exp);
645 			if(exp > 16)
646 			{
647 				if(R == std::round_toward_infinity)
648 					return hbits | (0x7C00-(hbits>>15));
649 				else if(R == std::round_toward_neg_infinity)
650 					return hbits | (0x7BFF+(hbits>>15));
651 				return hbits | (0x7BFF+(R!=std::round_toward_zero));
652 			}
653 			if(exp < -13)
654 				value = std::ldexp(value, 24);
655 			else
656 			{
657 				value = std::ldexp(value, 11-exp);
658 				hbits |= ((exp+13)<<10);
659 			}
660 			T ival, frac = std::modf(value, &ival);
661 			hbits += static_cast<uint16>(std::abs(static_cast<int>(ival)));
662 			if(R == std::round_to_nearest)
663 			{
664 				frac = std::abs(frac);
665 				#if HALF_ROUND_TIES_TO_EVEN
666 					hbits += (frac>T(0.5)) | ((frac==T(0.5))&hbits);
667 				#else
668 					hbits += frac >= T(0.5);
669 				#endif
670 			}
671 			else if(R == std::round_toward_infinity)
672 				hbits += frac > T();
673 			else if(R == std::round_toward_neg_infinity)
674 				hbits += frac < T();
675 			return hbits;
676 		}
677 
678 		/// Convert floating point to half-precision.
679 		/// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding
680 		/// \tparam T source type (builtin floating point type)
681 		/// \param value floating point value
682 		/// \return binary representation of half-precision value
float2half(T value)683 		template<std::float_round_style R,typename T> uint16 float2half(T value)
684 		{
685 			return float2half_impl<R>(value, bool_type<std::numeric_limits<T>::is_iec559&&sizeof(typename bits<T>::type)==sizeof(T)>());
686 		}
687 
688 		/// Convert integer to half-precision floating point.
689 		/// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding
690 		/// \tparam S `true` if value negative, `false` else
691 		/// \tparam T type to convert (builtin integer type)
692 		/// \param value non-negative integral value
693 		/// \return binary representation of half-precision value
int2half_impl(T value)694 		template<std::float_round_style R,bool S,typename T> uint16 int2half_impl(T value)
695 		{
696 		#if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
697 			static_assert(std::is_integral<T>::value, "int to half conversion only supports builtin integer types");
698 		#endif
699 			if(S)
700 				value = -value;
701 			uint16 bits = S << 15;
702 			if(value > 0xFFFF)
703 			{
704 				if(R == std::round_toward_infinity)
705 					bits |= 0x7C00 - S;
706 				else if(R == std::round_toward_neg_infinity)
707 					bits |= 0x7BFF + S;
708 				else
709 					bits |= 0x7BFF + (R!=std::round_toward_zero);
710 			}
711 			else if(value)
712 			{
713 				unsigned int m = value, exp = 24;
714 				for(; m<0x400; m<<=1,--exp) ;
715 				for(; m>0x7FF; m>>=1,++exp) ;
716 				bits |= (exp<<10) + m;
717 				if(exp > 24)
718 				{
719 					if(R == std::round_to_nearest)
720 						bits += (value>>(exp-25)) & 1
721 						#if HALF_ROUND_TIES_TO_EVEN
722 							& (((((1<<(exp-25))-1)&value)!=0)|bits)
723 						#endif
724 						;
725 					else if(R == std::round_toward_infinity)
726 						bits += ((value&((1<<(exp-24))-1))!=0) & !S;
727 					else if(R == std::round_toward_neg_infinity)
728 						bits += ((value&((1<<(exp-24))-1))!=0) & S;
729 				}
730 			}
731 			return bits;
732 		}
733 
734 		/// Convert integer to half-precision floating point.
735 		/// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding
736 		/// \tparam T type to convert (builtin integer type)
737 		/// \param value integral value
738 		/// \return binary representation of half-precision value
int2half(T value)739 		template<std::float_round_style R,typename T> uint16 int2half(T value)
740 		{
741 			return (value<0) ? int2half_impl<R,true>(value) : int2half_impl<R,false>(value);
742 		}
743 
744 		/// Convert half-precision to IEEE single-precision.
745 		/// Credit for this goes to [Jeroen van der Zijp](ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf).
746 		/// \param value binary representation of half-precision value
747 		/// \return single-precision value
half2float_impl(uint16 value,float,true_type)748 		inline float half2float_impl(uint16 value, float, true_type)
749 		{
750 			typedef bits<float>::type uint32;
751 /*			uint32 bits = static_cast<uint32>(value&0x8000) << 16;
752 			int abs = value & 0x7FFF;
753 			if(abs)
754 			{
755 				bits |= 0x38000000 << static_cast<unsigned>(abs>=0x7C00);
756 				for(; abs<0x400; abs<<=1,bits-=0x800000) ;
757 				bits += static_cast<uint32>(abs) << 13;
758 			}
759 */			static const uint32 mantissa_table[2048] = {
760 				0x00000000, 0x33800000, 0x34000000, 0x34400000, 0x34800000, 0x34A00000, 0x34C00000, 0x34E00000, 0x35000000, 0x35100000, 0x35200000, 0x35300000, 0x35400000, 0x35500000, 0x35600000, 0x35700000,
761 				0x35800000, 0x35880000, 0x35900000, 0x35980000, 0x35A00000, 0x35A80000, 0x35B00000, 0x35B80000, 0x35C00000, 0x35C80000, 0x35D00000, 0x35D80000, 0x35E00000, 0x35E80000, 0x35F00000, 0x35F80000,
762 				0x36000000, 0x36040000, 0x36080000, 0x360C0000, 0x36100000, 0x36140000, 0x36180000, 0x361C0000, 0x36200000, 0x36240000, 0x36280000, 0x362C0000, 0x36300000, 0x36340000, 0x36380000, 0x363C0000,
763 				0x36400000, 0x36440000, 0x36480000, 0x364C0000, 0x36500000, 0x36540000, 0x36580000, 0x365C0000, 0x36600000, 0x36640000, 0x36680000, 0x366C0000, 0x36700000, 0x36740000, 0x36780000, 0x367C0000,
764 				0x36800000, 0x36820000, 0x36840000, 0x36860000, 0x36880000, 0x368A0000, 0x368C0000, 0x368E0000, 0x36900000, 0x36920000, 0x36940000, 0x36960000, 0x36980000, 0x369A0000, 0x369C0000, 0x369E0000,
765 				0x36A00000, 0x36A20000, 0x36A40000, 0x36A60000, 0x36A80000, 0x36AA0000, 0x36AC0000, 0x36AE0000, 0x36B00000, 0x36B20000, 0x36B40000, 0x36B60000, 0x36B80000, 0x36BA0000, 0x36BC0000, 0x36BE0000,
766 				0x36C00000, 0x36C20000, 0x36C40000, 0x36C60000, 0x36C80000, 0x36CA0000, 0x36CC0000, 0x36CE0000, 0x36D00000, 0x36D20000, 0x36D40000, 0x36D60000, 0x36D80000, 0x36DA0000, 0x36DC0000, 0x36DE0000,
767 				0x36E00000, 0x36E20000, 0x36E40000, 0x36E60000, 0x36E80000, 0x36EA0000, 0x36EC0000, 0x36EE0000, 0x36F00000, 0x36F20000, 0x36F40000, 0x36F60000, 0x36F80000, 0x36FA0000, 0x36FC0000, 0x36FE0000,
768 				0x37000000, 0x37010000, 0x37020000, 0x37030000, 0x37040000, 0x37050000, 0x37060000, 0x37070000, 0x37080000, 0x37090000, 0x370A0000, 0x370B0000, 0x370C0000, 0x370D0000, 0x370E0000, 0x370F0000,
769 				0x37100000, 0x37110000, 0x37120000, 0x37130000, 0x37140000, 0x37150000, 0x37160000, 0x37170000, 0x37180000, 0x37190000, 0x371A0000, 0x371B0000, 0x371C0000, 0x371D0000, 0x371E0000, 0x371F0000,
770 				0x37200000, 0x37210000, 0x37220000, 0x37230000, 0x37240000, 0x37250000, 0x37260000, 0x37270000, 0x37280000, 0x37290000, 0x372A0000, 0x372B0000, 0x372C0000, 0x372D0000, 0x372E0000, 0x372F0000,
771 				0x37300000, 0x37310000, 0x37320000, 0x37330000, 0x37340000, 0x37350000, 0x37360000, 0x37370000, 0x37380000, 0x37390000, 0x373A0000, 0x373B0000, 0x373C0000, 0x373D0000, 0x373E0000, 0x373F0000,
772 				0x37400000, 0x37410000, 0x37420000, 0x37430000, 0x37440000, 0x37450000, 0x37460000, 0x37470000, 0x37480000, 0x37490000, 0x374A0000, 0x374B0000, 0x374C0000, 0x374D0000, 0x374E0000, 0x374F0000,
773 				0x37500000, 0x37510000, 0x37520000, 0x37530000, 0x37540000, 0x37550000, 0x37560000, 0x37570000, 0x37580000, 0x37590000, 0x375A0000, 0x375B0000, 0x375C0000, 0x375D0000, 0x375E0000, 0x375F0000,
774 				0x37600000, 0x37610000, 0x37620000, 0x37630000, 0x37640000, 0x37650000, 0x37660000, 0x37670000, 0x37680000, 0x37690000, 0x376A0000, 0x376B0000, 0x376C0000, 0x376D0000, 0x376E0000, 0x376F0000,
775 				0x37700000, 0x37710000, 0x37720000, 0x37730000, 0x37740000, 0x37750000, 0x37760000, 0x37770000, 0x37780000, 0x37790000, 0x377A0000, 0x377B0000, 0x377C0000, 0x377D0000, 0x377E0000, 0x377F0000,
776 				0x37800000, 0x37808000, 0x37810000, 0x37818000, 0x37820000, 0x37828000, 0x37830000, 0x37838000, 0x37840000, 0x37848000, 0x37850000, 0x37858000, 0x37860000, 0x37868000, 0x37870000, 0x37878000,
777 				0x37880000, 0x37888000, 0x37890000, 0x37898000, 0x378A0000, 0x378A8000, 0x378B0000, 0x378B8000, 0x378C0000, 0x378C8000, 0x378D0000, 0x378D8000, 0x378E0000, 0x378E8000, 0x378F0000, 0x378F8000,
778 				0x37900000, 0x37908000, 0x37910000, 0x37918000, 0x37920000, 0x37928000, 0x37930000, 0x37938000, 0x37940000, 0x37948000, 0x37950000, 0x37958000, 0x37960000, 0x37968000, 0x37970000, 0x37978000,
779 				0x37980000, 0x37988000, 0x37990000, 0x37998000, 0x379A0000, 0x379A8000, 0x379B0000, 0x379B8000, 0x379C0000, 0x379C8000, 0x379D0000, 0x379D8000, 0x379E0000, 0x379E8000, 0x379F0000, 0x379F8000,
780 				0x37A00000, 0x37A08000, 0x37A10000, 0x37A18000, 0x37A20000, 0x37A28000, 0x37A30000, 0x37A38000, 0x37A40000, 0x37A48000, 0x37A50000, 0x37A58000, 0x37A60000, 0x37A68000, 0x37A70000, 0x37A78000,
781 				0x37A80000, 0x37A88000, 0x37A90000, 0x37A98000, 0x37AA0000, 0x37AA8000, 0x37AB0000, 0x37AB8000, 0x37AC0000, 0x37AC8000, 0x37AD0000, 0x37AD8000, 0x37AE0000, 0x37AE8000, 0x37AF0000, 0x37AF8000,
782 				0x37B00000, 0x37B08000, 0x37B10000, 0x37B18000, 0x37B20000, 0x37B28000, 0x37B30000, 0x37B38000, 0x37B40000, 0x37B48000, 0x37B50000, 0x37B58000, 0x37B60000, 0x37B68000, 0x37B70000, 0x37B78000,
783 				0x37B80000, 0x37B88000, 0x37B90000, 0x37B98000, 0x37BA0000, 0x37BA8000, 0x37BB0000, 0x37BB8000, 0x37BC0000, 0x37BC8000, 0x37BD0000, 0x37BD8000, 0x37BE0000, 0x37BE8000, 0x37BF0000, 0x37BF8000,
784 				0x37C00000, 0x37C08000, 0x37C10000, 0x37C18000, 0x37C20000, 0x37C28000, 0x37C30000, 0x37C38000, 0x37C40000, 0x37C48000, 0x37C50000, 0x37C58000, 0x37C60000, 0x37C68000, 0x37C70000, 0x37C78000,
785 				0x37C80000, 0x37C88000, 0x37C90000, 0x37C98000, 0x37CA0000, 0x37CA8000, 0x37CB0000, 0x37CB8000, 0x37CC0000, 0x37CC8000, 0x37CD0000, 0x37CD8000, 0x37CE0000, 0x37CE8000, 0x37CF0000, 0x37CF8000,
786 				0x37D00000, 0x37D08000, 0x37D10000, 0x37D18000, 0x37D20000, 0x37D28000, 0x37D30000, 0x37D38000, 0x37D40000, 0x37D48000, 0x37D50000, 0x37D58000, 0x37D60000, 0x37D68000, 0x37D70000, 0x37D78000,
787 				0x37D80000, 0x37D88000, 0x37D90000, 0x37D98000, 0x37DA0000, 0x37DA8000, 0x37DB0000, 0x37DB8000, 0x37DC0000, 0x37DC8000, 0x37DD0000, 0x37DD8000, 0x37DE0000, 0x37DE8000, 0x37DF0000, 0x37DF8000,
788 				0x37E00000, 0x37E08000, 0x37E10000, 0x37E18000, 0x37E20000, 0x37E28000, 0x37E30000, 0x37E38000, 0x37E40000, 0x37E48000, 0x37E50000, 0x37E58000, 0x37E60000, 0x37E68000, 0x37E70000, 0x37E78000,
789 				0x37E80000, 0x37E88000, 0x37E90000, 0x37E98000, 0x37EA0000, 0x37EA8000, 0x37EB0000, 0x37EB8000, 0x37EC0000, 0x37EC8000, 0x37ED0000, 0x37ED8000, 0x37EE0000, 0x37EE8000, 0x37EF0000, 0x37EF8000,
790 				0x37F00000, 0x37F08000, 0x37F10000, 0x37F18000, 0x37F20000, 0x37F28000, 0x37F30000, 0x37F38000, 0x37F40000, 0x37F48000, 0x37F50000, 0x37F58000, 0x37F60000, 0x37F68000, 0x37F70000, 0x37F78000,
791 				0x37F80000, 0x37F88000, 0x37F90000, 0x37F98000, 0x37FA0000, 0x37FA8000, 0x37FB0000, 0x37FB8000, 0x37FC0000, 0x37FC8000, 0x37FD0000, 0x37FD8000, 0x37FE0000, 0x37FE8000, 0x37FF0000, 0x37FF8000,
792 				0x38000000, 0x38004000, 0x38008000, 0x3800C000, 0x38010000, 0x38014000, 0x38018000, 0x3801C000, 0x38020000, 0x38024000, 0x38028000, 0x3802C000, 0x38030000, 0x38034000, 0x38038000, 0x3803C000,
793 				0x38040000, 0x38044000, 0x38048000, 0x3804C000, 0x38050000, 0x38054000, 0x38058000, 0x3805C000, 0x38060000, 0x38064000, 0x38068000, 0x3806C000, 0x38070000, 0x38074000, 0x38078000, 0x3807C000,
794 				0x38080000, 0x38084000, 0x38088000, 0x3808C000, 0x38090000, 0x38094000, 0x38098000, 0x3809C000, 0x380A0000, 0x380A4000, 0x380A8000, 0x380AC000, 0x380B0000, 0x380B4000, 0x380B8000, 0x380BC000,
795 				0x380C0000, 0x380C4000, 0x380C8000, 0x380CC000, 0x380D0000, 0x380D4000, 0x380D8000, 0x380DC000, 0x380E0000, 0x380E4000, 0x380E8000, 0x380EC000, 0x380F0000, 0x380F4000, 0x380F8000, 0x380FC000,
796 				0x38100000, 0x38104000, 0x38108000, 0x3810C000, 0x38110000, 0x38114000, 0x38118000, 0x3811C000, 0x38120000, 0x38124000, 0x38128000, 0x3812C000, 0x38130000, 0x38134000, 0x38138000, 0x3813C000,
797 				0x38140000, 0x38144000, 0x38148000, 0x3814C000, 0x38150000, 0x38154000, 0x38158000, 0x3815C000, 0x38160000, 0x38164000, 0x38168000, 0x3816C000, 0x38170000, 0x38174000, 0x38178000, 0x3817C000,
798 				0x38180000, 0x38184000, 0x38188000, 0x3818C000, 0x38190000, 0x38194000, 0x38198000, 0x3819C000, 0x381A0000, 0x381A4000, 0x381A8000, 0x381AC000, 0x381B0000, 0x381B4000, 0x381B8000, 0x381BC000,
799 				0x381C0000, 0x381C4000, 0x381C8000, 0x381CC000, 0x381D0000, 0x381D4000, 0x381D8000, 0x381DC000, 0x381E0000, 0x381E4000, 0x381E8000, 0x381EC000, 0x381F0000, 0x381F4000, 0x381F8000, 0x381FC000,
800 				0x38200000, 0x38204000, 0x38208000, 0x3820C000, 0x38210000, 0x38214000, 0x38218000, 0x3821C000, 0x38220000, 0x38224000, 0x38228000, 0x3822C000, 0x38230000, 0x38234000, 0x38238000, 0x3823C000,
801 				0x38240000, 0x38244000, 0x38248000, 0x3824C000, 0x38250000, 0x38254000, 0x38258000, 0x3825C000, 0x38260000, 0x38264000, 0x38268000, 0x3826C000, 0x38270000, 0x38274000, 0x38278000, 0x3827C000,
802 				0x38280000, 0x38284000, 0x38288000, 0x3828C000, 0x38290000, 0x38294000, 0x38298000, 0x3829C000, 0x382A0000, 0x382A4000, 0x382A8000, 0x382AC000, 0x382B0000, 0x382B4000, 0x382B8000, 0x382BC000,
803 				0x382C0000, 0x382C4000, 0x382C8000, 0x382CC000, 0x382D0000, 0x382D4000, 0x382D8000, 0x382DC000, 0x382E0000, 0x382E4000, 0x382E8000, 0x382EC000, 0x382F0000, 0x382F4000, 0x382F8000, 0x382FC000,
804 				0x38300000, 0x38304000, 0x38308000, 0x3830C000, 0x38310000, 0x38314000, 0x38318000, 0x3831C000, 0x38320000, 0x38324000, 0x38328000, 0x3832C000, 0x38330000, 0x38334000, 0x38338000, 0x3833C000,
805 				0x38340000, 0x38344000, 0x38348000, 0x3834C000, 0x38350000, 0x38354000, 0x38358000, 0x3835C000, 0x38360000, 0x38364000, 0x38368000, 0x3836C000, 0x38370000, 0x38374000, 0x38378000, 0x3837C000,
806 				0x38380000, 0x38384000, 0x38388000, 0x3838C000, 0x38390000, 0x38394000, 0x38398000, 0x3839C000, 0x383A0000, 0x383A4000, 0x383A8000, 0x383AC000, 0x383B0000, 0x383B4000, 0x383B8000, 0x383BC000,
807 				0x383C0000, 0x383C4000, 0x383C8000, 0x383CC000, 0x383D0000, 0x383D4000, 0x383D8000, 0x383DC000, 0x383E0000, 0x383E4000, 0x383E8000, 0x383EC000, 0x383F0000, 0x383F4000, 0x383F8000, 0x383FC000,
808 				0x38400000, 0x38404000, 0x38408000, 0x3840C000, 0x38410000, 0x38414000, 0x38418000, 0x3841C000, 0x38420000, 0x38424000, 0x38428000, 0x3842C000, 0x38430000, 0x38434000, 0x38438000, 0x3843C000,
809 				0x38440000, 0x38444000, 0x38448000, 0x3844C000, 0x38450000, 0x38454000, 0x38458000, 0x3845C000, 0x38460000, 0x38464000, 0x38468000, 0x3846C000, 0x38470000, 0x38474000, 0x38478000, 0x3847C000,
810 				0x38480000, 0x38484000, 0x38488000, 0x3848C000, 0x38490000, 0x38494000, 0x38498000, 0x3849C000, 0x384A0000, 0x384A4000, 0x384A8000, 0x384AC000, 0x384B0000, 0x384B4000, 0x384B8000, 0x384BC000,
811 				0x384C0000, 0x384C4000, 0x384C8000, 0x384CC000, 0x384D0000, 0x384D4000, 0x384D8000, 0x384DC000, 0x384E0000, 0x384E4000, 0x384E8000, 0x384EC000, 0x384F0000, 0x384F4000, 0x384F8000, 0x384FC000,
812 				0x38500000, 0x38504000, 0x38508000, 0x3850C000, 0x38510000, 0x38514000, 0x38518000, 0x3851C000, 0x38520000, 0x38524000, 0x38528000, 0x3852C000, 0x38530000, 0x38534000, 0x38538000, 0x3853C000,
813 				0x38540000, 0x38544000, 0x38548000, 0x3854C000, 0x38550000, 0x38554000, 0x38558000, 0x3855C000, 0x38560000, 0x38564000, 0x38568000, 0x3856C000, 0x38570000, 0x38574000, 0x38578000, 0x3857C000,
814 				0x38580000, 0x38584000, 0x38588000, 0x3858C000, 0x38590000, 0x38594000, 0x38598000, 0x3859C000, 0x385A0000, 0x385A4000, 0x385A8000, 0x385AC000, 0x385B0000, 0x385B4000, 0x385B8000, 0x385BC000,
815 				0x385C0000, 0x385C4000, 0x385C8000, 0x385CC000, 0x385D0000, 0x385D4000, 0x385D8000, 0x385DC000, 0x385E0000, 0x385E4000, 0x385E8000, 0x385EC000, 0x385F0000, 0x385F4000, 0x385F8000, 0x385FC000,
816 				0x38600000, 0x38604000, 0x38608000, 0x3860C000, 0x38610000, 0x38614000, 0x38618000, 0x3861C000, 0x38620000, 0x38624000, 0x38628000, 0x3862C000, 0x38630000, 0x38634000, 0x38638000, 0x3863C000,
817 				0x38640000, 0x38644000, 0x38648000, 0x3864C000, 0x38650000, 0x38654000, 0x38658000, 0x3865C000, 0x38660000, 0x38664000, 0x38668000, 0x3866C000, 0x38670000, 0x38674000, 0x38678000, 0x3867C000,
818 				0x38680000, 0x38684000, 0x38688000, 0x3868C000, 0x38690000, 0x38694000, 0x38698000, 0x3869C000, 0x386A0000, 0x386A4000, 0x386A8000, 0x386AC000, 0x386B0000, 0x386B4000, 0x386B8000, 0x386BC000,
819 				0x386C0000, 0x386C4000, 0x386C8000, 0x386CC000, 0x386D0000, 0x386D4000, 0x386D8000, 0x386DC000, 0x386E0000, 0x386E4000, 0x386E8000, 0x386EC000, 0x386F0000, 0x386F4000, 0x386F8000, 0x386FC000,
820 				0x38700000, 0x38704000, 0x38708000, 0x3870C000, 0x38710000, 0x38714000, 0x38718000, 0x3871C000, 0x38720000, 0x38724000, 0x38728000, 0x3872C000, 0x38730000, 0x38734000, 0x38738000, 0x3873C000,
821 				0x38740000, 0x38744000, 0x38748000, 0x3874C000, 0x38750000, 0x38754000, 0x38758000, 0x3875C000, 0x38760000, 0x38764000, 0x38768000, 0x3876C000, 0x38770000, 0x38774000, 0x38778000, 0x3877C000,
822 				0x38780000, 0x38784000, 0x38788000, 0x3878C000, 0x38790000, 0x38794000, 0x38798000, 0x3879C000, 0x387A0000, 0x387A4000, 0x387A8000, 0x387AC000, 0x387B0000, 0x387B4000, 0x387B8000, 0x387BC000,
823 				0x387C0000, 0x387C4000, 0x387C8000, 0x387CC000, 0x387D0000, 0x387D4000, 0x387D8000, 0x387DC000, 0x387E0000, 0x387E4000, 0x387E8000, 0x387EC000, 0x387F0000, 0x387F4000, 0x387F8000, 0x387FC000,
824 				0x38000000, 0x38002000, 0x38004000, 0x38006000, 0x38008000, 0x3800A000, 0x3800C000, 0x3800E000, 0x38010000, 0x38012000, 0x38014000, 0x38016000, 0x38018000, 0x3801A000, 0x3801C000, 0x3801E000,
825 				0x38020000, 0x38022000, 0x38024000, 0x38026000, 0x38028000, 0x3802A000, 0x3802C000, 0x3802E000, 0x38030000, 0x38032000, 0x38034000, 0x38036000, 0x38038000, 0x3803A000, 0x3803C000, 0x3803E000,
826 				0x38040000, 0x38042000, 0x38044000, 0x38046000, 0x38048000, 0x3804A000, 0x3804C000, 0x3804E000, 0x38050000, 0x38052000, 0x38054000, 0x38056000, 0x38058000, 0x3805A000, 0x3805C000, 0x3805E000,
827 				0x38060000, 0x38062000, 0x38064000, 0x38066000, 0x38068000, 0x3806A000, 0x3806C000, 0x3806E000, 0x38070000, 0x38072000, 0x38074000, 0x38076000, 0x38078000, 0x3807A000, 0x3807C000, 0x3807E000,
828 				0x38080000, 0x38082000, 0x38084000, 0x38086000, 0x38088000, 0x3808A000, 0x3808C000, 0x3808E000, 0x38090000, 0x38092000, 0x38094000, 0x38096000, 0x38098000, 0x3809A000, 0x3809C000, 0x3809E000,
829 				0x380A0000, 0x380A2000, 0x380A4000, 0x380A6000, 0x380A8000, 0x380AA000, 0x380AC000, 0x380AE000, 0x380B0000, 0x380B2000, 0x380B4000, 0x380B6000, 0x380B8000, 0x380BA000, 0x380BC000, 0x380BE000,
830 				0x380C0000, 0x380C2000, 0x380C4000, 0x380C6000, 0x380C8000, 0x380CA000, 0x380CC000, 0x380CE000, 0x380D0000, 0x380D2000, 0x380D4000, 0x380D6000, 0x380D8000, 0x380DA000, 0x380DC000, 0x380DE000,
831 				0x380E0000, 0x380E2000, 0x380E4000, 0x380E6000, 0x380E8000, 0x380EA000, 0x380EC000, 0x380EE000, 0x380F0000, 0x380F2000, 0x380F4000, 0x380F6000, 0x380F8000, 0x380FA000, 0x380FC000, 0x380FE000,
832 				0x38100000, 0x38102000, 0x38104000, 0x38106000, 0x38108000, 0x3810A000, 0x3810C000, 0x3810E000, 0x38110000, 0x38112000, 0x38114000, 0x38116000, 0x38118000, 0x3811A000, 0x3811C000, 0x3811E000,
833 				0x38120000, 0x38122000, 0x38124000, 0x38126000, 0x38128000, 0x3812A000, 0x3812C000, 0x3812E000, 0x38130000, 0x38132000, 0x38134000, 0x38136000, 0x38138000, 0x3813A000, 0x3813C000, 0x3813E000,
834 				0x38140000, 0x38142000, 0x38144000, 0x38146000, 0x38148000, 0x3814A000, 0x3814C000, 0x3814E000, 0x38150000, 0x38152000, 0x38154000, 0x38156000, 0x38158000, 0x3815A000, 0x3815C000, 0x3815E000,
835 				0x38160000, 0x38162000, 0x38164000, 0x38166000, 0x38168000, 0x3816A000, 0x3816C000, 0x3816E000, 0x38170000, 0x38172000, 0x38174000, 0x38176000, 0x38178000, 0x3817A000, 0x3817C000, 0x3817E000,
836 				0x38180000, 0x38182000, 0x38184000, 0x38186000, 0x38188000, 0x3818A000, 0x3818C000, 0x3818E000, 0x38190000, 0x38192000, 0x38194000, 0x38196000, 0x38198000, 0x3819A000, 0x3819C000, 0x3819E000,
837 				0x381A0000, 0x381A2000, 0x381A4000, 0x381A6000, 0x381A8000, 0x381AA000, 0x381AC000, 0x381AE000, 0x381B0000, 0x381B2000, 0x381B4000, 0x381B6000, 0x381B8000, 0x381BA000, 0x381BC000, 0x381BE000,
838 				0x381C0000, 0x381C2000, 0x381C4000, 0x381C6000, 0x381C8000, 0x381CA000, 0x381CC000, 0x381CE000, 0x381D0000, 0x381D2000, 0x381D4000, 0x381D6000, 0x381D8000, 0x381DA000, 0x381DC000, 0x381DE000,
839 				0x381E0000, 0x381E2000, 0x381E4000, 0x381E6000, 0x381E8000, 0x381EA000, 0x381EC000, 0x381EE000, 0x381F0000, 0x381F2000, 0x381F4000, 0x381F6000, 0x381F8000, 0x381FA000, 0x381FC000, 0x381FE000,
840 				0x38200000, 0x38202000, 0x38204000, 0x38206000, 0x38208000, 0x3820A000, 0x3820C000, 0x3820E000, 0x38210000, 0x38212000, 0x38214000, 0x38216000, 0x38218000, 0x3821A000, 0x3821C000, 0x3821E000,
841 				0x38220000, 0x38222000, 0x38224000, 0x38226000, 0x38228000, 0x3822A000, 0x3822C000, 0x3822E000, 0x38230000, 0x38232000, 0x38234000, 0x38236000, 0x38238000, 0x3823A000, 0x3823C000, 0x3823E000,
842 				0x38240000, 0x38242000, 0x38244000, 0x38246000, 0x38248000, 0x3824A000, 0x3824C000, 0x3824E000, 0x38250000, 0x38252000, 0x38254000, 0x38256000, 0x38258000, 0x3825A000, 0x3825C000, 0x3825E000,
843 				0x38260000, 0x38262000, 0x38264000, 0x38266000, 0x38268000, 0x3826A000, 0x3826C000, 0x3826E000, 0x38270000, 0x38272000, 0x38274000, 0x38276000, 0x38278000, 0x3827A000, 0x3827C000, 0x3827E000,
844 				0x38280000, 0x38282000, 0x38284000, 0x38286000, 0x38288000, 0x3828A000, 0x3828C000, 0x3828E000, 0x38290000, 0x38292000, 0x38294000, 0x38296000, 0x38298000, 0x3829A000, 0x3829C000, 0x3829E000,
845 				0x382A0000, 0x382A2000, 0x382A4000, 0x382A6000, 0x382A8000, 0x382AA000, 0x382AC000, 0x382AE000, 0x382B0000, 0x382B2000, 0x382B4000, 0x382B6000, 0x382B8000, 0x382BA000, 0x382BC000, 0x382BE000,
846 				0x382C0000, 0x382C2000, 0x382C4000, 0x382C6000, 0x382C8000, 0x382CA000, 0x382CC000, 0x382CE000, 0x382D0000, 0x382D2000, 0x382D4000, 0x382D6000, 0x382D8000, 0x382DA000, 0x382DC000, 0x382DE000,
847 				0x382E0000, 0x382E2000, 0x382E4000, 0x382E6000, 0x382E8000, 0x382EA000, 0x382EC000, 0x382EE000, 0x382F0000, 0x382F2000, 0x382F4000, 0x382F6000, 0x382F8000, 0x382FA000, 0x382FC000, 0x382FE000,
848 				0x38300000, 0x38302000, 0x38304000, 0x38306000, 0x38308000, 0x3830A000, 0x3830C000, 0x3830E000, 0x38310000, 0x38312000, 0x38314000, 0x38316000, 0x38318000, 0x3831A000, 0x3831C000, 0x3831E000,
849 				0x38320000, 0x38322000, 0x38324000, 0x38326000, 0x38328000, 0x3832A000, 0x3832C000, 0x3832E000, 0x38330000, 0x38332000, 0x38334000, 0x38336000, 0x38338000, 0x3833A000, 0x3833C000, 0x3833E000,
850 				0x38340000, 0x38342000, 0x38344000, 0x38346000, 0x38348000, 0x3834A000, 0x3834C000, 0x3834E000, 0x38350000, 0x38352000, 0x38354000, 0x38356000, 0x38358000, 0x3835A000, 0x3835C000, 0x3835E000,
851 				0x38360000, 0x38362000, 0x38364000, 0x38366000, 0x38368000, 0x3836A000, 0x3836C000, 0x3836E000, 0x38370000, 0x38372000, 0x38374000, 0x38376000, 0x38378000, 0x3837A000, 0x3837C000, 0x3837E000,
852 				0x38380000, 0x38382000, 0x38384000, 0x38386000, 0x38388000, 0x3838A000, 0x3838C000, 0x3838E000, 0x38390000, 0x38392000, 0x38394000, 0x38396000, 0x38398000, 0x3839A000, 0x3839C000, 0x3839E000,
853 				0x383A0000, 0x383A2000, 0x383A4000, 0x383A6000, 0x383A8000, 0x383AA000, 0x383AC000, 0x383AE000, 0x383B0000, 0x383B2000, 0x383B4000, 0x383B6000, 0x383B8000, 0x383BA000, 0x383BC000, 0x383BE000,
854 				0x383C0000, 0x383C2000, 0x383C4000, 0x383C6000, 0x383C8000, 0x383CA000, 0x383CC000, 0x383CE000, 0x383D0000, 0x383D2000, 0x383D4000, 0x383D6000, 0x383D8000, 0x383DA000, 0x383DC000, 0x383DE000,
855 				0x383E0000, 0x383E2000, 0x383E4000, 0x383E6000, 0x383E8000, 0x383EA000, 0x383EC000, 0x383EE000, 0x383F0000, 0x383F2000, 0x383F4000, 0x383F6000, 0x383F8000, 0x383FA000, 0x383FC000, 0x383FE000,
856 				0x38400000, 0x38402000, 0x38404000, 0x38406000, 0x38408000, 0x3840A000, 0x3840C000, 0x3840E000, 0x38410000, 0x38412000, 0x38414000, 0x38416000, 0x38418000, 0x3841A000, 0x3841C000, 0x3841E000,
857 				0x38420000, 0x38422000, 0x38424000, 0x38426000, 0x38428000, 0x3842A000, 0x3842C000, 0x3842E000, 0x38430000, 0x38432000, 0x38434000, 0x38436000, 0x38438000, 0x3843A000, 0x3843C000, 0x3843E000,
858 				0x38440000, 0x38442000, 0x38444000, 0x38446000, 0x38448000, 0x3844A000, 0x3844C000, 0x3844E000, 0x38450000, 0x38452000, 0x38454000, 0x38456000, 0x38458000, 0x3845A000, 0x3845C000, 0x3845E000,
859 				0x38460000, 0x38462000, 0x38464000, 0x38466000, 0x38468000, 0x3846A000, 0x3846C000, 0x3846E000, 0x38470000, 0x38472000, 0x38474000, 0x38476000, 0x38478000, 0x3847A000, 0x3847C000, 0x3847E000,
860 				0x38480000, 0x38482000, 0x38484000, 0x38486000, 0x38488000, 0x3848A000, 0x3848C000, 0x3848E000, 0x38490000, 0x38492000, 0x38494000, 0x38496000, 0x38498000, 0x3849A000, 0x3849C000, 0x3849E000,
861 				0x384A0000, 0x384A2000, 0x384A4000, 0x384A6000, 0x384A8000, 0x384AA000, 0x384AC000, 0x384AE000, 0x384B0000, 0x384B2000, 0x384B4000, 0x384B6000, 0x384B8000, 0x384BA000, 0x384BC000, 0x384BE000,
862 				0x384C0000, 0x384C2000, 0x384C4000, 0x384C6000, 0x384C8000, 0x384CA000, 0x384CC000, 0x384CE000, 0x384D0000, 0x384D2000, 0x384D4000, 0x384D6000, 0x384D8000, 0x384DA000, 0x384DC000, 0x384DE000,
863 				0x384E0000, 0x384E2000, 0x384E4000, 0x384E6000, 0x384E8000, 0x384EA000, 0x384EC000, 0x384EE000, 0x384F0000, 0x384F2000, 0x384F4000, 0x384F6000, 0x384F8000, 0x384FA000, 0x384FC000, 0x384FE000,
864 				0x38500000, 0x38502000, 0x38504000, 0x38506000, 0x38508000, 0x3850A000, 0x3850C000, 0x3850E000, 0x38510000, 0x38512000, 0x38514000, 0x38516000, 0x38518000, 0x3851A000, 0x3851C000, 0x3851E000,
865 				0x38520000, 0x38522000, 0x38524000, 0x38526000, 0x38528000, 0x3852A000, 0x3852C000, 0x3852E000, 0x38530000, 0x38532000, 0x38534000, 0x38536000, 0x38538000, 0x3853A000, 0x3853C000, 0x3853E000,
866 				0x38540000, 0x38542000, 0x38544000, 0x38546000, 0x38548000, 0x3854A000, 0x3854C000, 0x3854E000, 0x38550000, 0x38552000, 0x38554000, 0x38556000, 0x38558000, 0x3855A000, 0x3855C000, 0x3855E000,
867 				0x38560000, 0x38562000, 0x38564000, 0x38566000, 0x38568000, 0x3856A000, 0x3856C000, 0x3856E000, 0x38570000, 0x38572000, 0x38574000, 0x38576000, 0x38578000, 0x3857A000, 0x3857C000, 0x3857E000,
868 				0x38580000, 0x38582000, 0x38584000, 0x38586000, 0x38588000, 0x3858A000, 0x3858C000, 0x3858E000, 0x38590000, 0x38592000, 0x38594000, 0x38596000, 0x38598000, 0x3859A000, 0x3859C000, 0x3859E000,
869 				0x385A0000, 0x385A2000, 0x385A4000, 0x385A6000, 0x385A8000, 0x385AA000, 0x385AC000, 0x385AE000, 0x385B0000, 0x385B2000, 0x385B4000, 0x385B6000, 0x385B8000, 0x385BA000, 0x385BC000, 0x385BE000,
870 				0x385C0000, 0x385C2000, 0x385C4000, 0x385C6000, 0x385C8000, 0x385CA000, 0x385CC000, 0x385CE000, 0x385D0000, 0x385D2000, 0x385D4000, 0x385D6000, 0x385D8000, 0x385DA000, 0x385DC000, 0x385DE000,
871 				0x385E0000, 0x385E2000, 0x385E4000, 0x385E6000, 0x385E8000, 0x385EA000, 0x385EC000, 0x385EE000, 0x385F0000, 0x385F2000, 0x385F4000, 0x385F6000, 0x385F8000, 0x385FA000, 0x385FC000, 0x385FE000,
872 				0x38600000, 0x38602000, 0x38604000, 0x38606000, 0x38608000, 0x3860A000, 0x3860C000, 0x3860E000, 0x38610000, 0x38612000, 0x38614000, 0x38616000, 0x38618000, 0x3861A000, 0x3861C000, 0x3861E000,
873 				0x38620000, 0x38622000, 0x38624000, 0x38626000, 0x38628000, 0x3862A000, 0x3862C000, 0x3862E000, 0x38630000, 0x38632000, 0x38634000, 0x38636000, 0x38638000, 0x3863A000, 0x3863C000, 0x3863E000,
874 				0x38640000, 0x38642000, 0x38644000, 0x38646000, 0x38648000, 0x3864A000, 0x3864C000, 0x3864E000, 0x38650000, 0x38652000, 0x38654000, 0x38656000, 0x38658000, 0x3865A000, 0x3865C000, 0x3865E000,
875 				0x38660000, 0x38662000, 0x38664000, 0x38666000, 0x38668000, 0x3866A000, 0x3866C000, 0x3866E000, 0x38670000, 0x38672000, 0x38674000, 0x38676000, 0x38678000, 0x3867A000, 0x3867C000, 0x3867E000,
876 				0x38680000, 0x38682000, 0x38684000, 0x38686000, 0x38688000, 0x3868A000, 0x3868C000, 0x3868E000, 0x38690000, 0x38692000, 0x38694000, 0x38696000, 0x38698000, 0x3869A000, 0x3869C000, 0x3869E000,
877 				0x386A0000, 0x386A2000, 0x386A4000, 0x386A6000, 0x386A8000, 0x386AA000, 0x386AC000, 0x386AE000, 0x386B0000, 0x386B2000, 0x386B4000, 0x386B6000, 0x386B8000, 0x386BA000, 0x386BC000, 0x386BE000,
878 				0x386C0000, 0x386C2000, 0x386C4000, 0x386C6000, 0x386C8000, 0x386CA000, 0x386CC000, 0x386CE000, 0x386D0000, 0x386D2000, 0x386D4000, 0x386D6000, 0x386D8000, 0x386DA000, 0x386DC000, 0x386DE000,
879 				0x386E0000, 0x386E2000, 0x386E4000, 0x386E6000, 0x386E8000, 0x386EA000, 0x386EC000, 0x386EE000, 0x386F0000, 0x386F2000, 0x386F4000, 0x386F6000, 0x386F8000, 0x386FA000, 0x386FC000, 0x386FE000,
880 				0x38700000, 0x38702000, 0x38704000, 0x38706000, 0x38708000, 0x3870A000, 0x3870C000, 0x3870E000, 0x38710000, 0x38712000, 0x38714000, 0x38716000, 0x38718000, 0x3871A000, 0x3871C000, 0x3871E000,
881 				0x38720000, 0x38722000, 0x38724000, 0x38726000, 0x38728000, 0x3872A000, 0x3872C000, 0x3872E000, 0x38730000, 0x38732000, 0x38734000, 0x38736000, 0x38738000, 0x3873A000, 0x3873C000, 0x3873E000,
882 				0x38740000, 0x38742000, 0x38744000, 0x38746000, 0x38748000, 0x3874A000, 0x3874C000, 0x3874E000, 0x38750000, 0x38752000, 0x38754000, 0x38756000, 0x38758000, 0x3875A000, 0x3875C000, 0x3875E000,
883 				0x38760000, 0x38762000, 0x38764000, 0x38766000, 0x38768000, 0x3876A000, 0x3876C000, 0x3876E000, 0x38770000, 0x38772000, 0x38774000, 0x38776000, 0x38778000, 0x3877A000, 0x3877C000, 0x3877E000,
884 				0x38780000, 0x38782000, 0x38784000, 0x38786000, 0x38788000, 0x3878A000, 0x3878C000, 0x3878E000, 0x38790000, 0x38792000, 0x38794000, 0x38796000, 0x38798000, 0x3879A000, 0x3879C000, 0x3879E000,
885 				0x387A0000, 0x387A2000, 0x387A4000, 0x387A6000, 0x387A8000, 0x387AA000, 0x387AC000, 0x387AE000, 0x387B0000, 0x387B2000, 0x387B4000, 0x387B6000, 0x387B8000, 0x387BA000, 0x387BC000, 0x387BE000,
886 				0x387C0000, 0x387C2000, 0x387C4000, 0x387C6000, 0x387C8000, 0x387CA000, 0x387CC000, 0x387CE000, 0x387D0000, 0x387D2000, 0x387D4000, 0x387D6000, 0x387D8000, 0x387DA000, 0x387DC000, 0x387DE000,
887 				0x387E0000, 0x387E2000, 0x387E4000, 0x387E6000, 0x387E8000, 0x387EA000, 0x387EC000, 0x387EE000, 0x387F0000, 0x387F2000, 0x387F4000, 0x387F6000, 0x387F8000, 0x387FA000, 0x387FC000, 0x387FE000 };
888 			static const uint32 exponent_table[64] = {
889 				0x00000000, 0x00800000, 0x01000000, 0x01800000, 0x02000000, 0x02800000, 0x03000000, 0x03800000, 0x04000000, 0x04800000, 0x05000000, 0x05800000, 0x06000000, 0x06800000, 0x07000000, 0x07800000,
890 				0x08000000, 0x08800000, 0x09000000, 0x09800000, 0x0A000000, 0x0A800000, 0x0B000000, 0x0B800000, 0x0C000000, 0x0C800000, 0x0D000000, 0x0D800000, 0x0E000000, 0x0E800000, 0x0F000000, 0x47800000,
891 				0x80000000, 0x80800000, 0x81000000, 0x81800000, 0x82000000, 0x82800000, 0x83000000, 0x83800000, 0x84000000, 0x84800000, 0x85000000, 0x85800000, 0x86000000, 0x86800000, 0x87000000, 0x87800000,
892 				0x88000000, 0x88800000, 0x89000000, 0x89800000, 0x8A000000, 0x8A800000, 0x8B000000, 0x8B800000, 0x8C000000, 0x8C800000, 0x8D000000, 0x8D800000, 0x8E000000, 0x8E800000, 0x8F000000, 0xC7800000 };
893 			static const unsigned short offset_table[64] = {
894 				   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,
895 				   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 };
896 			uint32 bits = mantissa_table[offset_table[value>>10]+(value&0x3FF)] + exponent_table[value>>10];
897 //			return *reinterpret_cast<float*>(&bits);			//violating strict aliasing!
898 			float out;
899 			std::memcpy(&out, &bits, sizeof(float));
900 			return out;
901 		}
902 
903 		/// Convert half-precision to IEEE double-precision.
904 		/// \param value binary representation of half-precision value
905 		/// \return double-precision value
half2float_impl(uint16 value,double,true_type)906 		inline double half2float_impl(uint16 value, double, true_type)
907 		{
908 			typedef bits<float>::type uint32;
909 			typedef bits<double>::type uint64;
910 			uint32 hi = static_cast<uint32>(value&0x8000) << 16;
911 			int abs = value & 0x7FFF;
912 			if(abs)
913 			{
914 				hi |= 0x3F000000 << static_cast<unsigned>(abs>=0x7C00);
915 				for(; abs<0x400; abs<<=1,hi-=0x100000) ;
916 				hi += static_cast<uint32>(abs) << 10;
917 			}
918 			uint64 bits = static_cast<uint64>(hi) << 32;
919 //			return *reinterpret_cast<double*>(&bits);			//violating strict aliasing!
920 			double out;
921 			std::memcpy(&out, &bits, sizeof(double));
922 			return out;
923 		}
924 
925 		/// Convert half-precision to non-IEEE floating point.
926 		/// \tparam T type to convert to (builtin integer type)
927 		/// \param value binary representation of half-precision value
928 		/// \return floating point value
half2float_impl(uint16 value,T,...)929 		template<typename T> T half2float_impl(uint16 value, T, ...)
930 		{
931 			T out;
932 			int abs = value & 0x7FFF;
933 			if(abs > 0x7C00)
934 				out = std::numeric_limits<T>::has_quiet_NaN ? std::numeric_limits<T>::quiet_NaN() : T();
935 			else if(abs == 0x7C00)
936 				out = std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : std::numeric_limits<T>::max();
937 			else if(abs > 0x3FF)
938 				out = std::ldexp(static_cast<T>((abs&0x3FF)|0x400), (abs>>10)-25);
939 			else
940 				out = std::ldexp(static_cast<T>(abs), -24);
941 			return (value&0x8000) ? -out : out;
942 		}
943 
944 		/// Convert half-precision to floating point.
945 		/// \tparam T type to convert to (builtin integer type)
946 		/// \param value binary representation of half-precision value
947 		/// \return floating point value
half2float(uint16 value)948 		template<typename T> T half2float(uint16 value)
949 		{
950 			return half2float_impl(value, T(), bool_type<std::numeric_limits<T>::is_iec559&&sizeof(typename bits<T>::type)==sizeof(T)>());
951 		}
952 
953 		/// Convert half-precision floating point to integer.
954 		/// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding
955 		/// \tparam E `true` for round to even, `false` for round away from zero
956 		/// \tparam T type to convert to (buitlin integer type with at least 16 bits precision, excluding any implicit sign bits)
957 		/// \param value binary representation of half-precision value
958 		/// \return integral value
half2int_impl(uint16 value)959 		template<std::float_round_style R,bool E,typename T> T half2int_impl(uint16 value)
960 		{
961 		#if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
962 			static_assert(std::is_integral<T>::value, "half to int conversion only supports builtin integer types");
963 		#endif
964 			unsigned int e = value & 0x7FFF;
965 			if(e >= 0x7C00)
966 				return (value&0x8000) ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max();
967 			if(e < 0x3800)
968 			{
969 				if(R == std::round_toward_infinity)
970 					return T(~(value>>15)&(e!=0));
971 				else if(R == std::round_toward_neg_infinity)
972 					return -T(value>0x8000);
973 				return T();
974 			}
975 			unsigned int m = (value&0x3FF) | 0x400;
976 			e >>= 10;
977 			if(e < 25)
978 			{
979 				if(R == std::round_to_nearest)
980 					m += (1<<(24-e)) - (~(m>>(25-e))&E);
981 				else if(R == std::round_toward_infinity)
982 					m += ((value>>15)-1) & ((1<<(25-e))-1U);
983 				else if(R == std::round_toward_neg_infinity)
984 					m += -(value>>15) & ((1<<(25-e))-1U);
985 				m >>= 25 - e;
986 			}
987 			else
988 				m <<= e - 25;
989 			return (value&0x8000) ? -static_cast<T>(m) : static_cast<T>(m);
990 		}
991 
992 		/// Convert half-precision floating point to integer.
993 		/// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding
994 		/// \tparam T type to convert to (buitlin integer type with at least 16 bits precision, excluding any implicit sign bits)
995 		/// \param value binary representation of half-precision value
996 		/// \return integral value
half2int(uint16 value)997 		template<std::float_round_style R,typename T> T half2int(uint16 value) { return half2int_impl<R,HALF_ROUND_TIES_TO_EVEN,T>(value); }
998 
999 		/// Convert half-precision floating point to integer using round-to-nearest-away-from-zero.
1000 		/// \tparam T type to convert to (buitlin integer type with at least 16 bits precision, excluding any implicit sign bits)
1001 		/// \param value binary representation of half-precision value
1002 		/// \return integral value
half2int_up(uint16 value)1003 		template<typename T> T half2int_up(uint16 value) { return half2int_impl<std::round_to_nearest,0,T>(value); }
1004 
1005 		/// Round half-precision number to nearest integer value.
1006 		/// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding
1007 		/// \tparam E `true` for round to even, `false` for round away from zero
1008 		/// \param value binary representation of half-precision value
1009 		/// \return half-precision bits for nearest integral value
round_half_impl(uint16 value)1010 		template<std::float_round_style R,bool E> uint16 round_half_impl(uint16 value)
1011 		{
1012 			unsigned int e = value & 0x7FFF;
1013 			uint16 result = value;
1014 			if(e < 0x3C00)
1015 			{
1016 				result &= 0x8000;
1017 				if(R == std::round_to_nearest)
1018 					result |= 0x3C00U & -(e>=(0x3800+E));
1019 				else if(R == std::round_toward_infinity)
1020 					result |= 0x3C00U & -(~(value>>15)&(e!=0));
1021 				else if(R == std::round_toward_neg_infinity)
1022 					result |= 0x3C00U & -(value>0x8000);
1023 			}
1024 			else if(e < 0x6400)
1025 			{
1026 				e = 25 - (e>>10);
1027 				unsigned int mask = (1<<e) - 1;
1028 				if(R == std::round_to_nearest)
1029 					result += (1<<(e-1)) - (~(result>>e)&E);
1030 				else if(R == std::round_toward_infinity)
1031 					result += mask & ((value>>15)-1);
1032 				else if(R == std::round_toward_neg_infinity)
1033 					result += mask & -(value>>15);
1034 				result &= ~mask;
1035 			}
1036 			return result;
1037 		}
1038 
1039 		/// Round half-precision number to nearest integer value.
1040 		/// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding
1041 		/// \param value binary representation of half-precision value
1042 		/// \return half-precision bits for nearest integral value
round_half(uint16 value)1043 		template<std::float_round_style R> uint16 round_half(uint16 value) { return round_half_impl<R,HALF_ROUND_TIES_TO_EVEN>(value); }
1044 
1045 		/// Round half-precision number to nearest integer value using round-to-nearest-away-from-zero.
1046 		/// \param value binary representation of half-precision value
1047 		/// \return half-precision bits for nearest integral value
round_half_up(uint16 value)1048 		inline uint16 round_half_up(uint16 value) { return round_half_impl<std::round_to_nearest,0>(value); }
1049 		/// \}
1050 
1051 		struct functions;
1052 		template<typename> struct unary_specialized;
1053 		template<typename,typename> struct binary_specialized;
1054 		template<typename,typename,std::float_round_style> struct half_caster;
1055 	}
1056 
1057 	/// Half-precision floating point type.
1058 	/// This class implements an IEEE-conformant half-precision floating point type with the usual arithmetic operators and
1059 	/// conversions. It is implicitly convertible to single-precision floating point, which makes artihmetic expressions and
1060 	/// functions with mixed-type operands to be of the most precise operand type. Additionally all arithmetic operations
1061 	/// (and many mathematical functions) are carried out in single-precision internally. All conversions from single- to
1062 	/// half-precision are done using the library's default rounding mode, but temporary results inside chained arithmetic
1063 	/// expressions are kept in single-precision as long as possible (while of course still maintaining a strong half-precision type).
1064 	///
1065 	/// According to the C++98/03 definition, the half type is not a POD type. But according to C++11's less strict and
1066 	/// extended definitions it is both a standard layout type and a trivially copyable type (even if not a POD type), which
1067 	/// means it can be standard-conformantly copied using raw binary copies. But in this context some more words about the
1068 	/// actual size of the type. Although the half is representing an IEEE 16-bit type, it does not neccessarily have to be of
1069 	/// exactly 16-bits size. But on any reasonable implementation the actual binary representation of this type will most
1070 	/// probably not ivolve any additional "magic" or padding beyond the simple binary representation of the underlying 16-bit
1071 	/// IEEE number, even if not strictly guaranteed by the standard. But even then it only has an actual size of 16 bits if
1072 	/// your C++ implementation supports an unsigned integer type of exactly 16 bits width. But this should be the case on
1073 	/// nearly any reasonable platform.
1074 	///
1075 	/// So if your C++ implementation is not totally exotic or imposes special alignment requirements, it is a reasonable
1076 	/// assumption that the data of a half is just comprised of the 2 bytes of the underlying IEEE representation.
1077 	class half
1078 	{
1079 		friend struct detail::functions;
1080 		friend struct detail::unary_specialized<half>;
1081 		friend struct detail::binary_specialized<half,half>;
1082 		template<typename,typename,std::float_round_style> friend struct detail::half_caster;
1083 		friend class std::numeric_limits<half>;
1084 	#if HALF_ENABLE_CPP11_HASH
1085 		friend struct std::hash<half>;
1086 	#endif
1087 	#if HALF_ENABLE_CPP11_USER_LITERALS
1088 		friend half literal::operator""_h(long double);
1089 	#endif
1090 
1091 	public:
1092 		/// Default constructor.
1093 		/// This initializes the half to 0. Although this does not match the builtin types' default-initialization semantics
1094 		/// and may be less efficient than no initialization, it is needed to provide proper value-initialization semantics.
half()1095 		HALF_CONSTEXPR half() HALF_NOEXCEPT : data_() {}
1096 
1097 		/// Copy constructor.
1098 		/// \tparam T type of concrete half expression
1099 		/// \param rhs half expression to copy from
half(detail::expr rhs)1100 		half(detail::expr rhs) : data_(detail::float2half<round_style>(static_cast<float>(rhs))) {}
1101 
1102 		/// Conversion constructor.
1103 		/// \param rhs float to convert
half(float rhs)1104 		explicit half(float rhs) : data_(detail::float2half<round_style>(rhs)) {}
1105 
1106 		/// Conversion to single-precision.
1107 		/// \return single precision value representing expression value
operator float() const1108 		operator float() const { return detail::half2float<float>(data_); }
1109 
1110 		/// Assignment operator.
1111 		/// \tparam T type of concrete half expression
1112 		/// \param rhs half expression to copy from
1113 		/// \return reference to this half
operator =(detail::expr rhs)1114 		half& operator=(detail::expr rhs) { return *this = static_cast<float>(rhs); }
1115 
1116 		/// Arithmetic assignment.
1117 		/// \tparam T type of concrete half expression
1118 		/// \param rhs half expression to add
1119 		/// \return reference to this half
operator +=(T rhs)1120 		template<typename T> typename detail::enable<half&,T>::type operator+=(T rhs) { return *this += static_cast<float>(rhs); }
1121 
1122 		/// Arithmetic assignment.
1123 		/// \tparam T type of concrete half expression
1124 		/// \param rhs half expression to subtract
1125 		/// \return reference to this half
operator -=(T rhs)1126 		template<typename T> typename detail::enable<half&,T>::type operator-=(T rhs) { return *this -= static_cast<float>(rhs); }
1127 
1128 		/// Arithmetic assignment.
1129 		/// \tparam T type of concrete half expression
1130 		/// \param rhs half expression to multiply with
1131 		/// \return reference to this half
operator *=(T rhs)1132 		template<typename T> typename detail::enable<half&,T>::type operator*=(T rhs) { return *this *= static_cast<float>(rhs); }
1133 
1134 		/// Arithmetic assignment.
1135 		/// \tparam T type of concrete half expression
1136 		/// \param rhs half expression to divide by
1137 		/// \return reference to this half
operator /=(T rhs)1138 		template<typename T> typename detail::enable<half&,T>::type operator/=(T rhs) { return *this /= static_cast<float>(rhs); }
1139 
1140 		/// Assignment operator.
1141 		/// \param rhs single-precision value to copy from
1142 		/// \return reference to this half
operator =(float rhs)1143 		half& operator=(float rhs) { data_ = detail::float2half<round_style>(rhs); return *this; }
1144 
1145 		/// Arithmetic assignment.
1146 		/// \param rhs single-precision value to add
1147 		/// \return reference to this half
operator +=(float rhs)1148 		half& operator+=(float rhs) { data_ = detail::float2half<round_style>(detail::half2float<float>(data_)+rhs); return *this; }
1149 
1150 		/// Arithmetic assignment.
1151 		/// \param rhs single-precision value to subtract
1152 		/// \return reference to this half
operator -=(float rhs)1153 		half& operator-=(float rhs) { data_ = detail::float2half<round_style>(detail::half2float<float>(data_)-rhs); return *this; }
1154 
1155 		/// Arithmetic assignment.
1156 		/// \param rhs single-precision value to multiply with
1157 		/// \return reference to this half
operator *=(float rhs)1158 		half& operator*=(float rhs) { data_ = detail::float2half<round_style>(detail::half2float<float>(data_)*rhs); return *this; }
1159 
1160 		/// Arithmetic assignment.
1161 		/// \param rhs single-precision value to divide by
1162 		/// \return reference to this half
operator /=(float rhs)1163 		half& operator/=(float rhs) { data_ = detail::float2half<round_style>(detail::half2float<float>(data_)/rhs); return *this; }
1164 
1165 		/// Prefix increment.
1166 		/// \return incremented half value
operator ++()1167 		half& operator++() { return *this += 1.0f; }
1168 
1169 		/// Prefix decrement.
1170 		/// \return decremented half value
operator --()1171 		half& operator--() { return *this -= 1.0f; }
1172 
1173 		/// Postfix increment.
1174 		/// \return non-incremented half value
operator ++(int)1175 		half operator++(int) { half out(*this); ++*this; return out; }
1176 
1177 		/// Postfix decrement.
1178 		/// \return non-decremented half value
operator --(int)1179 		half operator--(int) { half out(*this); --*this; return out; }
1180 
1181 	private:
1182 		/// Rounding mode to use
1183 		static const std::float_round_style round_style = (std::float_round_style)(HALF_ROUND_STYLE);
1184 
1185 		/// Constructor.
1186 		/// \param bits binary representation to set half to
half(detail::binary_t,detail::uint16 bits)1187 		HALF_CONSTEXPR half(detail::binary_t, detail::uint16 bits) HALF_NOEXCEPT : data_(bits) {}
1188 
1189 		/// Internal binary representation
1190 		detail::uint16 data_;
1191 	};
1192 
1193 #if HALF_ENABLE_CPP11_USER_LITERALS
1194 	namespace literal
1195 	{
1196 		/// Half literal.
1197 		/// While this returns an actual half-precision value, half literals can unfortunately not be constant expressions due
1198 		/// to rather involved conversions.
1199 		/// \param value literal value
1200 		/// \return half with given value (if representable)
operator ""_h(long double value)1201 		inline half operator""_h(long double value) { return half(detail::binary, detail::float2half<half::round_style>(value)); }
1202 	}
1203 #endif
1204 
1205 	namespace detail
1206 	{
1207 		/// Wrapper implementing unspecialized half-precision functions.
1208 		struct functions
1209 		{
1210 			/// Addition implementation.
1211 			/// \param x first operand
1212 			/// \param y second operand
1213 			/// \return Half-precision sum stored in single-precision
plushalf_float::detail::functions1214 			static expr plus(float x, float y) { return expr(x+y); }
1215 
1216 			/// Subtraction implementation.
1217 			/// \param x first operand
1218 			/// \param y second operand
1219 			/// \return Half-precision difference stored in single-precision
minushalf_float::detail::functions1220 			static expr minus(float x, float y) { return expr(x-y); }
1221 
1222 			/// Multiplication implementation.
1223 			/// \param x first operand
1224 			/// \param y second operand
1225 			/// \return Half-precision product stored in single-precision
multiplieshalf_float::detail::functions1226 			static expr multiplies(float x, float y) { return expr(x*y); }
1227 
1228 			/// Division implementation.
1229 			/// \param x first operand
1230 			/// \param y second operand
1231 			/// \return Half-precision quotient stored in single-precision
divideshalf_float::detail::functions1232 			static expr divides(float x, float y) { return expr(x/y); }
1233 
1234 			/// Output implementation.
1235 			/// \param out stream to write to
1236 			/// \param arg value to write
1237 			/// \return reference to stream
writehalf_float::detail::functions1238 			template<typename charT,typename traits> static std::basic_ostream<charT,traits>& write(std::basic_ostream<charT,traits> &out, float arg) { return out << arg; }
1239 
1240 			/// Input implementation.
1241 			/// \param in stream to read from
1242 			/// \param arg half to read into
1243 			/// \return reference to stream
readhalf_float::detail::functions1244 			template<typename charT,typename traits> static std::basic_istream<charT,traits>& read(std::basic_istream<charT,traits> &in, half &arg)
1245 			{
1246 				float f;
1247 				if(in >> f)
1248 					arg = f;
1249 				return in;
1250 			}
1251 
1252 			/// Modulo implementation.
1253 			/// \param x first operand
1254 			/// \param y second operand
1255 			/// \return Half-precision division remainder stored in single-precision
fmodhalf_float::detail::functions1256 			static expr fmod(float x, float y) { return expr(std::fmod(x, y)); }
1257 
1258 			/// Remainder implementation.
1259 			/// \param x first operand
1260 			/// \param y second operand
1261 			/// \return Half-precision division remainder stored in single-precision
remainderhalf_float::detail::functions1262 			static expr remainder(float x, float y)
1263 			{
1264 			#if HALF_ENABLE_CPP11_CMATH
1265 				return expr(std::remainder(x, y));
1266 			#else
1267 				if(builtin_isnan(x) || builtin_isnan(y))
1268 					return expr(std::numeric_limits<float>::quiet_NaN());
1269 				float ax = std::fabs(x), ay = std::fabs(y);
1270 				if(ax >= 65536.0f || ay < std::ldexp(1.0f, -24))
1271 					return expr(std::numeric_limits<float>::quiet_NaN());
1272 				if(ay >= 65536.0f)
1273 					return expr(x);
1274 				if(ax == ay)
1275 					return expr(builtin_signbit(x) ? -0.0f : 0.0f);
1276 				ax = std::fmod(ax, ay+ay);
1277 				float y2 = 0.5f * ay;
1278 				if(ax > y2)
1279 				{
1280 					ax -= ay;
1281 					if(ax >= y2)
1282 						ax -= ay;
1283 				}
1284 				return expr(builtin_signbit(x) ? -ax : ax);
1285 			#endif
1286 			}
1287 
1288 			/// Remainder implementation.
1289 			/// \param x first operand
1290 			/// \param y second operand
1291 			/// \param quo address to store quotient bits at
1292 			/// \return Half-precision division remainder stored in single-precision
remquohalf_float::detail::functions1293 			static expr remquo(float x, float y, int *quo)
1294 			{
1295 			#if HALF_ENABLE_CPP11_CMATH
1296 				return expr(std::remquo(x, y, quo));
1297 			#else
1298 				if(builtin_isnan(x) || builtin_isnan(y))
1299 					return expr(std::numeric_limits<float>::quiet_NaN());
1300 				bool sign = builtin_signbit(x), qsign = static_cast<bool>(sign^builtin_signbit(y));
1301 				float ax = std::fabs(x), ay = std::fabs(y);
1302 				if(ax >= 65536.0f || ay < std::ldexp(1.0f, -24))
1303 					return expr(std::numeric_limits<float>::quiet_NaN());
1304 				if(ay >= 65536.0f)
1305 					return expr(x);
1306 				if(ax == ay)
1307 					return *quo = qsign ? -1 : 1, expr(sign ? -0.0f : 0.0f);
1308 				ax = std::fmod(ax, 8.0f*ay);
1309 				int cquo = 0;
1310 				if(ax >= 4.0f * ay)
1311 				{
1312 					ax -= 4.0f * ay;
1313 					cquo += 4;
1314 				}
1315 				if(ax >= 2.0f * ay)
1316 				{
1317 					ax -= 2.0f * ay;
1318 					cquo += 2;
1319 				}
1320 				float y2 = 0.5f * ay;
1321 				if(ax > y2)
1322 				{
1323 					ax -= ay;
1324 					++cquo;
1325 					if(ax >= y2)
1326 					{
1327 						ax -= ay;
1328 						++cquo;
1329 					}
1330 				}
1331 				return *quo = qsign ? -cquo : cquo, expr(sign ? -ax : ax);
1332 			#endif
1333 			}
1334 
1335 			/// Positive difference implementation.
1336 			/// \param x first operand
1337 			/// \param y second operand
1338 			/// \return Positive difference stored in single-precision
fdimhalf_float::detail::functions1339 			static expr fdim(float x, float y)
1340 			{
1341 			#if HALF_ENABLE_CPP11_CMATH
1342 				return expr(std::fdim(x, y));
1343 			#else
1344 				return expr((x<=y) ? 0.0f : (x-y));
1345 			#endif
1346 			}
1347 
1348 			/// Fused multiply-add implementation.
1349 			/// \param x first operand
1350 			/// \param y second operand
1351 			/// \param z third operand
1352 			/// \return \a x * \a y + \a z stored in single-precision
fmahalf_float::detail::functions1353 			static expr fma(float x, float y, float z)
1354 			{
1355 			#if HALF_ENABLE_CPP11_CMATH && defined(FP_FAST_FMAF)
1356 				return expr(std::fma(x, y, z));
1357 			#else
1358 				return expr(x*y+z);
1359 			#endif
1360 			}
1361 
1362 			/// Get NaN.
1363 			/// \return Half-precision quiet NaN
nanhhalf_float::detail::functions1364 			static half nanh() { return half(binary, 0x7FFF); }
1365 
1366 			/// Exponential implementation.
1367 			/// \param arg function argument
1368 			/// \return function value stored in single-preicision
exphalf_float::detail::functions1369 			static expr exp(float arg) { return expr(std::exp(arg)); }
1370 
1371 			/// Exponential implementation.
1372 			/// \param arg function argument
1373 			/// \return function value stored in single-preicision
expm1half_float::detail::functions1374 			static expr expm1(float arg)
1375 			{
1376 			#if HALF_ENABLE_CPP11_CMATH
1377 				return expr(std::expm1(arg));
1378 			#else
1379 				return expr(static_cast<float>(std::exp(static_cast<double>(arg))-1.0));
1380 			#endif
1381 			}
1382 
1383 			/// Binary exponential implementation.
1384 			/// \param arg function argument
1385 			/// \return function value stored in single-preicision
exp2half_float::detail::functions1386 			static expr exp2(float arg)
1387 			{
1388 			#if HALF_ENABLE_CPP11_CMATH
1389 				return expr(std::exp2(arg));
1390 			#else
1391 				return expr(static_cast<float>(std::exp(arg*0.69314718055994530941723212145818)));
1392 			#endif
1393 			}
1394 
1395 			/// Logarithm implementation.
1396 			/// \param arg function argument
1397 			/// \return function value stored in single-preicision
loghalf_float::detail::functions1398 			static expr log(float arg) { return expr(std::log(arg)); }
1399 
1400 			/// Common logarithm implementation.
1401 			/// \param arg function argument
1402 			/// \return function value stored in single-preicision
log10half_float::detail::functions1403 			static expr log10(float arg) { return expr(std::log10(arg)); }
1404 
1405 			/// Logarithm implementation.
1406 			/// \param arg function argument
1407 			/// \return function value stored in single-preicision
log1phalf_float::detail::functions1408 			static expr log1p(float arg)
1409 			{
1410 			#if HALF_ENABLE_CPP11_CMATH
1411 				return expr(std::log1p(arg));
1412 			#else
1413 				return expr(static_cast<float>(std::log(1.0+arg)));
1414 			#endif
1415 			}
1416 
1417 			/// Binary logarithm implementation.
1418 			/// \param arg function argument
1419 			/// \return function value stored in single-preicision
log2half_float::detail::functions1420 			static expr log2(float arg)
1421 			{
1422 			#if HALF_ENABLE_CPP11_CMATH
1423 				return expr(std::log2(arg));
1424 			#else
1425 				return expr(static_cast<float>(std::log(static_cast<double>(arg))*1.4426950408889634073599246810019));
1426 			#endif
1427 			}
1428 
1429 			/// Square root implementation.
1430 			/// \param arg function argument
1431 			/// \return function value stored in single-preicision
sqrthalf_float::detail::functions1432 			static expr sqrt(float arg) { return expr(std::sqrt(arg)); }
1433 
1434 			/// Cubic root implementation.
1435 			/// \param arg function argument
1436 			/// \return function value stored in single-preicision
cbrthalf_float::detail::functions1437 			static expr cbrt(float arg)
1438 			{
1439 			#if HALF_ENABLE_CPP11_CMATH
1440 				return expr(std::cbrt(arg));
1441 			#else
1442 				if(builtin_isnan(arg) || builtin_isinf(arg))
1443 					return expr(arg);
1444 				return expr(builtin_signbit(arg) ? -static_cast<float>(std::pow(-static_cast<double>(arg), 1.0/3.0)) :
1445 					static_cast<float>(std::pow(static_cast<double>(arg), 1.0/3.0)));
1446 			#endif
1447 			}
1448 
1449 			/// Hypotenuse implementation.
1450 			/// \param x first argument
1451 			/// \param y second argument
1452 			/// \return function value stored in single-preicision
hypothalf_float::detail::functions1453 			static expr hypot(float x, float y)
1454 			{
1455 			#if HALF_ENABLE_CPP11_CMATH
1456 				return expr(std::hypot(x, y));
1457 			#else
1458 				return expr((builtin_isinf(x) || builtin_isinf(y)) ? std::numeric_limits<float>::infinity() :
1459 					static_cast<float>(std::sqrt(static_cast<double>(x)*x+static_cast<double>(y)*y)));
1460 			#endif
1461 			}
1462 
1463 			/// Power implementation.
1464 			/// \param base value to exponentiate
1465 			/// \param exp power to expontiate to
1466 			/// \return function value stored in single-preicision
powhalf_float::detail::functions1467 			static expr pow(float base, float exp) { return expr(std::pow(base, exp)); }
1468 
1469 			/// Sine implementation.
1470 			/// \param arg function argument
1471 			/// \return function value stored in single-preicision
sinhalf_float::detail::functions1472 			static expr sin(float arg) { return expr(std::sin(arg)); }
1473 
1474 			/// Cosine implementation.
1475 			/// \param arg function argument
1476 			/// \return function value stored in single-preicision
coshalf_float::detail::functions1477 			static expr cos(float arg) { return expr(std::cos(arg)); }
1478 
1479 			/// Tan implementation.
1480 			/// \param arg function argument
1481 			/// \return function value stored in single-preicision
tanhalf_float::detail::functions1482 			static expr tan(float arg) { return expr(std::tan(arg)); }
1483 
1484 			/// Arc sine implementation.
1485 			/// \param arg function argument
1486 			/// \return function value stored in single-preicision
asinhalf_float::detail::functions1487 			static expr asin(float arg) { return expr(std::asin(arg)); }
1488 
1489 			/// Arc cosine implementation.
1490 			/// \param arg function argument
1491 			/// \return function value stored in single-preicision
acoshalf_float::detail::functions1492 			static expr acos(float arg) { return expr(std::acos(arg)); }
1493 
1494 			/// Arc tangent implementation.
1495 			/// \param arg function argument
1496 			/// \return function value stored in single-preicision
atanhalf_float::detail::functions1497 			static expr atan(float arg) { return expr(std::atan(arg)); }
1498 
1499 			/// Arc tangent implementation.
1500 			/// \param x first argument
1501 			/// \param y second argument
1502 			/// \return function value stored in single-preicision
atan2half_float::detail::functions1503 			static expr atan2(float x, float y) { return expr(std::atan2(x, y)); }
1504 
1505 			/// Hyperbolic sine implementation.
1506 			/// \param arg function argument
1507 			/// \return function value stored in single-preicision
sinhhalf_float::detail::functions1508 			static expr sinh(float arg) { return expr(std::sinh(arg)); }
1509 
1510 			/// Hyperbolic cosine implementation.
1511 			/// \param arg function argument
1512 			/// \return function value stored in single-preicision
coshhalf_float::detail::functions1513 			static expr cosh(float arg) { return expr(std::cosh(arg)); }
1514 
1515 			/// Hyperbolic tangent implementation.
1516 			/// \param arg function argument
1517 			/// \return function value stored in single-preicision
tanhhalf_float::detail::functions1518 			static expr tanh(float arg) { return expr(std::tanh(arg)); }
1519 
1520 			/// Hyperbolic area sine implementation.
1521 			/// \param arg function argument
1522 			/// \return function value stored in single-preicision
asinhhalf_float::detail::functions1523 			static expr asinh(float arg)
1524 			{
1525 			#if HALF_ENABLE_CPP11_CMATH
1526 				return expr(std::asinh(arg));
1527 			#else
1528 				return expr((arg==-std::numeric_limits<float>::infinity()) ? arg : static_cast<float>(std::log(arg+std::sqrt(arg*arg+1.0))));
1529 			#endif
1530 			}
1531 
1532 			/// Hyperbolic area cosine implementation.
1533 			/// \param arg function argument
1534 			/// \return function value stored in single-preicision
acoshhalf_float::detail::functions1535 			static expr acosh(float arg)
1536 			{
1537 			#if HALF_ENABLE_CPP11_CMATH
1538 				return expr(std::acosh(arg));
1539 			#else
1540 				return expr((arg<-1.0f) ? std::numeric_limits<float>::quiet_NaN() : static_cast<float>(std::log(arg+std::sqrt(arg*arg-1.0))));
1541 			#endif
1542 			}
1543 
1544 			/// Hyperbolic area tangent implementation.
1545 			/// \param arg function argument
1546 			/// \return function value stored in single-preicision
atanhhalf_float::detail::functions1547 			static expr atanh(float arg)
1548 			{
1549 			#if HALF_ENABLE_CPP11_CMATH
1550 				return expr(std::atanh(arg));
1551 			#else
1552 				return expr(static_cast<float>(0.5*std::log((1.0+arg)/(1.0-arg))));
1553 			#endif
1554 			}
1555 
1556 			/// Error function implementation.
1557 			/// \param arg function argument
1558 			/// \return function value stored in single-preicision
erfhalf_float::detail::functions1559 			static expr erf(float arg)
1560 			{
1561 			#if HALF_ENABLE_CPP11_CMATH
1562 				return expr(std::erf(arg));
1563 			#else
1564 				return expr(static_cast<float>(erf(static_cast<double>(arg))));
1565 			#endif
1566 			}
1567 
1568 			/// Complementary implementation.
1569 			/// \param arg function argument
1570 			/// \return function value stored in single-preicision
erfchalf_float::detail::functions1571 			static expr erfc(float arg)
1572 			{
1573 			#if HALF_ENABLE_CPP11_CMATH
1574 				return expr(std::erfc(arg));
1575 			#else
1576 				return expr(static_cast<float>(1.0-erf(static_cast<double>(arg))));
1577 			#endif
1578 			}
1579 
1580 			/// Gamma logarithm implementation.
1581 			/// \param arg function argument
1582 			/// \return function value stored in single-preicision
lgammahalf_float::detail::functions1583 			static expr lgamma(float arg)
1584 			{
1585 			#if HALF_ENABLE_CPP11_CMATH
1586 				return expr(std::lgamma(arg));
1587 			#else
1588 				if(builtin_isinf(arg))
1589 					return expr(std::numeric_limits<float>::infinity());
1590 				if(arg < 0.0f)
1591 				{
1592 					float i, f = std::modf(-arg, &i);
1593 					if(f == 0.0f)
1594 						return expr(std::numeric_limits<float>::infinity());
1595 					return expr(static_cast<float>(1.1447298858494001741434273513531-
1596 						std::log(std::abs(std::sin(3.1415926535897932384626433832795*f)))-lgamma(1.0-arg)));
1597 				}
1598 				return expr(static_cast<float>(lgamma(static_cast<double>(arg))));
1599 			#endif
1600 			}
1601 
1602 			/// Gamma implementation.
1603 			/// \param arg function argument
1604 			/// \return function value stored in single-preicision
tgammahalf_float::detail::functions1605 			static expr tgamma(float arg)
1606 			{
1607 			#if HALF_ENABLE_CPP11_CMATH
1608 				return expr(std::tgamma(arg));
1609 			#else
1610 				if(arg == 0.0f)
1611 					return builtin_signbit(arg) ? expr(-std::numeric_limits<float>::infinity()) : expr(std::numeric_limits<float>::infinity());
1612 				if(arg < 0.0f)
1613 				{
1614 					float i, f = std::modf(-arg, &i);
1615 					if(f == 0.0f)
1616 						return expr(std::numeric_limits<float>::quiet_NaN());
1617 					double value = 3.1415926535897932384626433832795 / (std::sin(3.1415926535897932384626433832795*f)*std::exp(lgamma(1.0-arg)));
1618 					return expr(static_cast<float>((std::fmod(i, 2.0f)==0.0f) ? -value : value));
1619 				}
1620 				if(builtin_isinf(arg))
1621 					return expr(arg);
1622 				return expr(static_cast<float>(std::exp(lgamma(static_cast<double>(arg)))));
1623 			#endif
1624 			}
1625 
1626 			/// Floor implementation.
1627 			/// \param arg value to round
1628 			/// \return rounded value
floorhalf_float::detail::functions1629 			static half floor(half arg) { return half(binary, round_half<std::round_toward_neg_infinity>(arg.data_)); }
1630 
1631 			/// Ceiling implementation.
1632 			/// \param arg value to round
1633 			/// \return rounded value
ceilhalf_float::detail::functions1634 			static half ceil(half arg) { return half(binary, round_half<std::round_toward_infinity>(arg.data_)); }
1635 
1636 			/// Truncation implementation.
1637 			/// \param arg value to round
1638 			/// \return rounded value
trunchalf_float::detail::functions1639 			static half trunc(half arg) { return half(binary, round_half<std::round_toward_zero>(arg.data_)); }
1640 
1641 			/// Nearest integer implementation.
1642 			/// \param arg value to round
1643 			/// \return rounded value
roundhalf_float::detail::functions1644 			static half round(half arg) { return half(binary, round_half_up(arg.data_)); }
1645 
1646 			/// Nearest integer implementation.
1647 			/// \param arg value to round
1648 			/// \return rounded value
lroundhalf_float::detail::functions1649 			static long lround(half arg) { return detail::half2int_up<long>(arg.data_); }
1650 
1651 			/// Nearest integer implementation.
1652 			/// \param arg value to round
1653 			/// \return rounded value
rinthalf_float::detail::functions1654 			static half rint(half arg) { return half(binary, round_half<half::round_style>(arg.data_)); }
1655 
1656 			/// Nearest integer implementation.
1657 			/// \param arg value to round
1658 			/// \return rounded value
lrinthalf_float::detail::functions1659 			static long lrint(half arg) { return detail::half2int<half::round_style,long>(arg.data_); }
1660 
1661 		#if HALF_ENABLE_CPP11_LONG_LONG
1662 			/// Nearest integer implementation.
1663 			/// \param arg value to round
1664 			/// \return rounded value
llroundhalf_float::detail::functions1665 			static long long llround(half arg) { return detail::half2int_up<long long>(arg.data_); }
1666 
1667 			/// Nearest integer implementation.
1668 			/// \param arg value to round
1669 			/// \return rounded value
llrinthalf_float::detail::functions1670 			static long long llrint(half arg) { return detail::half2int<half::round_style,long long>(arg.data_); }
1671 		#endif
1672 
1673 			/// Decompression implementation.
1674 			/// \param arg number to decompress
1675 			/// \param exp address to store exponent at
1676 			/// \return normalized significant
frexphalf_float::detail::functions1677 			static half frexp(half arg, int *exp)
1678 			{
1679 				int m = arg.data_ & 0x7FFF, e = -14;
1680 				if(m >= 0x7C00 || !m)
1681 					return *exp = 0, arg;
1682 				for(; m<0x400; m<<=1,--e) ;
1683 				return *exp = e+(m>>10), half(binary, (arg.data_&0x8000)|0x3800|(m&0x3FF));
1684 			}
1685 
1686 			/// Decompression implementation.
1687 			/// \param arg number to decompress
1688 			/// \param iptr address to store integer part at
1689 			/// \return fractional part
modfhalf_float::detail::functions1690 			static half modf(half arg, half *iptr)
1691 			{
1692 				unsigned int e = arg.data_ & 0x7FFF;
1693 				if(e >= 0x6400)
1694 					return *iptr = arg, half(binary, arg.data_&(0x8000U|-(e>0x7C00)));
1695 				if(e < 0x3C00)
1696 					return iptr->data_ = arg.data_ & 0x8000, arg;
1697 				e >>= 10;
1698 				unsigned int mask = (1<<(25-e)) - 1, m = arg.data_ & mask;
1699 				iptr->data_ = arg.data_ & ~mask;
1700 				if(!m)
1701 					return half(binary, arg.data_&0x8000);
1702 				for(; m<0x400; m<<=1,--e) ;
1703 				return half(binary, static_cast<uint16>((arg.data_&0x8000)|(e<<10)|(m&0x3FF)));
1704 			}
1705 
1706 			/// Scaling implementation.
1707 			/// \param arg number to scale
1708 			/// \param exp power of two to scale by
1709 			/// \return scaled number
scalblnhalf_float::detail::functions1710 			static half scalbln(half arg, long exp)
1711 			{
1712 				unsigned int m = arg.data_ & 0x7FFF;
1713 				if(m >= 0x7C00 || !m)
1714 					return arg;
1715 				for(; m<0x400; m<<=1,--exp) ;
1716 				exp += m >> 10;
1717 				uint16 value = arg.data_ & 0x8000;
1718 				if(exp > 30)
1719 				{
1720 					if(half::round_style == std::round_toward_zero)
1721 						value |= 0x7BFF;
1722 					else if(half::round_style == std::round_toward_infinity)
1723 						value |= 0x7C00 - (value>>15);
1724 					else if(half::round_style == std::round_toward_neg_infinity)
1725 						value |= 0x7BFF + (value>>15);
1726 					else
1727 						value |= 0x7C00;
1728 				}
1729 				else if(exp > 0)
1730 					value |= (exp<<10) | (m&0x3FF);
1731 				else if(exp > -11)
1732 				{
1733 					m = (m&0x3FF) | 0x400;
1734 					if(half::round_style == std::round_to_nearest)
1735 					{
1736 						m += 1 << -exp;
1737 					#if HALF_ROUND_TIES_TO_EVEN
1738 						m -= (m>>(1-exp)) & 1;
1739 					#endif
1740 					}
1741 					else if(half::round_style == std::round_toward_infinity)
1742 						m += ((value>>15)-1) & ((1<<(1-exp))-1U);
1743 					else if(half::round_style == std::round_toward_neg_infinity)
1744 						m += -(value>>15) & ((1<<(1-exp))-1U);
1745 					value |= m >> (1-exp);
1746 				}
1747 				else if(half::round_style == std::round_toward_infinity)
1748 					value -= (value>>15) - 1;
1749 				else if(half::round_style == std::round_toward_neg_infinity)
1750 					value += value >> 15;
1751 				return half(binary, value);
1752 			}
1753 
1754 			/// Exponent implementation.
1755 			/// \param arg number to query
1756 			/// \return floating point exponent
ilogbhalf_float::detail::functions1757 			static int ilogb(half arg)
1758 			{
1759 				int abs = arg.data_ & 0x7FFF;
1760 				if(!abs)
1761 					return FP_ILOGB0;
1762 				if(abs < 0x7C00)
1763 				{
1764 					int exp = (abs>>10) - 15;
1765 					if(abs < 0x400)
1766 						for(; abs<0x200; abs<<=1,--exp) ;
1767 					return exp;
1768 				}
1769 				if(abs > 0x7C00)
1770 					return FP_ILOGBNAN;
1771 				return INT_MAX;
1772 			}
1773 
1774 			/// Exponent implementation.
1775 			/// \param arg number to query
1776 			/// \return floating point exponent
logbhalf_float::detail::functions1777 			static half logb(half arg)
1778 			{
1779 				int abs = arg.data_ & 0x7FFF;
1780 				if(!abs)
1781 					return half(binary, 0xFC00);
1782 				if(abs < 0x7C00)
1783 				{
1784 					int exp = (abs>>10) - 15;
1785 					if(abs < 0x400)
1786 						for(; abs<0x200; abs<<=1,--exp) ;
1787 					uint16 bits = (exp<0) << 15;
1788 					if(exp)
1789 					{
1790 						unsigned int m = std::abs(exp) << 6, e = 18;
1791 						for(; m<0x400; m<<=1,--e) ;
1792 						bits |= (e<<10) + m;
1793 					}
1794 					return half(binary, bits);
1795 				}
1796 				if(abs > 0x7C00)
1797 					return arg;
1798 				return half(binary, 0x7C00);
1799 			}
1800 
1801 			/// Enumeration implementation.
1802 			/// \param from number to increase/decrease
1803 			/// \param to direction to enumerate into
1804 			/// \return next representable number
nextafterhalf_float::detail::functions1805 			static half nextafter(half from, half to)
1806 			{
1807 				uint16 fabs = from.data_ & 0x7FFF, tabs = to.data_ & 0x7FFF;
1808 				if(fabs > 0x7C00)
1809 					return from;
1810 				if(tabs > 0x7C00 || from.data_ == to.data_ || !(fabs|tabs))
1811 					return to;
1812 				if(!fabs)
1813 					return half(binary, (to.data_&0x8000)+1);
1814 				bool lt = ((fabs==from.data_) ? static_cast<int>(fabs) : -static_cast<int>(fabs)) <
1815 					((tabs==to.data_) ? static_cast<int>(tabs) : -static_cast<int>(tabs));
1816 				return half(binary, from.data_+(((from.data_>>15)^static_cast<unsigned>(lt))<<1)-1);
1817 			}
1818 
1819 			/// Enumeration implementation.
1820 			/// \param from number to increase/decrease
1821 			/// \param to direction to enumerate into
1822 			/// \return next representable number
nexttowardhalf_float::detail::functions1823 			static half nexttoward(half from, long double to)
1824 			{
1825 				if(isnan(from))
1826 					return from;
1827 				long double lfrom = static_cast<long double>(from);
1828 				if(builtin_isnan(to) || lfrom == to)
1829 					return half(static_cast<float>(to));
1830 				if(!(from.data_&0x7FFF))
1831 					return half(binary, (static_cast<detail::uint16>(builtin_signbit(to))<<15)+1);
1832 				return half(binary, from.data_+(((from.data_>>15)^static_cast<unsigned>(lfrom<to))<<1)-1);
1833 			}
1834 
1835 			/// Sign implementation
1836 			/// \param x first operand
1837 			/// \param y second operand
1838 			/// \return composed value
copysignhalf_float::detail::functions1839 			static half copysign(half x, half y) { return half(binary, x.data_^((x.data_^y.data_)&0x8000)); }
1840 
1841 			/// Classification implementation.
1842 			/// \param arg value to classify
1843 			/// \retval true if infinite number
1844 			/// \retval false else
fpclassifyhalf_float::detail::functions1845 			static int fpclassify(half arg)
1846 			{
1847 				unsigned int abs = arg.data_ & 0x7FFF;
1848 				return abs ? ((abs>0x3FF) ? ((abs>=0x7C00) ? ((abs>0x7C00) ? FP_NAN : FP_INFINITE) : FP_NORMAL) :FP_SUBNORMAL) : FP_ZERO;
1849 			}
1850 
1851 			/// Classification implementation.
1852 			/// \param arg value to classify
1853 			/// \retval true if finite number
1854 			/// \retval false else
isfinitehalf_float::detail::functions1855 			static bool isfinite(half arg) { return (arg.data_&0x7C00) != 0x7C00; }
1856 
1857 			/// Classification implementation.
1858 			/// \param arg value to classify
1859 			/// \retval true if infinite number
1860 			/// \retval false else
isinfhalf_float::detail::functions1861 			static bool isinf(half arg) { return (arg.data_&0x7FFF) == 0x7C00; }
1862 
1863 			/// Classification implementation.
1864 			/// \param arg value to classify
1865 			/// \retval true if not a number
1866 			/// \retval false else
isnanhalf_float::detail::functions1867 			static bool isnan(half arg) { return (arg.data_&0x7FFF) > 0x7C00; }
1868 
1869 			/// Classification implementation.
1870 			/// \param arg value to classify
1871 			/// \retval true if normal number
1872 			/// \retval false else
isnormalhalf_float::detail::functions1873 			static bool isnormal(half arg) { return ((arg.data_&0x7C00)!=0) & ((arg.data_&0x7C00)!=0x7C00); }
1874 
1875 			/// Sign bit implementation.
1876 			/// \param arg value to check
1877 			/// \retval true if signed
1878 			/// \retval false if unsigned
signbithalf_float::detail::functions1879 			static bool signbit(half arg) { return (arg.data_&0x8000) != 0; }
1880 
1881 			/// Comparison implementation.
1882 			/// \param x first operand
1883 			/// \param y second operand
1884 			/// \retval true if operands equal
1885 			/// \retval false else
isequalhalf_float::detail::functions1886 			static bool isequal(half x, half y) { return (x.data_==y.data_ || !((x.data_|y.data_)&0x7FFF)) && !isnan(x); }
1887 
1888 			/// Comparison implementation.
1889 			/// \param x first operand
1890 			/// \param y second operand
1891 			/// \retval true if operands not equal
1892 			/// \retval false else
isnotequalhalf_float::detail::functions1893 			static bool isnotequal(half x, half y) { return (x.data_!=y.data_ && ((x.data_|y.data_)&0x7FFF)) || isnan(x); }
1894 
1895 			/// Comparison implementation.
1896 			/// \param x first operand
1897 			/// \param y second operand
1898 			/// \retval true if \a x > \a y
1899 			/// \retval false else
isgreaterhalf_float::detail::functions1900 			static bool isgreater(half x, half y)
1901 			{
1902 				int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF;
1903 				return xabs<=0x7C00 && yabs<=0x7C00 && (((xabs==x.data_) ? xabs : -xabs) > ((yabs==y.data_) ? yabs : -yabs));
1904 			}
1905 
1906 			/// Comparison implementation.
1907 			/// \param x first operand
1908 			/// \param y second operand
1909 			/// \retval true if \a x >= \a y
1910 			/// \retval false else
isgreaterequalhalf_float::detail::functions1911 			static bool isgreaterequal(half x, half y)
1912 			{
1913 				int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF;
1914 				return xabs<=0x7C00 && yabs<=0x7C00 && (((xabs==x.data_) ? xabs : -xabs) >= ((yabs==y.data_) ? yabs : -yabs));
1915 			}
1916 
1917 			/// Comparison implementation.
1918 			/// \param x first operand
1919 			/// \param y second operand
1920 			/// \retval true if \a x < \a y
1921 			/// \retval false else
islesshalf_float::detail::functions1922 			static bool isless(half x, half y)
1923 			{
1924 				int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF;
1925 				return xabs<=0x7C00 && yabs<=0x7C00 && (((xabs==x.data_) ? xabs : -xabs) < ((yabs==y.data_) ? yabs : -yabs));
1926 			}
1927 
1928 			/// Comparison implementation.
1929 			/// \param x first operand
1930 			/// \param y second operand
1931 			/// \retval true if \a x <= \a y
1932 			/// \retval false else
islessequalhalf_float::detail::functions1933 			static bool islessequal(half x, half y)
1934 			{
1935 				int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF;
1936 				return xabs<=0x7C00 && yabs<=0x7C00 && (((xabs==x.data_) ? xabs : -xabs) <= ((yabs==y.data_) ? yabs : -yabs));
1937 			}
1938 
1939 			/// Comparison implementation.
1940 			/// \param x first operand
1941 			/// \param y second operand
1942 			/// \retval true if either \a x > \a y nor \a x < \a y
1943 			/// \retval false else
islessgreaterhalf_float::detail::functions1944 			static bool islessgreater(half x, half y)
1945 			{
1946 				int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF;
1947 				if(xabs > 0x7C00 || yabs > 0x7C00)
1948 					return false;
1949 				int a = (xabs==x.data_) ? xabs : -xabs, b = (yabs==y.data_) ? yabs : -yabs;
1950 				return a < b || a > b;
1951 			}
1952 
1953 			/// Comparison implementation.
1954 			/// \param x first operand
1955 			/// \param y second operand
1956 			/// \retval true if operand unordered
1957 			/// \retval false else
isunorderedhalf_float::detail::functions1958 			static bool isunordered(half x, half y) { return isnan(x) || isnan(y); }
1959 
1960 		private:
erfhalf_float::detail::functions1961 			static double erf(double arg)
1962 			{
1963 				if(builtin_isinf(arg))
1964 					return (arg<0.0) ? -1.0 : 1.0;
1965 				double x2 = arg * arg, ax2 = 0.147 * x2, value = std::sqrt(1.0-std::exp(-x2*(1.2732395447351626861510701069801+ax2)/(1.0+ax2)));
1966 				return builtin_signbit(arg) ? -value : value;
1967 			}
1968 
lgammahalf_float::detail::functions1969 			static double lgamma(double arg)
1970 			{
1971 				double v = 1.0;
1972 				for(; arg<8.0; ++arg) v *= arg;
1973 				double w = 1.0 / (arg*arg);
1974 				return (((((((-0.02955065359477124183006535947712*w+0.00641025641025641025641025641026)*w+
1975 					-0.00191752691752691752691752691753)*w+8.4175084175084175084175084175084e-4)*w+
1976 					-5.952380952380952380952380952381e-4)*w+7.9365079365079365079365079365079e-4)*w+
1977 					-0.00277777777777777777777777777778)*w+0.08333333333333333333333333333333)/arg +
1978 					0.91893853320467274178032973640562 - std::log(v) - arg + (arg-0.5) * std::log(arg);
1979 			}
1980 		};
1981 
1982 		/// Wrapper for unary half-precision functions needing specialization for individual argument types.
1983 		/// \tparam T argument type
1984 		template<typename T> struct unary_specialized
1985 		{
1986 			/// Negation implementation.
1987 			/// \param arg value to negate
1988 			/// \return negated value
negatehalf_float::detail::unary_specialized1989 			static HALF_CONSTEXPR half negate(half arg) { return half(binary, arg.data_^0x8000); }
1990 
1991 			/// Absolute value implementation.
1992 			/// \param arg function argument
1993 			/// \return absolute value
fabshalf_float::detail::unary_specialized1994 			static half fabs(half arg) { return half(binary, arg.data_&0x7FFF); }
1995 		};
1996 		template<> struct unary_specialized<expr>
1997 		{
negatehalf_float::detail::unary_specialized1998 			static HALF_CONSTEXPR expr negate(float arg) { return expr(-arg); }
fabshalf_float::detail::unary_specialized1999 			static expr fabs(float arg) { return expr(std::fabs(arg)); }
2000 		};
2001 
2002 		/// Wrapper for binary half-precision functions needing specialization for individual argument types.
2003 		/// \tparam T first argument type
2004 		/// \tparam U first argument type
2005 		template<typename T,typename U> struct binary_specialized
2006 		{
2007 			/// Minimum implementation.
2008 			/// \param x first operand
2009 			/// \param y second operand
2010 			/// \return minimum value
fminhalf_float::detail::binary_specialized2011 			static expr fmin(float x, float y)
2012 			{
2013 			#if HALF_ENABLE_CPP11_CMATH
2014 				return expr(std::fmin(x, y));
2015 			#else
2016 				if(builtin_isnan(x))
2017 					return expr(y);
2018 				if(builtin_isnan(y))
2019 					return expr(x);
2020 				return expr(std::min(x, y));
2021 			#endif
2022 			}
2023 
2024 			/// Maximum implementation.
2025 			/// \param x first operand
2026 			/// \param y second operand
2027 			/// \return maximum value
fmaxhalf_float::detail::binary_specialized2028 			static expr fmax(float x, float y)
2029 			{
2030 			#if HALF_ENABLE_CPP11_CMATH
2031 				return expr(std::fmax(x, y));
2032 			#else
2033 				if(builtin_isnan(x))
2034 					return expr(y);
2035 				if(builtin_isnan(y))
2036 					return expr(x);
2037 				return expr(std::max(x, y));
2038 			#endif
2039 			}
2040 		};
2041 		template<> struct binary_specialized<half,half>
2042 		{
fminhalf_float::detail::binary_specialized2043 			static half fmin(half x, half y)
2044 			{
2045 				int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF;
2046 				if(xabs > 0x7C00)
2047 					return y;
2048 				if(yabs > 0x7C00)
2049 					return x;
2050 				return (((xabs==x.data_) ? xabs : -xabs) > ((yabs==y.data_) ? yabs : -yabs)) ? y : x;
2051 			}
fmaxhalf_float::detail::binary_specialized2052 			static half fmax(half x, half y)
2053 			{
2054 				int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF;
2055 				if(xabs > 0x7C00)
2056 					return y;
2057 				if(yabs > 0x7C00)
2058 					return x;
2059 				return (((xabs==x.data_) ? xabs : -xabs) < ((yabs==y.data_) ? yabs : -yabs)) ? y : x;
2060 			}
2061 		};
2062 
2063 		/// Helper class for half casts.
2064 		/// This class template has to be specialized for all valid cast argument to define an appropriate static `cast` member
2065 		/// function and a corresponding `type` member denoting its return type.
2066 		/// \tparam T destination type
2067 		/// \tparam U source type
2068 		/// \tparam R rounding mode to use
2069 		template<typename T,typename U,std::float_round_style R=(std::float_round_style)(HALF_ROUND_STYLE)> struct half_caster {};
2070 		template<typename U,std::float_round_style R> struct half_caster<half,U,R>
2071 		{
2072 		#if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
2073 			static_assert(std::is_arithmetic<U>::value, "half_cast from non-arithmetic type unsupported");
2074 		#endif
2075 
casthalf_float::detail::half_caster2076 			static half cast(U arg) { return cast_impl(arg, is_float<U>()); };
2077 
2078 		private:
cast_implhalf_float::detail::half_caster2079 			static half cast_impl(U arg, true_type) { return half(binary, float2half<R>(arg)); }
cast_implhalf_float::detail::half_caster2080 			static half cast_impl(U arg, false_type) { return half(binary, int2half<R>(arg)); }
2081 		};
2082 		template<typename T,std::float_round_style R> struct half_caster<T,half,R>
2083 		{
2084 		#if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
2085 			static_assert(std::is_arithmetic<T>::value, "half_cast to non-arithmetic type unsupported");
2086 		#endif
2087 
casthalf_float::detail::half_caster2088 			static T cast(half arg) { return cast_impl(arg, is_float<T>()); }
2089 
2090 		private:
cast_implhalf_float::detail::half_caster2091 			static T cast_impl(half arg, true_type) { return half2float<T>(arg.data_); }
cast_implhalf_float::detail::half_caster2092 			static T cast_impl(half arg, false_type) { return half2int<R,T>(arg.data_); }
2093 		};
2094 		template<typename T,std::float_round_style R> struct half_caster<T,expr,R>
2095 		{
2096 		#if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
2097 			static_assert(std::is_arithmetic<T>::value, "half_cast to non-arithmetic type unsupported");
2098 		#endif
2099 
casthalf_float::detail::half_caster2100 			static T cast(expr arg) { return cast_impl(arg, is_float<T>()); }
2101 
2102 		private:
cast_implhalf_float::detail::half_caster2103 			static T cast_impl(float arg, true_type) { return static_cast<T>(arg); }
cast_implhalf_float::detail::half_caster2104 			static T cast_impl(half arg, false_type) { return half2int<R,T>(arg.data_); }
2105 		};
2106 		template<std::float_round_style R> struct half_caster<half,half,R>
2107 		{
casthalf_float::detail::half_caster2108 			static half cast(half arg) { return arg; }
2109 		};
2110 		template<std::float_round_style R> struct half_caster<half,expr,R> : half_caster<half,half,R> {};
2111 
2112 		/// \name Comparison operators
2113 		/// \{
2114 
2115 		/// Comparison for equality.
2116 		/// \param x first operand
2117 		/// \param y second operand
2118 		/// \retval true if operands equal
2119 		/// \retval false else
operator ==(T x,U y)2120 		template<typename T,typename U> typename enable<bool,T,U>::type operator==(T x, U y) { return functions::isequal(x, y); }
2121 
2122 		/// Comparison for inequality.
2123 		/// \param x first operand
2124 		/// \param y second operand
2125 		/// \retval true if operands not equal
2126 		/// \retval false else
operator !=(T x,U y)2127 		template<typename T,typename U> typename enable<bool,T,U>::type operator!=(T x, U y) { return functions::isnotequal(x, y); }
2128 
2129 		/// Comparison for less than.
2130 		/// \param x first operand
2131 		/// \param y second operand
2132 		/// \retval true if \a x less than \a y
2133 		/// \retval false else
operator <(T x,U y)2134 		template<typename T,typename U> typename enable<bool,T,U>::type operator<(T x, U y) { return functions::isless(x, y); }
2135 
2136 		/// Comparison for greater than.
2137 		/// \param x first operand
2138 		/// \param y second operand
2139 		/// \retval true if \a x greater than \a y
2140 		/// \retval false else
operator >(T x,U y)2141 		template<typename T,typename U> typename enable<bool,T,U>::type operator>(T x, U y) { return functions::isgreater(x, y); }
2142 
2143 		/// Comparison for less equal.
2144 		/// \param x first operand
2145 		/// \param y second operand
2146 		/// \retval true if \a x less equal \a y
2147 		/// \retval false else
operator <=(T x,U y)2148 		template<typename T,typename U> typename enable<bool,T,U>::type operator<=(T x, U y) { return functions::islessequal(x, y); }
2149 
2150 		/// Comparison for greater equal.
2151 		/// \param x first operand
2152 		/// \param y second operand
2153 		/// \retval true if \a x greater equal \a y
2154 		/// \retval false else
operator >=(T x,U y)2155 		template<typename T,typename U> typename enable<bool,T,U>::type operator>=(T x, U y) { return functions::isgreaterequal(x, y); }
2156 
2157 		/// \}
2158 		/// \name Arithmetic operators
2159 		/// \{
2160 
2161 		/// Add halfs.
2162 		/// \param x left operand
2163 		/// \param y right operand
2164 		/// \return sum of half expressions
operator +(T x,U y)2165 		template<typename T,typename U> typename enable<expr,T,U>::type operator+(T x, U y) { return functions::plus(x, y); }
2166 
2167 		/// Subtract halfs.
2168 		/// \param x left operand
2169 		/// \param y right operand
2170 		/// \return difference of half expressions
operator -(T x,U y)2171 		template<typename T,typename U> typename enable<expr,T,U>::type operator-(T x, U y) { return functions::minus(x, y); }
2172 
2173 		/// Multiply halfs.
2174 		/// \param x left operand
2175 		/// \param y right operand
2176 		/// \return product of half expressions
operator *(T x,U y)2177 		template<typename T,typename U> typename enable<expr,T,U>::type operator*(T x, U y) { return functions::multiplies(x, y); }
2178 
2179 		/// Divide halfs.
2180 		/// \param x left operand
2181 		/// \param y right operand
2182 		/// \return quotient of half expressions
operator /(T x,U y)2183 		template<typename T,typename U> typename enable<expr,T,U>::type operator/(T x, U y) { return functions::divides(x, y); }
2184 
2185 		/// Identity.
2186 		/// \param arg operand
2187 		/// \return uncahnged operand
operator +(T arg)2188 		template<typename T> HALF_CONSTEXPR typename enable<T,T>::type operator+(T arg) { return arg; }
2189 
2190 		/// Negation.
2191 		/// \param arg operand
2192 		/// \return negated operand
operator -(T arg)2193 		template<typename T> HALF_CONSTEXPR typename enable<T,T>::type operator-(T arg) { return unary_specialized<T>::negate(arg); }
2194 
2195 		/// \}
2196 		/// \name Input and output
2197 		/// \{
2198 
2199 		/// Output operator.
2200 		/// \param out output stream to write into
2201 		/// \param arg half expression to write
2202 		/// \return reference to output stream
2203 		template<typename T,typename charT,typename traits> typename enable<std::basic_ostream<charT,traits>&,T>::type
operator <<(std::basic_ostream<charT,traits> & out,T arg)2204 			operator<<(std::basic_ostream<charT,traits> &out, T arg) { return functions::write(out, arg); }
2205 
2206 		/// Input operator.
2207 		/// \param in input stream to read from
2208 		/// \param arg half to read into
2209 		/// \return reference to input stream
2210 		template<typename charT,typename traits> std::basic_istream<charT,traits>&
operator >>(std::basic_istream<charT,traits> & in,half & arg)2211 			operator>>(std::basic_istream<charT,traits> &in, half &arg) { return functions::read(in, arg); }
2212 
2213 		/// \}
2214 		/// \name Basic mathematical operations
2215 		/// \{
2216 
2217 		/// Absolute value.
2218 		/// \param arg operand
2219 		/// \return absolute value of \a arg
2220 //		template<typename T> typename enable<T,T>::type abs(T arg) { return unary_specialized<T>::fabs(arg); }
abs(half arg)2221 		inline half abs(half arg) { return unary_specialized<half>::fabs(arg); }
abs(expr arg)2222 		inline expr abs(expr arg) { return unary_specialized<expr>::fabs(arg); }
2223 
2224 		/// Absolute value.
2225 		/// \param arg operand
2226 		/// \return absolute value of \a arg
2227 //		template<typename T> typename enable<T,T>::type fabs(T arg) { return unary_specialized<T>::fabs(arg); }
fabs(half arg)2228 		inline half fabs(half arg) { return unary_specialized<half>::fabs(arg); }
fabs(expr arg)2229 		inline expr fabs(expr arg) { return unary_specialized<expr>::fabs(arg); }
2230 
2231 		/// Remainder of division.
2232 		/// \param x first operand
2233 		/// \param y second operand
2234 		/// \return remainder of floating point division.
2235 //		template<typename T,typename U> typename enable<expr,T,U>::type fmod(T x, U y) { return functions::fmod(x, y); }
fmod(half x,half y)2236 		inline expr fmod(half x, half y) { return functions::fmod(x, y); }
fmod(half x,expr y)2237 		inline expr fmod(half x, expr y) { return functions::fmod(x, y); }
fmod(expr x,half y)2238 		inline expr fmod(expr x, half y) { return functions::fmod(x, y); }
fmod(expr x,expr y)2239 		inline expr fmod(expr x, expr y) { return functions::fmod(x, y); }
2240 
2241 		/// Remainder of division.
2242 		/// \param x first operand
2243 		/// \param y second operand
2244 		/// \return remainder of floating point division.
2245 //		template<typename T,typename U> typename enable<expr,T,U>::type remainder(T x, U y) { return functions::remainder(x, y); }
remainder(half x,half y)2246 		inline expr remainder(half x, half y) { return functions::remainder(x, y); }
remainder(half x,expr y)2247 		inline expr remainder(half x, expr y) { return functions::remainder(x, y); }
remainder(expr x,half y)2248 		inline expr remainder(expr x, half y) { return functions::remainder(x, y); }
remainder(expr x,expr y)2249 		inline expr remainder(expr x, expr y) { return functions::remainder(x, y); }
2250 
2251 		/// Remainder of division.
2252 		/// \param x first operand
2253 		/// \param y second operand
2254 		/// \param quo address to store some bits of quotient at
2255 		/// \return remainder of floating point division.
2256 //		template<typename T,typename U> typename enable<expr,T,U>::type remquo(T x, U y, int *quo) { return functions::remquo(x, y, quo); }
remquo(half x,half y,int * quo)2257 		inline expr remquo(half x, half y, int *quo) { return functions::remquo(x, y, quo); }
remquo(half x,expr y,int * quo)2258 		inline expr remquo(half x, expr y, int *quo) { return functions::remquo(x, y, quo); }
remquo(expr x,half y,int * quo)2259 		inline expr remquo(expr x, half y, int *quo) { return functions::remquo(x, y, quo); }
remquo(expr x,expr y,int * quo)2260 		inline expr remquo(expr x, expr y, int *quo) { return functions::remquo(x, y, quo); }
2261 
2262 		/// Fused multiply add.
2263 		/// \param x first operand
2264 		/// \param y second operand
2265 		/// \param z third operand
2266 		/// \return ( \a x * \a y ) + \a z rounded as one operation.
2267 //		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); }
fma(half x,half y,half z)2268 		inline expr fma(half x, half y, half z) { return functions::fma(x, y, z); }
fma(half x,half y,expr z)2269 		inline expr fma(half x, half y, expr z) { return functions::fma(x, y, z); }
fma(half x,expr y,half z)2270 		inline expr fma(half x, expr y, half z) { return functions::fma(x, y, z); }
fma(half x,expr y,expr z)2271 		inline expr fma(half x, expr y, expr z) { return functions::fma(x, y, z); }
fma(expr x,half y,half z)2272 		inline expr fma(expr x, half y, half z) { return functions::fma(x, y, z); }
fma(expr x,half y,expr z)2273 		inline expr fma(expr x, half y, expr z) { return functions::fma(x, y, z); }
fma(expr x,expr y,half z)2274 		inline expr fma(expr x, expr y, half z) { return functions::fma(x, y, z); }
fma(expr x,expr y,expr z)2275 		inline expr fma(expr x, expr y, expr z) { return functions::fma(x, y, z); }
2276 
2277 		/// Maximum of half expressions.
2278 		/// \param x first operand
2279 		/// \param y second operand
2280 		/// \return maximum of operands
2281 //		template<typename T,typename U> typename result<T,U>::type fmax(T x, U y) { return binary_specialized<T,U>::fmax(x, y); }
fmax(half x,half y)2282 		inline half fmax(half x, half y) { return binary_specialized<half,half>::fmax(x, y); }
fmax(half x,expr y)2283 		inline expr fmax(half x, expr y) { return binary_specialized<half,expr>::fmax(x, y); }
fmax(expr x,half y)2284 		inline expr fmax(expr x, half y) { return binary_specialized<expr,half>::fmax(x, y); }
fmax(expr x,expr y)2285 		inline expr fmax(expr x, expr y) { return binary_specialized<expr,expr>::fmax(x, y); }
2286 
2287 		/// Minimum of half expressions.
2288 		/// \param x first operand
2289 		/// \param y second operand
2290 		/// \return minimum of operands
2291 //		template<typename T,typename U> typename result<T,U>::type fmin(T x, U y) { return binary_specialized<T,U>::fmin(x, y); }
fmin(half x,half y)2292 		inline half fmin(half x, half y) { return binary_specialized<half,half>::fmin(x, y); }
fmin(half x,expr y)2293 		inline expr fmin(half x, expr y) { return binary_specialized<half,expr>::fmin(x, y); }
fmin(expr x,half y)2294 		inline expr fmin(expr x, half y) { return binary_specialized<expr,half>::fmin(x, y); }
fmin(expr x,expr y)2295 		inline expr fmin(expr x, expr y) { return binary_specialized<expr,expr>::fmin(x, y); }
2296 
2297 		/// Positive difference.
2298 		/// \param x first operand
2299 		/// \param y second operand
2300 		/// \return \a x - \a y or 0 if difference negative
2301 //		template<typename T,typename U> typename enable<expr,T,U>::type fdim(T x, U y) { return functions::fdim(x, y); }
fdim(half x,half y)2302 		inline expr fdim(half x, half y) { return functions::fdim(x, y); }
fdim(half x,expr y)2303 		inline expr fdim(half x, expr y) { return functions::fdim(x, y); }
fdim(expr x,half y)2304 		inline expr fdim(expr x, half y) { return functions::fdim(x, y); }
fdim(expr x,expr y)2305 		inline expr fdim(expr x, expr y) { return functions::fdim(x, y); }
2306 
2307 		/// Get NaN value.
2308 		/// \return quiet NaN
nanh(const char *)2309 		inline half nanh(const char*) { return functions::nanh(); }
2310 
2311 		/// \}
2312 		/// \name Exponential functions
2313 		/// \{
2314 
2315 		/// Exponential function.
2316 		/// \param arg function argument
2317 		/// \return e raised to \a arg
2318 //		template<typename T> typename enable<expr,T>::type exp(T arg) { return functions::exp(arg); }
exp(half arg)2319 		inline expr exp(half arg) { return functions::exp(arg); }
exp(expr arg)2320 		inline expr exp(expr arg) { return functions::exp(arg); }
2321 
2322 		/// Exponential minus one.
2323 		/// \param arg function argument
2324 		/// \return e raised to \a arg subtracted by 1
2325 //		template<typename T> typename enable<expr,T>::type expm1(T arg) { return functions::expm1(arg); }
expm1(half arg)2326 		inline expr expm1(half arg) { return functions::expm1(arg); }
expm1(expr arg)2327 		inline expr expm1(expr arg) { return functions::expm1(arg); }
2328 
2329 		/// Binary exponential.
2330 		/// \param arg function argument
2331 		/// \return 2 raised to \a arg
2332 //		template<typename T> typename enable<expr,T>::type exp2(T arg) { return functions::exp2(arg); }
exp2(half arg)2333 		inline expr exp2(half arg) { return functions::exp2(arg); }
exp2(expr arg)2334 		inline expr exp2(expr arg) { return functions::exp2(arg); }
2335 
2336 		/// Natural logorithm.
2337 		/// \param arg function argument
2338 		/// \return logarithm of \a arg to base e
2339 //		template<typename T> typename enable<expr,T>::type log(T arg) { return functions::log(arg); }
log(half arg)2340 		inline expr log(half arg) { return functions::log(arg); }
log(expr arg)2341 		inline expr log(expr arg) { return functions::log(arg); }
2342 
2343 		/// Common logorithm.
2344 		/// \param arg function argument
2345 		/// \return logarithm of \a arg to base 10
2346 //		template<typename T> typename enable<expr,T>::type log10(T arg) { return functions::log10(arg); }
log10(half arg)2347 		inline expr log10(half arg) { return functions::log10(arg); }
log10(expr arg)2348 		inline expr log10(expr arg) { return functions::log10(arg); }
2349 
2350 		/// Natural logorithm.
2351 		/// \param arg function argument
2352 		/// \return logarithm of \a arg plus 1 to base e
2353 //		template<typename T> typename enable<expr,T>::type log1p(T arg) { return functions::log1p(arg); }
log1p(half arg)2354 		inline expr log1p(half arg) { return functions::log1p(arg); }
log1p(expr arg)2355 		inline expr log1p(expr arg) { return functions::log1p(arg); }
2356 
2357 		/// Binary logorithm.
2358 		/// \param arg function argument
2359 		/// \return logarithm of \a arg to base 2
2360 //		template<typename T> typename enable<expr,T>::type log2(T arg) { return functions::log2(arg); }
log2(half arg)2361 		inline expr log2(half arg) { return functions::log2(arg); }
log2(expr arg)2362 		inline expr log2(expr arg) { return functions::log2(arg); }
2363 
2364 		/// \}
2365 		/// \name Power functions
2366 		/// \{
2367 
2368 		/// Square root.
2369 		/// \param arg function argument
2370 		/// \return square root of \a arg
2371 //		template<typename T> typename enable<expr,T>::type sqrt(T arg) { return functions::sqrt(arg); }
sqrt(half arg)2372 		inline expr sqrt(half arg) { return functions::sqrt(arg); }
sqrt(expr arg)2373 		inline expr sqrt(expr arg) { return functions::sqrt(arg); }
2374 
2375 		/// Cubic root.
2376 		/// \param arg function argument
2377 		/// \return cubic root of \a arg
2378 //		template<typename T> typename enable<expr,T>::type cbrt(T arg) { return functions::cbrt(arg); }
cbrt(half arg)2379 		inline expr cbrt(half arg) { return functions::cbrt(arg); }
cbrt(expr arg)2380 		inline expr cbrt(expr arg) { return functions::cbrt(arg); }
2381 
2382 		/// Hypotenuse function.
2383 		/// \param x first argument
2384 		/// \param y second argument
2385 		/// \return square root of sum of squares without internal over- or underflows
2386 //		template<typename T,typename U> typename enable<expr,T,U>::type hypot(T x, U y) { return functions::hypot(x, y); }
hypot(half x,half y)2387 		inline expr hypot(half x, half y) { return functions::hypot(x, y); }
hypot(half x,expr y)2388 		inline expr hypot(half x, expr y) { return functions::hypot(x, y); }
hypot(expr x,half y)2389 		inline expr hypot(expr x, half y) { return functions::hypot(x, y); }
hypot(expr x,expr y)2390 		inline expr hypot(expr x, expr y) { return functions::hypot(x, y); }
2391 
2392 		/// Power function.
2393 		/// \param base first argument
2394 		/// \param exp second argument
2395 		/// \return \a base raised to \a exp
2396 //		template<typename T,typename U> typename enable<expr,T,U>::type pow(T base, U exp) { return functions::pow(base, exp); }
pow(half base,half exp)2397 		inline expr pow(half base, half exp) { return functions::pow(base, exp); }
pow(half base,expr exp)2398 		inline expr pow(half base, expr exp) { return functions::pow(base, exp); }
pow(expr base,half exp)2399 		inline expr pow(expr base, half exp) { return functions::pow(base, exp); }
pow(expr base,expr exp)2400 		inline expr pow(expr base, expr exp) { return functions::pow(base, exp); }
2401 
2402 		/// \}
2403 		/// \name Trigonometric functions
2404 		/// \{
2405 
2406 		/// Sine function.
2407 		/// \param arg function argument
2408 		/// \return sine value of \a arg
2409 //		template<typename T> typename enable<expr,T>::type sin(T arg) { return functions::sin(arg); }
sin(half arg)2410 		inline expr sin(half arg) { return functions::sin(arg); }
sin(expr arg)2411 		inline expr sin(expr arg) { return functions::sin(arg); }
2412 
2413 		/// Cosine function.
2414 		/// \param arg function argument
2415 		/// \return cosine value of \a arg
2416 //		template<typename T> typename enable<expr,T>::type cos(T arg) { return functions::cos(arg); }
cos(half arg)2417 		inline expr cos(half arg) { return functions::cos(arg); }
cos(expr arg)2418 		inline expr cos(expr arg) { return functions::cos(arg); }
2419 
2420 		/// Tangent function.
2421 		/// \param arg function argument
2422 		/// \return tangent value of \a arg
2423 //		template<typename T> typename enable<expr,T>::type tan(T arg) { return functions::tan(arg); }
tan(half arg)2424 		inline expr tan(half arg) { return functions::tan(arg); }
tan(expr arg)2425 		inline expr tan(expr arg) { return functions::tan(arg); }
2426 
2427 		/// Arc sine.
2428 		/// \param arg function argument
2429 		/// \return arc sine value of \a arg
2430 //		template<typename T> typename enable<expr,T>::type asin(T arg) { return functions::asin(arg); }
asin(half arg)2431 		inline expr asin(half arg) { return functions::asin(arg); }
asin(expr arg)2432 		inline expr asin(expr arg) { return functions::asin(arg); }
2433 
2434 		/// Arc cosine function.
2435 		/// \param arg function argument
2436 		/// \return arc cosine value of \a arg
2437 //		template<typename T> typename enable<expr,T>::type acos(T arg) { return functions::acos(arg); }
acos(half arg)2438 		inline expr acos(half arg) { return functions::acos(arg); }
acos(expr arg)2439 		inline expr acos(expr arg) { return functions::acos(arg); }
2440 
2441 		/// Arc tangent function.
2442 		/// \param arg function argument
2443 		/// \return arc tangent value of \a arg
2444 //		template<typename T> typename enable<expr,T>::type atan(T arg) { return functions::atan(arg); }
atan(half arg)2445 		inline expr atan(half arg) { return functions::atan(arg); }
atan(expr arg)2446 		inline expr atan(expr arg) { return functions::atan(arg); }
2447 
2448 		/// Arc tangent function.
2449 		/// \param x first argument
2450 		/// \param y second argument
2451 		/// \return arc tangent value
2452 //		template<typename T,typename U> typename enable<expr,T,U>::type atan2(T x, U y) { return functions::atan2(x, y); }
atan2(half x,half y)2453 		inline expr atan2(half x, half y) { return functions::atan2(x, y); }
atan2(half x,expr y)2454 		inline expr atan2(half x, expr y) { return functions::atan2(x, y); }
atan2(expr x,half y)2455 		inline expr atan2(expr x, half y) { return functions::atan2(x, y); }
atan2(expr x,expr y)2456 		inline expr atan2(expr x, expr y) { return functions::atan2(x, y); }
2457 
2458 		/// \}
2459 		/// \name Hyperbolic functions
2460 		/// \{
2461 
2462 		/// Hyperbolic sine.
2463 		/// \param arg function argument
2464 		/// \return hyperbolic sine value of \a arg
2465 //		template<typename T> typename enable<expr,T>::type sinh(T arg) { return functions::sinh(arg); }
sinh(half arg)2466 		inline expr sinh(half arg) { return functions::sinh(arg); }
sinh(expr arg)2467 		inline expr sinh(expr arg) { return functions::sinh(arg); }
2468 
2469 		/// Hyperbolic cosine.
2470 		/// \param arg function argument
2471 		/// \return hyperbolic cosine value of \a arg
2472 //		template<typename T> typename enable<expr,T>::type cosh(T arg) { return functions::cosh(arg); }
cosh(half arg)2473 		inline expr cosh(half arg) { return functions::cosh(arg); }
cosh(expr arg)2474 		inline expr cosh(expr arg) { return functions::cosh(arg); }
2475 
2476 		/// Hyperbolic tangent.
2477 		/// \param arg function argument
2478 		/// \return hyperbolic tangent value of \a arg
2479 //		template<typename T> typename enable<expr,T>::type tanh(T arg) { return functions::tanh(arg); }
tanh(half arg)2480 		inline expr tanh(half arg) { return functions::tanh(arg); }
tanh(expr arg)2481 		inline expr tanh(expr arg) { return functions::tanh(arg); }
2482 
2483 		/// Hyperbolic area sine.
2484 		/// \param arg function argument
2485 		/// \return area sine value of \a arg
2486 //		template<typename T> typename enable<expr,T>::type asinh(T arg) { return functions::asinh(arg); }
asinh(half arg)2487 		inline expr asinh(half arg) { return functions::asinh(arg); }
asinh(expr arg)2488 		inline expr asinh(expr arg) { return functions::asinh(arg); }
2489 
2490 		/// Hyperbolic area cosine.
2491 		/// \param arg function argument
2492 		/// \return area cosine value of \a arg
2493 //		template<typename T> typename enable<expr,T>::type acosh(T arg) { return functions::acosh(arg); }
acosh(half arg)2494 		inline expr acosh(half arg) { return functions::acosh(arg); }
acosh(expr arg)2495 		inline expr acosh(expr arg) { return functions::acosh(arg); }
2496 
2497 		/// Hyperbolic area tangent.
2498 		/// \param arg function argument
2499 		/// \return area tangent value of \a arg
2500 //		template<typename T> typename enable<expr,T>::type atanh(T arg) { return functions::atanh(arg); }
atanh(half arg)2501 		inline expr atanh(half arg) { return functions::atanh(arg); }
atanh(expr arg)2502 		inline expr atanh(expr arg) { return functions::atanh(arg); }
2503 
2504 		/// \}
2505 		/// \name Error and gamma functions
2506 		/// \{
2507 
2508 		/// Error function.
2509 		/// \param arg function argument
2510 		/// \return error function value of \a arg
2511 //		template<typename T> typename enable<expr,T>::type erf(T arg) { return functions::erf(arg); }
erf(half arg)2512 		inline expr erf(half arg) { return functions::erf(arg); }
erf(expr arg)2513 		inline expr erf(expr arg) { return functions::erf(arg); }
2514 
2515 		/// Complementary error function.
2516 		/// \param arg function argument
2517 		/// \return 1 minus error function value of \a arg
2518 //		template<typename T> typename enable<expr,T>::type erfc(T arg) { return functions::erfc(arg); }
erfc(half arg)2519 		inline expr erfc(half arg) { return functions::erfc(arg); }
erfc(expr arg)2520 		inline expr erfc(expr arg) { return functions::erfc(arg); }
2521 
2522 		/// Natural logarithm of gamma function.
2523 		/// \param arg function argument
2524 		/// \return natural logarith of gamma function for \a arg
2525 //		template<typename T> typename enable<expr,T>::type lgamma(T arg) { return functions::lgamma(arg); }
lgamma(half arg)2526 		inline expr lgamma(half arg) { return functions::lgamma(arg); }
lgamma(expr arg)2527 		inline expr lgamma(expr arg) { return functions::lgamma(arg); }
2528 
2529 		/// Gamma function.
2530 		/// \param arg function argument
2531 		/// \return gamma function value of \a arg
2532 //		template<typename T> typename enable<expr,T>::type tgamma(T arg) { return functions::tgamma(arg); }
tgamma(half arg)2533 		inline expr tgamma(half arg) { return functions::tgamma(arg); }
tgamma(expr arg)2534 		inline expr tgamma(expr arg) { return functions::tgamma(arg); }
2535 
2536 		/// \}
2537 		/// \name Rounding
2538 		/// \{
2539 
2540 		/// Nearest integer not less than half value.
2541 		/// \param arg half to round
2542 		/// \return nearest integer not less than \a arg
2543 //		template<typename T> typename enable<half,T>::type ceil(T arg) { return functions::ceil(arg); }
ceil(half arg)2544 		inline half ceil(half arg) { return functions::ceil(arg); }
ceil(expr arg)2545 		inline half ceil(expr arg) { return functions::ceil(arg); }
2546 
2547 		/// Nearest integer not greater than half value.
2548 		/// \param arg half to round
2549 		/// \return nearest integer not greater than \a arg
2550 //		template<typename T> typename enable<half,T>::type floor(T arg) { return functions::floor(arg); }
floor(half arg)2551 		inline half floor(half arg) { return functions::floor(arg); }
floor(expr arg)2552 		inline half floor(expr arg) { return functions::floor(arg); }
2553 
2554 		/// Nearest integer not greater in magnitude than half value.
2555 		/// \param arg half to round
2556 		/// \return nearest integer not greater in magnitude than \a arg
2557 //		template<typename T> typename enable<half,T>::type trunc(T arg) { return functions::trunc(arg); }
trunc(half arg)2558 		inline half trunc(half arg) { return functions::trunc(arg); }
trunc(expr arg)2559 		inline half trunc(expr arg) { return functions::trunc(arg); }
2560 
2561 		/// Nearest integer.
2562 		/// \param arg half to round
2563 		/// \return nearest integer, rounded away from zero in half-way cases
2564 //		template<typename T> typename enable<half,T>::type round(T arg) { return functions::round(arg); }
round(half arg)2565 		inline half round(half arg) { return functions::round(arg); }
round(expr arg)2566 		inline half round(expr arg) { return functions::round(arg); }
2567 
2568 		/// Nearest integer.
2569 		/// \param arg half to round
2570 		/// \return nearest integer, rounded away from zero in half-way cases
2571 //		template<typename T> typename enable<long,T>::type lround(T arg) { return functions::lround(arg); }
lround(half arg)2572 		inline long lround(half arg) { return functions::lround(arg); }
lround(expr arg)2573 		inline long lround(expr arg) { return functions::lround(arg); }
2574 
2575 		/// Nearest integer using half's internal rounding mode.
2576 		/// \param arg half expression to round
2577 		/// \return nearest integer using default rounding mode
2578 //		template<typename T> typename enable<half,T>::type nearbyint(T arg) { return functions::nearbyint(arg); }
nearbyint(half arg)2579 		inline half nearbyint(half arg) { return functions::rint(arg); }
nearbyint(expr arg)2580 		inline half nearbyint(expr arg) { return functions::rint(arg); }
2581 
2582 		/// Nearest integer using half's internal rounding mode.
2583 		/// \param arg half expression to round
2584 		/// \return nearest integer using default rounding mode
2585 //		template<typename T> typename enable<half,T>::type rint(T arg) { return functions::rint(arg); }
rint(half arg)2586 		inline half rint(half arg) { return functions::rint(arg); }
rint(expr arg)2587 		inline half rint(expr arg) { return functions::rint(arg); }
2588 
2589 		/// Nearest integer using half's internal rounding mode.
2590 		/// \param arg half expression to round
2591 		/// \return nearest integer using default rounding mode
2592 //		template<typename T> typename enable<long,T>::type lrint(T arg) { return functions::lrint(arg); }
lrint(half arg)2593 		inline long lrint(half arg) { return functions::lrint(arg); }
lrint(expr arg)2594 		inline long lrint(expr arg) { return functions::lrint(arg); }
2595 	#if HALF_ENABLE_CPP11_LONG_LONG
2596 		/// Nearest integer.
2597 		/// \param arg half to round
2598 		/// \return nearest integer, rounded away from zero in half-way cases
2599 //		template<typename T> typename enable<long long,T>::type llround(T arg) { return functions::llround(arg); }
llround(half arg)2600 		inline long long llround(half arg) { return functions::llround(arg); }
llround(expr arg)2601 		inline long long llround(expr arg) { return functions::llround(arg); }
2602 
2603 		/// Nearest integer using half's internal rounding mode.
2604 		/// \param arg half expression to round
2605 		/// \return nearest integer using default rounding mode
2606 //		template<typename T> typename enable<long long,T>::type llrint(T arg) { return functions::llrint(arg); }
llrint(half arg)2607 		inline long long llrint(half arg) { return functions::llrint(arg); }
llrint(expr arg)2608 		inline long long llrint(expr arg) { return functions::llrint(arg); }
2609 	#endif
2610 
2611 		/// \}
2612 		/// \name Floating point manipulation
2613 		/// \{
2614 
2615 		/// Decompress floating point number.
2616 		/// \param arg number to decompress
2617 		/// \param exp address to store exponent at
2618 		/// \return significant in range [0.5, 1)
2619 //		template<typename T> typename enable<half,T>::type frexp(T arg, int *exp) { return functions::frexp(arg, exp); }
frexp(half arg,int * exp)2620 		inline half frexp(half arg, int *exp) { return functions::frexp(arg, exp); }
frexp(expr arg,int * exp)2621 		inline half frexp(expr arg, int *exp) { return functions::frexp(arg, exp); }
2622 
2623 		/// Multiply by power of two.
2624 		/// \param arg number to modify
2625 		/// \param exp power of two to multiply with
2626 		/// \return \a arg multplied by 2 raised to \a exp
2627 //		template<typename T> typename enable<half,T>::type ldexp(T arg, int exp) { return functions::scalbln(arg, exp); }
ldexp(half arg,int exp)2628 		inline half ldexp(half arg, int exp) { return functions::scalbln(arg, exp); }
ldexp(expr arg,int exp)2629 		inline half ldexp(expr arg, int exp) { return functions::scalbln(arg, exp); }
2630 
2631 		/// Extract integer and fractional parts.
2632 		/// \param arg number to decompress
2633 		/// \param iptr address to store integer part at
2634 		/// \return fractional part
2635 //		template<typename T> typename enable<half,T>::type modf(T arg, half *iptr) { return functions::modf(arg, iptr); }
modf(half arg,half * iptr)2636 		inline half modf(half arg, half *iptr) { return functions::modf(arg, iptr); }
modf(expr arg,half * iptr)2637 		inline half modf(expr arg, half *iptr) { return functions::modf(arg, iptr); }
2638 
2639 		/// Multiply by power of two.
2640 		/// \param arg number to modify
2641 		/// \param exp power of two to multiply with
2642 		/// \return \a arg multplied by 2 raised to \a exp
2643 //		template<typename T> typename enable<half,T>::type scalbn(T arg, int exp) { return functions::scalbln(arg, exp); }
scalbn(half arg,int exp)2644 		inline half scalbn(half arg, int exp) { return functions::scalbln(arg, exp); }
scalbn(expr arg,int exp)2645 		inline half scalbn(expr arg, int exp) { return functions::scalbln(arg, exp); }
2646 
2647 		/// Multiply by power of two.
2648 		/// \param arg number to modify
2649 		/// \param exp power of two to multiply with
2650 		/// \return \a arg multplied by 2 raised to \a exp
2651 //		template<typename T> typename enable<half,T>::type scalbln(T arg, long exp) { return functions::scalbln(arg, exp); }
scalbln(half arg,long exp)2652 		inline half scalbln(half arg, long exp) { return functions::scalbln(arg, exp); }
scalbln(expr arg,long exp)2653 		inline half scalbln(expr arg, long exp) { return functions::scalbln(arg, exp); }
2654 
2655 		/// Extract exponent.
2656 		/// \param arg number to query
2657 		/// \return floating point exponent
2658 		/// \retval FP_ILOGB0 for zero
2659 		/// \retval FP_ILOGBNAN for NaN
2660 		/// \retval MAX_INT for infinity
2661 //		template<typename T> typename enable<int,T>::type ilogb(T arg) { return functions::ilogb(arg); }
ilogb(half arg)2662 		inline int ilogb(half arg) { return functions::ilogb(arg); }
ilogb(expr arg)2663 		inline int ilogb(expr arg) { return functions::ilogb(arg); }
2664 
2665 		/// Extract exponent.
2666 		/// \param arg number to query
2667 		/// \return floating point exponent
2668 //		template<typename T> typename enable<half,T>::type logb(T arg) { return functions::logb(arg); }
logb(half arg)2669 		inline half logb(half arg) { return functions::logb(arg); }
logb(expr arg)2670 		inline half logb(expr arg) { return functions::logb(arg); }
2671 
2672 		/// Next representable value.
2673 		/// \param from value to compute next representable value for
2674 		/// \param to direction towards which to compute next value
2675 		/// \return next representable value after \a from in direction towards \a to
2676 //		template<typename T,typename U> typename enable<half,T,U>::type nextafter(T from, U to) { return functions::nextafter(from, to); }
nextafter(half from,half to)2677 		inline half nextafter(half from, half to) { return functions::nextafter(from, to); }
nextafter(half from,expr to)2678 		inline half nextafter(half from, expr to) { return functions::nextafter(from, to); }
nextafter(expr from,half to)2679 		inline half nextafter(expr from, half to) { return functions::nextafter(from, to); }
nextafter(expr from,expr to)2680 		inline half nextafter(expr from, expr to) { return functions::nextafter(from, to); }
2681 
2682 		/// Next representable value.
2683 		/// \param from value to compute next representable value for
2684 		/// \param to direction towards which to compute next value
2685 		/// \return next representable value after \a from in direction towards \a to
2686 //		template<typename T> typename enable<half,T>::type nexttoward(T from, long double to) { return functions::nexttoward(from, to); }
nexttoward(half from,long double to)2687 		inline half nexttoward(half from, long double to) { return functions::nexttoward(from, to); }
nexttoward(expr from,long double to)2688 		inline half nexttoward(expr from, long double to) { return functions::nexttoward(from, to); }
2689 
2690 		/// Take sign.
2691 		/// \param x value to change sign for
2692 		/// \param y value to take sign from
2693 		/// \return value equal to \a x in magnitude and to \a y in sign
2694 //		template<typename T,typename U> typename enable<half,T,U>::type copysign(T x, U y) { return functions::copysign(x, y); }
copysign(half x,half y)2695 		inline half copysign(half x, half y) { return functions::copysign(x, y); }
copysign(half x,expr y)2696 		inline half copysign(half x, expr y) { return functions::copysign(x, y); }
copysign(expr x,half y)2697 		inline half copysign(expr x, half y) { return functions::copysign(x, y); }
copysign(expr x,expr y)2698 		inline half copysign(expr x, expr y) { return functions::copysign(x, y); }
2699 
2700 		/// \}
2701 		/// \name Floating point classification
2702 		/// \{
2703 
2704 
2705 		/// Classify floating point value.
2706 		/// \param arg number to classify
2707 		/// \retval FP_ZERO for positive and negative zero
2708 		/// \retval FP_SUBNORMAL for subnormal numbers
2709 		/// \retval FP_INFINITY for positive and negative infinity
2710 		/// \retval FP_NAN for NaNs
2711 		/// \retval FP_NORMAL for all other (normal) values
2712 //		template<typename T> typename enable<int,T>::type fpclassify(T arg) { return functions::fpclassify(arg); }
fpclassify(half arg)2713 		inline int fpclassify(half arg) { return functions::fpclassify(arg); }
fpclassify(expr arg)2714 		inline int fpclassify(expr arg) { return functions::fpclassify(arg); }
2715 
2716 		/// Check if finite number.
2717 		/// \param arg number to check
2718 		/// \retval true if neither infinity nor NaN
2719 		/// \retval false else
2720 //		template<typename T> typename enable<bool,T>::type isfinite(T arg) { return functions::isfinite(arg); }
isfinite(half arg)2721 		inline bool isfinite(half arg) { return functions::isfinite(arg); }
isfinite(expr arg)2722 		inline bool isfinite(expr arg) { return functions::isfinite(arg); }
2723 
2724 		/// Check for infinity.
2725 		/// \param arg number to check
2726 		/// \retval true for positive or negative infinity
2727 		/// \retval false else
2728 //		template<typename T> typename enable<bool,T>::type isinf(T arg) { return functions::isinf(arg); }
isinf(half arg)2729 		inline bool isinf(half arg) { return functions::isinf(arg); }
isinf(expr arg)2730 		inline bool isinf(expr arg) { return functions::isinf(arg); }
2731 
2732 		/// Check for NaN.
2733 		/// \param arg number to check
2734 		/// \retval true for NaNs
2735 		/// \retval false else
2736 //		template<typename T> typename enable<bool,T>::type isnan(T arg) { return functions::isnan(arg); }
isnan(half arg)2737 		inline bool isnan(half arg) { return functions::isnan(arg); }
isnan(expr arg)2738 		inline bool isnan(expr arg) { return functions::isnan(arg); }
2739 
2740 		/// Check if normal number.
2741 		/// \param arg number to check
2742 		/// \retval true if normal number
2743 		/// \retval false if either subnormal, zero, infinity or NaN
2744 //		template<typename T> typename enable<bool,T>::type isnormal(T arg) { return functions::isnormal(arg); }
isnormal(half arg)2745 		inline bool isnormal(half arg) { return functions::isnormal(arg); }
isnormal(expr arg)2746 		inline bool isnormal(expr arg) { return functions::isnormal(arg); }
2747 
2748 		/// Check sign.
2749 		/// \param arg number to check
2750 		/// \retval true for negative number
2751 		/// \retval false for positive number
2752 //		template<typename T> typename enable<bool,T>::type signbit(T arg) { return functions::signbit(arg); }
signbit(half arg)2753 		inline bool signbit(half arg) { return functions::signbit(arg); }
signbit(expr arg)2754 		inline bool signbit(expr arg) { return functions::signbit(arg); }
2755 
2756 		/// \}
2757 		/// \name Comparison
2758 		/// \{
2759 
2760 		/// Comparison for greater than.
2761 		/// \param x first operand
2762 		/// \param y second operand
2763 		/// \retval true if \a x greater than \a y
2764 		/// \retval false else
2765 //		template<typename T,typename U> typename enable<bool,T,U>::type isgreater(T x, U y) { return functions::isgreater(x, y); }
isgreater(half x,half y)2766 		inline bool isgreater(half x, half y) { return functions::isgreater(x, y); }
isgreater(half x,expr y)2767 		inline bool isgreater(half x, expr y) { return functions::isgreater(x, y); }
isgreater(expr x,half y)2768 		inline bool isgreater(expr x, half y) { return functions::isgreater(x, y); }
isgreater(expr x,expr y)2769 		inline bool isgreater(expr x, expr y) { return functions::isgreater(x, y); }
2770 
2771 		/// Comparison for greater equal.
2772 		/// \param x first operand
2773 		/// \param y second operand
2774 		/// \retval true if \a x greater equal \a y
2775 		/// \retval false else
2776 //		template<typename T,typename U> typename enable<bool,T,U>::type isgreaterequal(T x, U y) { return functions::isgreaterequal(x, y); }
isgreaterequal(half x,half y)2777 		inline bool isgreaterequal(half x, half y) { return functions::isgreaterequal(x, y); }
isgreaterequal(half x,expr y)2778 		inline bool isgreaterequal(half x, expr y) { return functions::isgreaterequal(x, y); }
isgreaterequal(expr x,half y)2779 		inline bool isgreaterequal(expr x, half y) { return functions::isgreaterequal(x, y); }
isgreaterequal(expr x,expr y)2780 		inline bool isgreaterequal(expr x, expr y) { return functions::isgreaterequal(x, y); }
2781 
2782 		/// Comparison for less than.
2783 		/// \param x first operand
2784 		/// \param y second operand
2785 		/// \retval true if \a x less than \a y
2786 		/// \retval false else
2787 //		template<typename T,typename U> typename enable<bool,T,U>::type isless(T x, U y) { return functions::isless(x, y); }
isless(half x,half y)2788 		inline bool isless(half x, half y) { return functions::isless(x, y); }
isless(half x,expr y)2789 		inline bool isless(half x, expr y) { return functions::isless(x, y); }
isless(expr x,half y)2790 		inline bool isless(expr x, half y) { return functions::isless(x, y); }
isless(expr x,expr y)2791 		inline bool isless(expr x, expr y) { return functions::isless(x, y); }
2792 
2793 		/// Comparison for less equal.
2794 		/// \param x first operand
2795 		/// \param y second operand
2796 		/// \retval true if \a x less equal \a y
2797 		/// \retval false else
2798 //		template<typename T,typename U> typename enable<bool,T,U>::type islessequal(T x, U y) { return functions::islessequal(x, y); }
islessequal(half x,half y)2799 		inline bool islessequal(half x, half y) { return functions::islessequal(x, y); }
islessequal(half x,expr y)2800 		inline bool islessequal(half x, expr y) { return functions::islessequal(x, y); }
islessequal(expr x,half y)2801 		inline bool islessequal(expr x, half y) { return functions::islessequal(x, y); }
islessequal(expr x,expr y)2802 		inline bool islessequal(expr x, expr y) { return functions::islessequal(x, y); }
2803 
2804 		/// Comarison for less or greater.
2805 		/// \param x first operand
2806 		/// \param y second operand
2807 		/// \retval true if either less or greater
2808 		/// \retval false else
2809 //		template<typename T,typename U> typename enable<bool,T,U>::type islessgreater(T x, U y) { return functions::islessgreater(x, y); }
islessgreater(half x,half y)2810 		inline bool islessgreater(half x, half y) { return functions::islessgreater(x, y); }
islessgreater(half x,expr y)2811 		inline bool islessgreater(half x, expr y) { return functions::islessgreater(x, y); }
islessgreater(expr x,half y)2812 		inline bool islessgreater(expr x, half y) { return functions::islessgreater(x, y); }
islessgreater(expr x,expr y)2813 		inline bool islessgreater(expr x, expr y) { return functions::islessgreater(x, y); }
2814 
2815 		/// Check if unordered.
2816 		/// \param x first operand
2817 		/// \param y second operand
2818 		/// \retval true if unordered (one or two NaN operands)
2819 		/// \retval false else
2820 //		template<typename T,typename U> typename enable<bool,T,U>::type isunordered(T x, U y) { return functions::isunordered(x, y); }
isunordered(half x,half y)2821 		inline bool isunordered(half x, half y) { return functions::isunordered(x, y); }
isunordered(half x,expr y)2822 		inline bool isunordered(half x, expr y) { return functions::isunordered(x, y); }
isunordered(expr x,half y)2823 		inline bool isunordered(expr x, half y) { return functions::isunordered(x, y); }
isunordered(expr x,expr y)2824 		inline bool isunordered(expr x, expr y) { return functions::isunordered(x, y); }
2825 
2826 		/// \name Casting
2827 		/// \{
2828 
2829 		/// Cast to or from half-precision floating point number.
2830 		/// This casts between [half](\ref half_float::half) and any built-in arithmetic type. The values are converted
2831 		/// directly using the given rounding mode, without any roundtrip over `float` that a `static_cast` would otherwise do.
2832 		/// It uses the default rounding mode.
2833 		///
2834 		/// Using this cast with neither of the two types being a [half](\ref half_float::half) or with any of the two types
2835 		/// not being a built-in arithmetic type (apart from [half](\ref half_float::half), of course) results in a compiler
2836 		/// error and casting between [half](\ref half_float::half)s is just a no-op.
2837 		/// \tparam T destination type (half or built-in arithmetic type)
2838 		/// \tparam U source type (half or built-in arithmetic type)
2839 		/// \param arg value to cast
2840 		/// \return \a arg converted to destination type
half_cast(U arg)2841 		template<typename T,typename U> T half_cast(U arg) { return half_caster<T,U>::cast(arg); }
2842 
2843 		/// Cast to or from half-precision floating point number.
2844 		/// This casts between [half](\ref half_float::half) and any built-in arithmetic type. The values are converted
2845 		/// directly using the given rounding mode, without any roundtrip over `float` that a `static_cast` would otherwise do.
2846 		///
2847 		/// Using this cast with neither of the two types being a [half](\ref half_float::half) or with any of the two types
2848 		/// not being a built-in arithmetic type (apart from [half](\ref half_float::half), of course) results in a compiler
2849 		/// error and casting between [half](\ref half_float::half)s is just a no-op.
2850 		/// \tparam T destination type (half or built-in arithmetic type)
2851 		/// \tparam R rounding mode to use.
2852 		/// \tparam U source type (half or built-in arithmetic type)
2853 		/// \param arg value to cast
2854 		/// \return \a arg converted to destination type
half_cast(U arg)2855 		template<typename T,std::float_round_style R,typename U> T half_cast(U arg) { return half_caster<T,U,R>::cast(arg); }
2856 		/// \}
2857 	}
2858 
2859 	using detail::operator==;
2860 	using detail::operator!=;
2861 	using detail::operator<;
2862 	using detail::operator>;
2863 	using detail::operator<=;
2864 	using detail::operator>=;
2865 	using detail::operator+;
2866 	using detail::operator-;
2867 	using detail::operator*;
2868 	using detail::operator/;
2869 	using detail::operator<<;
2870 	using detail::operator>>;
2871 
2872 	using detail::abs;
2873 	using detail::fabs;
2874 	using detail::fmod;
2875 	using detail::remainder;
2876 	using detail::remquo;
2877 	using detail::fma;
2878 	using detail::fmax;
2879 	using detail::fmin;
2880 	using detail::fdim;
2881 	using detail::nanh;
2882 	using detail::exp;
2883 	using detail::expm1;
2884 	using detail::exp2;
2885 	using detail::log;
2886 	using detail::log10;
2887 	using detail::log1p;
2888 	using detail::log2;
2889 	using detail::sqrt;
2890 	using detail::cbrt;
2891 	using detail::hypot;
2892 	using detail::pow;
2893 	using detail::sin;
2894 	using detail::cos;
2895 	using detail::tan;
2896 	using detail::asin;
2897 	using detail::acos;
2898 	using detail::atan;
2899 	using detail::atan2;
2900 	using detail::sinh;
2901 	using detail::cosh;
2902 	using detail::tanh;
2903 	using detail::asinh;
2904 	using detail::acosh;
2905 	using detail::atanh;
2906 	using detail::erf;
2907 	using detail::erfc;
2908 	using detail::lgamma;
2909 	using detail::tgamma;
2910 	using detail::ceil;
2911 	using detail::floor;
2912 	using detail::trunc;
2913 	using detail::round;
2914 	using detail::lround;
2915 	using detail::nearbyint;
2916 	using detail::rint;
2917 	using detail::lrint;
2918 #if HALF_ENABLE_CPP11_LONG_LONG
2919 	using detail::llround;
2920 	using detail::llrint;
2921 #endif
2922 	using detail::frexp;
2923 	using detail::ldexp;
2924 	using detail::modf;
2925 	using detail::scalbn;
2926 	using detail::scalbln;
2927 	using detail::ilogb;
2928 	using detail::logb;
2929 	using detail::nextafter;
2930 	using detail::nexttoward;
2931 	using detail::copysign;
2932 	using detail::fpclassify;
2933 	using detail::isfinite;
2934 	using detail::isinf;
2935 	using detail::isnan;
2936 	using detail::isnormal;
2937 	using detail::signbit;
2938 	using detail::isgreater;
2939 	using detail::isgreaterequal;
2940 	using detail::isless;
2941 	using detail::islessequal;
2942 	using detail::islessgreater;
2943 	using detail::isunordered;
2944 
2945 	using detail::half_cast;
2946 }
2947 
2948 
2949 /// Extensions to the C++ standard library.
2950 namespace std
2951 {
2952 	/// Numeric limits for half-precision floats.
2953 	/// Because of the underlying single-precision implementation of many operations, it inherits some properties from
2954 	/// `std::numeric_limits<float>`.
2955 	template<> class numeric_limits<half_float::half> : public numeric_limits<float>
2956 	{
2957 	public:
2958 		/// Supports signed values.
2959 		static HALF_CONSTEXPR_CONST bool is_signed = true;
2960 
2961 		/// Is not exact.
2962 		static HALF_CONSTEXPR_CONST bool is_exact = false;
2963 
2964 		/// Doesn't provide modulo arithmetic.
2965 		static HALF_CONSTEXPR_CONST bool is_modulo = false;
2966 
2967 		/// IEEE conformant.
2968 		static HALF_CONSTEXPR_CONST bool is_iec559 = true;
2969 
2970 		/// Supports infinity.
2971 		static HALF_CONSTEXPR_CONST bool has_infinity = true;
2972 
2973 		/// Supports quiet NaNs.
2974 		static HALF_CONSTEXPR_CONST bool has_quiet_NaN = true;
2975 
2976 		/// Supports subnormal values.
2977 		static HALF_CONSTEXPR_CONST float_denorm_style has_denorm = denorm_present;
2978 
2979 		/// Rounding mode.
2980 		/// Due to the mix of internal single-precision computations (using the rounding mode of the underlying
2981 		/// single-precision implementation) with the rounding mode of the single-to-half conversions, the actual rounding
2982 		/// mode might be `std::round_indeterminate` if the default half-precision rounding mode doesn't match the
2983 		/// single-precision rounding mode.
2984 		static HALF_CONSTEXPR_CONST float_round_style round_style = (std::numeric_limits<float>::round_style==
2985 			half_float::half::round_style) ? half_float::half::round_style : round_indeterminate;
2986 
2987 		/// Significant digits.
2988 		static HALF_CONSTEXPR_CONST int digits = 11;
2989 
2990 		/// Significant decimal digits.
2991 		static HALF_CONSTEXPR_CONST int digits10 = 3;
2992 
2993 		/// Required decimal digits to represent all possible values.
2994 		static HALF_CONSTEXPR_CONST int max_digits10 = 5;
2995 
2996 		/// Number base.
2997 		static HALF_CONSTEXPR_CONST int radix = 2;
2998 
2999 		/// One more than smallest exponent.
3000 		static HALF_CONSTEXPR_CONST int min_exponent = -13;
3001 
3002 		/// Smallest normalized representable power of 10.
3003 		static HALF_CONSTEXPR_CONST int min_exponent10 = -4;
3004 
3005 		/// One more than largest exponent
3006 		static HALF_CONSTEXPR_CONST int max_exponent = 16;
3007 
3008 		/// Largest finitely representable power of 10.
3009 		static HALF_CONSTEXPR_CONST int max_exponent10 = 4;
3010 
3011 		/// Smallest positive normal value.
min()3012 		static HALF_CONSTEXPR half_float::half min() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x0400); }
3013 
3014 		/// Smallest finite value.
lowest()3015 		static HALF_CONSTEXPR half_float::half lowest() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0xFBFF); }
3016 
3017 		/// Largest finite value.
max()3018 		static HALF_CONSTEXPR half_float::half max() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x7BFF); }
3019 
3020 		/// Difference between one and next representable value.
epsilon()3021 		static HALF_CONSTEXPR half_float::half epsilon() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x1400); }
3022 
3023 		/// Maximum rounding error.
round_error()3024 		static HALF_CONSTEXPR half_float::half round_error() HALF_NOTHROW
3025 			{ return half_float::half(half_float::detail::binary, (round_style==std::round_to_nearest) ? 0x3800 : 0x3C00); }
3026 
3027 		/// Positive infinity.
infinity()3028 		static HALF_CONSTEXPR half_float::half infinity() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x7C00); }
3029 
3030 		/// Quiet NaN.
quiet_NaN()3031 		static HALF_CONSTEXPR half_float::half quiet_NaN() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x7FFF); }
3032 
3033 		/// Signalling NaN.
signaling_NaN()3034 		static HALF_CONSTEXPR half_float::half signaling_NaN() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x7DFF); }
3035 
3036 		/// Smallest positive subnormal value.
denorm_min()3037 		static HALF_CONSTEXPR half_float::half denorm_min() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x0001); }
3038 	};
3039 
3040 #if HALF_ENABLE_CPP11_HASH
3041 	/// Hash function for half-precision floats.
3042 	/// This is only defined if C++11 `std::hash` is supported and enabled.
3043 	template<> struct hash<half_float::half> //: unary_function<half_float::half,size_t>
3044 	{
3045 		/// Type of function argument.
3046 		typedef half_float::half argument_type;
3047 
3048 		/// Function return type.
3049 		typedef size_t result_type;
3050 
3051 		/// Compute hash function.
3052 		/// \param arg half to hash
3053 		/// \return hash value
operator ()std::hash3054 		result_type operator()(argument_type arg) const
3055 			{ return hash<half_float::detail::uint16>()(static_cast<unsigned>(arg.data_)&-(arg.data_!=0x8000)); }
3056 	};
3057 #endif
3058 }
3059 
3060 
3061 #undef HALF_CONSTEXPR
3062 #undef HALF_CONSTEXPR_CONST
3063 #undef HALF_NOEXCEPT
3064 #undef HALF_NOTHROW
3065 #ifdef HALF_POP_WARNINGS
3066 	#pragma warning(pop)
3067 	#undef HALF_POP_WARNINGS
3068 #endif
3069 
3070 #endif
3071