RMW desert 1.0
Loading...
Searching...
No Matches
half.hpp
Go to the documentation of this file.
1// half - IEEE 754-based half-precision floating-point library.
2//
3// Copyright (c) 2012-2021 Christian Rau <rauy@users.sourceforge.net>
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
6// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
7// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
8// Software is furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11//
12// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
13// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
14// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
15// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16
17// Version 2.2.0
18
23
24#ifndef HALF_HALF_HPP
25#define HALF_HALF_HPP
26
27#define HALF_GCC_VERSION (__GNUC__*100+__GNUC_MINOR__)
28
29#if defined(__INTEL_COMPILER)
30 #define HALF_ICC_VERSION __INTEL_COMPILER
31#elif defined(__ICC)
32 #define HALF_ICC_VERSION __ICC
33#elif defined(__ICL)
34 #define HALF_ICC_VERSION __ICL
35#else
36 #define HALF_ICC_VERSION 0
37#endif
38
39// check C++11 language features
40#if defined(__clang__) // clang
41 #if __has_feature(cxx_static_assert) && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
42 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
43 #endif
44 #if __has_feature(cxx_constexpr) && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
45 #define HALF_ENABLE_CPP11_CONSTEXPR 1
46 #endif
47 #if __has_feature(cxx_noexcept) && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
48 #define HALF_ENABLE_CPP11_NOEXCEPT 1
49 #endif
50 #if __has_feature(cxx_user_literals) && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
51 #define HALF_ENABLE_CPP11_USER_LITERALS 1
52 #endif
53 #if __has_feature(cxx_thread_local) && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
54 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
55 #endif
56 #if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) && !defined(HALF_ENABLE_CPP11_LONG_LONG)
57 #define HALF_ENABLE_CPP11_LONG_LONG 1
58 #endif
59#elif HALF_ICC_VERSION && defined(__INTEL_CXX11_MODE__) // Intel C++
60 #if HALF_ICC_VERSION >= 1500 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
61 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
62 #endif
63 #if HALF_ICC_VERSION >= 1500 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
64 #define HALF_ENABLE_CPP11_USER_LITERALS 1
65 #endif
66 #if HALF_ICC_VERSION >= 1400 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
67 #define HALF_ENABLE_CPP11_CONSTEXPR 1
68 #endif
69 #if HALF_ICC_VERSION >= 1400 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
70 #define HALF_ENABLE_CPP11_NOEXCEPT 1
71 #endif
72 #if HALF_ICC_VERSION >= 1110 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
73 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
74 #endif
75 #if HALF_ICC_VERSION >= 1110 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
76 #define HALF_ENABLE_CPP11_LONG_LONG 1
77 #endif
78#elif defined(__GNUC__) // gcc
79 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
80 #if HALF_GCC_VERSION >= 408 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
81 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
82 #endif
83 #if HALF_GCC_VERSION >= 407 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
84 #define HALF_ENABLE_CPP11_USER_LITERALS 1
85 #endif
86 #if HALF_GCC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
87 #define HALF_ENABLE_CPP11_CONSTEXPR 1
88 #endif
89 #if HALF_GCC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
90 #define HALF_ENABLE_CPP11_NOEXCEPT 1
91 #endif
92 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
93 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
94 #endif
95 #if !defined(HALF_ENABLE_CPP11_LONG_LONG)
96 #define HALF_ENABLE_CPP11_LONG_LONG 1
97 #endif
98 #endif
99 #define HALF_TWOS_COMPLEMENT_INT 1
100#elif defined(_MSC_VER) // Visual C++
101 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
102 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
103 #endif
104 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
105 #define HALF_ENABLE_CPP11_USER_LITERALS 1
106 #endif
107 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
108 #define HALF_ENABLE_CPP11_CONSTEXPR 1
109 #endif
110 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
111 #define HALF_ENABLE_CPP11_NOEXCEPT 1
112 #endif
113 #if _MSC_VER >= 1600 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
114 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
115 #endif
116 #if _MSC_VER >= 1310 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
117 #define HALF_ENABLE_CPP11_LONG_LONG 1
118 #endif
119 #define HALF_TWOS_COMPLEMENT_INT 1
120 #define HALF_POP_WARNINGS 1
121 #pragma warning(push)
122 #pragma warning(disable : 4099 4127 4146) //struct vs class, constant in if, negative unsigned
123#endif
124
125// check C++11 library features
126// \cond
127#include <utility>
128// \endcond
129#if defined(_LIBCPP_VERSION) // libc++
130 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
131 #ifndef HALF_ENABLE_CPP11_TYPE_TRAITS
132 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
133 #endif
134 #ifndef HALF_ENABLE_CPP11_CSTDINT
135 #define HALF_ENABLE_CPP11_CSTDINT 1
136 #endif
137 #ifndef HALF_ENABLE_CPP11_CMATH
138 #define HALF_ENABLE_CPP11_CMATH 1
139 #endif
140 #ifndef HALF_ENABLE_CPP11_HASH
141 #define HALF_ENABLE_CPP11_HASH 1
142 #endif
143 #ifndef HALF_ENABLE_CPP11_CFENV
144 #define HALF_ENABLE_CPP11_CFENV 1
145 #endif
146 #endif
147#elif defined(__GLIBCXX__) // libstdc++
148 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
149 #ifdef __clang__
150 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
151 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
152 #endif
153 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CSTDINT)
154 #define HALF_ENABLE_CPP11_CSTDINT 1
155 #endif
156 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CMATH)
157 #define HALF_ENABLE_CPP11_CMATH 1
158 #endif
159 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_HASH)
160 #define HALF_ENABLE_CPP11_HASH 1
161 #endif
162 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CFENV)
163 #define HALF_ENABLE_CPP11_CFENV 1
164 #endif
165 #else
166 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
167 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
168 #endif
169 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CSTDINT)
170 #define HALF_ENABLE_CPP11_CSTDINT 1
171 #endif
172 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CMATH)
173 #define HALF_ENABLE_CPP11_CMATH 1
174 #endif
175 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_HASH)
176 #define HALF_ENABLE_CPP11_HASH 1
177 #endif
178 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CFENV)
179 #define HALF_ENABLE_CPP11_CFENV 1
180 #endif
181 #endif
182 #endif
183#elif defined(_CPPLIB_VER) // Dinkumware/Visual C++
184 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
185 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
186 #endif
187 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_CSTDINT)
188 #define HALF_ENABLE_CPP11_CSTDINT 1
189 #endif
190 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_HASH)
191 #define HALF_ENABLE_CPP11_HASH 1
192 #endif
193 #if _CPPLIB_VER >= 610 && !defined(HALF_ENABLE_CPP11_CMATH)
194 #define HALF_ENABLE_CPP11_CMATH 1
195 #endif
196 #if _CPPLIB_VER >= 610 && !defined(HALF_ENABLE_CPP11_CFENV)
197 #define HALF_ENABLE_CPP11_CFENV 1
198 #endif
199#endif
200#undef HALF_GCC_VERSION
201#undef HALF_ICC_VERSION
202
203// any error throwing C++ exceptions?
204#if defined(HALF_ERRHANDLING_THROW_INVALID) || defined(HALF_ERRHANDLING_THROW_DIVBYZERO) || defined(HALF_ERRHANDLING_THROW_OVERFLOW) || defined(HALF_ERRHANDLING_THROW_UNDERFLOW) || defined(HALF_ERRHANDLING_THROW_INEXACT)
205#define HALF_ERRHANDLING_THROWS 1
206#endif
207
208// any error handling enabled?
209#define HALF_ERRHANDLING (HALF_ERRHANDLING_FLAGS||HALF_ERRHANDLING_ERRNO||HALF_ERRHANDLING_FENV||HALF_ERRHANDLING_THROWS)
210
211#if HALF_ERRHANDLING
212 #define HALF_UNUSED_NOERR(name) name
213#else
214 #define HALF_UNUSED_NOERR(name)
215#endif
216
217// support constexpr
218#if HALF_ENABLE_CPP11_CONSTEXPR
219 #define HALF_CONSTEXPR constexpr
220 #define HALF_CONSTEXPR_CONST constexpr
221 #if HALF_ERRHANDLING
222 #define HALF_CONSTEXPR_NOERR
223 #else
224 #define HALF_CONSTEXPR_NOERR constexpr
225 #endif
226#else
227 #define HALF_CONSTEXPR
228 #define HALF_CONSTEXPR_CONST const
229 #define HALF_CONSTEXPR_NOERR
230#endif
231
232// support noexcept
233#if HALF_ENABLE_CPP11_NOEXCEPT
234 #define HALF_NOEXCEPT noexcept
235 #define HALF_NOTHROW noexcept
236#else
237 #define HALF_NOEXCEPT
238 #define HALF_NOTHROW throw()
239#endif
240
241// support thread storage
242#if HALF_ENABLE_CPP11_THREAD_LOCAL
243 #define HALF_THREAD_LOCAL thread_local
244#else
245 #define HALF_THREAD_LOCAL static
246#endif
247
248// \cond
249#include <utility>
250#include <algorithm>
251#include <istream>
252#include <ostream>
253#include <limits>
254#include <stdexcept>
255#include <climits>
256#include <cmath>
257#include <cstring>
258#include <cstdlib>
259#if HALF_ENABLE_CPP11_TYPE_TRAITS
260 #include <type_traits>
261#endif
262#if HALF_ENABLE_CPP11_CSTDINT
263 #include <cstdint>
264#endif
265#if HALF_ERRHANDLING_ERRNO
266 #include <cerrno>
267#endif
268#if HALF_ENABLE_CPP11_CFENV
269 #include <cfenv>
270#endif
271#if HALF_ENABLE_CPP11_HASH
272 #include <functional>
273#endif
274// \endcond
275
276#ifndef HALF_ENABLE_F16C_INTRINSICS
283 #define HALF_ENABLE_F16C_INTRINSICS __F16C__
284#endif
285#if HALF_ENABLE_F16C_INTRINSICS
286 #include <immintrin.h>
287#endif
288
289#ifdef HALF_DOXYGEN_ONLY
295#define HALF_ARITHMETIC_TYPE (undefined)
296
300#define HALF_ERRHANDLING_FLAGS 0
301
307#define HALF_ERRHANDLING_ERRNO 0
308
315#define HALF_ERRHANDLING_FENV 0
316
320#define HALF_ERRHANDLING_THROW_INVALID (undefined)
321
325#define HALF_ERRHANDLING_THROW_DIVBYZERO (undefined)
326
330#define HALF_ERRHANDLING_THROW_OVERFLOW (undefined)
331
335#define HALF_ERRHANDLING_THROW_UNDERFLOW (undefined)
336
340#define HALF_ERRHANDLING_THROW_INEXACT (undefined)
341#endif
342
343#ifndef HALF_ERRHANDLING_OVERFLOW_TO_INEXACT
347#define HALF_ERRHANDLING_OVERFLOW_TO_INEXACT 1
348#endif
349
350#ifndef HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
357#define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT 1
358#endif
359
378#ifndef HALF_ROUND_STYLE
379 #define HALF_ROUND_STYLE 1 // = std::round_to_nearest
380#endif
381
387#define HUGE_VALH std::numeric_limits<half_float::half>::infinity()
388
394#define FP_FAST_FMAH 1
395
401#define HLF_ROUNDS HALF_ROUND_STYLE
402
403#ifndef FP_ILOGB0
404 #define FP_ILOGB0 INT_MIN
405#endif
406#ifndef FP_ILOGBNAN
407 #define FP_ILOGBNAN INT_MAX
408#endif
409#ifndef FP_SUBNORMAL
410 #define FP_SUBNORMAL 0
411#endif
412#ifndef FP_ZERO
413 #define FP_ZERO 1
414#endif
415#ifndef FP_NAN
416 #define FP_NAN 2
417#endif
418#ifndef FP_INFINITE
419 #define FP_INFINITE 3
420#endif
421#ifndef FP_NORMAL
422 #define FP_NORMAL 4
423#endif
424
425#if !HALF_ENABLE_CPP11_CFENV && !defined(FE_ALL_EXCEPT)
426 #define FE_INVALID 0x10
427 #define FE_DIVBYZERO 0x08
428 #define FE_OVERFLOW 0x04
429 #define FE_UNDERFLOW 0x02
430 #define FE_INEXACT 0x01
431 #define FE_ALL_EXCEPT (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW|FE_INEXACT)
432#endif
433
434
437namespace half_float
438{
439 class half;
440
441#if HALF_ENABLE_CPP11_USER_LITERALS
448 namespace literal
449 {
450 half operator "" _h(long double);
451 }
452#endif
453
456 namespace detail
457 {
458 #if HALF_ENABLE_CPP11_TYPE_TRAITS
460 template<bool B,typename T,typename F> struct conditional : std::conditional<B,T,F> {};
461
463 template<bool B> struct bool_type : std::integral_constant<bool,B> {};
464 using std::true_type;
465 using std::false_type;
466
468 template<typename T> struct is_float : std::is_floating_point<T> {};
469 #else
471 template<bool,typename T,typename> struct conditional { typedef T type; };
472 template<typename T,typename F> struct conditional<false,T,F> { typedef F type; };
473
475 template<bool> struct bool_type {};
478
480 template<typename> struct is_float : false_type {};
481 template<typename T> struct is_float<const T> : is_float<T> {};
482 template<typename T> struct is_float<volatile T> : is_float<T> {};
483 template<typename T> struct is_float<const volatile T> : is_float<T> {};
484 template<> struct is_float<float> : true_type {};
485 template<> struct is_float<double> : true_type {};
486 template<> struct is_float<long double> : true_type {};
487 #endif
488
490 template<typename T> struct bits { typedef unsigned char type; };
491 template<typename T> struct bits<const T> : bits<T> {};
492 template<typename T> struct bits<volatile T> : bits<T> {};
493 template<typename T> struct bits<const volatile T> : bits<T> {};
494
495 #if HALF_ENABLE_CPP11_CSTDINT
497 typedef std::uint_least16_t uint16;
498
500 typedef std::uint_fast32_t uint32;
501
503 typedef std::int_fast32_t int32;
504
506 template<> struct bits<float> { typedef std::uint_least32_t type; };
507
509 template<> struct bits<double> { typedef std::uint_least64_t type; };
510 #else
512 typedef unsigned short uint16;
513
515 typedef unsigned long uint32;
516
518 typedef long int32;
519
521 template<> struct bits<float> : conditional<std::numeric_limits<unsigned int>::digits>=32,unsigned int,unsigned long> {};
522
523 #if HALF_ENABLE_CPP11_LONG_LONG
525 template<> struct bits<double> : conditional<std::numeric_limits<unsigned long>::digits>=64,unsigned long,unsigned long long> {};
526 #else
528 template<> struct bits<double> { typedef unsigned long type; };
529 #endif
530 #endif
531
532 #ifdef HALF_ARITHMETIC_TYPE
534 typedef HALF_ARITHMETIC_TYPE internal_t;
535 #endif
536
538 struct binary_t {};
539
541 HALF_CONSTEXPR_CONST binary_t binary = binary_t();
542
545
551 template<typename T> bool builtin_isinf(T arg)
552 {
553 #if HALF_ENABLE_CPP11_CMATH
554 return std::isinf(arg);
555 #elif defined(_MSC_VER)
556 return !::_finite(static_cast<double>(arg)) && !::_isnan(static_cast<double>(arg));
557 #else
558 return arg == std::numeric_limits<T>::infinity() || arg == -std::numeric_limits<T>::infinity();
559 #endif
560 }
561
567 template<typename T> bool builtin_isnan(T arg)
568 {
569 #if HALF_ENABLE_CPP11_CMATH
570 return std::isnan(arg);
571 #elif defined(_MSC_VER)
572 return ::_isnan(static_cast<double>(arg)) != 0;
573 #else
574 return arg != arg;
575 #endif
576 }
577
583 template<typename T> bool builtin_signbit(T arg)
584 {
585 #if HALF_ENABLE_CPP11_CMATH
586 return std::signbit(arg);
587 #else
588 return arg < T() || (arg == T() && T(1)/arg < T());
589 #endif
590 }
591
597 {
598 static const int N = std::numeric_limits<uint32>::digits - 1;
599 #if HALF_TWOS_COMPLEMENT_INT
600 return static_cast<int32>(arg) >> N;
601 #else
602 return -((arg>>N)&1);
603 #endif
604 }
605
610 inline uint32 arithmetic_shift(uint32 arg, int i)
611 {
612 #if HALF_TWOS_COMPLEMENT_INT
613 return static_cast<int32>(arg) >> i;
614 #else
615 return static_cast<int32>(arg)/(static_cast<int32>(1)<<i) - ((arg>>(std::numeric_limits<uint32>::digits-1))&1);
616 #endif
617 }
618
622
625 inline int& errflags() { HALF_THREAD_LOCAL int flags = 0; return flags; }
626
630 inline void raise(int HALF_UNUSED_NOERR(flags), bool HALF_UNUSED_NOERR(cond) = true)
631 {
632 #if HALF_ERRHANDLING
633 if(!cond)
634 return;
635 #if HALF_ERRHANDLING_FLAGS
636 errflags() |= flags;
637 #endif
638 #if HALF_ERRHANDLING_ERRNO
639 if(flags & FE_INVALID)
640 errno = EDOM;
641 else if(flags & (FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW))
642 errno = ERANGE;
643 #endif
644 #if HALF_ERRHANDLING_FENV && HALF_ENABLE_CPP11_CFENV
645 std::feraiseexcept(flags);
646 #endif
647 #ifdef HALF_ERRHANDLING_THROW_INVALID
648 if(flags & FE_INVALID)
649 throw std::domain_error(HALF_ERRHANDLING_THROW_INVALID);
650 #endif
651 #ifdef HALF_ERRHANDLING_THROW_DIVBYZERO
652 if(flags & FE_DIVBYZERO)
653 throw std::domain_error(HALF_ERRHANDLING_THROW_DIVBYZERO);
654 #endif
655 #ifdef HALF_ERRHANDLING_THROW_OVERFLOW
656 if(flags & FE_OVERFLOW)
657 throw std::overflow_error(HALF_ERRHANDLING_THROW_OVERFLOW);
658 #endif
659 #ifdef HALF_ERRHANDLING_THROW_UNDERFLOW
660 if(flags & FE_UNDERFLOW)
661 throw std::underflow_error(HALF_ERRHANDLING_THROW_UNDERFLOW);
662 #endif
663 #ifdef HALF_ERRHANDLING_THROW_INEXACT
664 if(flags & FE_INEXACT)
665 throw std::range_error(HALF_ERRHANDLING_THROW_INEXACT);
666 #endif
667 #if HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
668 if((flags & FE_UNDERFLOW) && !(flags & FE_INEXACT))
669 raise(FE_INEXACT);
670 #endif
671 #if HALF_ERRHANDLING_OVERFLOW_TO_INEXACT
672 if((flags & FE_OVERFLOW) && !(flags & FE_INEXACT))
673 raise(FE_INEXACT);
674 #endif
675 #endif
676 }
677
684 inline HALF_CONSTEXPR_NOERR bool compsignal(unsigned int x, unsigned int y)
685 {
686 #if HALF_ERRHANDLING
687 raise(FE_INVALID, (x&0x7FFF)>0x7C00 || (y&0x7FFF)>0x7C00);
688 #endif
689 return (x&0x7FFF) > 0x7C00 || (y&0x7FFF) > 0x7C00;
690 }
691
696 inline HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int nan)
697 {
698 #if HALF_ERRHANDLING
699 raise(FE_INVALID, !(nan&0x200));
700 #endif
701 return nan | 0x200;
702 }
703
709 inline HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int x, unsigned int y)
710 {
711 #if HALF_ERRHANDLING
712 raise(FE_INVALID, ((x&0x7FFF)>0x7C00 && !(x&0x200)) || ((y&0x7FFF)>0x7C00 && !(y&0x200)));
713 #endif
714 return ((x&0x7FFF)>0x7C00) ? (x|0x200) : (y|0x200);
715 }
716
723 inline HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int x, unsigned int y, unsigned int z)
724 {
725 #if HALF_ERRHANDLING
726 raise(FE_INVALID, ((x&0x7FFF)>0x7C00 && !(x&0x200)) || ((y&0x7FFF)>0x7C00 && !(y&0x200)) || ((z&0x7FFF)>0x7C00 && !(z&0x200)));
727 #endif
728 return ((x&0x7FFF)>0x7C00) ? (x|0x200) : ((y&0x7FFF)>0x7C00) ? (y|0x200) : (z|0x200);
729 }
730
736 inline HALF_CONSTEXPR_NOERR unsigned int select(unsigned int x, unsigned int HALF_UNUSED_NOERR(y))
737 {
738 #if HALF_ERRHANDLING
739 return (((y&0x7FFF)>0x7C00) && !(y&0x200)) ? signal(y) : x;
740 #else
741 return x;
742 #endif
743 }
744
748 inline HALF_CONSTEXPR_NOERR unsigned int invalid()
749 {
750 #if HALF_ERRHANDLING
751 raise(FE_INVALID);
752 #endif
753 return 0x7FFF;
754 }
755
760 inline HALF_CONSTEXPR_NOERR unsigned int pole(unsigned int sign = 0)
761 {
762 #if HALF_ERRHANDLING
763 raise(FE_DIVBYZERO);
764 #endif
765 return sign | 0x7C00;
766 }
767
772 inline HALF_CONSTEXPR_NOERR unsigned int check_underflow(unsigned int arg)
773 {
774 #if HALF_ERRHANDLING && !HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
775 raise(FE_UNDERFLOW, !(arg&0x7C00));
776 #endif
777 return arg;
778 }
779
783
789 template<std::float_round_style R> HALF_CONSTEXPR_NOERR unsigned int overflow(unsigned int sign = 0)
790 {
791 #if HALF_ERRHANDLING
792 raise(FE_OVERFLOW);
793 #endif
794 return (R==std::round_toward_infinity) ? (sign+0x7C00-(sign>>15)) :
795 (R==std::round_toward_neg_infinity) ? (sign+0x7BFF+(sign>>15)) :
796 (R==std::round_toward_zero) ? (sign|0x7BFF) :
797 (sign|0x7C00);
798 }
799
805 template<std::float_round_style R> HALF_CONSTEXPR_NOERR unsigned int underflow(unsigned int sign = 0)
806 {
807 #if HALF_ERRHANDLING
808 raise(FE_UNDERFLOW);
809 #endif
810 return (R==std::round_toward_infinity) ? (sign+1-(sign>>15)) :
811 (R==std::round_toward_neg_infinity) ? (sign+(sign>>15)) :
812 sign;
813 }
814
825 template<std::float_round_style R,bool I> HALF_CONSTEXPR_NOERR unsigned int rounded(unsigned int value, int g, int s)
826 {
827 #if HALF_ERRHANDLING
828 value += (R==std::round_to_nearest) ? (g&(s|value)) :
829 (R==std::round_toward_infinity) ? (~(value>>15)&(g|s)) :
830 (R==std::round_toward_neg_infinity) ? ((value>>15)&(g|s)) : 0;
831 if((value&0x7C00) == 0x7C00)
832 raise(FE_OVERFLOW);
833 else if(value & 0x7C00)
834 raise(FE_INEXACT, I || (g|s)!=0);
835 else
836 raise(FE_UNDERFLOW, !(HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT) || I || (g|s)!=0);
837 return value;
838 #else
839 return (R==std::round_to_nearest) ? (value+(g&(s|value))) :
840 (R==std::round_toward_infinity) ? (value+(~(value>>15)&(g|s))) :
841 (R==std::round_toward_neg_infinity) ? (value+((value>>15)&(g|s))) :
842 value;
843 #endif
844 }
845
854 template<std::float_round_style R,bool E,bool I> unsigned int integral(unsigned int value)
855 {
856 unsigned int abs = value & 0x7FFF;
857 if(abs < 0x3C00)
858 {
859 raise(FE_INEXACT, I);
860 return ((R==std::round_to_nearest) ? (0x3C00&-static_cast<unsigned>(abs>=(0x3800+E))) :
861 (R==std::round_toward_infinity) ? (0x3C00&-(~(value>>15)&(abs!=0))) :
862 (R==std::round_toward_neg_infinity) ? (0x3C00&-static_cast<unsigned>(value>0x8000)) :
863 0) | (value&0x8000);
864 }
865 if(abs >= 0x6400)
866 return (abs>0x7C00) ? signal(value) : value;
867 unsigned int exp = 25 - (abs>>10), mask = (1<<exp) - 1;
868 raise(FE_INEXACT, I && (value&mask));
869 return (( (R==std::round_to_nearest) ? ((1<<(exp-1))-(~(value>>exp)&E)) :
870 (R==std::round_toward_infinity) ? (mask&((value>>15)-1)) :
871 (R==std::round_toward_neg_infinity) ? (mask&-(value>>15)) :
872 0) + value) & ~mask;
873 }
874
889 template<std::float_round_style R,unsigned int F,bool S,bool N,bool I> unsigned int fixed2half(uint32 m, int exp = 14, unsigned int sign = 0, int s = 0)
890 {
891 if(S)
892 {
893 uint32 msign = sign_mask(m);
894 m = (m^msign) - msign;
895 sign = msign & 0x8000;
896 }
897 if(N)
898 for(; m<(static_cast<uint32>(1)<<F) && exp; m<<=1,--exp) ;
899 else if(exp < 0)
900 return rounded<R,I>(sign+(m>>(F-10-exp)), (m>>(F-11-exp))&1, s|((m&((static_cast<uint32>(1)<<(F-11-exp))-1))!=0));
901 return rounded<R,I>(sign+(exp<<10)+(m>>(F-10)), (m>>(F-11))&1, s|((m&((static_cast<uint32>(1)<<(F-11))-1))!=0));
902 }
903
912 template<std::float_round_style R> unsigned int float2half_impl(float value, true_type)
913 {
914 #if HALF_ENABLE_F16C_INTRINSICS
915 return _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_set_ss(value),
916 (R==std::round_to_nearest) ? _MM_FROUND_TO_NEAREST_INT :
917 (R==std::round_toward_zero) ? _MM_FROUND_TO_ZERO :
918 (R==std::round_toward_infinity) ? _MM_FROUND_TO_POS_INF :
919 (R==std::round_toward_neg_infinity) ? _MM_FROUND_TO_NEG_INF :
920 _MM_FROUND_CUR_DIRECTION));
921 #else
922 bits<float>::type fbits;
923 std::memcpy(&fbits, &value, sizeof(float));
924 #if 1
925 unsigned int sign = (fbits>>16) & 0x8000;
926 fbits &= 0x7FFFFFFF;
927 if(fbits >= 0x7F800000)
928 return sign | 0x7C00 | ((fbits>0x7F800000) ? (0x200|((fbits>>13)&0x3FF)) : 0);
929 if(fbits >= 0x47800000)
930 return overflow<R>(sign);
931 if(fbits >= 0x38800000)
932 return rounded<R,false>(sign|(((fbits>>23)-112)<<10)|((fbits>>13)&0x3FF), (fbits>>12)&1, (fbits&0xFFF)!=0);
933 if(fbits >= 0x33000000)
934 {
935 int i = 125 - (fbits>>23);
936 fbits = (fbits&0x7FFFFF) | 0x800000;
937 return rounded<R,false>(sign|(fbits>>(i+1)), (fbits>>i)&1, (fbits&((static_cast<uint32>(1)<<i)-1))!=0);
938 }
939 if(fbits != 0)
940 return underflow<R>(sign);
941 return sign;
942 #else
943 static const uint16 base_table[512] = {
944 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
945 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
946 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
947 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
948 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
949 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
950 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
951 0x0200, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00,
952 0x4000, 0x4400, 0x4800, 0x4C00, 0x5000, 0x5400, 0x5800, 0x5C00, 0x6000, 0x6400, 0x6800, 0x6C00, 0x7000, 0x7400, 0x7800, 0x7BFF,
953 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
954 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
955 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
956 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
957 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
958 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
959 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7C00,
960 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
961 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
962 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
963 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
964 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
965 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
966 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001, 0x8002, 0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100,
967 0x8200, 0x8400, 0x8800, 0x8C00, 0x9000, 0x9400, 0x9800, 0x9C00, 0xA000, 0xA400, 0xA800, 0xAC00, 0xB000, 0xB400, 0xB800, 0xBC00,
968 0xC000, 0xC400, 0xC800, 0xCC00, 0xD000, 0xD400, 0xD800, 0xDC00, 0xE000, 0xE400, 0xE800, 0xEC00, 0xF000, 0xF400, 0xF800, 0xFBFF,
969 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
970 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
971 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
972 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
973 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
974 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
975 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFC00 };
976 static const unsigned char shift_table[256] = {
977 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
978 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
979 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
980 25, 25, 25, 25, 25, 25, 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,
981 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,
982 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
983 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
984 24, 24, 24, 24, 24, 24, 24, 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 };
985 int sexp = fbits >> 23, exp = sexp & 0xFF, i = shift_table[exp];
986 fbits &= 0x7FFFFF;
987 uint32 m = (fbits|((exp!=0)<<23)) & -static_cast<uint32>(exp!=0xFF);
988 return rounded<R,false>(base_table[sexp]+(fbits>>i), (m>>(i-1))&1, (((static_cast<uint32>(1)<<(i-1))-1)&m)!=0);
989 #endif
990 #endif
991 }
992
1000 template<std::float_round_style R> unsigned int float2half_impl(double value, true_type)
1001 {
1002 #if HALF_ENABLE_F16C_INTRINSICS
1003 if(R == std::round_indeterminate)
1004 return _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_cvtpd_ps(_mm_set_sd(value)), _MM_FROUND_CUR_DIRECTION));
1005 #endif
1006 bits<double>::type dbits;
1007 std::memcpy(&dbits, &value, sizeof(double));
1008 uint32 hi = dbits >> 32, lo = dbits & 0xFFFFFFFF;
1009 unsigned int sign = (hi>>16) & 0x8000;
1010 hi &= 0x7FFFFFFF;
1011 if(hi >= 0x7FF00000)
1012 return sign | 0x7C00 | ((dbits&0xFFFFFFFFFFFFF) ? (0x200|((hi>>10)&0x3FF)) : 0);
1013 if(hi >= 0x40F00000)
1014 return overflow<R>(sign);
1015 if(hi >= 0x3F100000)
1016 return rounded<R,false>(sign|(((hi>>20)-1008)<<10)|((hi>>10)&0x3FF), (hi>>9)&1, ((hi&0x1FF)|lo)!=0);
1017 if(hi >= 0x3E600000)
1018 {
1019 int i = 1018 - (hi>>20);
1020 hi = (hi&0xFFFFF) | 0x100000;
1021 return rounded<R,false>(sign|(hi>>(i+1)), (hi>>i)&1, ((hi&((static_cast<uint32>(1)<<i)-1))|lo)!=0);
1022 }
1023 if((hi|lo) != 0)
1024 return underflow<R>(sign);
1025 return sign;
1026 }
1027
1036 template<std::float_round_style R,typename T> unsigned int float2half_impl(T value, ...)
1037 {
1038 unsigned int hbits = static_cast<unsigned>(builtin_signbit(value)) << 15;
1039 if(value == T())
1040 return hbits;
1041 if(builtin_isnan(value))
1042 return hbits | 0x7FFF;
1043 if(builtin_isinf(value))
1044 return hbits | 0x7C00;
1045 int exp;
1046 std::frexp(value, &exp);
1047 if(exp > 16)
1048 return overflow<R>(hbits);
1049 if(exp < -13)
1050 value = std::ldexp(value, 25);
1051 else
1052 {
1053 value = std::ldexp(value, 12-exp);
1054 hbits |= ((exp+13)<<10);
1055 }
1056 T ival, frac = std::modf(value, &ival);
1057 int m = std::abs(static_cast<int>(ival));
1058 return rounded<R,false>(hbits+(m>>1), m&1, frac!=T());
1059 }
1060
1069 template<std::float_round_style R,typename T> unsigned int float2half(T value)
1070 {
1071 return float2half_impl<R>(value, bool_type<std::numeric_limits<T>::is_iec559&&sizeof(typename bits<T>::type)==sizeof(T)>());
1072 }
1073
1081 template<std::float_round_style R,typename T> unsigned int int2half(T value)
1082 {
1083 unsigned int bits = static_cast<unsigned>(value<0) << 15;
1084 if(!value)
1085 return bits;
1086 if(bits)
1087 value = -value;
1088 if(value > 0xFFFF)
1089 return overflow<R>(bits);
1090 unsigned int m = static_cast<unsigned int>(value), exp = 24;
1091 for(; m<0x400; m<<=1,--exp) ;
1092 for(; m>0x7FF; m>>=1,++exp) ;
1093 bits |= (exp<<10) + m;
1094 return (exp>24) ? rounded<R,false>(bits, (value>>(exp-25))&1, (((1<<(exp-25))-1)&value)!=0) : bits;
1095 }
1096
1101 inline float half2float_impl(unsigned int value, float, true_type)
1102 {
1103 #if HALF_ENABLE_F16C_INTRINSICS
1104 return _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128(value)));
1105 #else
1106 #if 0
1107 bits<float>::type fbits = static_cast<bits<float>::type>(value&0x8000) << 16;
1108 int abs = value & 0x7FFF;
1109 if(abs)
1110 {
1111 fbits |= 0x38000000 << static_cast<unsigned>(abs>=0x7C00);
1112 for(; abs<0x400; abs<<=1,fbits-=0x800000) ;
1113 fbits += static_cast<bits<float>::type>(abs) << 13;
1114 }
1115 #else
1116 static const bits<float>::type mantissa_table[2048] = {
1117 0x00000000, 0x33800000, 0x34000000, 0x34400000, 0x34800000, 0x34A00000, 0x34C00000, 0x34E00000, 0x35000000, 0x35100000, 0x35200000, 0x35300000, 0x35400000, 0x35500000, 0x35600000, 0x35700000,
1118 0x35800000, 0x35880000, 0x35900000, 0x35980000, 0x35A00000, 0x35A80000, 0x35B00000, 0x35B80000, 0x35C00000, 0x35C80000, 0x35D00000, 0x35D80000, 0x35E00000, 0x35E80000, 0x35F00000, 0x35F80000,
1119 0x36000000, 0x36040000, 0x36080000, 0x360C0000, 0x36100000, 0x36140000, 0x36180000, 0x361C0000, 0x36200000, 0x36240000, 0x36280000, 0x362C0000, 0x36300000, 0x36340000, 0x36380000, 0x363C0000,
1120 0x36400000, 0x36440000, 0x36480000, 0x364C0000, 0x36500000, 0x36540000, 0x36580000, 0x365C0000, 0x36600000, 0x36640000, 0x36680000, 0x366C0000, 0x36700000, 0x36740000, 0x36780000, 0x367C0000,
1121 0x36800000, 0x36820000, 0x36840000, 0x36860000, 0x36880000, 0x368A0000, 0x368C0000, 0x368E0000, 0x36900000, 0x36920000, 0x36940000, 0x36960000, 0x36980000, 0x369A0000, 0x369C0000, 0x369E0000,
1122 0x36A00000, 0x36A20000, 0x36A40000, 0x36A60000, 0x36A80000, 0x36AA0000, 0x36AC0000, 0x36AE0000, 0x36B00000, 0x36B20000, 0x36B40000, 0x36B60000, 0x36B80000, 0x36BA0000, 0x36BC0000, 0x36BE0000,
1123 0x36C00000, 0x36C20000, 0x36C40000, 0x36C60000, 0x36C80000, 0x36CA0000, 0x36CC0000, 0x36CE0000, 0x36D00000, 0x36D20000, 0x36D40000, 0x36D60000, 0x36D80000, 0x36DA0000, 0x36DC0000, 0x36DE0000,
1124 0x36E00000, 0x36E20000, 0x36E40000, 0x36E60000, 0x36E80000, 0x36EA0000, 0x36EC0000, 0x36EE0000, 0x36F00000, 0x36F20000, 0x36F40000, 0x36F60000, 0x36F80000, 0x36FA0000, 0x36FC0000, 0x36FE0000,
1125 0x37000000, 0x37010000, 0x37020000, 0x37030000, 0x37040000, 0x37050000, 0x37060000, 0x37070000, 0x37080000, 0x37090000, 0x370A0000, 0x370B0000, 0x370C0000, 0x370D0000, 0x370E0000, 0x370F0000,
1126 0x37100000, 0x37110000, 0x37120000, 0x37130000, 0x37140000, 0x37150000, 0x37160000, 0x37170000, 0x37180000, 0x37190000, 0x371A0000, 0x371B0000, 0x371C0000, 0x371D0000, 0x371E0000, 0x371F0000,
1127 0x37200000, 0x37210000, 0x37220000, 0x37230000, 0x37240000, 0x37250000, 0x37260000, 0x37270000, 0x37280000, 0x37290000, 0x372A0000, 0x372B0000, 0x372C0000, 0x372D0000, 0x372E0000, 0x372F0000,
1128 0x37300000, 0x37310000, 0x37320000, 0x37330000, 0x37340000, 0x37350000, 0x37360000, 0x37370000, 0x37380000, 0x37390000, 0x373A0000, 0x373B0000, 0x373C0000, 0x373D0000, 0x373E0000, 0x373F0000,
1129 0x37400000, 0x37410000, 0x37420000, 0x37430000, 0x37440000, 0x37450000, 0x37460000, 0x37470000, 0x37480000, 0x37490000, 0x374A0000, 0x374B0000, 0x374C0000, 0x374D0000, 0x374E0000, 0x374F0000,
1130 0x37500000, 0x37510000, 0x37520000, 0x37530000, 0x37540000, 0x37550000, 0x37560000, 0x37570000, 0x37580000, 0x37590000, 0x375A0000, 0x375B0000, 0x375C0000, 0x375D0000, 0x375E0000, 0x375F0000,
1131 0x37600000, 0x37610000, 0x37620000, 0x37630000, 0x37640000, 0x37650000, 0x37660000, 0x37670000, 0x37680000, 0x37690000, 0x376A0000, 0x376B0000, 0x376C0000, 0x376D0000, 0x376E0000, 0x376F0000,
1132 0x37700000, 0x37710000, 0x37720000, 0x37730000, 0x37740000, 0x37750000, 0x37760000, 0x37770000, 0x37780000, 0x37790000, 0x377A0000, 0x377B0000, 0x377C0000, 0x377D0000, 0x377E0000, 0x377F0000,
1133 0x37800000, 0x37808000, 0x37810000, 0x37818000, 0x37820000, 0x37828000, 0x37830000, 0x37838000, 0x37840000, 0x37848000, 0x37850000, 0x37858000, 0x37860000, 0x37868000, 0x37870000, 0x37878000,
1134 0x37880000, 0x37888000, 0x37890000, 0x37898000, 0x378A0000, 0x378A8000, 0x378B0000, 0x378B8000, 0x378C0000, 0x378C8000, 0x378D0000, 0x378D8000, 0x378E0000, 0x378E8000, 0x378F0000, 0x378F8000,
1135 0x37900000, 0x37908000, 0x37910000, 0x37918000, 0x37920000, 0x37928000, 0x37930000, 0x37938000, 0x37940000, 0x37948000, 0x37950000, 0x37958000, 0x37960000, 0x37968000, 0x37970000, 0x37978000,
1136 0x37980000, 0x37988000, 0x37990000, 0x37998000, 0x379A0000, 0x379A8000, 0x379B0000, 0x379B8000, 0x379C0000, 0x379C8000, 0x379D0000, 0x379D8000, 0x379E0000, 0x379E8000, 0x379F0000, 0x379F8000,
1137 0x37A00000, 0x37A08000, 0x37A10000, 0x37A18000, 0x37A20000, 0x37A28000, 0x37A30000, 0x37A38000, 0x37A40000, 0x37A48000, 0x37A50000, 0x37A58000, 0x37A60000, 0x37A68000, 0x37A70000, 0x37A78000,
1138 0x37A80000, 0x37A88000, 0x37A90000, 0x37A98000, 0x37AA0000, 0x37AA8000, 0x37AB0000, 0x37AB8000, 0x37AC0000, 0x37AC8000, 0x37AD0000, 0x37AD8000, 0x37AE0000, 0x37AE8000, 0x37AF0000, 0x37AF8000,
1139 0x37B00000, 0x37B08000, 0x37B10000, 0x37B18000, 0x37B20000, 0x37B28000, 0x37B30000, 0x37B38000, 0x37B40000, 0x37B48000, 0x37B50000, 0x37B58000, 0x37B60000, 0x37B68000, 0x37B70000, 0x37B78000,
1140 0x37B80000, 0x37B88000, 0x37B90000, 0x37B98000, 0x37BA0000, 0x37BA8000, 0x37BB0000, 0x37BB8000, 0x37BC0000, 0x37BC8000, 0x37BD0000, 0x37BD8000, 0x37BE0000, 0x37BE8000, 0x37BF0000, 0x37BF8000,
1141 0x37C00000, 0x37C08000, 0x37C10000, 0x37C18000, 0x37C20000, 0x37C28000, 0x37C30000, 0x37C38000, 0x37C40000, 0x37C48000, 0x37C50000, 0x37C58000, 0x37C60000, 0x37C68000, 0x37C70000, 0x37C78000,
1142 0x37C80000, 0x37C88000, 0x37C90000, 0x37C98000, 0x37CA0000, 0x37CA8000, 0x37CB0000, 0x37CB8000, 0x37CC0000, 0x37CC8000, 0x37CD0000, 0x37CD8000, 0x37CE0000, 0x37CE8000, 0x37CF0000, 0x37CF8000,
1143 0x37D00000, 0x37D08000, 0x37D10000, 0x37D18000, 0x37D20000, 0x37D28000, 0x37D30000, 0x37D38000, 0x37D40000, 0x37D48000, 0x37D50000, 0x37D58000, 0x37D60000, 0x37D68000, 0x37D70000, 0x37D78000,
1144 0x37D80000, 0x37D88000, 0x37D90000, 0x37D98000, 0x37DA0000, 0x37DA8000, 0x37DB0000, 0x37DB8000, 0x37DC0000, 0x37DC8000, 0x37DD0000, 0x37DD8000, 0x37DE0000, 0x37DE8000, 0x37DF0000, 0x37DF8000,
1145 0x37E00000, 0x37E08000, 0x37E10000, 0x37E18000, 0x37E20000, 0x37E28000, 0x37E30000, 0x37E38000, 0x37E40000, 0x37E48000, 0x37E50000, 0x37E58000, 0x37E60000, 0x37E68000, 0x37E70000, 0x37E78000,
1146 0x37E80000, 0x37E88000, 0x37E90000, 0x37E98000, 0x37EA0000, 0x37EA8000, 0x37EB0000, 0x37EB8000, 0x37EC0000, 0x37EC8000, 0x37ED0000, 0x37ED8000, 0x37EE0000, 0x37EE8000, 0x37EF0000, 0x37EF8000,
1147 0x37F00000, 0x37F08000, 0x37F10000, 0x37F18000, 0x37F20000, 0x37F28000, 0x37F30000, 0x37F38000, 0x37F40000, 0x37F48000, 0x37F50000, 0x37F58000, 0x37F60000, 0x37F68000, 0x37F70000, 0x37F78000,
1148 0x37F80000, 0x37F88000, 0x37F90000, 0x37F98000, 0x37FA0000, 0x37FA8000, 0x37FB0000, 0x37FB8000, 0x37FC0000, 0x37FC8000, 0x37FD0000, 0x37FD8000, 0x37FE0000, 0x37FE8000, 0x37FF0000, 0x37FF8000,
1149 0x38000000, 0x38004000, 0x38008000, 0x3800C000, 0x38010000, 0x38014000, 0x38018000, 0x3801C000, 0x38020000, 0x38024000, 0x38028000, 0x3802C000, 0x38030000, 0x38034000, 0x38038000, 0x3803C000,
1150 0x38040000, 0x38044000, 0x38048000, 0x3804C000, 0x38050000, 0x38054000, 0x38058000, 0x3805C000, 0x38060000, 0x38064000, 0x38068000, 0x3806C000, 0x38070000, 0x38074000, 0x38078000, 0x3807C000,
1151 0x38080000, 0x38084000, 0x38088000, 0x3808C000, 0x38090000, 0x38094000, 0x38098000, 0x3809C000, 0x380A0000, 0x380A4000, 0x380A8000, 0x380AC000, 0x380B0000, 0x380B4000, 0x380B8000, 0x380BC000,
1152 0x380C0000, 0x380C4000, 0x380C8000, 0x380CC000, 0x380D0000, 0x380D4000, 0x380D8000, 0x380DC000, 0x380E0000, 0x380E4000, 0x380E8000, 0x380EC000, 0x380F0000, 0x380F4000, 0x380F8000, 0x380FC000,
1153 0x38100000, 0x38104000, 0x38108000, 0x3810C000, 0x38110000, 0x38114000, 0x38118000, 0x3811C000, 0x38120000, 0x38124000, 0x38128000, 0x3812C000, 0x38130000, 0x38134000, 0x38138000, 0x3813C000,
1154 0x38140000, 0x38144000, 0x38148000, 0x3814C000, 0x38150000, 0x38154000, 0x38158000, 0x3815C000, 0x38160000, 0x38164000, 0x38168000, 0x3816C000, 0x38170000, 0x38174000, 0x38178000, 0x3817C000,
1155 0x38180000, 0x38184000, 0x38188000, 0x3818C000, 0x38190000, 0x38194000, 0x38198000, 0x3819C000, 0x381A0000, 0x381A4000, 0x381A8000, 0x381AC000, 0x381B0000, 0x381B4000, 0x381B8000, 0x381BC000,
1156 0x381C0000, 0x381C4000, 0x381C8000, 0x381CC000, 0x381D0000, 0x381D4000, 0x381D8000, 0x381DC000, 0x381E0000, 0x381E4000, 0x381E8000, 0x381EC000, 0x381F0000, 0x381F4000, 0x381F8000, 0x381FC000,
1157 0x38200000, 0x38204000, 0x38208000, 0x3820C000, 0x38210000, 0x38214000, 0x38218000, 0x3821C000, 0x38220000, 0x38224000, 0x38228000, 0x3822C000, 0x38230000, 0x38234000, 0x38238000, 0x3823C000,
1158 0x38240000, 0x38244000, 0x38248000, 0x3824C000, 0x38250000, 0x38254000, 0x38258000, 0x3825C000, 0x38260000, 0x38264000, 0x38268000, 0x3826C000, 0x38270000, 0x38274000, 0x38278000, 0x3827C000,
1159 0x38280000, 0x38284000, 0x38288000, 0x3828C000, 0x38290000, 0x38294000, 0x38298000, 0x3829C000, 0x382A0000, 0x382A4000, 0x382A8000, 0x382AC000, 0x382B0000, 0x382B4000, 0x382B8000, 0x382BC000,
1160 0x382C0000, 0x382C4000, 0x382C8000, 0x382CC000, 0x382D0000, 0x382D4000, 0x382D8000, 0x382DC000, 0x382E0000, 0x382E4000, 0x382E8000, 0x382EC000, 0x382F0000, 0x382F4000, 0x382F8000, 0x382FC000,
1161 0x38300000, 0x38304000, 0x38308000, 0x3830C000, 0x38310000, 0x38314000, 0x38318000, 0x3831C000, 0x38320000, 0x38324000, 0x38328000, 0x3832C000, 0x38330000, 0x38334000, 0x38338000, 0x3833C000,
1162 0x38340000, 0x38344000, 0x38348000, 0x3834C000, 0x38350000, 0x38354000, 0x38358000, 0x3835C000, 0x38360000, 0x38364000, 0x38368000, 0x3836C000, 0x38370000, 0x38374000, 0x38378000, 0x3837C000,
1163 0x38380000, 0x38384000, 0x38388000, 0x3838C000, 0x38390000, 0x38394000, 0x38398000, 0x3839C000, 0x383A0000, 0x383A4000, 0x383A8000, 0x383AC000, 0x383B0000, 0x383B4000, 0x383B8000, 0x383BC000,
1164 0x383C0000, 0x383C4000, 0x383C8000, 0x383CC000, 0x383D0000, 0x383D4000, 0x383D8000, 0x383DC000, 0x383E0000, 0x383E4000, 0x383E8000, 0x383EC000, 0x383F0000, 0x383F4000, 0x383F8000, 0x383FC000,
1165 0x38400000, 0x38404000, 0x38408000, 0x3840C000, 0x38410000, 0x38414000, 0x38418000, 0x3841C000, 0x38420000, 0x38424000, 0x38428000, 0x3842C000, 0x38430000, 0x38434000, 0x38438000, 0x3843C000,
1166 0x38440000, 0x38444000, 0x38448000, 0x3844C000, 0x38450000, 0x38454000, 0x38458000, 0x3845C000, 0x38460000, 0x38464000, 0x38468000, 0x3846C000, 0x38470000, 0x38474000, 0x38478000, 0x3847C000,
1167 0x38480000, 0x38484000, 0x38488000, 0x3848C000, 0x38490000, 0x38494000, 0x38498000, 0x3849C000, 0x384A0000, 0x384A4000, 0x384A8000, 0x384AC000, 0x384B0000, 0x384B4000, 0x384B8000, 0x384BC000,
1168 0x384C0000, 0x384C4000, 0x384C8000, 0x384CC000, 0x384D0000, 0x384D4000, 0x384D8000, 0x384DC000, 0x384E0000, 0x384E4000, 0x384E8000, 0x384EC000, 0x384F0000, 0x384F4000, 0x384F8000, 0x384FC000,
1169 0x38500000, 0x38504000, 0x38508000, 0x3850C000, 0x38510000, 0x38514000, 0x38518000, 0x3851C000, 0x38520000, 0x38524000, 0x38528000, 0x3852C000, 0x38530000, 0x38534000, 0x38538000, 0x3853C000,
1170 0x38540000, 0x38544000, 0x38548000, 0x3854C000, 0x38550000, 0x38554000, 0x38558000, 0x3855C000, 0x38560000, 0x38564000, 0x38568000, 0x3856C000, 0x38570000, 0x38574000, 0x38578000, 0x3857C000,
1171 0x38580000, 0x38584000, 0x38588000, 0x3858C000, 0x38590000, 0x38594000, 0x38598000, 0x3859C000, 0x385A0000, 0x385A4000, 0x385A8000, 0x385AC000, 0x385B0000, 0x385B4000, 0x385B8000, 0x385BC000,
1172 0x385C0000, 0x385C4000, 0x385C8000, 0x385CC000, 0x385D0000, 0x385D4000, 0x385D8000, 0x385DC000, 0x385E0000, 0x385E4000, 0x385E8000, 0x385EC000, 0x385F0000, 0x385F4000, 0x385F8000, 0x385FC000,
1173 0x38600000, 0x38604000, 0x38608000, 0x3860C000, 0x38610000, 0x38614000, 0x38618000, 0x3861C000, 0x38620000, 0x38624000, 0x38628000, 0x3862C000, 0x38630000, 0x38634000, 0x38638000, 0x3863C000,
1174 0x38640000, 0x38644000, 0x38648000, 0x3864C000, 0x38650000, 0x38654000, 0x38658000, 0x3865C000, 0x38660000, 0x38664000, 0x38668000, 0x3866C000, 0x38670000, 0x38674000, 0x38678000, 0x3867C000,
1175 0x38680000, 0x38684000, 0x38688000, 0x3868C000, 0x38690000, 0x38694000, 0x38698000, 0x3869C000, 0x386A0000, 0x386A4000, 0x386A8000, 0x386AC000, 0x386B0000, 0x386B4000, 0x386B8000, 0x386BC000,
1176 0x386C0000, 0x386C4000, 0x386C8000, 0x386CC000, 0x386D0000, 0x386D4000, 0x386D8000, 0x386DC000, 0x386E0000, 0x386E4000, 0x386E8000, 0x386EC000, 0x386F0000, 0x386F4000, 0x386F8000, 0x386FC000,
1177 0x38700000, 0x38704000, 0x38708000, 0x3870C000, 0x38710000, 0x38714000, 0x38718000, 0x3871C000, 0x38720000, 0x38724000, 0x38728000, 0x3872C000, 0x38730000, 0x38734000, 0x38738000, 0x3873C000,
1178 0x38740000, 0x38744000, 0x38748000, 0x3874C000, 0x38750000, 0x38754000, 0x38758000, 0x3875C000, 0x38760000, 0x38764000, 0x38768000, 0x3876C000, 0x38770000, 0x38774000, 0x38778000, 0x3877C000,
1179 0x38780000, 0x38784000, 0x38788000, 0x3878C000, 0x38790000, 0x38794000, 0x38798000, 0x3879C000, 0x387A0000, 0x387A4000, 0x387A8000, 0x387AC000, 0x387B0000, 0x387B4000, 0x387B8000, 0x387BC000,
1180 0x387C0000, 0x387C4000, 0x387C8000, 0x387CC000, 0x387D0000, 0x387D4000, 0x387D8000, 0x387DC000, 0x387E0000, 0x387E4000, 0x387E8000, 0x387EC000, 0x387F0000, 0x387F4000, 0x387F8000, 0x387FC000,
1181 0x38000000, 0x38002000, 0x38004000, 0x38006000, 0x38008000, 0x3800A000, 0x3800C000, 0x3800E000, 0x38010000, 0x38012000, 0x38014000, 0x38016000, 0x38018000, 0x3801A000, 0x3801C000, 0x3801E000,
1182 0x38020000, 0x38022000, 0x38024000, 0x38026000, 0x38028000, 0x3802A000, 0x3802C000, 0x3802E000, 0x38030000, 0x38032000, 0x38034000, 0x38036000, 0x38038000, 0x3803A000, 0x3803C000, 0x3803E000,
1183 0x38040000, 0x38042000, 0x38044000, 0x38046000, 0x38048000, 0x3804A000, 0x3804C000, 0x3804E000, 0x38050000, 0x38052000, 0x38054000, 0x38056000, 0x38058000, 0x3805A000, 0x3805C000, 0x3805E000,
1184 0x38060000, 0x38062000, 0x38064000, 0x38066000, 0x38068000, 0x3806A000, 0x3806C000, 0x3806E000, 0x38070000, 0x38072000, 0x38074000, 0x38076000, 0x38078000, 0x3807A000, 0x3807C000, 0x3807E000,
1185 0x38080000, 0x38082000, 0x38084000, 0x38086000, 0x38088000, 0x3808A000, 0x3808C000, 0x3808E000, 0x38090000, 0x38092000, 0x38094000, 0x38096000, 0x38098000, 0x3809A000, 0x3809C000, 0x3809E000,
1186 0x380A0000, 0x380A2000, 0x380A4000, 0x380A6000, 0x380A8000, 0x380AA000, 0x380AC000, 0x380AE000, 0x380B0000, 0x380B2000, 0x380B4000, 0x380B6000, 0x380B8000, 0x380BA000, 0x380BC000, 0x380BE000,
1187 0x380C0000, 0x380C2000, 0x380C4000, 0x380C6000, 0x380C8000, 0x380CA000, 0x380CC000, 0x380CE000, 0x380D0000, 0x380D2000, 0x380D4000, 0x380D6000, 0x380D8000, 0x380DA000, 0x380DC000, 0x380DE000,
1188 0x380E0000, 0x380E2000, 0x380E4000, 0x380E6000, 0x380E8000, 0x380EA000, 0x380EC000, 0x380EE000, 0x380F0000, 0x380F2000, 0x380F4000, 0x380F6000, 0x380F8000, 0x380FA000, 0x380FC000, 0x380FE000,
1189 0x38100000, 0x38102000, 0x38104000, 0x38106000, 0x38108000, 0x3810A000, 0x3810C000, 0x3810E000, 0x38110000, 0x38112000, 0x38114000, 0x38116000, 0x38118000, 0x3811A000, 0x3811C000, 0x3811E000,
1190 0x38120000, 0x38122000, 0x38124000, 0x38126000, 0x38128000, 0x3812A000, 0x3812C000, 0x3812E000, 0x38130000, 0x38132000, 0x38134000, 0x38136000, 0x38138000, 0x3813A000, 0x3813C000, 0x3813E000,
1191 0x38140000, 0x38142000, 0x38144000, 0x38146000, 0x38148000, 0x3814A000, 0x3814C000, 0x3814E000, 0x38150000, 0x38152000, 0x38154000, 0x38156000, 0x38158000, 0x3815A000, 0x3815C000, 0x3815E000,
1192 0x38160000, 0x38162000, 0x38164000, 0x38166000, 0x38168000, 0x3816A000, 0x3816C000, 0x3816E000, 0x38170000, 0x38172000, 0x38174000, 0x38176000, 0x38178000, 0x3817A000, 0x3817C000, 0x3817E000,
1193 0x38180000, 0x38182000, 0x38184000, 0x38186000, 0x38188000, 0x3818A000, 0x3818C000, 0x3818E000, 0x38190000, 0x38192000, 0x38194000, 0x38196000, 0x38198000, 0x3819A000, 0x3819C000, 0x3819E000,
1194 0x381A0000, 0x381A2000, 0x381A4000, 0x381A6000, 0x381A8000, 0x381AA000, 0x381AC000, 0x381AE000, 0x381B0000, 0x381B2000, 0x381B4000, 0x381B6000, 0x381B8000, 0x381BA000, 0x381BC000, 0x381BE000,
1195 0x381C0000, 0x381C2000, 0x381C4000, 0x381C6000, 0x381C8000, 0x381CA000, 0x381CC000, 0x381CE000, 0x381D0000, 0x381D2000, 0x381D4000, 0x381D6000, 0x381D8000, 0x381DA000, 0x381DC000, 0x381DE000,
1196 0x381E0000, 0x381E2000, 0x381E4000, 0x381E6000, 0x381E8000, 0x381EA000, 0x381EC000, 0x381EE000, 0x381F0000, 0x381F2000, 0x381F4000, 0x381F6000, 0x381F8000, 0x381FA000, 0x381FC000, 0x381FE000,
1197 0x38200000, 0x38202000, 0x38204000, 0x38206000, 0x38208000, 0x3820A000, 0x3820C000, 0x3820E000, 0x38210000, 0x38212000, 0x38214000, 0x38216000, 0x38218000, 0x3821A000, 0x3821C000, 0x3821E000,
1198 0x38220000, 0x38222000, 0x38224000, 0x38226000, 0x38228000, 0x3822A000, 0x3822C000, 0x3822E000, 0x38230000, 0x38232000, 0x38234000, 0x38236000, 0x38238000, 0x3823A000, 0x3823C000, 0x3823E000,
1199 0x38240000, 0x38242000, 0x38244000, 0x38246000, 0x38248000, 0x3824A000, 0x3824C000, 0x3824E000, 0x38250000, 0x38252000, 0x38254000, 0x38256000, 0x38258000, 0x3825A000, 0x3825C000, 0x3825E000,
1200 0x38260000, 0x38262000, 0x38264000, 0x38266000, 0x38268000, 0x3826A000, 0x3826C000, 0x3826E000, 0x38270000, 0x38272000, 0x38274000, 0x38276000, 0x38278000, 0x3827A000, 0x3827C000, 0x3827E000,
1201 0x38280000, 0x38282000, 0x38284000, 0x38286000, 0x38288000, 0x3828A000, 0x3828C000, 0x3828E000, 0x38290000, 0x38292000, 0x38294000, 0x38296000, 0x38298000, 0x3829A000, 0x3829C000, 0x3829E000,
1202 0x382A0000, 0x382A2000, 0x382A4000, 0x382A6000, 0x382A8000, 0x382AA000, 0x382AC000, 0x382AE000, 0x382B0000, 0x382B2000, 0x382B4000, 0x382B6000, 0x382B8000, 0x382BA000, 0x382BC000, 0x382BE000,
1203 0x382C0000, 0x382C2000, 0x382C4000, 0x382C6000, 0x382C8000, 0x382CA000, 0x382CC000, 0x382CE000, 0x382D0000, 0x382D2000, 0x382D4000, 0x382D6000, 0x382D8000, 0x382DA000, 0x382DC000, 0x382DE000,
1204 0x382E0000, 0x382E2000, 0x382E4000, 0x382E6000, 0x382E8000, 0x382EA000, 0x382EC000, 0x382EE000, 0x382F0000, 0x382F2000, 0x382F4000, 0x382F6000, 0x382F8000, 0x382FA000, 0x382FC000, 0x382FE000,
1205 0x38300000, 0x38302000, 0x38304000, 0x38306000, 0x38308000, 0x3830A000, 0x3830C000, 0x3830E000, 0x38310000, 0x38312000, 0x38314000, 0x38316000, 0x38318000, 0x3831A000, 0x3831C000, 0x3831E000,
1206 0x38320000, 0x38322000, 0x38324000, 0x38326000, 0x38328000, 0x3832A000, 0x3832C000, 0x3832E000, 0x38330000, 0x38332000, 0x38334000, 0x38336000, 0x38338000, 0x3833A000, 0x3833C000, 0x3833E000,
1207 0x38340000, 0x38342000, 0x38344000, 0x38346000, 0x38348000, 0x3834A000, 0x3834C000, 0x3834E000, 0x38350000, 0x38352000, 0x38354000, 0x38356000, 0x38358000, 0x3835A000, 0x3835C000, 0x3835E000,
1208 0x38360000, 0x38362000, 0x38364000, 0x38366000, 0x38368000, 0x3836A000, 0x3836C000, 0x3836E000, 0x38370000, 0x38372000, 0x38374000, 0x38376000, 0x38378000, 0x3837A000, 0x3837C000, 0x3837E000,
1209 0x38380000, 0x38382000, 0x38384000, 0x38386000, 0x38388000, 0x3838A000, 0x3838C000, 0x3838E000, 0x38390000, 0x38392000, 0x38394000, 0x38396000, 0x38398000, 0x3839A000, 0x3839C000, 0x3839E000,
1210 0x383A0000, 0x383A2000, 0x383A4000, 0x383A6000, 0x383A8000, 0x383AA000, 0x383AC000, 0x383AE000, 0x383B0000, 0x383B2000, 0x383B4000, 0x383B6000, 0x383B8000, 0x383BA000, 0x383BC000, 0x383BE000,
1211 0x383C0000, 0x383C2000, 0x383C4000, 0x383C6000, 0x383C8000, 0x383CA000, 0x383CC000, 0x383CE000, 0x383D0000, 0x383D2000, 0x383D4000, 0x383D6000, 0x383D8000, 0x383DA000, 0x383DC000, 0x383DE000,
1212 0x383E0000, 0x383E2000, 0x383E4000, 0x383E6000, 0x383E8000, 0x383EA000, 0x383EC000, 0x383EE000, 0x383F0000, 0x383F2000, 0x383F4000, 0x383F6000, 0x383F8000, 0x383FA000, 0x383FC000, 0x383FE000,
1213 0x38400000, 0x38402000, 0x38404000, 0x38406000, 0x38408000, 0x3840A000, 0x3840C000, 0x3840E000, 0x38410000, 0x38412000, 0x38414000, 0x38416000, 0x38418000, 0x3841A000, 0x3841C000, 0x3841E000,
1214 0x38420000, 0x38422000, 0x38424000, 0x38426000, 0x38428000, 0x3842A000, 0x3842C000, 0x3842E000, 0x38430000, 0x38432000, 0x38434000, 0x38436000, 0x38438000, 0x3843A000, 0x3843C000, 0x3843E000,
1215 0x38440000, 0x38442000, 0x38444000, 0x38446000, 0x38448000, 0x3844A000, 0x3844C000, 0x3844E000, 0x38450000, 0x38452000, 0x38454000, 0x38456000, 0x38458000, 0x3845A000, 0x3845C000, 0x3845E000,
1216 0x38460000, 0x38462000, 0x38464000, 0x38466000, 0x38468000, 0x3846A000, 0x3846C000, 0x3846E000, 0x38470000, 0x38472000, 0x38474000, 0x38476000, 0x38478000, 0x3847A000, 0x3847C000, 0x3847E000,
1217 0x38480000, 0x38482000, 0x38484000, 0x38486000, 0x38488000, 0x3848A000, 0x3848C000, 0x3848E000, 0x38490000, 0x38492000, 0x38494000, 0x38496000, 0x38498000, 0x3849A000, 0x3849C000, 0x3849E000,
1218 0x384A0000, 0x384A2000, 0x384A4000, 0x384A6000, 0x384A8000, 0x384AA000, 0x384AC000, 0x384AE000, 0x384B0000, 0x384B2000, 0x384B4000, 0x384B6000, 0x384B8000, 0x384BA000, 0x384BC000, 0x384BE000,
1219 0x384C0000, 0x384C2000, 0x384C4000, 0x384C6000, 0x384C8000, 0x384CA000, 0x384CC000, 0x384CE000, 0x384D0000, 0x384D2000, 0x384D4000, 0x384D6000, 0x384D8000, 0x384DA000, 0x384DC000, 0x384DE000,
1220 0x384E0000, 0x384E2000, 0x384E4000, 0x384E6000, 0x384E8000, 0x384EA000, 0x384EC000, 0x384EE000, 0x384F0000, 0x384F2000, 0x384F4000, 0x384F6000, 0x384F8000, 0x384FA000, 0x384FC000, 0x384FE000,
1221 0x38500000, 0x38502000, 0x38504000, 0x38506000, 0x38508000, 0x3850A000, 0x3850C000, 0x3850E000, 0x38510000, 0x38512000, 0x38514000, 0x38516000, 0x38518000, 0x3851A000, 0x3851C000, 0x3851E000,
1222 0x38520000, 0x38522000, 0x38524000, 0x38526000, 0x38528000, 0x3852A000, 0x3852C000, 0x3852E000, 0x38530000, 0x38532000, 0x38534000, 0x38536000, 0x38538000, 0x3853A000, 0x3853C000, 0x3853E000,
1223 0x38540000, 0x38542000, 0x38544000, 0x38546000, 0x38548000, 0x3854A000, 0x3854C000, 0x3854E000, 0x38550000, 0x38552000, 0x38554000, 0x38556000, 0x38558000, 0x3855A000, 0x3855C000, 0x3855E000,
1224 0x38560000, 0x38562000, 0x38564000, 0x38566000, 0x38568000, 0x3856A000, 0x3856C000, 0x3856E000, 0x38570000, 0x38572000, 0x38574000, 0x38576000, 0x38578000, 0x3857A000, 0x3857C000, 0x3857E000,
1225 0x38580000, 0x38582000, 0x38584000, 0x38586000, 0x38588000, 0x3858A000, 0x3858C000, 0x3858E000, 0x38590000, 0x38592000, 0x38594000, 0x38596000, 0x38598000, 0x3859A000, 0x3859C000, 0x3859E000,
1226 0x385A0000, 0x385A2000, 0x385A4000, 0x385A6000, 0x385A8000, 0x385AA000, 0x385AC000, 0x385AE000, 0x385B0000, 0x385B2000, 0x385B4000, 0x385B6000, 0x385B8000, 0x385BA000, 0x385BC000, 0x385BE000,
1227 0x385C0000, 0x385C2000, 0x385C4000, 0x385C6000, 0x385C8000, 0x385CA000, 0x385CC000, 0x385CE000, 0x385D0000, 0x385D2000, 0x385D4000, 0x385D6000, 0x385D8000, 0x385DA000, 0x385DC000, 0x385DE000,
1228 0x385E0000, 0x385E2000, 0x385E4000, 0x385E6000, 0x385E8000, 0x385EA000, 0x385EC000, 0x385EE000, 0x385F0000, 0x385F2000, 0x385F4000, 0x385F6000, 0x385F8000, 0x385FA000, 0x385FC000, 0x385FE000,
1229 0x38600000, 0x38602000, 0x38604000, 0x38606000, 0x38608000, 0x3860A000, 0x3860C000, 0x3860E000, 0x38610000, 0x38612000, 0x38614000, 0x38616000, 0x38618000, 0x3861A000, 0x3861C000, 0x3861E000,
1230 0x38620000, 0x38622000, 0x38624000, 0x38626000, 0x38628000, 0x3862A000, 0x3862C000, 0x3862E000, 0x38630000, 0x38632000, 0x38634000, 0x38636000, 0x38638000, 0x3863A000, 0x3863C000, 0x3863E000,
1231 0x38640000, 0x38642000, 0x38644000, 0x38646000, 0x38648000, 0x3864A000, 0x3864C000, 0x3864E000, 0x38650000, 0x38652000, 0x38654000, 0x38656000, 0x38658000, 0x3865A000, 0x3865C000, 0x3865E000,
1232 0x38660000, 0x38662000, 0x38664000, 0x38666000, 0x38668000, 0x3866A000, 0x3866C000, 0x3866E000, 0x38670000, 0x38672000, 0x38674000, 0x38676000, 0x38678000, 0x3867A000, 0x3867C000, 0x3867E000,
1233 0x38680000, 0x38682000, 0x38684000, 0x38686000, 0x38688000, 0x3868A000, 0x3868C000, 0x3868E000, 0x38690000, 0x38692000, 0x38694000, 0x38696000, 0x38698000, 0x3869A000, 0x3869C000, 0x3869E000,
1234 0x386A0000, 0x386A2000, 0x386A4000, 0x386A6000, 0x386A8000, 0x386AA000, 0x386AC000, 0x386AE000, 0x386B0000, 0x386B2000, 0x386B4000, 0x386B6000, 0x386B8000, 0x386BA000, 0x386BC000, 0x386BE000,
1235 0x386C0000, 0x386C2000, 0x386C4000, 0x386C6000, 0x386C8000, 0x386CA000, 0x386CC000, 0x386CE000, 0x386D0000, 0x386D2000, 0x386D4000, 0x386D6000, 0x386D8000, 0x386DA000, 0x386DC000, 0x386DE000,
1236 0x386E0000, 0x386E2000, 0x386E4000, 0x386E6000, 0x386E8000, 0x386EA000, 0x386EC000, 0x386EE000, 0x386F0000, 0x386F2000, 0x386F4000, 0x386F6000, 0x386F8000, 0x386FA000, 0x386FC000, 0x386FE000,
1237 0x38700000, 0x38702000, 0x38704000, 0x38706000, 0x38708000, 0x3870A000, 0x3870C000, 0x3870E000, 0x38710000, 0x38712000, 0x38714000, 0x38716000, 0x38718000, 0x3871A000, 0x3871C000, 0x3871E000,
1238 0x38720000, 0x38722000, 0x38724000, 0x38726000, 0x38728000, 0x3872A000, 0x3872C000, 0x3872E000, 0x38730000, 0x38732000, 0x38734000, 0x38736000, 0x38738000, 0x3873A000, 0x3873C000, 0x3873E000,
1239 0x38740000, 0x38742000, 0x38744000, 0x38746000, 0x38748000, 0x3874A000, 0x3874C000, 0x3874E000, 0x38750000, 0x38752000, 0x38754000, 0x38756000, 0x38758000, 0x3875A000, 0x3875C000, 0x3875E000,
1240 0x38760000, 0x38762000, 0x38764000, 0x38766000, 0x38768000, 0x3876A000, 0x3876C000, 0x3876E000, 0x38770000, 0x38772000, 0x38774000, 0x38776000, 0x38778000, 0x3877A000, 0x3877C000, 0x3877E000,
1241 0x38780000, 0x38782000, 0x38784000, 0x38786000, 0x38788000, 0x3878A000, 0x3878C000, 0x3878E000, 0x38790000, 0x38792000, 0x38794000, 0x38796000, 0x38798000, 0x3879A000, 0x3879C000, 0x3879E000,
1242 0x387A0000, 0x387A2000, 0x387A4000, 0x387A6000, 0x387A8000, 0x387AA000, 0x387AC000, 0x387AE000, 0x387B0000, 0x387B2000, 0x387B4000, 0x387B6000, 0x387B8000, 0x387BA000, 0x387BC000, 0x387BE000,
1243 0x387C0000, 0x387C2000, 0x387C4000, 0x387C6000, 0x387C8000, 0x387CA000, 0x387CC000, 0x387CE000, 0x387D0000, 0x387D2000, 0x387D4000, 0x387D6000, 0x387D8000, 0x387DA000, 0x387DC000, 0x387DE000,
1244 0x387E0000, 0x387E2000, 0x387E4000, 0x387E6000, 0x387E8000, 0x387EA000, 0x387EC000, 0x387EE000, 0x387F0000, 0x387F2000, 0x387F4000, 0x387F6000, 0x387F8000, 0x387FA000, 0x387FC000, 0x387FE000 };
1245 static const bits<float>::type exponent_table[64] = {
1246 0x00000000, 0x00800000, 0x01000000, 0x01800000, 0x02000000, 0x02800000, 0x03000000, 0x03800000, 0x04000000, 0x04800000, 0x05000000, 0x05800000, 0x06000000, 0x06800000, 0x07000000, 0x07800000,
1247 0x08000000, 0x08800000, 0x09000000, 0x09800000, 0x0A000000, 0x0A800000, 0x0B000000, 0x0B800000, 0x0C000000, 0x0C800000, 0x0D000000, 0x0D800000, 0x0E000000, 0x0E800000, 0x0F000000, 0x47800000,
1248 0x80000000, 0x80800000, 0x81000000, 0x81800000, 0x82000000, 0x82800000, 0x83000000, 0x83800000, 0x84000000, 0x84800000, 0x85000000, 0x85800000, 0x86000000, 0x86800000, 0x87000000, 0x87800000,
1249 0x88000000, 0x88800000, 0x89000000, 0x89800000, 0x8A000000, 0x8A800000, 0x8B000000, 0x8B800000, 0x8C000000, 0x8C800000, 0x8D000000, 0x8D800000, 0x8E000000, 0x8E800000, 0x8F000000, 0xC7800000 };
1250 static const unsigned short offset_table[64] = {
1251 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,
1252 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 };
1253 bits<float>::type fbits = mantissa_table[offset_table[value>>10]+(value&0x3FF)] + exponent_table[value>>10];
1254 #endif
1255 float out;
1256 std::memcpy(&out, &fbits, sizeof(float));
1257 return out;
1258 #endif
1259 }
1260
1264 inline double half2float_impl(unsigned int value, double, true_type)
1265 {
1266 #if HALF_ENABLE_F16C_INTRINSICS
1267 return _mm_cvtsd_f64(_mm_cvtps_pd(_mm_cvtph_ps(_mm_cvtsi32_si128(value))));
1268 #else
1269 uint32 hi = static_cast<uint32>(value&0x8000) << 16;
1270 unsigned int abs = value & 0x7FFF;
1271 if(abs)
1272 {
1273 hi |= 0x3F000000 << static_cast<unsigned>(abs>=0x7C00);
1274 for(; abs<0x400; abs<<=1,hi-=0x100000) ;
1275 hi += static_cast<uint32>(abs) << 10;
1276 }
1277 bits<double>::type dbits = static_cast<bits<double>::type>(hi) << 32;
1278 double out;
1279 std::memcpy(&out, &dbits, sizeof(double));
1280 return out;
1281 #endif
1282 }
1283
1288 template<typename T> T half2float_impl(unsigned int value, T, ...)
1289 {
1290 T out;
1291 unsigned int abs = value & 0x7FFF;
1292 if(abs > 0x7C00)
1293 out = (std::numeric_limits<T>::has_signaling_NaN && !(abs&0x200)) ? std::numeric_limits<T>::signaling_NaN() :
1294 std::numeric_limits<T>::has_quiet_NaN ? std::numeric_limits<T>::quiet_NaN() : T();
1295 else if(abs == 0x7C00)
1296 out = std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : std::numeric_limits<T>::max();
1297 else if(abs > 0x3FF)
1298 out = std::ldexp(static_cast<T>((abs&0x3FF)|0x400), (abs>>10)-25);
1299 else
1300 out = std::ldexp(static_cast<T>(abs), -24);
1301 return (value&0x8000) ? -out : out;
1302 }
1303
1308 template<typename T> T half2float(unsigned int value)
1309 {
1310 return half2float_impl(value, T(), bool_type<std::numeric_limits<T>::is_iec559&&sizeof(typename bits<T>::type)==sizeof(T)>());
1311 }
1312
1322 template<std::float_round_style R,bool E,bool I,typename T> T half2int(unsigned int value)
1323 {
1324 unsigned int abs = value & 0x7FFF;
1325 if(abs >= 0x7C00)
1326 {
1327 raise(FE_INVALID);
1328 return (value&0x8000) ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max();
1329 }
1330 if(abs < 0x3800)
1331 {
1332 raise(FE_INEXACT, I);
1333 return (R==std::round_toward_infinity) ? T(~(value>>15)&(abs!=0)) :
1334 (R==std::round_toward_neg_infinity) ? -T(value>0x8000) :
1335 T();
1336 }
1337 int exp = 25 - (abs>>10);
1338 unsigned int m = (value&0x3FF) | 0x400;
1339 int32 i = static_cast<int32>((exp<=0) ? (m<<-exp) : ((m+(
1340 (R==std::round_to_nearest) ? ((1<<(exp-1))-(~(m>>exp)&E)) :
1341 (R==std::round_toward_infinity) ? (((1<<exp)-1)&((value>>15)-1)) :
1342 (R==std::round_toward_neg_infinity) ? (((1<<exp)-1)&-(value>>15)) : 0))>>exp));
1343 if((!std::numeric_limits<T>::is_signed && (value&0x8000)) || (std::numeric_limits<T>::digits<16 &&
1344 ((value&0x8000) ? (-i<std::numeric_limits<T>::min()) : (i>std::numeric_limits<T>::max()))))
1345 raise(FE_INVALID);
1346 else if(I && exp > 0 && (m&((1<<exp)-1)))
1347 raise(FE_INEXACT);
1348 return static_cast<T>((value&0x8000) ? -i : i);
1349 }
1350
1354
1360 template<std::float_round_style R> uint32 mulhi(uint32 x, uint32 y)
1361 {
1362 uint32 xy = (x>>16) * (y&0xFFFF), yx = (x&0xFFFF) * (y>>16), c = (xy&0xFFFF) + (yx&0xFFFF) + (((x&0xFFFF)*(y&0xFFFF))>>16);
1363 return (x>>16)*(y>>16) + (xy>>16) + (yx>>16) + (c>>16) +
1364 ((R==std::round_to_nearest) ? ((c>>15)&1) : (R==std::round_toward_infinity) ? ((c&0xFFFF)!=0) : 0);
1365 }
1366
1372 {
1373 #if HALF_ENABLE_CPP11_LONG_LONG
1374 return static_cast<uint32>((static_cast<unsigned long long>(x)*static_cast<unsigned long long>(y)+0x80000000)>>32);
1375 #else
1376 return mulhi<std::round_to_nearest>(x, y);
1377 #endif
1378 }
1379
1385 inline uint32 divide64(uint32 x, uint32 y, int &s)
1386 {
1387 #if HALF_ENABLE_CPP11_LONG_LONG
1388 unsigned long long xx = static_cast<unsigned long long>(x) << 32;
1389 return s = (xx%y!=0), static_cast<uint32>(xx/y);
1390 #else
1391 y >>= 1;
1392 uint32 rem = x, div = 0;
1393 for(unsigned int i=0; i<32; ++i)
1394 {
1395 div <<= 1;
1396 if(rem >= y)
1397 {
1398 rem -= y;
1399 div |= 1;
1400 }
1401 rem <<= 1;
1402 }
1403 return s = rem > 1, div;
1404 #endif
1405 }
1406
1414 template<bool Q,bool R> unsigned int mod(unsigned int x, unsigned int y, int *quo = NULL)
1415 {
1416 unsigned int q = 0;
1417 if(x > y)
1418 {
1419 int absx = x, absy = y, expx = 0, expy = 0;
1420 for(; absx<0x400; absx<<=1,--expx) ;
1421 for(; absy<0x400; absy<<=1,--expy) ;
1422 expx += absx >> 10;
1423 expy += absy >> 10;
1424 int mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400;
1425 for(int d=expx-expy; d; --d)
1426 {
1427 if(!Q && mx == my)
1428 return 0;
1429 if(mx >= my)
1430 {
1431 mx -= my;
1432 q += Q;
1433 }
1434 mx <<= 1;
1435 q <<= static_cast<int>(Q);
1436 }
1437 if(!Q && mx == my)
1438 return 0;
1439 if(mx >= my)
1440 {
1441 mx -= my;
1442 ++q;
1443 }
1444 if(Q)
1445 {
1446 q &= (1<<(std::numeric_limits<int>::digits-1)) - 1;
1447 if(!mx)
1448 return *quo = q, 0;
1449 }
1450 for(; mx<0x400; mx<<=1,--expy) ;
1451 x = (expy>0) ? ((expy<<10)|(mx&0x3FF)) : (mx>>(1-expy));
1452 }
1453 if(R)
1454 {
1455 unsigned int a, b;
1456 if(y < 0x800)
1457 {
1458 a = (x<0x400) ? (x<<1) : (x+0x400);
1459 b = y;
1460 }
1461 else
1462 {
1463 a = x;
1464 b = y - 0x400;
1465 }
1466 if(a > b || (a == b && (q&1)))
1467 {
1468 int exp = (y>>10) + (y<=0x3FF), d = exp - (x>>10) - (x<=0x3FF);
1469 int m = (((y&0x3FF)|((y>0x3FF)<<10))<<1) - (((x&0x3FF)|((x>0x3FF)<<10))<<(1-d));
1470 for(; m<0x800 && exp>1; m<<=1,--exp) ;
1471 x = 0x8000 + ((exp-1)<<10) + (m>>1);
1472 q += Q;
1473 }
1474 }
1475 if(Q)
1476 *quo = q;
1477 return x;
1478 }
1479
1485 template<unsigned int F> uint32 sqrt(uint32 &r, int &exp)
1486 {
1487 int i = exp & 1;
1488 r <<= i;
1489 exp = (exp-i) / 2;
1490 uint32 m = 0;
1491 for(uint32 bit=static_cast<uint32>(1)<<F; bit; bit>>=2)
1492 {
1493 if(r < m+bit)
1494 m >>= 1;
1495 else
1496 {
1497 r -= m + bit;
1498 m = (m>>1) + bit;
1499 }
1500 }
1501 return m;
1502 }
1503
1509 inline uint32 exp2(uint32 m, unsigned int n = 32)
1510 {
1511 static const uint32 logs[] = {
1512 0x80000000, 0x4AE00D1D, 0x2934F098, 0x15C01A3A, 0x0B31FB7D, 0x05AEB4DD, 0x02DCF2D1, 0x016FE50B,
1513 0x00B84E23, 0x005C3E10, 0x002E24CA, 0x001713D6, 0x000B8A47, 0x0005C53B, 0x0002E2A3, 0x00017153,
1514 0x0000B8AA, 0x00005C55, 0x00002E2B, 0x00001715, 0x00000B8B, 0x000005C5, 0x000002E3, 0x00000171,
1515 0x000000B9, 0x0000005C, 0x0000002E, 0x00000017, 0x0000000C, 0x00000006, 0x00000003, 0x00000001 };
1516 if(!m)
1517 return 0x80000000;
1518 uint32 mx = 0x80000000, my = 0;
1519 for(unsigned int i=1; i<n; ++i)
1520 {
1521 uint32 mz = my + logs[i];
1522 if(mz <= m)
1523 {
1524 my = mz;
1525 mx += mx >> i;
1526 }
1527 }
1528 return mx;
1529 }
1530
1536 inline uint32 log2(uint32 m, unsigned int n = 32)
1537 {
1538 static const uint32 logs[] = {
1539 0x80000000, 0x4AE00D1D, 0x2934F098, 0x15C01A3A, 0x0B31FB7D, 0x05AEB4DD, 0x02DCF2D1, 0x016FE50B,
1540 0x00B84E23, 0x005C3E10, 0x002E24CA, 0x001713D6, 0x000B8A47, 0x0005C53B, 0x0002E2A3, 0x00017153,
1541 0x0000B8AA, 0x00005C55, 0x00002E2B, 0x00001715, 0x00000B8B, 0x000005C5, 0x000002E3, 0x00000171,
1542 0x000000B9, 0x0000005C, 0x0000002E, 0x00000017, 0x0000000C, 0x00000006, 0x00000003, 0x00000001 };
1543 if(m == 0x40000000)
1544 return 0;
1545 uint32 mx = 0x40000000, my = 0;
1546 for(unsigned int i=1; i<n; ++i)
1547 {
1548 uint32 mz = mx + (mx>>i);
1549 if(mz <= m)
1550 {
1551 mx = mz;
1552 my += logs[i];
1553 }
1554 }
1555 return my;
1556 }
1557
1563 inline std::pair<uint32,uint32> sincos(uint32 mz, unsigned int n = 31)
1564 {
1565 static const uint32 angles[] = {
1566 0x3243F6A9, 0x1DAC6705, 0x0FADBAFD, 0x07F56EA7, 0x03FEAB77, 0x01FFD55C, 0x00FFFAAB, 0x007FFF55,
1567 0x003FFFEB, 0x001FFFFD, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, 0x00008000,
1568 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080,
1569 0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 };
1570 uint32 mx = 0x26DD3B6A, my = 0;
1571 for(unsigned int i=0; i<n; ++i)
1572 {
1573 uint32 sign = sign_mask(mz);
1574 uint32 tx = mx - (arithmetic_shift(my, i)^sign) + sign;
1575 uint32 ty = my + (arithmetic_shift(mx, i)^sign) - sign;
1576 mx = tx; my = ty; mz -= (angles[i]^sign) - sign;
1577 }
1578 return std::make_pair(my, mx);
1579 }
1580
1587 inline uint32 atan2(uint32 my, uint32 mx, unsigned int n = 31)
1588 {
1589 static const uint32 angles[] = {
1590 0x3243F6A9, 0x1DAC6705, 0x0FADBAFD, 0x07F56EA7, 0x03FEAB77, 0x01FFD55C, 0x00FFFAAB, 0x007FFF55,
1591 0x003FFFEB, 0x001FFFFD, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, 0x00008000,
1592 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080,
1593 0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 };
1594 uint32 mz = 0;
1595 for(unsigned int i=0; i<n; ++i)
1596 {
1597 uint32 sign = sign_mask(my);
1598 uint32 tx = mx + (arithmetic_shift(my, i)^sign) - sign;
1599 uint32 ty = my - (arithmetic_shift(mx, i)^sign) + sign;
1600 mx = tx; my = ty; mz += (angles[i]^sign) - sign;
1601 }
1602 return mz;
1603 }
1604
1609 inline uint32 angle_arg(unsigned int abs, int &k)
1610 {
1611 uint32 m = (abs&0x3FF) | ((abs>0x3FF)<<10);
1612 int exp = (abs>>10) + (abs<=0x3FF) - 15;
1613 if(abs < 0x3A48)
1614 return k = 0, m << (exp+20);
1615 #if HALF_ENABLE_CPP11_LONG_LONG
1616 unsigned long long y = m * 0xA2F9836E4E442, mask = (1ULL<<(62-exp)) - 1, yi = (y+(mask>>1)) & ~mask, f = y - yi;
1617 uint32 sign = -static_cast<uint32>(f>>63);
1618 k = static_cast<int>(yi>>(62-exp));
1619 return (multiply64(static_cast<uint32>((sign ? -f : f)>>(31-exp)), 0xC90FDAA2)^sign) - sign;
1620 #else
1621 uint32 yh = m*0xA2F98 + mulhi<std::round_toward_zero>(m, 0x36E4E442), yl = (m*0x36E4E442) & 0xFFFFFFFF;
1622 uint32 mask = (static_cast<uint32>(1)<<(30-exp)) - 1, yi = (yh+(mask>>1)) & ~mask, sign = -static_cast<uint32>(yi>yh);
1623 k = static_cast<int>(yi>>(30-exp));
1624 uint32 fh = (yh^sign) + (yi^~sign) - ~sign, fl = (yl^sign) - sign;
1625 return (multiply64((exp>-1) ? (((fh<<(1+exp))&0xFFFFFFFF)|((fl&0xFFFFFFFF)>>(31-exp))) : fh, 0xC90FDAA2)^sign) - sign;
1626 #endif
1627 }
1628
1632 inline std::pair<uint32,uint32> atan2_args(unsigned int abs)
1633 {
1634 int exp = -15;
1635 for(; abs<0x400; abs<<=1,--exp) ;
1636 exp += abs >> 10;
1637 uint32 my = ((abs&0x3FF)|0x400) << 5, r = my * my;
1638 int rexp = 2 * exp;
1639 r = 0x40000000 - ((rexp>-31) ? ((r>>-rexp)|((r&((static_cast<uint32>(1)<<-rexp)-1))!=0)) : 1);
1640 for(rexp=0; r<0x40000000; r<<=1,--rexp) ;
1641 uint32 mx = sqrt<30>(r, rexp);
1642 int d = exp - rexp;
1643 if(d < 0)
1644 return std::make_pair((d<-14) ? ((my>>(-d-14))+((my>>(-d-15))&1)) : (my<<(14+d)), (mx<<14)+(r<<13)/mx);
1645 if(d > 0)
1646 return std::make_pair(my<<14, (d>14) ? ((mx>>(d-14))+((mx>>(d-15))&1)) : ((d==14) ? mx : ((mx<<(14-d))+(r<<(13-d))/mx)));
1647 return std::make_pair(my<<13, (mx<<13)+(r<<12)/mx);
1648 }
1649
1655 inline std::pair<uint32,uint32> hyperbolic_args(unsigned int abs, int &exp, unsigned int n = 32)
1656 {
1657 uint32 mx = detail::multiply64(static_cast<uint32>((abs&0x3FF)+((abs>0x3FF)<<10))<<21, 0xB8AA3B29), my;
1658 int e = (abs>>10) + (abs<=0x3FF);
1659 if(e < 14)
1660 {
1661 exp = 0;
1662 mx >>= 14 - e;
1663 }
1664 else
1665 {
1666 exp = mx >> (45-e);
1667 mx = (mx<<(e-14)) & 0x7FFFFFFF;
1668 }
1669 mx = exp2(mx, n);
1670 int d = exp << 1, s;
1671 if(mx > 0x80000000)
1672 {
1673 my = divide64(0x80000000, mx, s);
1674 my |= s;
1675 ++d;
1676 }
1677 else
1678 my = mx;
1679 return std::make_pair(mx, (d<31) ? ((my>>d)|((my&((static_cast<uint32>(1)<<d)-1))!=0)) : 1);
1680 }
1681
1693 template<std::float_round_style R> unsigned int exp2_post(uint32 m, int exp, bool esign, unsigned int sign = 0, unsigned int n = 32)
1694 {
1695 if(esign)
1696 {
1697 exp = -exp - (m!=0);
1698 if(exp < -25)
1699 return underflow<R>(sign);
1700 else if(exp == -25)
1701 return rounded<R,false>(sign, 1, m!=0);
1702 }
1703 else if(exp > 15)
1704 return overflow<R>(sign);
1705 if(!m)
1706 return sign | (((exp+=15)>0) ? (exp<<10) : check_underflow(0x200>>-exp));
1707 m = exp2(m, n);
1708 int s = 0;
1709 if(esign)
1710 m = divide64(0x80000000, m, s);
1711 return fixed2half<R,31,false,false,true>(m, exp+14, sign, s);
1712 }
1713
1725 template<std::float_round_style R,uint32 L> unsigned int log2_post(uint32 m, int ilog, int exp, unsigned int sign = 0)
1726 {
1727 uint32 msign = sign_mask(ilog);
1728 m = (((static_cast<uint32>(ilog)<<27)+(m>>4))^msign) - msign;
1729 if(!m)
1730 return 0;
1731 for(; m<0x80000000; m<<=1,--exp) ;
1732 int i = m >= L, s;
1733 exp += i;
1734 m >>= 1 + i;
1735 sign ^= msign & 0x8000;
1736 if(exp < -11)
1737 return underflow<R>(sign);
1738 m = divide64(m, L, s);
1739 return fixed2half<R,30,false,false,true>(m, exp, sign, 1);
1740 }
1741
1750 template<std::float_round_style R> unsigned int hypot_post(uint32 r, int exp)
1751 {
1752 int i = r >> 31;
1753 if((exp+=i) > 46)
1754 return overflow<R>();
1755 if(exp < -34)
1756 return underflow<R>();
1757 r = (r>>i) | (r&i);
1758 uint32 m = sqrt<30>(r, exp+=15);
1759 return fixed2half<R,15,false,false,false>(m, exp-1, 0, r!=0);
1760 }
1761
1772 template<std::float_round_style R> unsigned int tangent_post(uint32 my, uint32 mx, int exp, unsigned int sign = 0)
1773 {
1774 int i = my >= mx, s;
1775 exp += i;
1776 if(exp > 29)
1777 return overflow<R>(sign);
1778 if(exp < -11)
1779 return underflow<R>(sign);
1780 uint32 m = divide64(my>>(i+1), mx, s);
1781 return fixed2half<R,30,false,false,true>(m, exp, sign, s);
1782 }
1783
1793 template<std::float_round_style R,bool S> unsigned int area(unsigned int arg)
1794 {
1795 int abs = arg & 0x7FFF, expx = (abs>>10) + (abs<=0x3FF) - 15, expy = -15, ilog, i;
1796 uint32 mx = static_cast<uint32>((abs&0x3FF)|((abs>0x3FF)<<10)) << 20, my, r;
1797 for(; abs<0x400; abs<<=1,--expy) ;
1798 expy += abs >> 10;
1799 r = ((abs&0x3FF)|0x400) << 5;
1800 r *= r;
1801 i = r >> 31;
1802 expy = 2*expy + i;
1803 r >>= i;
1804 if(S)
1805 {
1806 if(expy < 0)
1807 {
1808 r = 0x40000000 + ((expy>-30) ? ((r>>-expy)|((r&((static_cast<uint32>(1)<<-expy)-1))!=0)) : 1);
1809 expy = 0;
1810 }
1811 else
1812 {
1813 r += 0x40000000 >> expy;
1814 i = r >> 31;
1815 r = (r>>i) | (r&i);
1816 expy += i;
1817 }
1818 }
1819 else
1820 {
1821 r -= 0x40000000 >> expy;
1822 for(; r<0x40000000; r<<=1,--expy) ;
1823 }
1824 my = sqrt<30>(r, expy);
1825 my = (my<<15) + (r<<14)/my;
1826 if(S)
1827 {
1828 mx >>= expy - expx;
1829 ilog = expy;
1830 }
1831 else
1832 {
1833 my >>= expx - expy;
1834 ilog = expx;
1835 }
1836 my += mx;
1837 i = my >> 31;
1838 static const int G = S && (R==std::round_to_nearest);
1839 return log2_post<R,0xB8AA3B2A>(log2(my>>i, 26+S+G)+(G<<3), ilog+i, 17, arg&(static_cast<unsigned>(S)<<15));
1840 }
1841
1843 struct f31
1844 {
1848 HALF_CONSTEXPR f31(uint32 mant, int e) : m(mant), exp(e) {}
1849
1852 f31(unsigned int abs) : exp(-15)
1853 {
1854 for(; abs<0x400; abs<<=1,--exp) ;
1855 m = static_cast<uint32>((abs&0x3FF)|0x400) << 21;
1856 exp += (abs>>10);
1857 }
1858
1864 {
1865 if(b.exp > a.exp)
1866 std::swap(a, b);
1867 int d = a.exp - b.exp;
1868 uint32 m = a.m + ((d<32) ? (b.m>>d) : 0);
1869 int i = (m&0xFFFFFFFF) < a.m;
1870 return f31(((m+i)>>i)|0x80000000, a.exp+i);
1871 }
1872
1878 {
1879 int d = a.exp - b.exp, exp = a.exp;
1880 uint32 m = a.m - ((d<32) ? (b.m>>d) : 0);
1881 if(!m)
1882 return f31(0, -32);
1883 for(; m<0x80000000; m<<=1,--exp) ;
1884 return f31(m, exp);
1885 }
1886
1892 {
1893 uint32 m = multiply64(a.m, b.m);
1894 int i = m >> 31;
1895 return f31(m<<(1-i), a.exp + b.exp + i);
1896 }
1897
1903 {
1904 int i = a.m >= b.m, s;
1905 uint32 m = divide64((a.m+i)>>i, b.m, s);
1906 return f31(m, a.exp - b.exp + i - 1);
1907 }
1908
1910 int exp;
1911 };
1912
1923 template<std::float_round_style R,bool C> unsigned int erf(unsigned int arg)
1924 {
1925 unsigned int abs = arg & 0x7FFF, sign = arg & 0x8000;
1926 f31 x(abs), x2 = x * x * f31(0xB8AA3B29, 0), t = f31(0x80000000, 0) / (f31(0x80000000, 0)+f31(0xA7BA054A, -2)*x), t2 = t * t;
1927 f31 e = ((f31(0x87DC2213, 0)*t2+f31(0xB5F0E2AE, 0))*t2+f31(0x82790637, -2)-(f31(0xBA00E2B8, 0)*t2+f31(0x91A98E62, -2))*t) * t /
1928 ((x2.exp<0) ? f31(exp2((x2.exp>-32) ? (x2.m>>-x2.exp) : 0, 30), 0) : f31(exp2((x2.m<<x2.exp)&0x7FFFFFFF, 22), x2.m>>(31-x2.exp)));
1929 return (!C || sign) ? fixed2half<R,31,false,true,true>(0x80000000-(e.m>>(C-e.exp)), 14+C, sign&(C-1U)) :
1930 (e.exp<-25) ? underflow<R>() : fixed2half<R,30,false,false,true>(e.m>>1, e.exp+14, 0, e.m&1);
1931 }
1932
1942 template<std::float_round_style R,bool L> unsigned int gamma(unsigned int arg)
1943 {
1944/* static const double p[] ={ 2.50662827563479526904, 225.525584619175212544, -268.295973841304927459, 80.9030806934622512966, -5.00757863970517583837, 0.0114684895434781459556 };
1945 double t = arg + 4.65, s = p[0];
1946 for(unsigned int i=0; i<5; ++i)
1947 s += p[i+1] / (arg+i);
1948 return std::log(s) + (arg-0.5)*std::log(t) - t;
1949*/ static const f31 pi(0xC90FDAA2, 1), lbe(0xB8AA3B29, 0);
1950 unsigned int abs = arg & 0x7FFF, sign = arg & 0x8000;
1951 bool bsign = sign != 0;
1952 f31 z(abs), x = sign ? (z+f31(0x80000000, 0)) : z, t = x + f31(0x94CCCCCD, 2), s =
1953 f31(0xA06C9901, 1) + f31(0xBBE654E2, -7)/(x+f31(0x80000000, 2)) + f31(0xA1CE6098, 6)/(x+f31(0x80000000, 1))
1954 + f31(0xE1868CB7, 7)/x - f31(0x8625E279, 8)/(x+f31(0x80000000, 0)) - f31(0xA03E158F, 2)/(x+f31(0xC0000000, 1));
1955 int i = (s.exp>=2) + (s.exp>=4) + (s.exp>=8) + (s.exp>=16);
1956 s = f31((static_cast<uint32>(s.exp)<<(31-i))+(log2(s.m>>1, 28)>>i), i) / lbe;
1957 if(x.exp != -1 || x.m != 0x80000000)
1958 {
1959 i = (t.exp>=2) + (t.exp>=4) + (t.exp>=8);
1960 f31 l = f31((static_cast<uint32>(t.exp)<<(31-i))+(log2(t.m>>1, 30)>>i), i) / lbe;
1961 s = (x.exp<-1) ? (s-(f31(0x80000000, -1)-x)*l) : (s+(x-f31(0x80000000, -1))*l);
1962 }
1963 s = x.exp ? (s-t) : (t-s);
1964 if(bsign)
1965 {
1966 if(z.exp >= 0)
1967 {
1968 sign &= (L|((z.m>>(31-z.exp))&1)) - 1;
1969 for(z=f31((z.m<<(1+z.exp))&0xFFFFFFFF, -1); z.m<0x80000000; z.m<<=1,--z.exp) ;
1970 }
1971 if(z.exp == -1)
1972 z = f31(0x80000000, 0) - z;
1973 if(z.exp < -1)
1974 {
1975 z = z * pi;
1976 z.m = sincos(z.m>>(1-z.exp), 30).first;
1977 for(z.exp=1; z.m<0x80000000; z.m<<=1,--z.exp) ;
1978 }
1979 else
1980 z = f31(0x80000000, 0);
1981 }
1982 if(L)
1983 {
1984 if(bsign)
1985 {
1986 f31 l(0x92868247, 0);
1987 if(z.exp < 0)
1988 {
1989 uint32 m = log2((z.m+1)>>1, 27);
1990 z = f31(-((static_cast<uint32>(z.exp)<<26)+(m>>5)), 5);
1991 for(; z.m<0x80000000; z.m<<=1,--z.exp) ;
1992 l = l + z / lbe;
1993 }
1994 sign = static_cast<unsigned>(x.exp&&(l.exp<s.exp||(l.exp==s.exp&&l.m<s.m))) << 15;
1995 s = sign ? (s-l) : x.exp ? (l-s) : (l+s);
1996 }
1997 else
1998 {
1999 sign = static_cast<unsigned>(x.exp==0) << 15;
2000 if(s.exp < -24)
2001 return underflow<R>(sign);
2002 if(s.exp > 15)
2003 return overflow<R>(sign);
2004 }
2005 }
2006 else
2007 {
2008 s = s * lbe;
2009 uint32 m;
2010 if(s.exp < 0)
2011 {
2012 m = s.m >> -s.exp;
2013 s.exp = 0;
2014 }
2015 else
2016 {
2017 m = (s.m<<s.exp) & 0x7FFFFFFF;
2018 s.exp = (s.m>>(31-s.exp));
2019 }
2020 s.m = exp2(m, 27);
2021 if(!x.exp)
2022 s = f31(0x80000000, 0) / s;
2023 if(bsign)
2024 {
2025 if(z.exp < 0)
2026 s = s * z;
2027 s = pi / s;
2028 if(s.exp < -24)
2029 return underflow<R>(sign);
2030 }
2031 else if(z.exp > 0 && !(z.m&((1<<(31-z.exp))-1)))
2032 return ((s.exp+14)<<10) + (s.m>>21);
2033 if(s.exp > 15)
2034 return overflow<R>(sign);
2035 }
2036 return fixed2half<R,31,false,false,true>(s.m, s.exp+14, sign);
2037 }
2039
2040 template<typename,typename,std::float_round_style> struct half_caster;
2041 }
2042
2060 class half
2061 {
2062 public:
2065
2069 HALF_CONSTEXPR half() HALF_NOEXCEPT : data_() {}
2070
2074 explicit half(float rhs) : data_(static_cast<detail::uint16>(detail::float2half<round_style>(rhs))) {}
2075
2078 operator float() const { return detail::half2float<float>(data_); }
2079
2084 half& operator=(float rhs) { data_ = static_cast<detail::uint16>(detail::float2half<round_style>(rhs)); return *this; }
2085
2089
2095 half& operator+=(half rhs) { return *this = *this + rhs; }
2096
2102 half& operator-=(half rhs) { return *this = *this - rhs; }
2103
2109 half& operator*=(half rhs) { return *this = *this * rhs; }
2110
2116 half& operator/=(half rhs) { return *this = *this / rhs; }
2117
2122 half& operator+=(float rhs) { return *this = *this + rhs; }
2123
2128 half& operator-=(float rhs) { return *this = *this - rhs; }
2129
2134 half& operator*=(float rhs) { return *this = *this * rhs; }
2135
2140 half& operator/=(float rhs) { return *this = *this / rhs; }
2141
2145
2149 half& operator++() { return *this = *this + half(detail::binary, 0x3C00); }
2150
2154 half& operator--() { return *this = *this + half(detail::binary, 0xBC00); }
2155
2159 half operator++(int) { half out(*this); ++*this; return out; }
2160
2164 half operator--(int) { half out(*this); --*this; return out; }
2166
2167 private:
2169 static const std::float_round_style round_style = (std::float_round_style)(HALF_ROUND_STYLE);
2170
2173 HALF_CONSTEXPR half(detail::binary_t, unsigned int bits) HALF_NOEXCEPT : data_(static_cast<detail::uint16>(bits)) {}
2174
2176 detail::uint16 data_;
2177
2178 #ifndef HALF_DOXYGEN_ONLY
2179 friend HALF_CONSTEXPR_NOERR bool operator==(half, half);
2180 friend HALF_CONSTEXPR_NOERR bool operator!=(half, half);
2181 friend HALF_CONSTEXPR_NOERR bool operator<(half, half);
2182 friend HALF_CONSTEXPR_NOERR bool operator>(half, half);
2183 friend HALF_CONSTEXPR_NOERR bool operator<=(half, half);
2184 friend HALF_CONSTEXPR_NOERR bool operator>=(half, half);
2185 friend HALF_CONSTEXPR half operator-(half);
2186 friend half operator+(half, half);
2187 friend half operator-(half, half);
2188 friend half operator*(half, half);
2189 friend half operator/(half, half);
2190 template<typename charT,typename traits> friend std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT,traits>&, half);
2191 template<typename charT,typename traits> friend std::basic_istream<charT,traits>& operator>>(std::basic_istream<charT,traits>&, half&);
2192 friend HALF_CONSTEXPR half fabs(half);
2193 friend half fmod(half, half);
2194 friend half remainder(half, half);
2195 friend half remquo(half, half, int*);
2196 friend half fma(half, half, half);
2197 friend HALF_CONSTEXPR_NOERR half fmax(half, half);
2198 friend HALF_CONSTEXPR_NOERR half fmin(half, half);
2199 friend half fdim(half, half);
2200 friend half nanh(const char*);
2201 friend half exp(half);
2202 friend half exp2(half);
2203 friend half expm1(half);
2204 friend half log(half);
2205 friend half log10(half);
2206 friend half log2(half);
2207 friend half log1p(half);
2208 friend half sqrt(half);
2209 friend half rsqrt(half);
2210 friend half cbrt(half);
2211 friend half hypot(half, half);
2212 friend half hypot(half, half, half);
2213 friend half pow(half, half);
2214 friend void sincos(half, half*, half*);
2215 friend half sin(half);
2216 friend half cos(half);
2217 friend half tan(half);
2218 friend half asin(half);
2219 friend half acos(half);
2220 friend half atan(half);
2221 friend half atan2(half, half);
2222 friend half sinh(half);
2223 friend half cosh(half);
2224 friend half tanh(half);
2225 friend half asinh(half);
2226 friend half acosh(half);
2227 friend half atanh(half);
2228 friend half erf(half);
2229 friend half erfc(half);
2230 friend half lgamma(half);
2231 friend half tgamma(half);
2232 friend half ceil(half);
2233 friend half floor(half);
2234 friend half trunc(half);
2235 friend half round(half);
2236 friend long lround(half);
2237 friend half rint(half);
2238 friend long lrint(half);
2239 friend half nearbyint(half);
2240 #ifdef HALF_ENABLE_CPP11_LONG_LONG
2241 friend long long llround(half);
2242 friend long long llrint(half);
2243 #endif
2244 friend half frexp(half, int*);
2245 friend half scalbln(half, long);
2246 friend half modf(half, half*);
2247 friend int ilogb(half);
2248 friend half logb(half);
2249 friend half nextafter(half, half);
2250 friend half nexttoward(half, long double);
2251 friend HALF_CONSTEXPR half copysign(half, half);
2252 friend HALF_CONSTEXPR int fpclassify(half);
2253 friend HALF_CONSTEXPR bool isfinite(half);
2254 friend HALF_CONSTEXPR bool isinf(half);
2255 friend HALF_CONSTEXPR bool isnan(half);
2256 friend HALF_CONSTEXPR bool isnormal(half);
2257 friend HALF_CONSTEXPR bool signbit(half);
2258 friend HALF_CONSTEXPR bool isgreater(half, half);
2259 friend HALF_CONSTEXPR bool isgreaterequal(half, half);
2260 friend HALF_CONSTEXPR bool isless(half, half);
2261 friend HALF_CONSTEXPR bool islessequal(half, half);
2262 friend HALF_CONSTEXPR bool islessgreater(half, half);
2263 template<typename,typename,std::float_round_style> friend struct detail::half_caster;
2264 friend class std::numeric_limits<half>;
2265 #if HALF_ENABLE_CPP11_HASH
2266 friend struct std::hash<half>;
2267 #endif
2268 #if HALF_ENABLE_CPP11_USER_LITERALS
2269 friend half literal::operator "" _h(long double);
2270 #endif
2271 #endif
2272 };
2273
2274#if HALF_ENABLE_CPP11_USER_LITERALS
2275 namespace literal
2276 {
2284 inline half operator "" _h(long double value) { return half(detail::binary, detail::float2half<half::round_style>(value)); }
2285 }
2286#endif
2287
2288 namespace detail
2289 {
2296 template<typename T,typename U,std::float_round_style R=(std::float_round_style)(HALF_ROUND_STYLE)> struct half_caster {};
2297 template<typename U,std::float_round_style R> struct half_caster<half,U,R>
2298 {
2299 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
2300 static_assert(std::is_arithmetic<U>::value, "half_cast from non-arithmetic type unsupported");
2301 #endif
2302
2303 static half cast(U arg) { return cast_impl(arg, is_float<U>()); };
2304
2305 private:
2306 static half cast_impl(U arg, true_type) { return half(binary, float2half<R>(arg)); }
2307 static half cast_impl(U arg, false_type) { return half(binary, int2half<R>(arg)); }
2308 };
2309 template<typename T,std::float_round_style R> struct half_caster<T,half,R>
2310 {
2311 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
2312 static_assert(std::is_arithmetic<T>::value, "half_cast to non-arithmetic type unsupported");
2313 #endif
2314
2315 static T cast(half arg) { return cast_impl(arg, is_float<T>()); }
2316
2317 private:
2318 static T cast_impl(half arg, true_type) { return half2float<T>(arg.data_); }
2319 static T cast_impl(half arg, false_type) { return half2int<R,true,true,T>(arg.data_); }
2320 };
2321 template<std::float_round_style R> struct half_caster<half,half,R>
2322 {
2323 static half cast(half arg) { return arg; }
2324 };
2325 }
2326}
2327
2329namespace std
2330{
2333 template<> class numeric_limits<half_float::half>
2334 {
2335 public:
2337 static HALF_CONSTEXPR_CONST bool is_specialized = true;
2338
2340 static HALF_CONSTEXPR_CONST bool is_signed = true;
2341
2343 static HALF_CONSTEXPR_CONST bool is_integer = false;
2344
2346 static HALF_CONSTEXPR_CONST bool is_exact = false;
2347
2349 static HALF_CONSTEXPR_CONST bool is_modulo = false;
2350
2352 static HALF_CONSTEXPR_CONST bool is_bounded = true;
2353
2355 static HALF_CONSTEXPR_CONST bool is_iec559 = true;
2356
2358 static HALF_CONSTEXPR_CONST bool has_infinity = true;
2359
2361 static HALF_CONSTEXPR_CONST bool has_quiet_NaN = true;
2362
2364 static HALF_CONSTEXPR_CONST bool has_signaling_NaN = true;
2365
2367 static HALF_CONSTEXPR_CONST float_denorm_style has_denorm = denorm_present;
2368
2370 static HALF_CONSTEXPR_CONST bool has_denorm_loss = false;
2371
2372 #if HALF_ERRHANDLING_THROWS
2373 static HALF_CONSTEXPR_CONST bool traps = true;
2374 #else
2376 static HALF_CONSTEXPR_CONST bool traps = false;
2377 #endif
2378
2380 static HALF_CONSTEXPR_CONST bool tinyness_before = false;
2381
2383 static HALF_CONSTEXPR_CONST float_round_style round_style = half_float::half::round_style;
2384
2386 static HALF_CONSTEXPR_CONST int digits = 11;
2387
2389 static HALF_CONSTEXPR_CONST int digits10 = 3;
2390
2392 static HALF_CONSTEXPR_CONST int max_digits10 = 5;
2393
2395 static HALF_CONSTEXPR_CONST int radix = 2;
2396
2398 static HALF_CONSTEXPR_CONST int min_exponent = -13;
2399
2401 static HALF_CONSTEXPR_CONST int min_exponent10 = -4;
2402
2404 static HALF_CONSTEXPR_CONST int max_exponent = 16;
2405
2407 static HALF_CONSTEXPR_CONST int max_exponent10 = 4;
2408
2410 static HALF_CONSTEXPR half_float::half min() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x0400); }
2411
2413 static HALF_CONSTEXPR half_float::half lowest() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0xFBFF); }
2414
2416 static HALF_CONSTEXPR half_float::half max() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x7BFF); }
2417
2419 static HALF_CONSTEXPR half_float::half epsilon() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x1400); }
2420
2422 static HALF_CONSTEXPR half_float::half round_error() HALF_NOTHROW
2423 { return half_float::half(half_float::detail::binary, (round_style==std::round_to_nearest) ? 0x3800 : 0x3C00); }
2424
2426 static HALF_CONSTEXPR half_float::half infinity() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x7C00); }
2427
2429 static HALF_CONSTEXPR half_float::half quiet_NaN() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x7FFF); }
2430
2432 static HALF_CONSTEXPR half_float::half signaling_NaN() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x7DFF); }
2433
2435 static HALF_CONSTEXPR half_float::half denorm_min() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x0001); }
2436 };
2437
2438#if HALF_ENABLE_CPP11_HASH
2443 template<> struct hash<half_float::half>
2444 {
2446 typedef half_float::half argument_type;
2447
2449 typedef size_t result_type;
2450
2454 result_type operator()(argument_type arg) const { return hash<half_float::detail::uint16>()(arg.data_&-static_cast<unsigned>(arg.data_!=0x8000)); }
2455 };
2456#endif
2457}
2458
2459namespace half_float
2460{
2464
2471 inline HALF_CONSTEXPR_NOERR bool operator==(half x, half y)
2472 {
2473 return !detail::compsignal(x.data_, y.data_) && (x.data_==y.data_ || !((x.data_|y.data_)&0x7FFF));
2474 }
2475
2482 inline HALF_CONSTEXPR_NOERR bool operator!=(half x, half y)
2483 {
2484 return detail::compsignal(x.data_, y.data_) || (x.data_!=y.data_ && ((x.data_|y.data_)&0x7FFF));
2485 }
2486
2493 inline HALF_CONSTEXPR_NOERR bool operator<(half x, half y)
2494 {
2495 return !detail::compsignal(x.data_, y.data_) &&
2496 ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) < ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15));
2497 }
2498
2505 inline HALF_CONSTEXPR_NOERR bool operator>(half x, half y)
2506 {
2507 return !detail::compsignal(x.data_, y.data_) &&
2508 ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) > ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15));
2509 }
2510
2517 inline HALF_CONSTEXPR_NOERR bool operator<=(half x, half y)
2518 {
2519 return !detail::compsignal(x.data_, y.data_) &&
2520 ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) <= ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15));
2521 }
2522
2529 inline HALF_CONSTEXPR_NOERR bool operator>=(half x, half y)
2530 {
2531 return !detail::compsignal(x.data_, y.data_) &&
2532 ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) >= ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15));
2533 }
2534
2539
2543 inline HALF_CONSTEXPR half operator+(half arg) { return arg; }
2544
2548 inline HALF_CONSTEXPR half operator-(half arg) { return half(detail::binary, arg.data_^0x8000); }
2549
2558 {
2559 #ifdef HALF_ARITHMETIC_TYPE
2560 return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_)+detail::half2float<detail::internal_t>(y.data_)));
2561 #else
2562 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF;
2563 bool sub = ((x.data_^y.data_)&0x8000) != 0;
2564 if(absx >= 0x7C00 || absy >= 0x7C00)
2565 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) : (absy!=0x7C00) ? x.data_ :
2566 (sub && absx==0x7C00) ? detail::invalid() : y.data_);
2567 if(!absx)
2568 return absy ? y : half(detail::binary, (half::round_style==std::round_toward_neg_infinity) ? (x.data_|y.data_) : (x.data_&y.data_));
2569 if(!absy)
2570 return x;
2571 unsigned int sign = ((sub && absy>absx) ? y.data_ : x.data_) & 0x8000;
2572 if(absy > absx)
2573 std::swap(absx, absy);
2574 int exp = (absx>>10) + (absx<=0x3FF), d = exp - (absy>>10) - (absy<=0x3FF), mx = ((absx&0x3FF)|((absx>0x3FF)<<10)) << 3, my;
2575 if(d < 13)
2576 {
2577 my = ((absy&0x3FF)|((absy>0x3FF)<<10)) << 3;
2578 my = (my>>d) | ((my&((1<<d)-1))!=0);
2579 }
2580 else
2581 my = 1;
2582 if(sub)
2583 {
2584 if(!(mx-=my))
2585 return half(detail::binary, static_cast<unsigned>(half::round_style==std::round_toward_neg_infinity)<<15);
2586 for(; mx<0x2000 && exp>1; mx<<=1,--exp) ;
2587 }
2588 else
2589 {
2590 mx += my;
2591 int i = mx >> 14;
2592 if((exp+=i) > 30)
2593 return half(detail::binary, detail::overflow<half::round_style>(sign));
2594 mx = (mx>>i) | (mx&i);
2595 }
2596 return half(detail::binary, detail::rounded<half::round_style,false>(sign+((exp-1)<<10)+(mx>>3), (mx>>2)&1, (mx&0x3)!=0));
2597 #endif
2598 }
2599
2608 {
2609 #ifdef HALF_ARITHMETIC_TYPE
2610 return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_)-detail::half2float<detail::internal_t>(y.data_)));
2611 #else
2612 return x + -y;
2613 #endif
2614 }
2615
2624 {
2625 #ifdef HALF_ARITHMETIC_TYPE
2626 return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_)*detail::half2float<detail::internal_t>(y.data_)));
2627 #else
2628 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -16;
2629 unsigned int sign = (x.data_^y.data_) & 0x8000;
2630 if(absx >= 0x7C00 || absy >= 0x7C00)
2631 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2632 ((absx==0x7C00 && !absy)||(absy==0x7C00 && !absx)) ? detail::invalid() : (sign|0x7C00));
2633 if(!absx || !absy)
2634 return half(detail::binary, sign);
2635 for(; absx<0x400; absx<<=1,--exp) ;
2636 for(; absy<0x400; absy<<=1,--exp) ;
2637 detail::uint32 m = static_cast<detail::uint32>((absx&0x3FF)|0x400) * static_cast<detail::uint32>((absy&0x3FF)|0x400);
2638 int i = m >> 21, s = m & i;
2639 exp += (absx>>10) + (absy>>10) + i;
2640 if(exp > 29)
2641 return half(detail::binary, detail::overflow<half::round_style>(sign));
2642 else if(exp < -11)
2643 return half(detail::binary, detail::underflow<half::round_style>(sign));
2644 return half(detail::binary, detail::fixed2half<half::round_style,20,false,false,false>(m>>i, exp, sign, s));
2645 #endif
2646 }
2647
2657 {
2658 #ifdef HALF_ARITHMETIC_TYPE
2659 return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_)/detail::half2float<detail::internal_t>(y.data_)));
2660 #else
2661 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = 14;
2662 unsigned int sign = (x.data_^y.data_) & 0x8000;
2663 if(absx >= 0x7C00 || absy >= 0x7C00)
2664 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2665 (absx==absy) ? detail::invalid() : (sign|((absx==0x7C00) ? 0x7C00 : 0)));
2666 if(!absx)
2667 return half(detail::binary, absy ? sign : detail::invalid());
2668 if(!absy)
2669 return half(detail::binary, detail::pole(sign));
2670 for(; absx<0x400; absx<<=1,--exp) ;
2671 for(; absy<0x400; absy<<=1,++exp) ;
2672 detail::uint32 mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400;
2673 int i = mx < my;
2674 exp += (absx>>10) - (absy>>10) - i;
2675 if(exp > 29)
2676 return half(detail::binary, detail::overflow<half::round_style>(sign));
2677 else if(exp < -11)
2678 return half(detail::binary, detail::underflow<half::round_style>(sign));
2679 mx <<= 12 + i;
2680 my <<= 1;
2681 return half(detail::binary, detail::fixed2half<half::round_style,11,false,false,false>(mx/my, exp, sign, mx%my!=0));
2682 #endif
2683 }
2684
2689
2695 template<typename charT,typename traits> std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT,traits> &out, half arg)
2696 {
2697 #ifdef HALF_ARITHMETIC_TYPE
2698 return out << detail::half2float<detail::internal_t>(arg.data_);
2699 #else
2700 return out << detail::half2float<float>(arg.data_);
2701 #endif
2702 }
2703
2713 template<typename charT,typename traits> std::basic_istream<charT,traits>& operator>>(std::basic_istream<charT,traits> &in, half &arg)
2714 {
2715 #ifdef HALF_ARITHMETIC_TYPE
2716 detail::internal_t f;
2717 #else
2718 double f;
2719 #endif
2720 if(in >> f)
2721 arg.data_ = detail::float2half<half::round_style>(f);
2722 return in;
2723 }
2724
2729
2734 inline HALF_CONSTEXPR half fabs(half arg) { return half(detail::binary, arg.data_&0x7FFF); }
2735
2740 inline HALF_CONSTEXPR half abs(half arg) { return fabs(arg); }
2741
2748 inline half fmod(half x, half y)
2749 {
2750 unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000;
2751 if(absx >= 0x7C00 || absy >= 0x7C00)
2752 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2753 (absx==0x7C00) ? detail::invalid() : x.data_);
2754 if(!absy)
2755 return half(detail::binary, detail::invalid());
2756 if(!absx)
2757 return x;
2758 if(absx == absy)
2759 return half(detail::binary, sign);
2760 return half(detail::binary, sign|detail::mod<false,false>(absx, absy));
2761 }
2762
2770 {
2771 unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000;
2772 if(absx >= 0x7C00 || absy >= 0x7C00)
2773 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2774 (absx==0x7C00) ? detail::invalid() : x.data_);
2775 if(!absy)
2776 return half(detail::binary, detail::invalid());
2777 if(absx == absy)
2778 return half(detail::binary, sign);
2779 return half(detail::binary, sign^detail::mod<false,true>(absx, absy));
2780 }
2781
2789 inline half remquo(half x, half y, int *quo)
2790 {
2791 unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, value = x.data_ & 0x8000;
2792 if(absx >= 0x7C00 || absy >= 0x7C00)
2793 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2794 (absx==0x7C00) ? detail::invalid() : (*quo = 0, x.data_));
2795 if(!absy)
2796 return half(detail::binary, detail::invalid());
2797 bool qsign = ((value^y.data_)&0x8000) != 0;
2798 int q = 1;
2799 if(absx != absy)
2800 value ^= detail::mod<true, true>(absx, absy, &q);
2801 return *quo = qsign ? -q : q, half(detail::binary, value);
2802 }
2803
2814 inline half fma(half x, half y, half z)
2815 {
2816 #ifdef HALF_ARITHMETIC_TYPE
2817 detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_), fz = detail::half2float<detail::internal_t>(z.data_);
2818 #if HALF_ENABLE_CPP11_CMATH && FP_FAST_FMA
2819 return half(detail::binary, detail::float2half<half::round_style>(std::fma(fx, fy, fz)));
2820 #else
2821 return half(detail::binary, detail::float2half<half::round_style>(fx*fy+fz));
2822 #endif
2823 #else
2824 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, exp = -15;
2825 unsigned int sign = (x.data_^y.data_) & 0x8000;
2826 bool sub = ((sign^z.data_)&0x8000) != 0;
2827 if(absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
2828 return (absx>0x7C00 || absy>0x7C00 || absz>0x7C00) ? half(detail::binary, detail::signal(x.data_, y.data_, z.data_)) :
2829 (absx==0x7C00) ? half(detail::binary, (!absy || (sub && absz==0x7C00)) ? detail::invalid() : (sign|0x7C00)) :
2830 (absy==0x7C00) ? half(detail::binary, (!absx || (sub && absz==0x7C00)) ? detail::invalid() : (sign|0x7C00)) : z;
2831 if(!absx || !absy)
2832 return absz ? z : half(detail::binary, (half::round_style==std::round_toward_neg_infinity) ? (z.data_|sign) : (z.data_&sign));
2833 for(; absx<0x400; absx<<=1,--exp) ;
2834 for(; absy<0x400; absy<<=1,--exp) ;
2835 detail::uint32 m = static_cast<detail::uint32>((absx&0x3FF)|0x400) * static_cast<detail::uint32>((absy&0x3FF)|0x400);
2836 int i = m >> 21;
2837 exp += (absx>>10) + (absy>>10) + i;
2838 m <<= 3 - i;
2839 if(absz)
2840 {
2841 int expz = 0;
2842 for(; absz<0x400; absz<<=1,--expz) ;
2843 expz += absz >> 10;
2844 detail::uint32 mz = static_cast<detail::uint32>((absz&0x3FF)|0x400) << 13;
2845 if(expz > exp || (expz == exp && mz > m))
2846 {
2847 std::swap(m, mz);
2848 std::swap(exp, expz);
2849 if(sub)
2850 sign = z.data_ & 0x8000;
2851 }
2852 int d = exp - expz;
2853 mz = (d<23) ? ((mz>>d)|((mz&((static_cast<detail::uint32>(1)<<d)-1))!=0)) : 1;
2854 if(sub)
2855 {
2856 m = m - mz;
2857 if(!m)
2858 return half(detail::binary, static_cast<unsigned>(half::round_style==std::round_toward_neg_infinity)<<15);
2859 for(; m<0x800000; m<<=1,--exp) ;
2860 }
2861 else
2862 {
2863 m += mz;
2864 i = m >> 24;
2865 m = (m>>i) | (m&i);
2866 exp += i;
2867 }
2868 }
2869 if(exp > 30)
2870 return half(detail::binary, detail::overflow<half::round_style>(sign));
2871 else if(exp < -10)
2872 return half(detail::binary, detail::underflow<half::round_style>(sign));
2873 return half(detail::binary, detail::fixed2half<half::round_style,23,false,false,false>(m, exp-1, sign));
2874 #endif
2875 }
2876
2883 inline HALF_CONSTEXPR_NOERR half fmax(half x, half y)
2884 {
2885 return half(detail::binary, (!isnan(y) && (isnan(x) || (x.data_^(0x8000|(0x8000-(x.data_>>15)))) <
2886 (y.data_^(0x8000|(0x8000-(y.data_>>15)))))) ? detail::select(y.data_, x.data_) : detail::select(x.data_, y.data_));
2887 }
2888
2895 inline HALF_CONSTEXPR_NOERR half fmin(half x, half y)
2896 {
2897 return half(detail::binary, (!isnan(y) && (isnan(x) || (x.data_^(0x8000|(0x8000-(x.data_>>15)))) >
2898 (y.data_^(0x8000|(0x8000-(y.data_>>15)))))) ? detail::select(y.data_, x.data_) : detail::select(x.data_, y.data_));
2899 }
2900
2909 inline half fdim(half x, half y)
2910 {
2911 if(isnan(x) || isnan(y))
2912 return half(detail::binary, detail::signal(x.data_, y.data_));
2913 return (x.data_^(0x8000|(0x8000-(x.data_>>15)))) <= (y.data_^(0x8000|(0x8000-(y.data_>>15)))) ? half(detail::binary, 0) : (x-y);
2914 }
2915
2920 inline half nanh(const char *arg)
2921 {
2922 unsigned int value = 0x7FFF;
2923 while(*arg)
2924 value ^= static_cast<unsigned>(*arg++) & 0xFF;
2925 return half(detail::binary, value);
2926 }
2927
2932
2941 inline half exp(half arg)
2942 {
2943 #ifdef HALF_ARITHMETIC_TYPE
2944 return half(detail::binary, detail::float2half<half::round_style>(std::exp(detail::half2float<detail::internal_t>(arg.data_))));
2945 #else
2946 int abs = arg.data_ & 0x7FFF, e = (abs>>10) + (abs<=0x3FF), exp;
2947 if(!abs)
2948 return half(detail::binary, 0x3C00);
2949 if(abs >= 0x7C00)
2950 return half(detail::binary, (abs==0x7C00) ? (0x7C00&((arg.data_>>15)-1U)) : detail::signal(arg.data_));
2951 if(abs >= 0x4C80)
2952 return half(detail::binary, (arg.data_&0x8000) ? detail::underflow<half::round_style>() : detail::overflow<half::round_style>());
2953 detail::uint32 m = detail::multiply64(static_cast<detail::uint32>((abs&0x3FF)+((abs>0x3FF)<<10))<<21, 0xB8AA3B29);
2954 if(e < 14)
2955 {
2956 exp = 0;
2957 m >>= 14 - e;
2958 }
2959 else
2960 {
2961 exp = m >> (45-e);
2962 m = (m<<(e-14)) & 0x7FFFFFFF;
2963 }
2964 return half(detail::binary, detail::exp2_post<half::round_style>(m, exp, (arg.data_&0x8000)!=0, 0, 26));
2965 #endif
2966 }
2967
2976 inline half exp2(half arg)
2977 {
2978 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
2979 return half(detail::binary, detail::float2half<half::round_style>(std::exp2(detail::half2float<detail::internal_t>(arg.data_))));
2980 #else
2981 int abs = arg.data_ & 0x7FFF, e = (abs>>10) + (abs<=0x3FF), exp = (abs&0x3FF) + ((abs>0x3FF)<<10);
2982 if(!abs)
2983 return half(detail::binary, 0x3C00);
2984 if(abs >= 0x7C00)
2985 return half(detail::binary, (abs==0x7C00) ? (0x7C00&((arg.data_>>15)-1U)) : detail::signal(arg.data_));
2986 if(abs >= 0x4E40)
2987 return half(detail::binary, (arg.data_&0x8000) ? detail::underflow<half::round_style>() : detail::overflow<half::round_style>());
2988 return half(detail::binary, detail::exp2_post<half::round_style>(
2989 (static_cast<detail::uint32>(exp)<<(6+e))&0x7FFFFFFF, exp>>(25-e), (arg.data_&0x8000)!=0, 0, 28));
2990 #endif
2991 }
2992
3002 inline half expm1(half arg)
3003 {
3004 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3005 return half(detail::binary, detail::float2half<half::round_style>(std::expm1(detail::half2float<detail::internal_t>(arg.data_))));
3006 #else
3007 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000, e = (abs>>10) + (abs<=0x3FF), exp;
3008 if(!abs)
3009 return arg;
3010 if(abs >= 0x7C00)
3011 return half(detail::binary, (abs==0x7C00) ? (0x7C00+(sign>>1)) : detail::signal(arg.data_));
3012 if(abs >= 0x4A00)
3013 return half(detail::binary, (arg.data_&0x8000) ? detail::rounded<half::round_style,true>(0xBBFF, 1, 1) : detail::overflow<half::round_style>());
3014 detail::uint32 m = detail::multiply64(static_cast<detail::uint32>((abs&0x3FF)+((abs>0x3FF)<<10))<<21, 0xB8AA3B29);
3015 if(e < 14)
3016 {
3017 exp = 0;
3018 m >>= 14 - e;
3019 }
3020 else
3021 {
3022 exp = m >> (45-e);
3023 m = (m<<(e-14)) & 0x7FFFFFFF;
3024 }
3025 m = detail::exp2(m);
3026 if(sign)
3027 {
3028 int s = 0;
3029 if(m > 0x80000000)
3030 {
3031 ++exp;
3032 m = detail::divide64(0x80000000, m, s);
3033 }
3034 m = 0x80000000 - ((m>>exp)|((m&((static_cast<detail::uint32>(1)<<exp)-1))!=0)|s);
3035 exp = 0;
3036 }
3037 else
3038 m -= (exp<31) ? (0x80000000>>exp) : 1;
3039 for(exp+=14; m<0x80000000 && exp; m<<=1,--exp) ;
3040 if(exp > 29)
3041 return half(detail::binary, detail::overflow<half::round_style>());
3042 return half(detail::binary, detail::rounded<half::round_style,true>(sign+(exp<<10)+(m>>21), (m>>20)&1, (m&0xFFFFF)!=0));
3043 #endif
3044 }
3045
3055 inline half log(half arg)
3056 {
3057 #ifdef HALF_ARITHMETIC_TYPE
3058 return half(detail::binary, detail::float2half<half::round_style>(std::log(detail::half2float<detail::internal_t>(arg.data_))));
3059 #else
3060 int abs = arg.data_ & 0x7FFF, exp = -15;
3061 if(!abs)
3062 return half(detail::binary, detail::pole(0x8000));
3063 if(arg.data_ & 0x8000)
3064 return half(detail::binary, (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3065 if(abs >= 0x7C00)
3066 return (abs==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
3067 for(; abs<0x400; abs<<=1,--exp) ;
3068 exp += abs >> 10;
3069 return half(detail::binary, detail::log2_post<half::round_style,0xB8AA3B2A>(
3070 detail::log2(static_cast<detail::uint32>((abs&0x3FF)|0x400)<<20, 27)+8, exp, 17));
3071 #endif
3072 }
3073
3083 inline half log10(half arg)
3084 {
3085 #ifdef HALF_ARITHMETIC_TYPE
3086 return half(detail::binary, detail::float2half<half::round_style>(std::log10(detail::half2float<detail::internal_t>(arg.data_))));
3087 #else
3088 int abs = arg.data_ & 0x7FFF, exp = -15;
3089 if(!abs)
3090 return half(detail::binary, detail::pole(0x8000));
3091 if(arg.data_ & 0x8000)
3092 return half(detail::binary, (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3093 if(abs >= 0x7C00)
3094 return (abs==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
3095 switch(abs)
3096 {
3097 case 0x4900: return half(detail::binary, 0x3C00);
3098 case 0x5640: return half(detail::binary, 0x4000);
3099 case 0x63D0: return half(detail::binary, 0x4200);
3100 case 0x70E2: return half(detail::binary, 0x4400);
3101 }
3102 for(; abs<0x400; abs<<=1,--exp) ;
3103 exp += abs >> 10;
3104 return half(detail::binary, detail::log2_post<half::round_style,0xD49A784C>(
3105 detail::log2(static_cast<detail::uint32>((abs&0x3FF)|0x400)<<20, 27)+8, exp, 16));
3106 #endif
3107 }
3108
3118 inline half log2(half arg)
3119 {
3120 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3121 return half(detail::binary, detail::float2half<half::round_style>(std::log2(detail::half2float<detail::internal_t>(arg.data_))));
3122 #else
3123 int abs = arg.data_ & 0x7FFF, exp = -15, s = 0;
3124 if(!abs)
3125 return half(detail::binary, detail::pole(0x8000));
3126 if(arg.data_ & 0x8000)
3127 return half(detail::binary, (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3128 if(abs >= 0x7C00)
3129 return (abs==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
3130 if(abs == 0x3C00)
3131 return half(detail::binary, 0);
3132 for(; abs<0x400; abs<<=1,--exp) ;
3133 exp += (abs>>10);
3134 if(!(abs&0x3FF))
3135 {
3136 unsigned int value = static_cast<unsigned>(exp<0) << 15, m = std::abs(exp) << 6;
3137 for(exp=18; m<0x400; m<<=1,--exp) ;
3138 return half(detail::binary, value+(exp<<10)+m);
3139 }
3140 detail::uint32 ilog = exp, sign = detail::sign_mask(ilog), m =
3141 (((ilog<<27)+(detail::log2(static_cast<detail::uint32>((abs&0x3FF)|0x400)<<20, 28)>>4))^sign) - sign;
3142 if(!m)
3143 return half(detail::binary, 0);
3144 for(exp=14; m<0x8000000 && exp; m<<=1,--exp) ;
3145 for(; m>0xFFFFFFF; m>>=1,++exp)
3146 s |= m & 1;
3147 return half(detail::binary, detail::fixed2half<half::round_style,27,false,false,true>(m, exp, sign&0x8000, s));
3148 #endif
3149 }
3150
3161 inline half log1p(half arg)
3162 {
3163 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3164 return half(detail::binary, detail::float2half<half::round_style>(std::log1p(detail::half2float<detail::internal_t>(arg.data_))));
3165 #else
3166 if(arg.data_ >= 0xBC00)
3167 return half(detail::binary, (arg.data_==0xBC00) ? detail::pole(0x8000) : (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3168 int abs = arg.data_ & 0x7FFF, exp = -15;
3169 if(!abs || abs >= 0x7C00)
3170 return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3171 for(; abs<0x400; abs<<=1,--exp) ;
3172 exp += abs >> 10;
3173 detail::uint32 m = static_cast<detail::uint32>((abs&0x3FF)|0x400) << 20;
3174 if(arg.data_ & 0x8000)
3175 {
3176 m = 0x40000000 - (m>>-exp);
3177 for(exp=0; m<0x40000000; m<<=1,--exp) ;
3178 }
3179 else
3180 {
3181 if(exp < 0)
3182 {
3183 m = 0x40000000 + (m>>-exp);
3184 exp = 0;
3185 }
3186 else
3187 {
3188 m += 0x40000000 >> exp;
3189 int i = m >> 31;
3190 m >>= i;
3191 exp += i;
3192 }
3193 }
3194 return half(detail::binary, detail::log2_post<half::round_style,0xB8AA3B2A>(detail::log2(m), exp, 17));
3195 #endif
3196 }
3197
3202
3211 inline half sqrt(half arg)
3212 {
3213 #ifdef HALF_ARITHMETIC_TYPE
3214 return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(detail::half2float<detail::internal_t>(arg.data_))));
3215 #else
3216 int abs = arg.data_ & 0x7FFF, exp = 15;
3217 if(!abs || arg.data_ >= 0x7C00)
3218 return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (arg.data_>0x8000) ? detail::invalid() : arg.data_);
3219 for(; abs<0x400; abs<<=1,--exp) ;
3220 detail::uint32 r = static_cast<detail::uint32>((abs&0x3FF)|0x400) << 10, m = detail::sqrt<20>(r, exp+=abs>>10);
3221 return half(detail::binary, detail::rounded<half::round_style,false>((exp<<10)+(m&0x3FF), r>m, r!=0));
3222 #endif
3223 }
3224
3232 inline half rsqrt(half arg)
3233 {
3234 #ifdef HALF_ARITHMETIC_TYPE
3235 return half(detail::binary, detail::float2half<half::round_style>(detail::internal_t(1)/std::sqrt(detail::half2float<detail::internal_t>(arg.data_))));
3236 #else
3237 unsigned int abs = arg.data_ & 0x7FFF, bias = 0x4000;
3238 if(!abs || arg.data_ >= 0x7C00)
3239 return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (arg.data_>0x8000) ?
3240 detail::invalid() : !abs ? detail::pole(arg.data_&0x8000) : 0);
3241 for(; abs<0x400; abs<<=1,bias-=0x400) ;
3242 unsigned int frac = (abs+=bias) & 0x7FF;
3243 if(frac == 0x400)
3244 return half(detail::binary, 0x7A00-(abs>>1));
3245 if((half::round_style == std::round_to_nearest && (frac == 0x3FE || frac == 0x76C)) ||
3246 (half::round_style != std::round_to_nearest && (frac == 0x15A || frac == 0x3FC || frac == 0x401 || frac == 0x402 || frac == 0x67B)))
3247 return pow(arg, half(detail::binary, 0xB800));
3248 detail::uint32 f = 0x17376 - abs, mx = (abs&0x3FF) | 0x400, my = ((f>>1)&0x3FF) | 0x400, mz = my * my;
3249 int expy = (f>>11) - 31, expx = 32 - (abs>>10), i = mz >> 21;
3250 for(mz=0x60000000-(((mz>>i)*mx)>>(expx-2*expy-i)); mz<0x40000000; mz<<=1,--expy) ;
3251 i = (my*=mz>>10) >> 31;
3252 expy += i;
3253 my = (my>>(20+i)) + 1;
3254 i = (mz=my*my) >> 21;
3255 for(mz=0x60000000-(((mz>>i)*mx)>>(expx-2*expy-i)); mz<0x40000000; mz<<=1,--expy) ;
3256 i = (my*=(mz>>10)+1) >> 31;
3257 return half(detail::binary, detail::fixed2half<half::round_style,30,false,false,true>(my>>i, expy+i+14));
3258 #endif
3259 }
3260
3269 inline half cbrt(half arg)
3270 {
3271 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3272 return half(detail::binary, detail::float2half<half::round_style>(std::cbrt(detail::half2float<detail::internal_t>(arg.data_))));
3273 #else
3274 int abs = arg.data_ & 0x7FFF, exp = -15;
3275 if(!abs || abs == 0x3C00 || abs >= 0x7C00)
3276 return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3277 for(; abs<0x400; abs<<=1, --exp);
3278 detail::uint32 ilog = exp + (abs>>10), sign = detail::sign_mask(ilog), f, m =
3279 (((ilog<<27)+(detail::log2(static_cast<detail::uint32>((abs&0x3FF)|0x400)<<20, 24)>>4))^sign) - sign;
3280 for(exp=2; m<0x80000000; m<<=1,--exp) ;
3281 m = detail::multiply64(m, 0xAAAAAAAB);
3282 int i = m >> 31, s;
3283 exp += i;
3284 m <<= 1 - i;
3285 if(exp < 0)
3286 {
3287 f = m >> -exp;
3288 exp = 0;
3289 }
3290 else
3291 {
3292 f = (m<<exp) & 0x7FFFFFFF;
3293 exp = m >> (31-exp);
3294 }
3295 m = detail::exp2(f, (half::round_style==std::round_to_nearest) ? 29 : 26);
3296 if(sign)
3297 {
3298 if(m > 0x80000000)
3299 {
3300 m = detail::divide64(0x80000000, m, s);
3301 ++exp;
3302 }
3303 exp = -exp;
3304 }
3305 return half(detail::binary, (half::round_style==std::round_to_nearest) ?
3306 detail::fixed2half<half::round_style,31,false,false,false>(m, exp+14, arg.data_&0x8000) :
3307 detail::fixed2half<half::round_style,23,false,false,false>((m+0x80)>>8, exp+14, arg.data_&0x8000));
3308 #endif
3309 }
3310
3320 inline half hypot(half x, half y)
3321 {
3322 #ifdef HALF_ARITHMETIC_TYPE
3323 detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_);
3324 #if HALF_ENABLE_CPP11_CMATH
3325 return half(detail::binary, detail::float2half<half::round_style>(std::hypot(fx, fy)));
3326 #else
3327 return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(fx*fx+fy*fy)));
3328 #endif
3329 #else
3330 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, expx = 0, expy = 0;
3331 if(absx >= 0x7C00 || absy >= 0x7C00)
3332 return half(detail::binary, (absx==0x7C00) ? detail::select(0x7C00, y.data_) :
3333 (absy==0x7C00) ? detail::select(0x7C00, x.data_) : detail::signal(x.data_, y.data_));
3334 if(!absx)
3335 return half(detail::binary, absy ? detail::check_underflow(absy) : 0);
3336 if(!absy)
3337 return half(detail::binary, detail::check_underflow(absx));
3338 if(absy > absx)
3339 std::swap(absx, absy);
3340 for(; absx<0x400; absx<<=1,--expx) ;
3341 for(; absy<0x400; absy<<=1,--expy) ;
3342 detail::uint32 mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400;
3343 mx *= mx;
3344 my *= my;
3345 int ix = mx >> 21, iy = my >> 21;
3346 expx = 2*(expx+(absx>>10)) - 15 + ix;
3347 expy = 2*(expy+(absy>>10)) - 15 + iy;
3348 mx <<= 10 - ix;
3349 my <<= 10 - iy;
3350 int d = expx - expy;
3351 my = (d<30) ? ((my>>d)|((my&((static_cast<detail::uint32>(1)<<d)-1))!=0)) : 1;
3352 return half(detail::binary, detail::hypot_post<half::round_style>(mx+my, expx));
3353 #endif
3354 }
3355
3366 inline half hypot(half x, half y, half z)
3367 {
3368 #ifdef HALF_ARITHMETIC_TYPE
3369 detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_), fz = detail::half2float<detail::internal_t>(z.data_);
3370 return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(fx*fx+fy*fy+fz*fz)));
3371 #else
3372 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, expx = 0, expy = 0, expz = 0;
3373 if(!absx)
3374 return hypot(y, z);
3375 if(!absy)
3376 return hypot(x, z);
3377 if(!absz)
3378 return hypot(x, y);
3379 if(absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
3380 return half(detail::binary, (absx==0x7C00) ? detail::select(0x7C00, detail::select(y.data_, z.data_)) :
3381 (absy==0x7C00) ? detail::select(0x7C00, detail::select(x.data_, z.data_)) :
3382 (absz==0x7C00) ? detail::select(0x7C00, detail::select(x.data_, y.data_)) :
3383 detail::signal(x.data_, y.data_, z.data_));
3384 if(absz > absy)
3385 std::swap(absy, absz);
3386 if(absy > absx)
3387 std::swap(absx, absy);
3388 if(absz > absy)
3389 std::swap(absy, absz);
3390 for(; absx<0x400; absx<<=1,--expx) ;
3391 for(; absy<0x400; absy<<=1,--expy) ;
3392 for(; absz<0x400; absz<<=1,--expz) ;
3393 detail::uint32 mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400, mz = (absz&0x3FF) | 0x400;
3394 mx *= mx;
3395 my *= my;
3396 mz *= mz;
3397 int ix = mx >> 21, iy = my >> 21, iz = mz >> 21;
3398 expx = 2*(expx+(absx>>10)) - 15 + ix;
3399 expy = 2*(expy+(absy>>10)) - 15 + iy;
3400 expz = 2*(expz+(absz>>10)) - 15 + iz;
3401 mx <<= 10 - ix;
3402 my <<= 10 - iy;
3403 mz <<= 10 - iz;
3404 int d = expy - expz;
3405 mz = (d<30) ? ((mz>>d)|((mz&((static_cast<detail::uint32>(1)<<d)-1))!=0)) : 1;
3406 my += mz;
3407 if(my & 0x80000000)
3408 {
3409 my = (my>>1) | (my&1);
3410 if(++expy > expx)
3411 {
3412 std::swap(mx, my);
3413 std::swap(expx, expy);
3414 }
3415 }
3416 d = expx - expy;
3417 my = (d<30) ? ((my>>d)|((my&((static_cast<detail::uint32>(1)<<d)-1))!=0)) : 1;
3418 return half(detail::binary, detail::hypot_post<half::round_style>(mx+my, expx));
3419 #endif
3420 }
3421
3432 inline half pow(half x, half y)
3433 {
3434 #ifdef HALF_ARITHMETIC_TYPE
3435 return half(detail::binary, detail::float2half<half::round_style>(std::pow(detail::half2float<detail::internal_t>(x.data_), detail::half2float<detail::internal_t>(y.data_))));
3436 #else
3437 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -15;
3438 if(!absy || x.data_ == 0x3C00)
3439 return half(detail::binary, detail::select(0x3C00, (x.data_==0x3C00) ? y.data_ : x.data_));
3440 bool is_int = absy >= 0x6400 || (absy>=0x3C00 && !(absy&((1<<(25-(absy>>10)))-1)));
3441 unsigned int sign = x.data_ & (static_cast<unsigned>((absy<0x6800)&&is_int&&((absy>>(25-(absy>>10)))&1))<<15);
3442 if(absx >= 0x7C00 || absy >= 0x7C00)
3443 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
3444 (absy==0x7C00) ? ((absx==0x3C00) ? 0x3C00 : (!absx && y.data_==0xFC00) ? detail::pole() :
3445 (0x7C00&-((y.data_>>15)^(absx>0x3C00)))) : (sign|(0x7C00&((y.data_>>15)-1U))));
3446 if(!absx)
3447 return half(detail::binary, (y.data_&0x8000) ? detail::pole(sign) : sign);
3448 if((x.data_&0x8000) && !is_int)
3449 return half(detail::binary, detail::invalid());
3450 if(x.data_ == 0xBC00)
3451 return half(detail::binary, sign|0x3C00);
3452 switch(y.data_)
3453 {
3454 case 0x3800: return sqrt(x);
3455 case 0x3C00: return half(detail::binary, detail::check_underflow(x.data_));
3456 case 0x4000: return x * x;
3457 case 0xBC00: return half(detail::binary, 0x3C00) / x;
3458 }
3459 for(; absx<0x400; absx<<=1,--exp) ;
3460 detail::uint32 ilog = exp + (absx>>10), msign = detail::sign_mask(ilog), f, m =
3461 (((ilog<<27)+((detail::log2(static_cast<detail::uint32>((absx&0x3FF)|0x400)<<20)+8)>>4))^msign) - msign;
3462 for(exp=-11; m<0x80000000; m<<=1,--exp) ;
3463 for(; absy<0x400; absy<<=1,--exp) ;
3464 m = detail::multiply64(m, static_cast<detail::uint32>((absy&0x3FF)|0x400)<<21);
3465 int i = m >> 31;
3466 exp += (absy>>10) + i;
3467 m <<= 1 - i;
3468 if(exp < 0)
3469 {
3470 f = m >> -exp;
3471 exp = 0;
3472 }
3473 else
3474 {
3475 f = (m<<exp) & 0x7FFFFFFF;
3476 exp = m >> (31-exp);
3477 }
3478 return half(detail::binary, detail::exp2_post<half::round_style>(f, exp, ((msign&1)^(y.data_>>15))!=0, sign));
3479 #endif
3480 }
3481
3486
3496 inline void sincos(half arg, half *sin, half *cos)
3497 {
3498 #ifdef HALF_ARITHMETIC_TYPE
3499 detail::internal_t f = detail::half2float<detail::internal_t>(arg.data_);
3500 *sin = half(detail::binary, detail::float2half<half::round_style>(std::sin(f)));
3501 *cos = half(detail::binary, detail::float2half<half::round_style>(std::cos(f)));
3502 #else
3503 int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15, k;
3504 if(abs >= 0x7C00)
3505 *sin = *cos = half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3506 else if(!abs)
3507 {
3508 *sin = arg;
3509 *cos = half(detail::binary, 0x3C00);
3510 }
3511 else if(abs < 0x2500)
3512 {
3513 *sin = half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-1, 1, 1));
3514 *cos = half(detail::binary, detail::rounded<half::round_style,true>(0x3BFF, 1, 1));
3515 }
3516 else
3517 {
3518 if(half::round_style != std::round_to_nearest)
3519 {
3520 switch(abs)
3521 {
3522 case 0x48B7:
3523 *sin = half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x1D07, 1, 1));
3524 *cos = half(detail::binary, detail::rounded<half::round_style,true>(0xBBFF, 1, 1));
3525 return;
3526 case 0x598C:
3527 *sin = half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x3BFF, 1, 1));
3528 *cos = half(detail::binary, detail::rounded<half::round_style,true>(0x80FC, 1, 1));
3529 return;
3530 case 0x6A64:
3531 *sin = half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x3BFE, 1, 1));
3532 *cos = half(detail::binary, detail::rounded<half::round_style,true>(0x27FF, 1, 1));
3533 return;
3534 case 0x6D8C:
3535 *sin = half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x0FE6, 1, 1));
3536 *cos = half(detail::binary, detail::rounded<half::round_style,true>(0x3BFF, 1, 1));
3537 return;
3538 }
3539 }
3540 std::pair<detail::uint32,detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
3541 switch(k & 3)
3542 {
3543 case 1: sc = std::make_pair(sc.second, -sc.first); break;
3544 case 2: sc = std::make_pair(-sc.first, -sc.second); break;
3545 case 3: sc = std::make_pair(-sc.second, sc.first); break;
3546 }
3547 *sin = half(detail::binary, detail::fixed2half<half::round_style,30,true,true,true>((sc.first^-static_cast<detail::uint32>(sign))+sign));
3548 *cos = half(detail::binary, detail::fixed2half<half::round_style,30,true,true,true>(sc.second));
3549 }
3550 #endif
3551 }
3552
3561 inline half sin(half arg)
3562 {
3563 #ifdef HALF_ARITHMETIC_TYPE
3564 return half(detail::binary, detail::float2half<half::round_style>(std::sin(detail::half2float<detail::internal_t>(arg.data_))));
3565 #else
3566 int abs = arg.data_ & 0x7FFF, k;
3567 if(!abs)
3568 return arg;
3569 if(abs >= 0x7C00)
3570 return half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3571 if(abs < 0x2900)
3572 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-1, 1, 1));
3573 if(half::round_style != std::round_to_nearest)
3574 switch(abs)
3575 {
3576 case 0x48B7: return half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x1D07, 1, 1));
3577 case 0x6A64: return half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x3BFE, 1, 1));
3578 case 0x6D8C: return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x0FE6, 1, 1));
3579 }
3580 std::pair<detail::uint32,detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
3581 detail::uint32 sign = -static_cast<detail::uint32>(((k>>1)&1)^(arg.data_>>15));
3582 return half(detail::binary, detail::fixed2half<half::round_style,30,true,true,true>((((k&1) ? sc.second : sc.first)^sign) - sign));
3583 #endif
3584 }
3585
3594 inline half cos(half arg)
3595 {
3596 #ifdef HALF_ARITHMETIC_TYPE
3597 return half(detail::binary, detail::float2half<half::round_style>(std::cos(detail::half2float<detail::internal_t>(arg.data_))));
3598 #else
3599 int abs = arg.data_ & 0x7FFF, k;
3600 if(!abs)
3601 return half(detail::binary, 0x3C00);
3602 if(abs >= 0x7C00)
3603 return half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3604 if(abs < 0x2500)
3605 return half(detail::binary, detail::rounded<half::round_style,true>(0x3BFF, 1, 1));
3606 if(half::round_style != std::round_to_nearest && abs == 0x598C)
3607 return half(detail::binary, detail::rounded<half::round_style,true>(0x80FC, 1, 1));
3608 std::pair<detail::uint32,detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
3609 detail::uint32 sign = -static_cast<detail::uint32>(((k>>1)^k)&1);
3610 return half(detail::binary, detail::fixed2half<half::round_style,30,true,true,true>((((k&1) ? sc.first : sc.second)^sign) - sign));
3611 #endif
3612 }
3613
3622 inline half tan(half arg)
3623 {
3624 #ifdef HALF_ARITHMETIC_TYPE
3625 return half(detail::binary, detail::float2half<half::round_style>(std::tan(detail::half2float<detail::internal_t>(arg.data_))));
3626 #else
3627 int abs = arg.data_ & 0x7FFF, exp = 13, k;
3628 if(!abs)
3629 return arg;
3630 if(abs >= 0x7C00)
3631 return half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3632 if(abs < 0x2700)
3633 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_, 0, 1));
3634 if(half::round_style != std::round_to_nearest)
3635 switch(abs)
3636 {
3637 case 0x658C: return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x07E6, 1, 1));
3638 case 0x7330: return half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x4B62, 1, 1));
3639 }
3640 std::pair<detail::uint32,detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 30);
3641 if(k & 1)
3642 sc = std::make_pair(-sc.second, sc.first);
3643 detail::uint32 signy = detail::sign_mask(sc.first), signx = detail::sign_mask(sc.second);
3644 detail::uint32 my = (sc.first^signy) - signy, mx = (sc.second^signx) - signx;
3645 for(; my<0x80000000; my<<=1,--exp) ;
3646 for(; mx<0x80000000; mx<<=1,++exp) ;
3647 return half(detail::binary, detail::tangent_post<half::round_style>(my, mx, exp, (signy^signx^arg.data_)&0x8000));
3648 #endif
3649 }
3650
3659 inline half asin(half arg)
3660 {
3661 #ifdef HALF_ARITHMETIC_TYPE
3662 return half(detail::binary, detail::float2half<half::round_style>(std::asin(detail::half2float<detail::internal_t>(arg.data_))));
3663 #else
3664 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
3665 if(!abs)
3666 return arg;
3667 if(abs >= 0x3C00)
3668 return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (abs>0x3C00) ? detail::invalid() :
3669 detail::rounded<half::round_style,true>(sign|0x3E48, 0, 1));
3670 if(abs < 0x2900)
3671 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_, 0, 1));
3672 if(half::round_style != std::round_to_nearest && (abs == 0x2B44 || abs == 0x2DC3))
3673 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_+1, 1, 1));
3674 std::pair<detail::uint32,detail::uint32> sc = detail::atan2_args(abs);
3675 detail::uint32 m = detail::atan2(sc.first, sc.second, (half::round_style==std::round_to_nearest) ? 27 : 26);
3676 return half(detail::binary, detail::fixed2half<half::round_style,30,false,true,true>(m, 14, sign));
3677 #endif
3678 }
3679
3688 inline half acos(half arg)
3689 {
3690 #ifdef HALF_ARITHMETIC_TYPE
3691 return half(detail::binary, detail::float2half<half::round_style>(std::acos(detail::half2float<detail::internal_t>(arg.data_))));
3692 #else
3693 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15;
3694 if(!abs)
3695 return half(detail::binary, detail::rounded<half::round_style,true>(0x3E48, 0, 1));
3696 if(abs >= 0x3C00)
3697 return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (abs>0x3C00) ? detail::invalid() :
3698 sign ? detail::rounded<half::round_style,true>(0x4248, 0, 1) : 0);
3699 std::pair<detail::uint32,detail::uint32> cs = detail::atan2_args(abs);
3700 detail::uint32 m = detail::atan2(cs.second, cs.first, 28);
3701 return half(detail::binary, detail::fixed2half<half::round_style,31,false,true,true>(sign ? (0xC90FDAA2-m) : m, 15, 0, sign));
3702 #endif
3703 }
3704
3713 inline half atan(half arg)
3714 {
3715 #ifdef HALF_ARITHMETIC_TYPE
3716 return half(detail::binary, detail::float2half<half::round_style>(std::atan(detail::half2float<detail::internal_t>(arg.data_))));
3717 #else
3718 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
3719 if(!abs)
3720 return arg;
3721 if(abs >= 0x7C00)
3722 return half(detail::binary, (abs==0x7C00) ? detail::rounded<half::round_style,true>(sign|0x3E48, 0, 1) : detail::signal(arg.data_));
3723 if(abs <= 0x2700)
3724 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-1, 1, 1));
3725 int exp = (abs>>10) + (abs<=0x3FF);
3726 detail::uint32 my = (abs&0x3FF) | ((abs>0x3FF)<<10);
3727 detail::uint32 m = (exp>15) ? detail::atan2(my<<19, 0x20000000>>(exp-15), (half::round_style==std::round_to_nearest) ? 26 : 24) :
3728 detail::atan2(my<<(exp+4), 0x20000000, (half::round_style==std::round_to_nearest) ? 30 : 28);
3729 return half(detail::binary, detail::fixed2half<half::round_style,30,false,true,true>(m, 14, sign));
3730 #endif
3731 }
3732
3743 inline half atan2(half y, half x)
3744 {
3745 #ifdef HALF_ARITHMETIC_TYPE
3746 return half(detail::binary, detail::float2half<half::round_style>(std::atan2(detail::half2float<detail::internal_t>(y.data_), detail::half2float<detail::internal_t>(x.data_))));
3747 #else
3748 unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, signx = x.data_ >> 15, signy = y.data_ & 0x8000;
3749 if(absx >= 0x7C00 || absy >= 0x7C00)
3750 {
3751 if(absx > 0x7C00 || absy > 0x7C00)
3752 return half(detail::binary, detail::signal(x.data_, y.data_));
3753 if(absy == 0x7C00)
3754 return half(detail::binary, (absx<0x7C00) ? detail::rounded<half::round_style,true>(signy|0x3E48, 0, 1) :
3755 signx ? detail::rounded<half::round_style,true>(signy|0x40B6, 0, 1) :
3756 detail::rounded<half::round_style,true>(signy|0x3A48, 0, 1));
3757 return (x.data_==0x7C00) ? half(detail::binary, signy) : half(detail::binary, detail::rounded<half::round_style,true>(signy|0x4248, 0, 1));
3758 }
3759 if(!absy)
3760 return signx ? half(detail::binary, detail::rounded<half::round_style,true>(signy|0x4248, 0, 1)) : y;
3761 if(!absx)
3762 return half(detail::binary, detail::rounded<half::round_style,true>(signy|0x3E48, 0, 1));
3763 int d = (absy>>10) + (absy<=0x3FF) - (absx>>10) - (absx<=0x3FF);
3764 if(d > (signx ? 18 : 12))
3765 return half(detail::binary, detail::rounded<half::round_style,true>(signy|0x3E48, 0, 1));
3766 if(signx && d < -11)
3767 return half(detail::binary, detail::rounded<half::round_style,true>(signy|0x4248, 0, 1));
3768 if(!signx && d < ((half::round_style==std::round_toward_zero) ? -15 : -9))
3769 {
3770 for(; absy<0x400; absy<<=1,--d) ;
3771 detail::uint32 mx = ((absx<<1)&0x7FF) | 0x800, my = ((absy<<1)&0x7FF) | 0x800;
3772 int i = my < mx;
3773 d -= i;
3774 if(d < -25)
3775 return half(detail::binary, detail::underflow<half::round_style>(signy));
3776 my <<= 11 + i;
3777 return half(detail::binary, detail::fixed2half<half::round_style,11,false,false,true>(my/mx, d+14, signy, my%mx!=0));
3778 }
3779 detail::uint32 m = detail::atan2( ((absy&0x3FF)|((absy>0x3FF)<<10))<<(19+((d<0) ? d : (d>0) ? 0 : -1)),
3780 ((absx&0x3FF)|((absx>0x3FF)<<10))<<(19-((d>0) ? d : (d<0) ? 0 : 1)));
3781 return half(detail::binary, detail::fixed2half<half::round_style,31,false,true,true>(signx ? (0xC90FDAA2-m) : m, 15, signy, signx));
3782 #endif
3783 }
3784
3789
3798 inline half sinh(half arg)
3799 {
3800 #ifdef HALF_ARITHMETIC_TYPE
3801 return half(detail::binary, detail::float2half<half::round_style>(std::sinh(detail::half2float<detail::internal_t>(arg.data_))));
3802 #else
3803 int abs = arg.data_ & 0x7FFF, exp;
3804 if(!abs || abs >= 0x7C00)
3805 return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3806 if(abs <= 0x2900)
3807 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_, 0, 1));
3808 std::pair<detail::uint32,detail::uint32> mm = detail::hyperbolic_args(abs, exp, (half::round_style==std::round_to_nearest) ? 29 : 27);
3809 detail::uint32 m = mm.first - mm.second;
3810 for(exp+=13; m<0x80000000 && exp; m<<=1,--exp) ;
3811 unsigned int sign = arg.data_ & 0x8000;
3812 if(exp > 29)
3813 return half(detail::binary, detail::overflow<half::round_style>(sign));
3814 return half(detail::binary, detail::fixed2half<half::round_style,31,false,false,true>(m, exp, sign));
3815 #endif
3816 }
3817
3826 inline half cosh(half arg)
3827 {
3828 #ifdef HALF_ARITHMETIC_TYPE
3829 return half(detail::binary, detail::float2half<half::round_style>(std::cosh(detail::half2float<detail::internal_t>(arg.data_))));
3830 #else
3831 int abs = arg.data_ & 0x7FFF, exp;
3832 if(!abs)
3833 return half(detail::binary, 0x3C00);
3834 if(abs >= 0x7C00)
3835 return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : 0x7C00);
3836 std::pair<detail::uint32,detail::uint32> mm = detail::hyperbolic_args(abs, exp, (half::round_style==std::round_to_nearest) ? 23 : 26);
3837 detail::uint32 m = mm.first + mm.second, i = (~m&0xFFFFFFFF) >> 31;
3838 m = (m>>i) | (m&i) | 0x80000000;
3839 if((exp+=13+i) > 29)
3840 return half(detail::binary, detail::overflow<half::round_style>());
3841 return half(detail::binary, detail::fixed2half<half::round_style,31,false,false,true>(m, exp));
3842 #endif
3843 }
3844
3853 inline half tanh(half arg)
3854 {
3855 #ifdef HALF_ARITHMETIC_TYPE
3856 return half(detail::binary, detail::float2half<half::round_style>(std::tanh(detail::half2float<detail::internal_t>(arg.data_))));
3857 #else
3858 int abs = arg.data_ & 0x7FFF, exp;
3859 if(!abs)
3860 return arg;
3861 if(abs >= 0x7C00)
3862 return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (arg.data_-0x4000));
3863 if(abs >= 0x4500)
3864 return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x3BFF, 1, 1));
3865 if(abs < 0x2700)
3866 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-1, 1, 1));
3867 if(half::round_style != std::round_to_nearest && abs == 0x2D3F)
3868 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-3, 0, 1));
3869 std::pair<detail::uint32,detail::uint32> mm = detail::hyperbolic_args(abs, exp, 27);
3870 detail::uint32 my = mm.first - mm.second - (half::round_style!=std::round_to_nearest), mx = mm.first + mm.second, i = (~mx&0xFFFFFFFF) >> 31;
3871 for(exp=13; my<0x80000000; my<<=1,--exp) ;
3872 mx = (mx>>i) | 0x80000000;
3873 return half(detail::binary, detail::tangent_post<half::round_style>(my, mx, exp-i, arg.data_&0x8000));
3874 #endif
3875 }
3876
3885 inline half asinh(half arg)
3886 {
3887 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3888 return half(detail::binary, detail::float2half<half::round_style>(std::asinh(detail::half2float<detail::internal_t>(arg.data_))));
3889 #else
3890 int abs = arg.data_ & 0x7FFF;
3891 if(!abs || abs >= 0x7C00)
3892 return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3893 if(abs <= 0x2900)
3894 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-1, 1, 1));
3895 if(half::round_style != std::round_to_nearest)
3896 switch(abs)
3897 {
3898 case 0x32D4: return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-13, 1, 1));
3899 case 0x3B5B: return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-197, 1, 1));
3900 }
3901 return half(detail::binary, detail::area<half::round_style,true>(arg.data_));
3902 #endif
3903 }
3904
3913 inline half acosh(half arg)
3914 {
3915 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3916 return half(detail::binary, detail::float2half<half::round_style>(std::acosh(detail::half2float<detail::internal_t>(arg.data_))));
3917 #else
3918 int abs = arg.data_ & 0x7FFF;
3919 if((arg.data_&0x8000) || abs < 0x3C00)
3920 return half(detail::binary, (abs<=0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3921 if(abs == 0x3C00)
3922 return half(detail::binary, 0);
3923 if(arg.data_ >= 0x7C00)
3924 return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3925 return half(detail::binary, detail::area<half::round_style,false>(arg.data_));
3926 #endif
3927 }
3928
3938 inline half atanh(half arg)
3939 {
3940 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3941 return half(detail::binary, detail::float2half<half::round_style>(std::atanh(detail::half2float<detail::internal_t>(arg.data_))));
3942 #else
3943 int abs = arg.data_ & 0x7FFF, exp = 0;
3944 if(!abs)
3945 return arg;
3946 if(abs >= 0x3C00)
3947 return half(detail::binary, (abs==0x3C00) ? detail::pole(arg.data_&0x8000) : (abs<=0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3948 if(abs < 0x2700)
3949 return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_, 0, 1));
3950 detail::uint32 m = static_cast<detail::uint32>((abs&0x3FF)|((abs>0x3FF)<<10)) << ((abs>>10)+(abs<=0x3FF)+6), my = 0x80000000 + m, mx = 0x80000000 - m;
3951 for(; mx<0x80000000; mx<<=1,++exp) ;
3952 int i = my >= mx, s;
3953 return half(detail::binary, detail::log2_post<half::round_style,0xB8AA3B2A>(detail::log2(
3954 (detail::divide64(my>>i, mx, s)+1)>>1, 27)+0x10, exp+i-1, 16, arg.data_&0x8000));
3955 #endif
3956 }
3957
3962
3971 inline half erf(half arg)
3972 {
3973 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3974 return half(detail::binary, detail::float2half<half::round_style>(std::erf(detail::half2float<detail::internal_t>(arg.data_))));
3975 #else
3976 unsigned int abs = arg.data_ & 0x7FFF;
3977 if(!abs || abs >= 0x7C00)
3978 return (abs>=0x7C00) ? half(detail::binary, (abs==0x7C00) ? (arg.data_-0x4000) : detail::signal(arg.data_)) : arg;
3979 if(abs >= 0x4200)
3980 return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x3BFF, 1, 1));
3981 return half(detail::binary, detail::erf<half::round_style,false>(arg.data_));
3982 #endif
3983 }
3984
3993 inline half erfc(half arg)
3994 {
3995 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3996 return half(detail::binary, detail::float2half<half::round_style>(std::erfc(detail::half2float<detail::internal_t>(arg.data_))));
3997 #else
3998 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
3999 if(abs >= 0x7C00)
4000 return (abs>=0x7C00) ? half(detail::binary, (abs==0x7C00) ? (sign>>1) : detail::signal(arg.data_)) : arg;
4001 if(!abs)
4002 return half(detail::binary, 0x3C00);
4003 if(abs >= 0x4400)
4004 return half(detail::binary, detail::rounded<half::round_style,true>((sign>>1)-(sign>>15), sign>>15, 1));
4005 return half(detail::binary, detail::erf<half::round_style,true>(arg.data_));
4006 #endif
4007 }
4008
4018 inline half lgamma(half arg)
4019 {
4020 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
4021 return half(detail::binary, detail::float2half<half::round_style>(std::lgamma(detail::half2float<detail::internal_t>(arg.data_))));
4022 #else
4023 int abs = arg.data_ & 0x7FFF;
4024 if(abs >= 0x7C00)
4025 return half(detail::binary, (abs==0x7C00) ? 0x7C00 : detail::signal(arg.data_));
4026 if(!abs || arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(abs&((1<<(25-(abs>>10)))-1))))
4027 return half(detail::binary, detail::pole());
4028 if(arg.data_ == 0x3C00 || arg.data_ == 0x4000)
4029 return half(detail::binary, 0);
4030 return half(detail::binary, detail::gamma<half::round_style,true>(arg.data_));
4031 #endif
4032 }
4033
4043 inline half tgamma(half arg)
4044 {
4045 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
4046 return half(detail::binary, detail::float2half<half::round_style>(std::tgamma(detail::half2float<detail::internal_t>(arg.data_))));
4047 #else
4048 unsigned int abs = arg.data_ & 0x7FFF;
4049 if(!abs)
4050 return half(detail::binary, detail::pole(arg.data_));
4051 if(abs >= 0x7C00)
4052 return (arg.data_==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
4053 if(arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(abs&((1<<(25-(abs>>10)))-1))))
4054 return half(detail::binary, detail::invalid());
4055 if(arg.data_ >= 0xCA80)
4056 return half(detail::binary, detail::underflow<half::round_style>((1-((abs>>(25-(abs>>10)))&1))<<15));
4057 if(arg.data_ <= 0x100 || (arg.data_ >= 0x4900 && arg.data_ < 0x8000))
4058 return half(detail::binary, detail::overflow<half::round_style>());
4059 if(arg.data_ == 0x3C00)
4060 return arg;
4061 return half(detail::binary, detail::gamma<half::round_style,false>(arg.data_));
4062 #endif
4063 }
4064
4069
4076 inline half ceil(half arg) { return half(detail::binary, detail::integral<std::round_toward_infinity,true,true>(arg.data_)); }
4077
4084 inline half floor(half arg) { return half(detail::binary, detail::integral<std::round_toward_neg_infinity,true,true>(arg.data_)); }
4085
4092 inline half trunc(half arg) { return half(detail::binary, detail::integral<std::round_toward_zero,true,true>(arg.data_)); }
4093
4100 inline half round(half arg) { return half(detail::binary, detail::integral<std::round_to_nearest,false,true>(arg.data_)); }
4101
4107 inline long lround(half arg) { return detail::half2int<std::round_to_nearest,false,false,long>(arg.data_); }
4108
4115 inline half rint(half arg) { return half(detail::binary, detail::integral<half::round_style,true,true>(arg.data_)); }
4116
4123 inline long lrint(half arg) { return detail::half2int<half::round_style,true,true,long>(arg.data_); }
4124
4130 inline half nearbyint(half arg) { return half(detail::binary, detail::integral<half::round_style,true,false>(arg.data_)); }
4131#if HALF_ENABLE_CPP11_LONG_LONG
4137 inline long long llround(half arg) { return detail::half2int<std::round_to_nearest,false,false,long long>(arg.data_); }
4138
4145 inline long long llrint(half arg) { return detail::half2int<half::round_style,true,true,long long>(arg.data_); }
4146#endif
4147
4152
4159 inline half frexp(half arg, int *exp)
4160 {
4161 *exp = 0;
4162 unsigned int abs = arg.data_ & 0x7FFF;
4163 if(abs >= 0x7C00 || !abs)
4164 return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
4165 for(; abs<0x400; abs<<=1,--*exp) ;
4166 *exp += (abs>>10) - 14;
4167 return half(detail::binary, (arg.data_&0x8000)|0x3800|(abs&0x3FF));
4168 }
4169
4179 inline half scalbln(half arg, long exp)
4180 {
4181 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
4182 if(abs >= 0x7C00 || !abs)
4183 return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
4184 for(; abs<0x400; abs<<=1,--exp) ;
4185 exp += abs >> 10;
4186 if(exp > 30)
4187 return half(detail::binary, detail::overflow<half::round_style>(sign));
4188 else if(exp < -10)
4189 return half(detail::binary, detail::underflow<half::round_style>(sign));
4190 else if(exp > 0)
4191 return half(detail::binary, sign|(exp<<10)|(abs&0x3FF));
4192 unsigned int m = (abs&0x3FF) | 0x400;
4193 return half(detail::binary, detail::rounded<half::round_style,false>(sign|(m>>(1-exp)), (m>>-exp)&1, (m&((1<<-exp)-1))!=0));
4194 }
4195
4205 inline half scalbn(half arg, int exp) { return scalbln(arg, exp); }
4206
4216 inline half ldexp(half arg, int exp) { return scalbln(arg, exp); }
4217
4224 inline half modf(half arg, half *iptr)
4225 {
4226 unsigned int abs = arg.data_ & 0x7FFF;
4227 if(abs > 0x7C00)
4228 {
4229 arg = half(detail::binary, detail::signal(arg.data_));
4230 return *iptr = arg, arg;
4231 }
4232 if(abs >= 0x6400)
4233 return *iptr = arg, half(detail::binary, arg.data_&0x8000);
4234 if(abs < 0x3C00)
4235 return iptr->data_ = arg.data_ & 0x8000, arg;
4236 unsigned int exp = abs >> 10, mask = (1<<(25-exp)) - 1, m = arg.data_ & mask;
4237 iptr->data_ = arg.data_ & ~mask;
4238 if(!m)
4239 return half(detail::binary, arg.data_&0x8000);
4240 for(; m<0x400; m<<=1,--exp) ;
4241 return half(detail::binary, (arg.data_&0x8000)|(exp<<10)|(m&0x3FF));
4242 }
4243
4252 inline int ilogb(half arg)
4253 {
4254 int abs = arg.data_ & 0x7FFF, exp;
4255 if(!abs || abs >= 0x7C00)
4256 {
4257 detail::raise(FE_INVALID);
4258 return !abs ? FP_ILOGB0 : (abs==0x7C00) ? INT_MAX : FP_ILOGBNAN;
4259 }
4260 for(exp=(abs>>10)-15; abs<0x200; abs<<=1,--exp) ;
4261 return exp;
4262 }
4263
4270 inline half logb(half arg)
4271 {
4272 int abs = arg.data_ & 0x7FFF, exp;
4273 if(!abs)
4274 return half(detail::binary, detail::pole(0x8000));
4275 if(abs >= 0x7C00)
4276 return half(detail::binary, (abs==0x7C00) ? 0x7C00 : detail::signal(arg.data_));
4277 for(exp=(abs>>10)-15; abs<0x200; abs<<=1,--exp) ;
4278 unsigned int value = static_cast<unsigned>(exp<0) << 15;
4279 if(exp)
4280 {
4281 unsigned int m = std::abs(exp) << 6;
4282 for(exp=18; m<0x400; m<<=1,--exp) ;
4283 value |= (exp<<10) + m;
4284 }
4285 return half(detail::binary, value);
4286 }
4287
4296 inline half nextafter(half from, half to)
4297 {
4298 int fabs = from.data_ & 0x7FFF, tabs = to.data_ & 0x7FFF;
4299 if(fabs > 0x7C00 || tabs > 0x7C00)
4300 return half(detail::binary, detail::signal(from.data_, to.data_));
4301 if(from.data_ == to.data_ || !(fabs|tabs))
4302 return to;
4303 if(!fabs)
4304 {
4305 detail::raise(FE_UNDERFLOW, !HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT);
4306 return half(detail::binary, (to.data_&0x8000)+1);
4307 }
4308 unsigned int out = from.data_ + (((from.data_>>15)^static_cast<unsigned>(
4309 (from.data_^(0x8000|(0x8000-(from.data_>>15))))<(to.data_^(0x8000|(0x8000-(to.data_>>15))))))<<1) - 1;
4310 detail::raise(FE_OVERFLOW, fabs<0x7C00 && (out&0x7C00)==0x7C00);
4311 detail::raise(FE_UNDERFLOW, !HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT && (out&0x7C00)<0x400);
4312 return half(detail::binary, out);
4313 }
4314
4323 inline half nexttoward(half from, long double to)
4324 {
4325 int fabs = from.data_ & 0x7FFF;
4326 if(fabs > 0x7C00)
4327 return half(detail::binary, detail::signal(from.data_));
4328 long double lfrom = static_cast<long double>(from);
4329 if(detail::builtin_isnan(to) || lfrom == to)
4330 return half(static_cast<float>(to));
4331 if(!fabs)
4332 {
4333 detail::raise(FE_UNDERFLOW, !HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT);
4334 return half(detail::binary, (static_cast<unsigned>(detail::builtin_signbit(to))<<15)+1);
4335 }
4336 unsigned int out = from.data_ + (((from.data_>>15)^static_cast<unsigned>(lfrom<to))<<1) - 1;
4337 detail::raise(FE_OVERFLOW, (out&0x7FFF)==0x7C00);
4338 detail::raise(FE_UNDERFLOW, !HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT && (out&0x7FFF)<0x400);
4339 return half(detail::binary, out);
4340 }
4341
4347 inline HALF_CONSTEXPR half copysign(half x, half y) { return half(detail::binary, x.data_^((x.data_^y.data_)&0x8000)); }
4348
4353
4362 inline HALF_CONSTEXPR int fpclassify(half arg)
4363 {
4364 return !(arg.data_&0x7FFF) ? FP_ZERO :
4365 ((arg.data_&0x7FFF)<0x400) ? FP_SUBNORMAL :
4366 ((arg.data_&0x7FFF)<0x7C00) ? FP_NORMAL :
4367 ((arg.data_&0x7FFF)==0x7C00) ? FP_INFINITE :
4368 FP_NAN;
4369 }
4370
4376 inline HALF_CONSTEXPR bool isfinite(half arg) { return (arg.data_&0x7C00) != 0x7C00; }
4377
4383 inline HALF_CONSTEXPR bool isinf(half arg) { return (arg.data_&0x7FFF) == 0x7C00; }
4384
4390 inline HALF_CONSTEXPR bool isnan(half arg) { return (arg.data_&0x7FFF) > 0x7C00; }
4391
4397 inline HALF_CONSTEXPR bool isnormal(half arg) { return ((arg.data_&0x7C00)!=0) & ((arg.data_&0x7C00)!=0x7C00); }
4398
4404 inline HALF_CONSTEXPR bool signbit(half arg) { return (arg.data_&0x8000) != 0; }
4405
4410
4417 inline HALF_CONSTEXPR bool isgreater(half x, half y)
4418 {
4419 return ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) > ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15)) && !isnan(x) && !isnan(y);
4420 }
4421
4428 inline HALF_CONSTEXPR bool isgreaterequal(half x, half y)
4429 {
4430 return ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) >= ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15)) && !isnan(x) && !isnan(y);
4431 }
4432
4439 inline HALF_CONSTEXPR bool isless(half x, half y)
4440 {
4441 return ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) < ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15)) && !isnan(x) && !isnan(y);
4442 }
4443
4450 inline HALF_CONSTEXPR bool islessequal(half x, half y)
4451 {
4452 return ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) <= ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15)) && !isnan(x) && !isnan(y);
4453 }
4454
4461 inline HALF_CONSTEXPR bool islessgreater(half x, half y)
4462 {
4463 return x.data_!=y.data_ && ((x.data_|y.data_)&0x7FFF) && !isnan(x) && !isnan(y);
4464 }
4465
4472 inline HALF_CONSTEXPR bool isunordered(half x, half y) { return isnan(x) || isnan(y); }
4473
4478
4492 template<typename T,typename U> T half_cast(U arg) { return detail::half_caster<T,U>::cast(arg); }
4493
4508 template<typename T,std::float_round_style R,typename U> T half_cast(U arg) { return detail::half_caster<T,U,R>::cast(arg); }
4510
4515
4523 inline int feclearexcept(int excepts) { detail::errflags() &= ~excepts; return 0; }
4524
4532 inline int fetestexcept(int excepts) { return detail::errflags() & excepts; }
4533
4543 inline int feraiseexcept(int excepts) { detail::errflags() |= excepts; detail::raise(excepts); return 0; }
4544
4553 inline int fegetexceptflag(int *flagp, int excepts) { *flagp = detail::errflags() & excepts; return 0; }
4554
4564 inline int fesetexceptflag(const int *flagp, int excepts) { detail::errflags() = (detail::errflags()|(*flagp&excepts)) & (*flagp|~excepts); return 0; }
4565
4577 inline void fethrowexcept(int excepts, const char *msg = "")
4578 {
4579 excepts &= detail::errflags();
4580 if(excepts & (FE_INVALID|FE_DIVBYZERO))
4581 throw std::domain_error(msg);
4582 if(excepts & FE_OVERFLOW)
4583 throw std::overflow_error(msg);
4584 if(excepts & FE_UNDERFLOW)
4585 throw std::underflow_error(msg);
4586 if(excepts & FE_INEXACT)
4587 throw std::range_error(msg);
4588 }
4590}
4591
4592
4593#undef HALF_UNUSED_NOERR
4594#undef HALF_CONSTEXPR
4595#undef HALF_CONSTEXPR_CONST
4596#undef HALF_CONSTEXPR_NOERR
4597#undef HALF_NOEXCEPT
4598#undef HALF_NOTHROW
4599#undef HALF_THREAD_LOCAL
4600#undef HALF_TWOS_COMPLEMENT_INT
4601#ifdef HALF_POP_WARNINGS
4602 #pragma warning(pop)
4603 #undef HALF_POP_WARNINGS
4604#endif
4605
4606#endif
Definition half.hpp:2061
half & operator=(float rhs)
Definition half.hpp:2084
friend half asinh(half)
Definition half.hpp:3885
friend void sincos(half, half *, half *)
Definition half.hpp:3496
friend half exp2(half)
Definition half.hpp:2976
half operator++(int)
Definition half.hpp:2159
friend half tanh(half)
Definition half.hpp:3853
friend long lrint(half)
Definition half.hpp:4123
friend half nanh(const char *)
Definition half.hpp:2920
friend half atanh(half)
Definition half.hpp:3938
friend half atan(half)
Definition half.hpp:3713
half & operator+=(float rhs)
Definition half.hpp:2122
friend half tan(half)
Definition half.hpp:3622
half & operator*=(half rhs)
Definition half.hpp:2109
friend half nearbyint(half)
Definition half.hpp:4130
friend half log1p(half)
Definition half.hpp:3161
friend half pow(half, half)
Definition half.hpp:3432
half & operator*=(float rhs)
Definition half.hpp:2134
friend half remquo(half, half, int *)
Definition half.hpp:2789
HALF_CONSTEXPR half() HALF_NOEXCEPT
Definition half.hpp:2069
friend half sqrt(half)
Definition half.hpp:3211
friend half ceil(half)
Definition half.hpp:4076
friend half erf(half)
Definition half.hpp:3971
friend std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &, half)
Definition half.hpp:2695
friend half atan2(half, half)
Definition half.hpp:3743
friend half modf(half, half *)
Definition half.hpp:4224
friend half operator*(half, half)
Definition half.hpp:2623
friend half sin(half)
Definition half.hpp:3561
friend half trunc(half)
Definition half.hpp:4092
friend half nexttoward(half, long double)
Definition half.hpp:4323
friend half lgamma(half)
Definition half.hpp:4018
friend HALF_CONSTEXPR bool isgreaterequal(half, half)
Definition half.hpp:4428
friend half nextafter(half, half)
Definition half.hpp:4296
friend HALF_CONSTEXPR half copysign(half, half)
Definition half.hpp:4347
friend half operator/(half, half)
Definition half.hpp:2656
friend half tgamma(half)
Definition half.hpp:4043
friend half exp(half)
Definition half.hpp:2941
friend HALF_CONSTEXPR half operator-(half)
Definition half.hpp:2548
friend half log10(half)
Definition half.hpp:3083
friend HALF_CONSTEXPR bool isnan(half)
Definition half.hpp:4390
friend half scalbln(half, long)
Definition half.hpp:4179
friend half frexp(half, int *)
Definition half.hpp:4159
friend half cbrt(half)
Definition half.hpp:3269
friend half log(half)
Definition half.hpp:3055
friend HALF_CONSTEXPR half fabs(half)
Definition half.hpp:2734
friend HALF_CONSTEXPR bool islessgreater(half, half)
Definition half.hpp:4461
friend HALF_CONSTEXPR bool isnormal(half)
Definition half.hpp:4397
friend half fdim(half, half)
Definition half.hpp:2909
friend HALF_CONSTEXPR int fpclassify(half)
Definition half.hpp:4362
friend HALF_CONSTEXPR_NOERR bool operator==(half, half)
Definition half.hpp:2471
friend half cos(half)
Definition half.hpp:3594
half & operator--()
Definition half.hpp:2154
half & operator+=(half rhs)
Definition half.hpp:2095
friend HALF_CONSTEXPR bool isfinite(half)
Definition half.hpp:4376
friend half rsqrt(half)
Definition half.hpp:3232
half & operator/=(float rhs)
Definition half.hpp:2140
friend HALF_CONSTEXPR bool isgreater(half, half)
Definition half.hpp:4417
friend half fmod(half, half)
Definition half.hpp:2748
half(float rhs)
Definition half.hpp:2074
friend HALF_CONSTEXPR bool signbit(half)
Definition half.hpp:4404
friend half acos(half)
Definition half.hpp:3688
friend half remainder(half, half)
Definition half.hpp:2769
friend half cosh(half)
Definition half.hpp:3826
friend HALF_CONSTEXPR_NOERR half fmax(half, half)
Definition half.hpp:2883
friend long lround(half)
Definition half.hpp:4107
half & operator-=(float rhs)
Definition half.hpp:2128
friend HALF_CONSTEXPR_NOERR bool operator<=(half, half)
Definition half.hpp:2517
friend half acosh(half)
Definition half.hpp:3913
friend half log2(half)
Definition half.hpp:3118
friend half round(half)
Definition half.hpp:4100
friend HALF_CONSTEXPR bool isless(half, half)
Definition half.hpp:4439
friend half expm1(half)
Definition half.hpp:3002
friend HALF_CONSTEXPR_NOERR bool operator>=(half, half)
Definition half.hpp:2529
friend half hypot(half, half)
Definition half.hpp:3320
half & operator-=(half rhs)
Definition half.hpp:2102
half & operator/=(half rhs)
Definition half.hpp:2116
friend std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &, half &)
Definition half.hpp:2713
friend HALF_CONSTEXPR_NOERR bool operator!=(half, half)
Definition half.hpp:2482
friend HALF_CONSTEXPR_NOERR bool operator<(half, half)
Definition half.hpp:2493
half & operator++()
Definition half.hpp:2149
friend half erfc(half)
Definition half.hpp:3993
friend half operator+(half, half)
Definition half.hpp:2557
friend half floor(half)
Definition half.hpp:4084
friend HALF_CONSTEXPR_NOERR half fmin(half, half)
Definition half.hpp:2895
half operator--(int)
Definition half.hpp:2164
friend HALF_CONSTEXPR bool isinf(half)
Definition half.hpp:4383
friend int ilogb(half)
Definition half.hpp:4252
friend half fma(half, half, half)
Definition half.hpp:2814
friend half sinh(half)
Definition half.hpp:3798
friend half rint(half)
Definition half.hpp:4115
friend HALF_CONSTEXPR bool islessequal(half, half)
Definition half.hpp:4450
friend half asin(half)
Definition half.hpp:3659
friend half logb(half)
Definition half.hpp:4270
friend HALF_CONSTEXPR_NOERR bool operator>(half, half)
Definition half.hpp:2505
static HALF_CONSTEXPR half_float::half max() HALF_NOTHROW
Largest finite value.
Definition half.hpp:2416
static HALF_CONSTEXPR half_float::half quiet_NaN() HALF_NOTHROW
Quiet NaN.
Definition half.hpp:2429
static HALF_CONSTEXPR half_float::half min() HALF_NOTHROW
Smallest positive normal value.
Definition half.hpp:2410
static HALF_CONSTEXPR half_float::half round_error() HALF_NOTHROW
Maximum rounding error in ULP (units in the last place).
Definition half.hpp:2422
static HALF_CONSTEXPR half_float::half infinity() HALF_NOTHROW
Positive infinity.
Definition half.hpp:2426
static HALF_CONSTEXPR half_float::half epsilon() HALF_NOTHROW
Difference between 1 and next representable value.
Definition half.hpp:2419
static HALF_CONSTEXPR half_float::half lowest() HALF_NOTHROW
Smallest finite value.
Definition half.hpp:2413
static HALF_CONSTEXPR half_float::half signaling_NaN() HALF_NOTHROW
Signaling NaN.
Definition half.hpp:2432
static HALF_CONSTEXPR half_float::half denorm_min() HALF_NOTHROW
Smallest positive subnormal value.
Definition half.hpp:2435
HALF_CONSTEXPR_CONST binary_t binary
Tag for binary construction.
Definition half.hpp:541
unsigned int integral(unsigned int value)
Definition half.hpp:854
uint32 exp2(uint32 m, unsigned int n=32)
Definition half.hpp:1509
bool builtin_signbit(T arg)
Definition half.hpp:583
unsigned int hypot_post(uint32 r, int exp)
Definition half.hpp:1750
bool builtin_isnan(T arg)
Definition half.hpp:567
unsigned short uint16
Unsigned integer of (at least) 16 bits width.
Definition half.hpp:512
HALF_CONSTEXPR_NOERR unsigned int check_underflow(unsigned int arg)
Definition half.hpp:772
unsigned int fixed2half(uint32 m, int exp=14, unsigned int sign=0, int s=0)
Definition half.hpp:889
unsigned int mod(unsigned int x, unsigned int y, int *quo=NULL)
Definition half.hpp:1414
uint32 sqrt(uint32 &r, int &exp)
Definition half.hpp:1485
HALF_CONSTEXPR_NOERR unsigned int select(unsigned int x, unsigned int HALF_UNUSED_NOERR(y))
Definition half.hpp:736
float half2float_impl(unsigned int value, float, true_type)
Definition half.hpp:1101
HALF_CONSTEXPR_NOERR unsigned int overflow(unsigned int sign=0)
Definition half.hpp:789
std::pair< uint32, uint32 > sincos(uint32 mz, unsigned int n=31)
Definition half.hpp:1563
uint32 multiply64(uint32 x, uint32 y)
Definition half.hpp:1371
int & errflags()
Definition half.hpp:625
T half2int(unsigned int value)
Definition half.hpp:1322
uint32 mulhi(uint32 x, uint32 y)
Definition half.hpp:1360
HALF_CONSTEXPR_NOERR bool compsignal(unsigned int x, unsigned int y)
Definition half.hpp:684
uint32 atan2(uint32 my, uint32 mx, unsigned int n=31)
Definition half.hpp:1587
long int32
Fastest unsigned integer of (at least) 32 bits width.
Definition half.hpp:518
unsigned int float2half(T value)
Definition half.hpp:1069
std::pair< uint32, uint32 > hyperbolic_args(unsigned int abs, int &exp, unsigned int n=32)
Definition half.hpp:1655
HALF_CONSTEXPR_NOERR unsigned int underflow(unsigned int sign=0)
Definition half.hpp:805
HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int nan)
Definition half.hpp:696
HALF_CONSTEXPR_NOERR unsigned int invalid()
Definition half.hpp:748
unsigned int gamma(unsigned int arg)
Definition half.hpp:1942
uint32 arithmetic_shift(uint32 arg, int i)
Definition half.hpp:610
std::pair< uint32, uint32 > atan2_args(unsigned int abs)
Definition half.hpp:1632
uint32 log2(uint32 m, unsigned int n=32)
Definition half.hpp:1536
T half2float(unsigned int value)
Definition half.hpp:1308
uint32 divide64(uint32 x, uint32 y, int &s)
Definition half.hpp:1385
void raise(int HALF_UNUSED_NOERR(flags), bool HALF_UNUSED_NOERR(cond)=true)
Definition half.hpp:630
uint32 angle_arg(unsigned int abs, int &k)
Definition half.hpp:1609
unsigned int log2_post(uint32 m, int ilog, int exp, unsigned int sign=0)
Definition half.hpp:1725
unsigned int area(unsigned int arg)
Definition half.hpp:1793
HALF_CONSTEXPR_NOERR unsigned int rounded(unsigned int value, int g, int s)
Definition half.hpp:825
unsigned long uint32
Fastest unsigned integer of (at least) 32 bits width.
Definition half.hpp:515
unsigned int float2half_impl(float value, true_type)
Definition half.hpp:912
uint32 sign_mask(uint32 arg)
Definition half.hpp:596
bool builtin_isinf(T arg)
Definition half.hpp:551
unsigned int erf(unsigned int arg)
Definition half.hpp:1923
unsigned int int2half(T value)
Definition half.hpp:1081
#define HALF_ROUND_STYLE
Definition half.hpp:379
unsigned int tangent_post(uint32 my, uint32 mx, int exp, unsigned int sign=0)
Definition half.hpp:1772
unsigned int exp2_post(uint32 m, int exp, bool esign, unsigned int sign=0, unsigned int n=32)
Definition half.hpp:1693
HALF_CONSTEXPR_NOERR unsigned int pole(unsigned int sign=0)
Definition half.hpp:760
#define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
Definition half.hpp:357
Definition half.hpp:438
half asinh(half arg)
Definition half.hpp:3885
half sinh(half arg)
Definition half.hpp:3798
int feclearexcept(int excepts)
Definition half.hpp:4523
HALF_CONSTEXPR half fabs(half arg)
Definition half.hpp:2734
half nextafter(half from, half to)
Definition half.hpp:4296
half atan(half arg)
Definition half.hpp:3713
half hypot(half x, half y)
Definition half.hpp:3320
HALF_CONSTEXPR bool isunordered(half x, half y)
Definition half.hpp:4472
half fdim(half x, half y)
Definition half.hpp:2909
half remquo(half x, half y, int *quo)
Definition half.hpp:2789
int fegetexceptflag(int *flagp, int excepts)
Definition half.hpp:4553
int ilogb(half arg)
Definition half.hpp:4252
half lgamma(half arg)
Definition half.hpp:4018
HALF_CONSTEXPR half copysign(half x, half y)
Definition half.hpp:4347
HALF_CONSTEXPR bool isfinite(half arg)
Definition half.hpp:4376
int fesetexceptflag(const int *flagp, int excepts)
Definition half.hpp:4564
HALF_CONSTEXPR half abs(half arg)
Definition half.hpp:2740
half fma(half x, half y, half z)
Definition half.hpp:2814
HALF_CONSTEXPR_NOERR half fmin(half x, half y)
Definition half.hpp:2895
half nearbyint(half arg)
Definition half.hpp:4130
half expm1(half arg)
Definition half.hpp:3002
half ldexp(half arg, int exp)
Definition half.hpp:4216
half sin(half arg)
Definition half.hpp:3561
half tanh(half arg)
Definition half.hpp:3853
half rint(half arg)
Definition half.hpp:4115
HALF_CONSTEXPR_NOERR bool operator!=(half x, half y)
Definition half.hpp:2482
HALF_CONSTEXPR_NOERR half fmax(half x, half y)
Definition half.hpp:2883
HALF_CONSTEXPR_NOERR bool operator<(half x, half y)
Definition half.hpp:2493
HALF_CONSTEXPR half operator-(half arg)
Definition half.hpp:2548
T half_cast(U arg)
Definition half.hpp:4492
half fmod(half x, half y)
Definition half.hpp:2748
half log(half arg)
Definition half.hpp:3055
half cos(half arg)
Definition half.hpp:3594
half scalbn(half arg, int exp)
Definition half.hpp:4205
half exp2(half arg)
Definition half.hpp:2976
HALF_CONSTEXPR int fpclassify(half arg)
Definition half.hpp:4362
HALF_CONSTEXPR_NOERR bool operator>=(half x, half y)
Definition half.hpp:2529
half atanh(half arg)
Definition half.hpp:3938
std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &in, half &arg)
Definition half.hpp:2713
half nexttoward(half from, long double to)
Definition half.hpp:4323
half round(half arg)
Definition half.hpp:4100
half log2(half arg)
Definition half.hpp:3118
HALF_CONSTEXPR bool isgreater(half x, half y)
Definition half.hpp:4417
half asin(half arg)
Definition half.hpp:3659
half sqrt(half arg)
Definition half.hpp:3211
half trunc(half arg)
Definition half.hpp:4092
half erfc(half arg)
Definition half.hpp:3993
half tan(half arg)
Definition half.hpp:3622
HALF_CONSTEXPR half operator+(half arg)
Definition half.hpp:2543
std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &out, half arg)
Definition half.hpp:2695
half log10(half arg)
Definition half.hpp:3083
half rsqrt(half arg)
Definition half.hpp:3232
HALF_CONSTEXPR bool signbit(half arg)
Definition half.hpp:4404
half floor(half arg)
Definition half.hpp:4084
half acosh(half arg)
Definition half.hpp:3913
HALF_CONSTEXPR bool isnan(half arg)
Definition half.hpp:4390
HALF_CONSTEXPR_NOERR bool operator<=(half x, half y)
Definition half.hpp:2517
half operator*(half x, half y)
Definition half.hpp:2623
HALF_CONSTEXPR bool isnormal(half arg)
Definition half.hpp:4397
half atan2(half y, half x)
Definition half.hpp:3743
int feraiseexcept(int excepts)
Definition half.hpp:4543
HALF_CONSTEXPR bool isless(half x, half y)
Definition half.hpp:4439
half scalbln(half arg, long exp)
Definition half.hpp:4179
half tgamma(half arg)
Definition half.hpp:4043
HALF_CONSTEXPR_NOERR bool operator==(half x, half y)
Definition half.hpp:2471
long lrint(half arg)
Definition half.hpp:4123
HALF_CONSTEXPR bool isinf(half arg)
Definition half.hpp:4383
HALF_CONSTEXPR_NOERR bool operator>(half x, half y)
Definition half.hpp:2505
half cosh(half arg)
Definition half.hpp:3826
half logb(half arg)
Definition half.hpp:4270
half erf(half arg)
Definition half.hpp:3971
void sincos(half arg, half *sin, half *cos)
Definition half.hpp:3496
half ceil(half arg)
Definition half.hpp:4076
half frexp(half arg, int *exp)
Definition half.hpp:4159
half log1p(half arg)
Definition half.hpp:3161
HALF_CONSTEXPR bool islessgreater(half x, half y)
Definition half.hpp:4461
long lround(half arg)
Definition half.hpp:4107
half acos(half arg)
Definition half.hpp:3688
HALF_CONSTEXPR bool islessequal(half x, half y)
Definition half.hpp:4450
half pow(half x, half y)
Definition half.hpp:3432
half nanh(const char *arg)
Definition half.hpp:2920
half modf(half arg, half *iptr)
Definition half.hpp:4224
half cbrt(half arg)
Definition half.hpp:3269
void fethrowexcept(int excepts, const char *msg="")
Definition half.hpp:4577
HALF_CONSTEXPR bool isgreaterequal(half x, half y)
Definition half.hpp:4428
int fetestexcept(int excepts)
Definition half.hpp:4532
half exp(half arg)
Definition half.hpp:2941
half remainder(half x, half y)
Definition half.hpp:2769
half operator/(half x, half y)
Definition half.hpp:2656
Extensions to the C++ standard library.
Definition half.hpp:2330
Tag type for binary construction.
Definition half.hpp:538
Type traits for floating-point bits.
Definition half.hpp:490
Helper for tag dispatching.
Definition half.hpp:475
Conditional type.
Definition half.hpp:471
Class for 1.31 unsigned floating-point computation.
Definition half.hpp:1844
friend f31 operator-(f31 a, f31 b)
Definition half.hpp:1877
int exp
exponent.
Definition half.hpp:1910
friend f31 operator*(f31 a, f31 b)
Definition half.hpp:1891
friend f31 operator/(f31 a, f31 b)
Definition half.hpp:1902
friend f31 operator+(f31 a, f31 b)
Definition half.hpp:1863
f31(unsigned int abs)
Definition half.hpp:1852
HALF_CONSTEXPR f31(uint32 mant, int e)
Definition half.hpp:1848
uint32 m
mantissa as 1.31.
Definition half.hpp:1909
Definition half.hpp:2296
Type traits for floating-point types.
Definition half.hpp:480