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