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