WarpTwin
Documentation for WarpTwin models and classes.
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-2025 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.1
18
21
22#ifndef HALF_HALF_HPP
23#define HALF_HALF_HPP
24
25#define HALF_GCC_VERSION (__GNUC__*100+__GNUC_MINOR__)
26
27#if defined(__INTEL_COMPILER)
28 #define HALF_ICC_VERSION __INTEL_COMPILER
29#elif defined(__ICC)
30 #define HALF_ICC_VERSION __ICC
31#elif defined(__ICL)
32 #define HALF_ICC_VERSION __ICL
33#else
34 #define HALF_ICC_VERSION 0
35#endif
36
37// check C++11 language features
38#if defined(__clang__) // clang
39 #if __has_feature(cxx_static_assert) && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
40 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
41 #endif
42 #if __has_feature(cxx_constexpr) && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
43 #define HALF_ENABLE_CPP11_CONSTEXPR 1
44 #endif
45 #if __has_feature(cxx_noexcept) && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
46 #define HALF_ENABLE_CPP11_NOEXCEPT 1
47 #endif
48 #if __has_feature(cxx_user_literals) && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
49 #define HALF_ENABLE_CPP11_USER_LITERALS 1
50 #endif
51 #if __has_feature(cxx_thread_local) && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
52 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
53 #endif
54 #if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) && !defined(HALF_ENABLE_CPP11_LONG_LONG)
55 #define HALF_ENABLE_CPP11_LONG_LONG 1
56 #endif
57#elif HALF_ICC_VERSION && defined(__INTEL_CXX11_MODE__) // Intel C++
58 #if HALF_ICC_VERSION >= 1500 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
59 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
60 #endif
61 #if HALF_ICC_VERSION >= 1500 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
62 #define HALF_ENABLE_CPP11_USER_LITERALS 1
63 #endif
64 #if HALF_ICC_VERSION >= 1400 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
65 #define HALF_ENABLE_CPP11_CONSTEXPR 1
66 #endif
67 #if HALF_ICC_VERSION >= 1400 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
68 #define HALF_ENABLE_CPP11_NOEXCEPT 1
69 #endif
70 #if HALF_ICC_VERSION >= 1110 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
71 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
72 #endif
73 #if HALF_ICC_VERSION >= 1110 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
74 #define HALF_ENABLE_CPP11_LONG_LONG 1
75 #endif
76#elif defined(__GNUC__) // gcc
77 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
78 #if HALF_GCC_VERSION >= 408 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
79 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
80 #endif
81 #if HALF_GCC_VERSION >= 407 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
82 #define HALF_ENABLE_CPP11_USER_LITERALS 1
83 #endif
84 #if HALF_GCC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
85 #define HALF_ENABLE_CPP11_CONSTEXPR 1
86 #endif
87 #if HALF_GCC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
88 #define HALF_ENABLE_CPP11_NOEXCEPT 1
89 #endif
90 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
91 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
92 #endif
93 #if !defined(HALF_ENABLE_CPP11_LONG_LONG)
94 #define HALF_ENABLE_CPP11_LONG_LONG 1
95 #endif
96 #endif
97 #define HALF_TWOS_COMPLEMENT_INT 1
98#elif defined(_MSC_VER) // Visual C++
99 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_THREAD_LOCAL)
100 #define HALF_ENABLE_CPP11_THREAD_LOCAL 1
101 #endif
102 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_USER_LITERALS)
103 #define HALF_ENABLE_CPP11_USER_LITERALS 1
104 #endif
105 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_CONSTEXPR)
106 #define HALF_ENABLE_CPP11_CONSTEXPR 1
107 #endif
108 #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_NOEXCEPT)
109 #define HALF_ENABLE_CPP11_NOEXCEPT 1
110 #endif
111 #if _MSC_VER >= 1600 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT)
112 #define HALF_ENABLE_CPP11_STATIC_ASSERT 1
113 #endif
114 #if _MSC_VER >= 1310 && !defined(HALF_ENABLE_CPP11_LONG_LONG)
115 #define HALF_ENABLE_CPP11_LONG_LONG 1
116 #endif
117 #define HALF_TWOS_COMPLEMENT_INT 1
118 #define HALF_POP_WARNINGS 1
119 #pragma warning(push)
120 #pragma warning(disable : 4099 4127 4146) //struct vs class, constant in if, negative unsigned
121#endif
122
123// check C++11 library features
124#include <utility>
125#if defined(_LIBCPP_VERSION) // libc++
126 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
127 #ifndef HALF_ENABLE_CPP11_TYPE_TRAITS
128 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
129 #endif
130 #ifndef HALF_ENABLE_CPP11_CSTDINT
131 #define HALF_ENABLE_CPP11_CSTDINT 1
132 #endif
133 #ifndef HALF_ENABLE_CPP11_CMATH
134 #define HALF_ENABLE_CPP11_CMATH 1
135 #endif
136 #ifndef HALF_ENABLE_CPP11_HASH
137 #define HALF_ENABLE_CPP11_HASH 1
138 #endif
139 #ifndef HALF_ENABLE_CPP11_CFENV
140 #define HALF_ENABLE_CPP11_CFENV 1
141 #endif
142 #endif
143#elif defined(__GLIBCXX__) // libstdc++
144 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103
145 #ifdef __clang__
146 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
147 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
148 #endif
149 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CSTDINT)
150 #define HALF_ENABLE_CPP11_CSTDINT 1
151 #endif
152 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CMATH)
153 #define HALF_ENABLE_CPP11_CMATH 1
154 #endif
155 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_HASH)
156 #define HALF_ENABLE_CPP11_HASH 1
157 #endif
158 #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CFENV)
159 #define HALF_ENABLE_CPP11_CFENV 1
160 #endif
161 #else
162 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
163 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
164 #endif
165 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CSTDINT)
166 #define HALF_ENABLE_CPP11_CSTDINT 1
167 #endif
168 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CMATH)
169 #define HALF_ENABLE_CPP11_CMATH 1
170 #endif
171 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_HASH)
172 #define HALF_ENABLE_CPP11_HASH 1
173 #endif
174 #if HALF_GCC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CFENV)
175 #define HALF_ENABLE_CPP11_CFENV 1
176 #endif
177 #endif
178 #endif
179#elif defined(_CPPLIB_VER) // Dinkumware/Visual C++
180 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS)
181 #define HALF_ENABLE_CPP11_TYPE_TRAITS 1
182 #endif
183 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_CSTDINT)
184 #define HALF_ENABLE_CPP11_CSTDINT 1
185 #endif
186 #if _CPPLIB_VER >= 520 && !defined(HALF_ENABLE_CPP11_HASH)
187 #define HALF_ENABLE_CPP11_HASH 1
188 #endif
189 #if _CPPLIB_VER >= 610 && !defined(HALF_ENABLE_CPP11_CMATH)
190 #define HALF_ENABLE_CPP11_CMATH 1
191 #endif
192 #if _CPPLIB_VER >= 610 && !defined(HALF_ENABLE_CPP11_CFENV)
193 #define HALF_ENABLE_CPP11_CFENV 1
194 #endif
195#endif
196#undef HALF_GCC_VERSION
197#undef HALF_ICC_VERSION
198
199// any error throwing C++ exceptions?
200#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)
201#define HALF_ERRHANDLING_THROWS 1
202#endif
203
204// any error handling enabled?
205#define HALF_ERRHANDLING (HALF_ERRHANDLING_FLAGS||HALF_ERRHANDLING_ERRNO||HALF_ERRHANDLING_FENV||HALF_ERRHANDLING_THROWS)
206
207#if HALF_ERRHANDLING
208 #define HALF_UNUSED_NOERR(name) name
209#else
210 #define HALF_UNUSED_NOERR(name)
211#endif
212
213// support constexpr
214#if HALF_ENABLE_CPP11_CONSTEXPR
215 #define HALF_CONSTEXPR constexpr
216 #define HALF_CONSTEXPR_CONST constexpr
217 #if HALF_ERRHANDLING
218 #define HALF_CONSTEXPR_NOERR
219 #else
220 #define HALF_CONSTEXPR_NOERR constexpr
221 #endif
222#else
223 #define HALF_CONSTEXPR
224 #define HALF_CONSTEXPR_CONST const
225 #define HALF_CONSTEXPR_NOERR
226#endif
227
228// support noexcept
229#if HALF_ENABLE_CPP11_NOEXCEPT
230 #define HALF_NOEXCEPT noexcept
231 #define HALF_NOTHROW noexcept
232#else
233 #define HALF_NOEXCEPT
234 #define HALF_NOTHROW throw()
235#endif
236
237// support thread storage
238#if HALF_ENABLE_CPP11_THREAD_LOCAL
239 #define HALF_THREAD_LOCAL thread_local
240#else
241 #define HALF_THREAD_LOCAL static
242#endif
243
244#include <utility>
245#include <algorithm>
246#include <istream>
247#include <ostream>
248#include <limits>
249#include <stdexcept>
250#include <climits>
251#include <cmath>
252#include <cstring>
253#include <cstdlib>
254#if HALF_ENABLE_CPP11_TYPE_TRAITS
255 #include <type_traits>
256#endif
257#if HALF_ENABLE_CPP11_CSTDINT
258 #include <cstdint>
259#endif
260#if HALF_ERRHANDLING_ERRNO
261 #include <cerrno>
262#endif
263#if HALF_ENABLE_CPP11_CFENV
264 #include <cfenv>
265#endif
266#if HALF_ENABLE_CPP11_HASH
267 #include <functional>
268#endif
269
270
271#ifndef HALF_ENABLE_F16C_INTRINSICS
278 #define HALF_ENABLE_F16C_INTRINSICS __F16C__
279#endif
280#if HALF_ENABLE_F16C_INTRINSICS
281 #include <immintrin.h>
282#endif
283
284#ifdef HALF_DOXYGEN_ONLY
290#define HALF_ARITHMETIC_TYPE (undefined)
291
295#define HALF_ERRHANDLING_FLAGS 0
296
302#define HALF_ERRHANDLING_ERRNO 0
303
310#define HALF_ERRHANDLING_FENV 0
311
315#define HALF_ERRHANDLING_THROW_INVALID (undefined)
316
320#define HALF_ERRHANDLING_THROW_DIVBYZERO (undefined)
321
325#define HALF_ERRHANDLING_THROW_OVERFLOW (undefined)
326
330#define HALF_ERRHANDLING_THROW_UNDERFLOW (undefined)
331
335#define HALF_ERRHANDLING_THROW_INEXACT (undefined)
336#endif
337
338#ifndef HALF_ERRHANDLING_OVERFLOW_TO_INEXACT
342#define HALF_ERRHANDLING_OVERFLOW_TO_INEXACT 1
343#endif
344
345#ifndef HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
352#define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT 1
353#endif
354
373#ifndef HALF_ROUND_STYLE
374 #define HALF_ROUND_STYLE 1 // = std::round_to_nearest
375#endif
376
382#define HUGE_VALH std::numeric_limits<half_float::half>::infinity()
383
389#define FP_FAST_FMAH 1
390
396#define HLF_ROUNDS HALF_ROUND_STYLE
397
398#ifndef FP_ILOGB0
399 #define FP_ILOGB0 INT_MIN
400#endif
401#ifndef FP_ILOGBNAN
402 #define FP_ILOGBNAN INT_MAX
403#endif
404#ifndef FP_SUBNORMAL
405 #define FP_SUBNORMAL 0
406#endif
407#ifndef FP_ZERO
408 #define FP_ZERO 1
409#endif
410#ifndef FP_NAN
411 #define FP_NAN 2
412#endif
413#ifndef FP_INFINITE
414 #define FP_INFINITE 3
415#endif
416#ifndef FP_NORMAL
417 #define FP_NORMAL 4
418#endif
419
420#if !HALF_ENABLE_CPP11_CFENV && !defined(FE_ALL_EXCEPT)
421 #define FE_INVALID 0x10
422 #define FE_DIVBYZERO 0x08
423 #define FE_OVERFLOW 0x04
424 #define FE_UNDERFLOW 0x02
425 #define FE_INEXACT 0x01
426 #define FE_ALL_EXCEPT (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW|FE_INEXACT)
427#endif
428
429
432namespace half_float
433{
434 class half;
435
436#if HALF_ENABLE_CPP11_USER_LITERALS
443 namespace literal
444 {
445 half operator "" _h(long double);
446 }
447#endif
448
451 namespace detail
452 {
453 #if HALF_ENABLE_CPP11_TYPE_TRAITS
455 template<bool B,typename T,typename F> struct conditional : std::conditional<B,T,F> {};
456
458 template<bool B> struct bool_type : std::integral_constant<bool,B> {};
459 using std::true_type;
460 using std::false_type;
461
463 template<typename T> struct is_float : std::is_floating_point<T> {};
464 #else
466 template<bool,typename T,typename> struct conditional { typedef T type; };
467 template<typename T,typename F> struct conditional<false,T,F> { typedef F type; };
468
470 template<bool> struct bool_type {};
473
475 template<typename> struct is_float : false_type {};
476 template<typename T> struct is_float<const T> : is_float<T> {};
477 template<typename T> struct is_float<volatile T> : is_float<T> {};
478 template<typename T> struct is_float<const volatile T> : is_float<T> {};
479 template<> struct is_float<float> : true_type {};
480 template<> struct is_float<double> : true_type {};
481 template<> struct is_float<long double> : true_type {};
482 #endif
483
485 template<typename T> struct bits { typedef unsigned char type; };
486 template<typename T> struct bits<const T> : bits<T> {};
487 template<typename T> struct bits<volatile T> : bits<T> {};
488 template<typename T> struct bits<const volatile T> : bits<T> {};
489
490 #if HALF_ENABLE_CPP11_CSTDINT
492 typedef std::uint_least16_t uint16;
493
495 typedef std::uint_fast32_t uint32;
496
498 typedef std::int_fast32_t int32;
499
501 template<> struct bits<float> { typedef std::uint_least32_t type; };
502
504 template<> struct bits<double> { typedef std::uint_least64_t type; };
505 #else
507 typedef unsigned short uint16;
508
510 typedef unsigned long uint32;
511
513 typedef long int32;
514
516 template<> struct bits<float> : conditional<std::numeric_limits<unsigned int>::digits>=32,unsigned int,unsigned long> {};
517
518 #if HALF_ENABLE_CPP11_LONG_LONG
520 template<> struct bits<double> : conditional<std::numeric_limits<unsigned long>::digits>=64,unsigned long,unsigned long long> {};
521 #else
523 template<> struct bits<double> { typedef unsigned long type; };
524 #endif
525 #endif
526
527 #ifdef HALF_ARITHMETIC_TYPE
529 typedef HALF_ARITHMETIC_TYPE internal_t;
530 #endif
531
533 struct binary_t {};
534
537
540
546 template<typename T> bool builtin_isinf(T arg)
547 {
548 #if HALF_ENABLE_CPP11_CMATH
549 return std::isinf(arg);
550 #elif defined(_MSC_VER)
551 return !::_finite(static_cast<double>(arg)) && !::_isnan(static_cast<double>(arg));
552 #else
553 return arg == std::numeric_limits<T>::infinity() || arg == -std::numeric_limits<T>::infinity();
554 #endif
555 }
556
562 template<typename T> bool builtin_isnan(T arg)
563 {
564 #if HALF_ENABLE_CPP11_CMATH
565 return std::isnan(arg);
566 #elif defined(_MSC_VER)
567 return ::_isnan(static_cast<double>(arg)) != 0;
568 #else
569 return arg != arg;
570 #endif
571 }
572
578 template<typename T> bool builtin_signbit(T arg)
579 {
580 #if HALF_ENABLE_CPP11_CMATH
581 return std::signbit(arg);
582 #else
583 return arg < T() || (arg == T() && T(1)/arg < T());
584 #endif
585 }
586
592 {
593 static const int N = std::numeric_limits<uint32>::digits - 1;
594 #if HALF_TWOS_COMPLEMENT_INT
595 return static_cast<int32>(arg) >> N;
596 #else
597 return -((arg>>N)&1);
598 #endif
599 }
600
605 inline uint32 arithmetic_shift(uint32 arg, int i)
606 {
607 #if HALF_TWOS_COMPLEMENT_INT
608 return static_cast<int32>(arg) >> i;
609 #else
610 return static_cast<int32>(arg)/(static_cast<int32>(1)<<i) - ((arg>>(std::numeric_limits<uint32>::digits-1))&1);
611 #endif
612 }
613
617
620 inline int& errflags() { HALF_THREAD_LOCAL int flags = 0; return flags; }
621
625 inline void raise(int HALF_UNUSED_NOERR(flags), bool HALF_UNUSED_NOERR(cond) = true)
626 {
627 #if HALF_ERRHANDLING
628 if(!cond)
629 return;
630 #if HALF_ERRHANDLING_FLAGS
631 errflags() |= flags;
632 #endif
633 #if HALF_ERRHANDLING_ERRNO
634 if(flags & FE_INVALID)
635 errno = EDOM;
636 else if(flags & (FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW))
637 errno = ERANGE;
638 #endif
639 #if HALF_ERRHANDLING_FENV && HALF_ENABLE_CPP11_CFENV
640 std::feraiseexcept(flags);
641 #endif
642 #ifdef HALF_ERRHANDLING_THROW_INVALID
643 if(flags & FE_INVALID)
644 throw std::domain_error(HALF_ERRHANDLING_THROW_INVALID);
645 #endif
646 #ifdef HALF_ERRHANDLING_THROW_DIVBYZERO
647 if(flags & FE_DIVBYZERO)
648 throw std::domain_error(HALF_ERRHANDLING_THROW_DIVBYZERO);
649 #endif
650 #ifdef HALF_ERRHANDLING_THROW_OVERFLOW
651 if(flags & FE_OVERFLOW)
652 throw std::overflow_error(HALF_ERRHANDLING_THROW_OVERFLOW);
653 #endif
654 #ifdef HALF_ERRHANDLING_THROW_UNDERFLOW
655 if(flags & FE_UNDERFLOW)
656 throw std::underflow_error(HALF_ERRHANDLING_THROW_UNDERFLOW);
657 #endif
658 #ifdef HALF_ERRHANDLING_THROW_INEXACT
659 if(flags & FE_INEXACT)
660 throw std::range_error(HALF_ERRHANDLING_THROW_INEXACT);
661 #endif
662 #if HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
663 if((flags & FE_UNDERFLOW) && !(flags & FE_INEXACT))
665 #endif
666 #if HALF_ERRHANDLING_OVERFLOW_TO_INEXACT
667 if((flags & FE_OVERFLOW) && !(flags & FE_INEXACT))
669 #endif
670 #endif
671 }
672
679 inline HALF_CONSTEXPR_NOERR bool compsignal(unsigned int x, unsigned int y)
680 {
681 #if HALF_ERRHANDLING
682 detail::raise(FE_INVALID, (x&0x7FFF)>0x7C00 || (y&0x7FFF)>0x7C00);
683 #endif
684 return (x&0x7FFF) > 0x7C00 || (y&0x7FFF) > 0x7C00;
685 }
686
691 inline HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int nan)
692 {
693 #if HALF_ERRHANDLING
694 detail::raise(FE_INVALID, !(nan&0x200));
695 #endif
696 return nan | 0x200;
697 }
698
704 inline HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int x, unsigned int y)
705 {
706 #if HALF_ERRHANDLING
707 detail::raise(FE_INVALID, ((x&0x7FFF)>0x7C00 && !(x&0x200)) || ((y&0x7FFF)>0x7C00 && !(y&0x200)));
708 #endif
709 return ((x&0x7FFF)>0x7C00) ? (x|0x200) : (y|0x200);
710 }
711
718 inline HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int x, unsigned int y, unsigned int z)
719 {
720 #if HALF_ERRHANDLING
721 detail::raise(FE_INVALID, ((x&0x7FFF)>0x7C00 && !(x&0x200)) || ((y&0x7FFF)>0x7C00 && !(y&0x200)) || ((z&0x7FFF)>0x7C00 && !(z&0x200)));
722 #endif
723 return ((x&0x7FFF)>0x7C00) ? (x|0x200) : ((y&0x7FFF)>0x7C00) ? (y|0x200) : (z|0x200);
724 }
725
731 inline HALF_CONSTEXPR_NOERR unsigned int select(unsigned int x, unsigned int HALF_UNUSED_NOERR(y))
732 {
733 #if HALF_ERRHANDLING
734 return (((y&0x7FFF)>0x7C00) && !(y&0x200)) ? detail::signal(y) : x;
735 #else
736 return x;
737 #endif
738 }
739
743 inline HALF_CONSTEXPR_NOERR unsigned int invalid()
744 {
745 #if HALF_ERRHANDLING
747 #endif
748 return 0x7FFF;
749 }
750
755 inline HALF_CONSTEXPR_NOERR unsigned int pole(unsigned int sign = 0)
756 {
757 #if HALF_ERRHANDLING
759 #endif
760 return sign | 0x7C00;
761 }
762
767 inline HALF_CONSTEXPR_NOERR unsigned int check_underflow(unsigned int arg)
768 {
769 #if HALF_ERRHANDLING && !HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
770 detail::raise(FE_UNDERFLOW, !(arg&0x7C00));
771 #endif
772 return arg;
773 }
774
778
784 template<std::float_round_style R> HALF_CONSTEXPR_NOERR unsigned int overflow(unsigned int sign = 0)
785 {
786 #if HALF_ERRHANDLING
788 #endif
789 return (R==std::round_toward_infinity) ? (sign+0x7C00-(sign>>15)) :
790 (R==std::round_toward_neg_infinity) ? (sign+0x7BFF+(sign>>15)) :
791 (R==std::round_toward_zero) ? (sign|0x7BFF) :
792 (sign|0x7C00);
793 }
794
800 template<std::float_round_style R> HALF_CONSTEXPR_NOERR unsigned int underflow(unsigned int sign = 0)
801 {
802 #if HALF_ERRHANDLING
804 #endif
805 return (R==std::round_toward_infinity) ? (sign+1-(sign>>15)) :
806 (R==std::round_toward_neg_infinity) ? (sign+(sign>>15)) :
807 sign;
808 }
809
820 template<std::float_round_style R,bool I> HALF_CONSTEXPR_NOERR unsigned int rounded(unsigned int value, int g, int s)
821 {
822 #if HALF_ERRHANDLING
823 value += (R==std::round_to_nearest) ? (g&(s|value)) :
824 (R==std::round_toward_infinity) ? (~(value>>15)&(g|s)) :
825 (R==std::round_toward_neg_infinity) ? ((value>>15)&(g|s)) : 0;
826 if((value&0x7C00) == 0x7C00)
828 else if(value & 0x7C00)
829 detail::raise(FE_INEXACT, I || (g|s)!=0);
830 else
832 return value;
833 #else
834 return (R==std::round_to_nearest) ? (value+(g&(s|value))) :
835 (R==std::round_toward_infinity) ? (value+(~(value>>15)&(g|s))) :
836 (R==std::round_toward_neg_infinity) ? (value+((value>>15)&(g|s))) :
837 value;
838 #endif
839 }
840
849 template<std::float_round_style R,bool E,bool I> unsigned int integral(unsigned int value)
850 {
851 unsigned int abs = value & 0x7FFF;
852 if(abs < 0x3C00)
853 {
855 return ((R==std::round_to_nearest) ? (0x3C00&-static_cast<unsigned>(abs>=(0x3800+E))) :
856 (R==std::round_toward_infinity) ? (0x3C00&-(~(value>>15)&(abs!=0))) :
857 (R==std::round_toward_neg_infinity) ? (0x3C00&-static_cast<unsigned>(value>0x8000)) :
858 0) | (value&0x8000);
859 }
860 if(abs >= 0x6400)
861 return (abs>0x7C00) ? detail::signal(value) : value;
862 unsigned int exp = 25 - (abs>>10), mask = (1<<exp) - 1;
863 detail::raise(FE_INEXACT, I && (value&mask));
864 return (( (R==std::round_to_nearest) ? ((1<<(exp-1))-(~(value>>exp)&E)) :
865 (R==std::round_toward_infinity) ? (mask&((value>>15)-1)) :
866 (R==std::round_toward_neg_infinity) ? (mask&-(value>>15)) :
867 0) + value) & ~mask;
868 }
869
884 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)
885 {
886 if(S)
887 {
888 uint32 msign = sign_mask(m);
889 m = (m^msign) - msign;
890 sign = msign & 0x8000;
891 }
892 if(N)
893 for(; m<(static_cast<uint32>(1)<<F) && exp; m<<=1,--exp) ;
894 else if(exp < 0)
895 return rounded<R,I>(sign+static_cast<unsigned int>(m>>(F-10-exp)), static_cast<int>((m>>(F-11-exp))&1), s|((m&((static_cast<uint32>(1)<<(F-11-exp))-1))!=0));
896 return rounded<R,I>(sign+(exp<<10)+static_cast<unsigned int>(m>>(F-10)), static_cast<int>((m>>(F-11))&1), s|((m&((static_cast<uint32>(1)<<(F-11))-1))!=0));
897 }
898
907 template<std::float_round_style R> unsigned int float2half_impl(float value, true_type)
908 {
909 #if HALF_ENABLE_F16C_INTRINSICS
910 return _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_set_ss(value),
911 (R==std::round_to_nearest) ? _MM_FROUND_TO_NEAREST_INT :
912 (R==std::round_toward_zero) ? _MM_FROUND_TO_ZERO :
913 (R==std::round_toward_infinity) ? _MM_FROUND_TO_POS_INF :
914 (R==std::round_toward_neg_infinity) ? _MM_FROUND_TO_NEG_INF :
915 _MM_FROUND_CUR_DIRECTION));
916 #else
917 bits<float>::type fbits;
918 std::memcpy(&fbits, &value, sizeof(float));
919 #if 1
920 unsigned int sign = (fbits>>16) & 0x8000;
921 fbits &= 0x7FFFFFFF;
922 if(fbits >= 0x7F800000)
923 return sign | 0x7C00 | ((fbits>0x7F800000) ? (0x200|((fbits>>13)&0x3FF)) : 0);
924 if(fbits >= 0x47800000)
925 return overflow<R>(sign);
926 if(fbits >= 0x38800000)
927 return rounded<R,false>(sign|(((fbits>>23)-112)<<10)|((fbits>>13)&0x3FF), (fbits>>12)&1, (fbits&0xFFF)!=0);
928 if(fbits >= 0x33000000)
929 {
930 int i = 125 - (fbits>>23);
931 fbits = (fbits&0x7FFFFF) | 0x800000;
932 return rounded<R,false>(sign|(fbits>>(i+1)), (fbits>>i)&1, (fbits&((static_cast<uint32>(1)<<i)-1))!=0);
933 }
934 if(fbits != 0)
935 return underflow<R>(sign);
936 return sign;
937 #else
938 static const uint16 base_table[512] = {
939 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
940 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
941 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
942 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
943 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
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, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
946 0x0200, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00,
947 0x4000, 0x4400, 0x4800, 0x4C00, 0x5000, 0x5400, 0x5800, 0x5C00, 0x6000, 0x6400, 0x6800, 0x6C00, 0x7000, 0x7400, 0x7800, 0x7BFF,
948 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
949 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
950 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
951 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF,
952 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 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, 0x7C00,
955 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
956 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
957 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
958 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
959 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
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, 0x8001, 0x8002, 0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100,
962 0x8200, 0x8400, 0x8800, 0x8C00, 0x9000, 0x9400, 0x9800, 0x9C00, 0xA000, 0xA400, 0xA800, 0xAC00, 0xB000, 0xB400, 0xB800, 0xBC00,
963 0xC000, 0xC400, 0xC800, 0xCC00, 0xD000, 0xD400, 0xD800, 0xDC00, 0xE000, 0xE400, 0xE800, 0xEC00, 0xF000, 0xF400, 0xF800, 0xFBFF,
964 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
965 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
966 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
967 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF,
968 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 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, 0xFC00 };
971 static const unsigned char shift_table[256] = {
972 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,
973 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,
974 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,
975 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,
976 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,
977 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
978 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
979 24, 24, 24, 24, 24, 24, 24, 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 };
980 int sexp = fbits >> 23, exp = sexp & 0xFF, i = shift_table[exp];
981 fbits &= 0x7FFFFF;
982 uint32 m = (fbits|((exp!=0)<<23)) & -static_cast<uint32>(exp!=0xFF);
983 return rounded<R,false>(base_table[sexp]+(fbits>>i), (m>>(i-1))&1, (((static_cast<uint32>(1)<<(i-1))-1)&m)!=0);
984 #endif
985 #endif
986 }
987
995 template<std::float_round_style R> unsigned int float2half_impl(double value, true_type)
996 {
997 #if HALF_ENABLE_F16C_INTRINSICS
998 if(R == std::round_indeterminate)
999 return _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_cvtpd_ps(_mm_set_sd(value)), _MM_FROUND_CUR_DIRECTION));
1000 #endif
1001 bits<double>::type dbits;
1002 std::memcpy(&dbits, &value, sizeof(double));
1003 uint32 hi = dbits >> 32, lo = dbits & 0xFFFFFFFF;
1004 unsigned int sign = (hi>>16) & 0x8000;
1005 hi &= 0x7FFFFFFF;
1006 if(hi >= 0x7FF00000)
1007 return sign | 0x7C00 | ((dbits&0xFFFFFFFFFFFFF) ? (0x200|((hi>>10)&0x3FF)) : 0);
1008 if(hi >= 0x40F00000)
1009 return overflow<R>(sign);
1010 if(hi >= 0x3F100000)
1011 return rounded<R,false>(sign|static_cast<unsigned int>(((hi>>20)-1008)<<10)|static_cast<unsigned int>((hi>>10)&0x3FF), static_cast<unsigned int>((hi>>9)&1), ((hi&0x1FF)|lo)!=0);
1012 if(hi >= 0x3E600000)
1013 {
1014 int i = static_cast<int>(1018 - (hi>>20));
1015 hi = (hi&0xFFFFF) | 0x100000;
1016 return rounded<R,false>(sign|static_cast<unsigned int>(hi>>(i+1)), static_cast<unsigned int>((hi>>i)&1), ((hi&((static_cast<uint32>(1)<<i)-1))|lo)!=0);
1017 }
1018 if((hi|lo) != 0)
1019 return underflow<R>(sign);
1020 return sign;
1021 }
1022
1031 template<std::float_round_style R,typename T> unsigned int float2half_impl(T value, ...)
1032 {
1033 unsigned int hbits = static_cast<unsigned>(builtin_signbit(value)) << 15;
1034 if(value == T())
1035 return hbits;
1036 if(builtin_isnan(value))
1037 return hbits | 0x7FFF;
1038 if(builtin_isinf(value))
1039 return hbits | 0x7C00;
1040 int exp;
1041 std::frexp(value, &exp);
1042 if(exp > 16)
1043 return overflow<R>(hbits);
1044 if(exp < -13)
1045 value = std::ldexp(value, 25);
1046 else
1047 {
1048 value = std::ldexp(value, 12-exp);
1049 hbits |= ((exp+13)<<10);
1050 }
1051 T ival, frac = std::modf(value, &ival);
1052 int m = std::abs(static_cast<int>(ival));
1053 return rounded<R,false>(hbits+(m>>1), m&1, frac!=T());
1054 }
1055
1064 template<std::float_round_style R,typename T> unsigned int float2half(T value)
1065 {
1066 return float2half_impl<R>(value, bool_type<std::numeric_limits<T>::is_iec559&&sizeof(typename bits<T>::type)==sizeof(T)>());
1067 }
1068
1076 template<std::float_round_style R,typename T> unsigned int int2half(T value)
1077 {
1078 unsigned int bits = static_cast<unsigned>(value<0) << 15;
1079 if(!value)
1080 return bits;
1081 if(value > 0xFFE0 || (bits&&value < -0xFFE0))
1082 return overflow<R>(bits);
1083 unsigned int m = static_cast<unsigned int>(value), exp = 24;
1084 if(bits)
1085 m = -m;
1086 for(; m<0x400; m<<=1,--exp) ;
1087 for(; m>0x7FF; m>>=1,++exp) ;
1088 bits |= (exp<<10) + m;
1089 return (exp>24) ? rounded<R,false>(bits, static_cast<int>(value>>(exp-25))&1, (((1<<(exp-25))-1)&value)!=0) : bits;
1090 }
1091
1096 inline float half2float_impl(unsigned int value, float, true_type)
1097 {
1098 #if HALF_ENABLE_F16C_INTRINSICS
1099 return _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128(value)));
1100 #else
1101 #if 0
1102 bits<float>::type fbits = static_cast<bits<float>::type>(value&0x8000) << 16;
1103 int abs = value & 0x7FFF;
1104 if(abs)
1105 {
1106 fbits |= 0x38000000 << static_cast<unsigned>(abs>=0x7C00);
1107 for(; abs<0x400; abs<<=1,fbits-=0x800000) ;
1108 fbits += static_cast<bits<float>::type>(abs) << 13;
1109 }
1110 #else
1111 static const bits<float>::type mantissa_table[2048] = {
1112 0x00000000, 0x33800000, 0x34000000, 0x34400000, 0x34800000, 0x34A00000, 0x34C00000, 0x34E00000, 0x35000000, 0x35100000, 0x35200000, 0x35300000, 0x35400000, 0x35500000, 0x35600000, 0x35700000,
1113 0x35800000, 0x35880000, 0x35900000, 0x35980000, 0x35A00000, 0x35A80000, 0x35B00000, 0x35B80000, 0x35C00000, 0x35C80000, 0x35D00000, 0x35D80000, 0x35E00000, 0x35E80000, 0x35F00000, 0x35F80000,
1114 0x36000000, 0x36040000, 0x36080000, 0x360C0000, 0x36100000, 0x36140000, 0x36180000, 0x361C0000, 0x36200000, 0x36240000, 0x36280000, 0x362C0000, 0x36300000, 0x36340000, 0x36380000, 0x363C0000,
1115 0x36400000, 0x36440000, 0x36480000, 0x364C0000, 0x36500000, 0x36540000, 0x36580000, 0x365C0000, 0x36600000, 0x36640000, 0x36680000, 0x366C0000, 0x36700000, 0x36740000, 0x36780000, 0x367C0000,
1116 0x36800000, 0x36820000, 0x36840000, 0x36860000, 0x36880000, 0x368A0000, 0x368C0000, 0x368E0000, 0x36900000, 0x36920000, 0x36940000, 0x36960000, 0x36980000, 0x369A0000, 0x369C0000, 0x369E0000,
1117 0x36A00000, 0x36A20000, 0x36A40000, 0x36A60000, 0x36A80000, 0x36AA0000, 0x36AC0000, 0x36AE0000, 0x36B00000, 0x36B20000, 0x36B40000, 0x36B60000, 0x36B80000, 0x36BA0000, 0x36BC0000, 0x36BE0000,
1118 0x36C00000, 0x36C20000, 0x36C40000, 0x36C60000, 0x36C80000, 0x36CA0000, 0x36CC0000, 0x36CE0000, 0x36D00000, 0x36D20000, 0x36D40000, 0x36D60000, 0x36D80000, 0x36DA0000, 0x36DC0000, 0x36DE0000,
1119 0x36E00000, 0x36E20000, 0x36E40000, 0x36E60000, 0x36E80000, 0x36EA0000, 0x36EC0000, 0x36EE0000, 0x36F00000, 0x36F20000, 0x36F40000, 0x36F60000, 0x36F80000, 0x36FA0000, 0x36FC0000, 0x36FE0000,
1120 0x37000000, 0x37010000, 0x37020000, 0x37030000, 0x37040000, 0x37050000, 0x37060000, 0x37070000, 0x37080000, 0x37090000, 0x370A0000, 0x370B0000, 0x370C0000, 0x370D0000, 0x370E0000, 0x370F0000,
1121 0x37100000, 0x37110000, 0x37120000, 0x37130000, 0x37140000, 0x37150000, 0x37160000, 0x37170000, 0x37180000, 0x37190000, 0x371A0000, 0x371B0000, 0x371C0000, 0x371D0000, 0x371E0000, 0x371F0000,
1122 0x37200000, 0x37210000, 0x37220000, 0x37230000, 0x37240000, 0x37250000, 0x37260000, 0x37270000, 0x37280000, 0x37290000, 0x372A0000, 0x372B0000, 0x372C0000, 0x372D0000, 0x372E0000, 0x372F0000,
1123 0x37300000, 0x37310000, 0x37320000, 0x37330000, 0x37340000, 0x37350000, 0x37360000, 0x37370000, 0x37380000, 0x37390000, 0x373A0000, 0x373B0000, 0x373C0000, 0x373D0000, 0x373E0000, 0x373F0000,
1124 0x37400000, 0x37410000, 0x37420000, 0x37430000, 0x37440000, 0x37450000, 0x37460000, 0x37470000, 0x37480000, 0x37490000, 0x374A0000, 0x374B0000, 0x374C0000, 0x374D0000, 0x374E0000, 0x374F0000,
1125 0x37500000, 0x37510000, 0x37520000, 0x37530000, 0x37540000, 0x37550000, 0x37560000, 0x37570000, 0x37580000, 0x37590000, 0x375A0000, 0x375B0000, 0x375C0000, 0x375D0000, 0x375E0000, 0x375F0000,
1126 0x37600000, 0x37610000, 0x37620000, 0x37630000, 0x37640000, 0x37650000, 0x37660000, 0x37670000, 0x37680000, 0x37690000, 0x376A0000, 0x376B0000, 0x376C0000, 0x376D0000, 0x376E0000, 0x376F0000,
1127 0x37700000, 0x37710000, 0x37720000, 0x37730000, 0x37740000, 0x37750000, 0x37760000, 0x37770000, 0x37780000, 0x37790000, 0x377A0000, 0x377B0000, 0x377C0000, 0x377D0000, 0x377E0000, 0x377F0000,
1128 0x37800000, 0x37808000, 0x37810000, 0x37818000, 0x37820000, 0x37828000, 0x37830000, 0x37838000, 0x37840000, 0x37848000, 0x37850000, 0x37858000, 0x37860000, 0x37868000, 0x37870000, 0x37878000,
1129 0x37880000, 0x37888000, 0x37890000, 0x37898000, 0x378A0000, 0x378A8000, 0x378B0000, 0x378B8000, 0x378C0000, 0x378C8000, 0x378D0000, 0x378D8000, 0x378E0000, 0x378E8000, 0x378F0000, 0x378F8000,
1130 0x37900000, 0x37908000, 0x37910000, 0x37918000, 0x37920000, 0x37928000, 0x37930000, 0x37938000, 0x37940000, 0x37948000, 0x37950000, 0x37958000, 0x37960000, 0x37968000, 0x37970000, 0x37978000,
1131 0x37980000, 0x37988000, 0x37990000, 0x37998000, 0x379A0000, 0x379A8000, 0x379B0000, 0x379B8000, 0x379C0000, 0x379C8000, 0x379D0000, 0x379D8000, 0x379E0000, 0x379E8000, 0x379F0000, 0x379F8000,
1132 0x37A00000, 0x37A08000, 0x37A10000, 0x37A18000, 0x37A20000, 0x37A28000, 0x37A30000, 0x37A38000, 0x37A40000, 0x37A48000, 0x37A50000, 0x37A58000, 0x37A60000, 0x37A68000, 0x37A70000, 0x37A78000,
1133 0x37A80000, 0x37A88000, 0x37A90000, 0x37A98000, 0x37AA0000, 0x37AA8000, 0x37AB0000, 0x37AB8000, 0x37AC0000, 0x37AC8000, 0x37AD0000, 0x37AD8000, 0x37AE0000, 0x37AE8000, 0x37AF0000, 0x37AF8000,
1134 0x37B00000, 0x37B08000, 0x37B10000, 0x37B18000, 0x37B20000, 0x37B28000, 0x37B30000, 0x37B38000, 0x37B40000, 0x37B48000, 0x37B50000, 0x37B58000, 0x37B60000, 0x37B68000, 0x37B70000, 0x37B78000,
1135 0x37B80000, 0x37B88000, 0x37B90000, 0x37B98000, 0x37BA0000, 0x37BA8000, 0x37BB0000, 0x37BB8000, 0x37BC0000, 0x37BC8000, 0x37BD0000, 0x37BD8000, 0x37BE0000, 0x37BE8000, 0x37BF0000, 0x37BF8000,
1136 0x37C00000, 0x37C08000, 0x37C10000, 0x37C18000, 0x37C20000, 0x37C28000, 0x37C30000, 0x37C38000, 0x37C40000, 0x37C48000, 0x37C50000, 0x37C58000, 0x37C60000, 0x37C68000, 0x37C70000, 0x37C78000,
1137 0x37C80000, 0x37C88000, 0x37C90000, 0x37C98000, 0x37CA0000, 0x37CA8000, 0x37CB0000, 0x37CB8000, 0x37CC0000, 0x37CC8000, 0x37CD0000, 0x37CD8000, 0x37CE0000, 0x37CE8000, 0x37CF0000, 0x37CF8000,
1138 0x37D00000, 0x37D08000, 0x37D10000, 0x37D18000, 0x37D20000, 0x37D28000, 0x37D30000, 0x37D38000, 0x37D40000, 0x37D48000, 0x37D50000, 0x37D58000, 0x37D60000, 0x37D68000, 0x37D70000, 0x37D78000,
1139 0x37D80000, 0x37D88000, 0x37D90000, 0x37D98000, 0x37DA0000, 0x37DA8000, 0x37DB0000, 0x37DB8000, 0x37DC0000, 0x37DC8000, 0x37DD0000, 0x37DD8000, 0x37DE0000, 0x37DE8000, 0x37DF0000, 0x37DF8000,
1140 0x37E00000, 0x37E08000, 0x37E10000, 0x37E18000, 0x37E20000, 0x37E28000, 0x37E30000, 0x37E38000, 0x37E40000, 0x37E48000, 0x37E50000, 0x37E58000, 0x37E60000, 0x37E68000, 0x37E70000, 0x37E78000,
1141 0x37E80000, 0x37E88000, 0x37E90000, 0x37E98000, 0x37EA0000, 0x37EA8000, 0x37EB0000, 0x37EB8000, 0x37EC0000, 0x37EC8000, 0x37ED0000, 0x37ED8000, 0x37EE0000, 0x37EE8000, 0x37EF0000, 0x37EF8000,
1142 0x37F00000, 0x37F08000, 0x37F10000, 0x37F18000, 0x37F20000, 0x37F28000, 0x37F30000, 0x37F38000, 0x37F40000, 0x37F48000, 0x37F50000, 0x37F58000, 0x37F60000, 0x37F68000, 0x37F70000, 0x37F78000,
1143 0x37F80000, 0x37F88000, 0x37F90000, 0x37F98000, 0x37FA0000, 0x37FA8000, 0x37FB0000, 0x37FB8000, 0x37FC0000, 0x37FC8000, 0x37FD0000, 0x37FD8000, 0x37FE0000, 0x37FE8000, 0x37FF0000, 0x37FF8000,
1144 0x38000000, 0x38004000, 0x38008000, 0x3800C000, 0x38010000, 0x38014000, 0x38018000, 0x3801C000, 0x38020000, 0x38024000, 0x38028000, 0x3802C000, 0x38030000, 0x38034000, 0x38038000, 0x3803C000,
1145 0x38040000, 0x38044000, 0x38048000, 0x3804C000, 0x38050000, 0x38054000, 0x38058000, 0x3805C000, 0x38060000, 0x38064000, 0x38068000, 0x3806C000, 0x38070000, 0x38074000, 0x38078000, 0x3807C000,
1146 0x38080000, 0x38084000, 0x38088000, 0x3808C000, 0x38090000, 0x38094000, 0x38098000, 0x3809C000, 0x380A0000, 0x380A4000, 0x380A8000, 0x380AC000, 0x380B0000, 0x380B4000, 0x380B8000, 0x380BC000,
1147 0x380C0000, 0x380C4000, 0x380C8000, 0x380CC000, 0x380D0000, 0x380D4000, 0x380D8000, 0x380DC000, 0x380E0000, 0x380E4000, 0x380E8000, 0x380EC000, 0x380F0000, 0x380F4000, 0x380F8000, 0x380FC000,
1148 0x38100000, 0x38104000, 0x38108000, 0x3810C000, 0x38110000, 0x38114000, 0x38118000, 0x3811C000, 0x38120000, 0x38124000, 0x38128000, 0x3812C000, 0x38130000, 0x38134000, 0x38138000, 0x3813C000,
1149 0x38140000, 0x38144000, 0x38148000, 0x3814C000, 0x38150000, 0x38154000, 0x38158000, 0x3815C000, 0x38160000, 0x38164000, 0x38168000, 0x3816C000, 0x38170000, 0x38174000, 0x38178000, 0x3817C000,
1150 0x38180000, 0x38184000, 0x38188000, 0x3818C000, 0x38190000, 0x38194000, 0x38198000, 0x3819C000, 0x381A0000, 0x381A4000, 0x381A8000, 0x381AC000, 0x381B0000, 0x381B4000, 0x381B8000, 0x381BC000,
1151 0x381C0000, 0x381C4000, 0x381C8000, 0x381CC000, 0x381D0000, 0x381D4000, 0x381D8000, 0x381DC000, 0x381E0000, 0x381E4000, 0x381E8000, 0x381EC000, 0x381F0000, 0x381F4000, 0x381F8000, 0x381FC000,
1152 0x38200000, 0x38204000, 0x38208000, 0x3820C000, 0x38210000, 0x38214000, 0x38218000, 0x3821C000, 0x38220000, 0x38224000, 0x38228000, 0x3822C000, 0x38230000, 0x38234000, 0x38238000, 0x3823C000,
1153 0x38240000, 0x38244000, 0x38248000, 0x3824C000, 0x38250000, 0x38254000, 0x38258000, 0x3825C000, 0x38260000, 0x38264000, 0x38268000, 0x3826C000, 0x38270000, 0x38274000, 0x38278000, 0x3827C000,
1154 0x38280000, 0x38284000, 0x38288000, 0x3828C000, 0x38290000, 0x38294000, 0x38298000, 0x3829C000, 0x382A0000, 0x382A4000, 0x382A8000, 0x382AC000, 0x382B0000, 0x382B4000, 0x382B8000, 0x382BC000,
1155 0x382C0000, 0x382C4000, 0x382C8000, 0x382CC000, 0x382D0000, 0x382D4000, 0x382D8000, 0x382DC000, 0x382E0000, 0x382E4000, 0x382E8000, 0x382EC000, 0x382F0000, 0x382F4000, 0x382F8000, 0x382FC000,
1156 0x38300000, 0x38304000, 0x38308000, 0x3830C000, 0x38310000, 0x38314000, 0x38318000, 0x3831C000, 0x38320000, 0x38324000, 0x38328000, 0x3832C000, 0x38330000, 0x38334000, 0x38338000, 0x3833C000,
1157 0x38340000, 0x38344000, 0x38348000, 0x3834C000, 0x38350000, 0x38354000, 0x38358000, 0x3835C000, 0x38360000, 0x38364000, 0x38368000, 0x3836C000, 0x38370000, 0x38374000, 0x38378000, 0x3837C000,
1158 0x38380000, 0x38384000, 0x38388000, 0x3838C000, 0x38390000, 0x38394000, 0x38398000, 0x3839C000, 0x383A0000, 0x383A4000, 0x383A8000, 0x383AC000, 0x383B0000, 0x383B4000, 0x383B8000, 0x383BC000,
1159 0x383C0000, 0x383C4000, 0x383C8000, 0x383CC000, 0x383D0000, 0x383D4000, 0x383D8000, 0x383DC000, 0x383E0000, 0x383E4000, 0x383E8000, 0x383EC000, 0x383F0000, 0x383F4000, 0x383F8000, 0x383FC000,
1160 0x38400000, 0x38404000, 0x38408000, 0x3840C000, 0x38410000, 0x38414000, 0x38418000, 0x3841C000, 0x38420000, 0x38424000, 0x38428000, 0x3842C000, 0x38430000, 0x38434000, 0x38438000, 0x3843C000,
1161 0x38440000, 0x38444000, 0x38448000, 0x3844C000, 0x38450000, 0x38454000, 0x38458000, 0x3845C000, 0x38460000, 0x38464000, 0x38468000, 0x3846C000, 0x38470000, 0x38474000, 0x38478000, 0x3847C000,
1162 0x38480000, 0x38484000, 0x38488000, 0x3848C000, 0x38490000, 0x38494000, 0x38498000, 0x3849C000, 0x384A0000, 0x384A4000, 0x384A8000, 0x384AC000, 0x384B0000, 0x384B4000, 0x384B8000, 0x384BC000,
1163 0x384C0000, 0x384C4000, 0x384C8000, 0x384CC000, 0x384D0000, 0x384D4000, 0x384D8000, 0x384DC000, 0x384E0000, 0x384E4000, 0x384E8000, 0x384EC000, 0x384F0000, 0x384F4000, 0x384F8000, 0x384FC000,
1164 0x38500000, 0x38504000, 0x38508000, 0x3850C000, 0x38510000, 0x38514000, 0x38518000, 0x3851C000, 0x38520000, 0x38524000, 0x38528000, 0x3852C000, 0x38530000, 0x38534000, 0x38538000, 0x3853C000,
1165 0x38540000, 0x38544000, 0x38548000, 0x3854C000, 0x38550000, 0x38554000, 0x38558000, 0x3855C000, 0x38560000, 0x38564000, 0x38568000, 0x3856C000, 0x38570000, 0x38574000, 0x38578000, 0x3857C000,
1166 0x38580000, 0x38584000, 0x38588000, 0x3858C000, 0x38590000, 0x38594000, 0x38598000, 0x3859C000, 0x385A0000, 0x385A4000, 0x385A8000, 0x385AC000, 0x385B0000, 0x385B4000, 0x385B8000, 0x385BC000,
1167 0x385C0000, 0x385C4000, 0x385C8000, 0x385CC000, 0x385D0000, 0x385D4000, 0x385D8000, 0x385DC000, 0x385E0000, 0x385E4000, 0x385E8000, 0x385EC000, 0x385F0000, 0x385F4000, 0x385F8000, 0x385FC000,
1168 0x38600000, 0x38604000, 0x38608000, 0x3860C000, 0x38610000, 0x38614000, 0x38618000, 0x3861C000, 0x38620000, 0x38624000, 0x38628000, 0x3862C000, 0x38630000, 0x38634000, 0x38638000, 0x3863C000,
1169 0x38640000, 0x38644000, 0x38648000, 0x3864C000, 0x38650000, 0x38654000, 0x38658000, 0x3865C000, 0x38660000, 0x38664000, 0x38668000, 0x3866C000, 0x38670000, 0x38674000, 0x38678000, 0x3867C000,
1170 0x38680000, 0x38684000, 0x38688000, 0x3868C000, 0x38690000, 0x38694000, 0x38698000, 0x3869C000, 0x386A0000, 0x386A4000, 0x386A8000, 0x386AC000, 0x386B0000, 0x386B4000, 0x386B8000, 0x386BC000,
1171 0x386C0000, 0x386C4000, 0x386C8000, 0x386CC000, 0x386D0000, 0x386D4000, 0x386D8000, 0x386DC000, 0x386E0000, 0x386E4000, 0x386E8000, 0x386EC000, 0x386F0000, 0x386F4000, 0x386F8000, 0x386FC000,
1172 0x38700000, 0x38704000, 0x38708000, 0x3870C000, 0x38710000, 0x38714000, 0x38718000, 0x3871C000, 0x38720000, 0x38724000, 0x38728000, 0x3872C000, 0x38730000, 0x38734000, 0x38738000, 0x3873C000,
1173 0x38740000, 0x38744000, 0x38748000, 0x3874C000, 0x38750000, 0x38754000, 0x38758000, 0x3875C000, 0x38760000, 0x38764000, 0x38768000, 0x3876C000, 0x38770000, 0x38774000, 0x38778000, 0x3877C000,
1174 0x38780000, 0x38784000, 0x38788000, 0x3878C000, 0x38790000, 0x38794000, 0x38798000, 0x3879C000, 0x387A0000, 0x387A4000, 0x387A8000, 0x387AC000, 0x387B0000, 0x387B4000, 0x387B8000, 0x387BC000,
1175 0x387C0000, 0x387C4000, 0x387C8000, 0x387CC000, 0x387D0000, 0x387D4000, 0x387D8000, 0x387DC000, 0x387E0000, 0x387E4000, 0x387E8000, 0x387EC000, 0x387F0000, 0x387F4000, 0x387F8000, 0x387FC000,
1176 0x38000000, 0x38002000, 0x38004000, 0x38006000, 0x38008000, 0x3800A000, 0x3800C000, 0x3800E000, 0x38010000, 0x38012000, 0x38014000, 0x38016000, 0x38018000, 0x3801A000, 0x3801C000, 0x3801E000,
1177 0x38020000, 0x38022000, 0x38024000, 0x38026000, 0x38028000, 0x3802A000, 0x3802C000, 0x3802E000, 0x38030000, 0x38032000, 0x38034000, 0x38036000, 0x38038000, 0x3803A000, 0x3803C000, 0x3803E000,
1178 0x38040000, 0x38042000, 0x38044000, 0x38046000, 0x38048000, 0x3804A000, 0x3804C000, 0x3804E000, 0x38050000, 0x38052000, 0x38054000, 0x38056000, 0x38058000, 0x3805A000, 0x3805C000, 0x3805E000,
1179 0x38060000, 0x38062000, 0x38064000, 0x38066000, 0x38068000, 0x3806A000, 0x3806C000, 0x3806E000, 0x38070000, 0x38072000, 0x38074000, 0x38076000, 0x38078000, 0x3807A000, 0x3807C000, 0x3807E000,
1180 0x38080000, 0x38082000, 0x38084000, 0x38086000, 0x38088000, 0x3808A000, 0x3808C000, 0x3808E000, 0x38090000, 0x38092000, 0x38094000, 0x38096000, 0x38098000, 0x3809A000, 0x3809C000, 0x3809E000,
1181 0x380A0000, 0x380A2000, 0x380A4000, 0x380A6000, 0x380A8000, 0x380AA000, 0x380AC000, 0x380AE000, 0x380B0000, 0x380B2000, 0x380B4000, 0x380B6000, 0x380B8000, 0x380BA000, 0x380BC000, 0x380BE000,
1182 0x380C0000, 0x380C2000, 0x380C4000, 0x380C6000, 0x380C8000, 0x380CA000, 0x380CC000, 0x380CE000, 0x380D0000, 0x380D2000, 0x380D4000, 0x380D6000, 0x380D8000, 0x380DA000, 0x380DC000, 0x380DE000,
1183 0x380E0000, 0x380E2000, 0x380E4000, 0x380E6000, 0x380E8000, 0x380EA000, 0x380EC000, 0x380EE000, 0x380F0000, 0x380F2000, 0x380F4000, 0x380F6000, 0x380F8000, 0x380FA000, 0x380FC000, 0x380FE000,
1184 0x38100000, 0x38102000, 0x38104000, 0x38106000, 0x38108000, 0x3810A000, 0x3810C000, 0x3810E000, 0x38110000, 0x38112000, 0x38114000, 0x38116000, 0x38118000, 0x3811A000, 0x3811C000, 0x3811E000,
1185 0x38120000, 0x38122000, 0x38124000, 0x38126000, 0x38128000, 0x3812A000, 0x3812C000, 0x3812E000, 0x38130000, 0x38132000, 0x38134000, 0x38136000, 0x38138000, 0x3813A000, 0x3813C000, 0x3813E000,
1186 0x38140000, 0x38142000, 0x38144000, 0x38146000, 0x38148000, 0x3814A000, 0x3814C000, 0x3814E000, 0x38150000, 0x38152000, 0x38154000, 0x38156000, 0x38158000, 0x3815A000, 0x3815C000, 0x3815E000,
1187 0x38160000, 0x38162000, 0x38164000, 0x38166000, 0x38168000, 0x3816A000, 0x3816C000, 0x3816E000, 0x38170000, 0x38172000, 0x38174000, 0x38176000, 0x38178000, 0x3817A000, 0x3817C000, 0x3817E000,
1188 0x38180000, 0x38182000, 0x38184000, 0x38186000, 0x38188000, 0x3818A000, 0x3818C000, 0x3818E000, 0x38190000, 0x38192000, 0x38194000, 0x38196000, 0x38198000, 0x3819A000, 0x3819C000, 0x3819E000,
1189 0x381A0000, 0x381A2000, 0x381A4000, 0x381A6000, 0x381A8000, 0x381AA000, 0x381AC000, 0x381AE000, 0x381B0000, 0x381B2000, 0x381B4000, 0x381B6000, 0x381B8000, 0x381BA000, 0x381BC000, 0x381BE000,
1190 0x381C0000, 0x381C2000, 0x381C4000, 0x381C6000, 0x381C8000, 0x381CA000, 0x381CC000, 0x381CE000, 0x381D0000, 0x381D2000, 0x381D4000, 0x381D6000, 0x381D8000, 0x381DA000, 0x381DC000, 0x381DE000,
1191 0x381E0000, 0x381E2000, 0x381E4000, 0x381E6000, 0x381E8000, 0x381EA000, 0x381EC000, 0x381EE000, 0x381F0000, 0x381F2000, 0x381F4000, 0x381F6000, 0x381F8000, 0x381FA000, 0x381FC000, 0x381FE000,
1192 0x38200000, 0x38202000, 0x38204000, 0x38206000, 0x38208000, 0x3820A000, 0x3820C000, 0x3820E000, 0x38210000, 0x38212000, 0x38214000, 0x38216000, 0x38218000, 0x3821A000, 0x3821C000, 0x3821E000,
1193 0x38220000, 0x38222000, 0x38224000, 0x38226000, 0x38228000, 0x3822A000, 0x3822C000, 0x3822E000, 0x38230000, 0x38232000, 0x38234000, 0x38236000, 0x38238000, 0x3823A000, 0x3823C000, 0x3823E000,
1194 0x38240000, 0x38242000, 0x38244000, 0x38246000, 0x38248000, 0x3824A000, 0x3824C000, 0x3824E000, 0x38250000, 0x38252000, 0x38254000, 0x38256000, 0x38258000, 0x3825A000, 0x3825C000, 0x3825E000,
1195 0x38260000, 0x38262000, 0x38264000, 0x38266000, 0x38268000, 0x3826A000, 0x3826C000, 0x3826E000, 0x38270000, 0x38272000, 0x38274000, 0x38276000, 0x38278000, 0x3827A000, 0x3827C000, 0x3827E000,
1196 0x38280000, 0x38282000, 0x38284000, 0x38286000, 0x38288000, 0x3828A000, 0x3828C000, 0x3828E000, 0x38290000, 0x38292000, 0x38294000, 0x38296000, 0x38298000, 0x3829A000, 0x3829C000, 0x3829E000,
1197 0x382A0000, 0x382A2000, 0x382A4000, 0x382A6000, 0x382A8000, 0x382AA000, 0x382AC000, 0x382AE000, 0x382B0000, 0x382B2000, 0x382B4000, 0x382B6000, 0x382B8000, 0x382BA000, 0x382BC000, 0x382BE000,
1198 0x382C0000, 0x382C2000, 0x382C4000, 0x382C6000, 0x382C8000, 0x382CA000, 0x382CC000, 0x382CE000, 0x382D0000, 0x382D2000, 0x382D4000, 0x382D6000, 0x382D8000, 0x382DA000, 0x382DC000, 0x382DE000,
1199 0x382E0000, 0x382E2000, 0x382E4000, 0x382E6000, 0x382E8000, 0x382EA000, 0x382EC000, 0x382EE000, 0x382F0000, 0x382F2000, 0x382F4000, 0x382F6000, 0x382F8000, 0x382FA000, 0x382FC000, 0x382FE000,
1200 0x38300000, 0x38302000, 0x38304000, 0x38306000, 0x38308000, 0x3830A000, 0x3830C000, 0x3830E000, 0x38310000, 0x38312000, 0x38314000, 0x38316000, 0x38318000, 0x3831A000, 0x3831C000, 0x3831E000,
1201 0x38320000, 0x38322000, 0x38324000, 0x38326000, 0x38328000, 0x3832A000, 0x3832C000, 0x3832E000, 0x38330000, 0x38332000, 0x38334000, 0x38336000, 0x38338000, 0x3833A000, 0x3833C000, 0x3833E000,
1202 0x38340000, 0x38342000, 0x38344000, 0x38346000, 0x38348000, 0x3834A000, 0x3834C000, 0x3834E000, 0x38350000, 0x38352000, 0x38354000, 0x38356000, 0x38358000, 0x3835A000, 0x3835C000, 0x3835E000,
1203 0x38360000, 0x38362000, 0x38364000, 0x38366000, 0x38368000, 0x3836A000, 0x3836C000, 0x3836E000, 0x38370000, 0x38372000, 0x38374000, 0x38376000, 0x38378000, 0x3837A000, 0x3837C000, 0x3837E000,
1204 0x38380000, 0x38382000, 0x38384000, 0x38386000, 0x38388000, 0x3838A000, 0x3838C000, 0x3838E000, 0x38390000, 0x38392000, 0x38394000, 0x38396000, 0x38398000, 0x3839A000, 0x3839C000, 0x3839E000,
1205 0x383A0000, 0x383A2000, 0x383A4000, 0x383A6000, 0x383A8000, 0x383AA000, 0x383AC000, 0x383AE000, 0x383B0000, 0x383B2000, 0x383B4000, 0x383B6000, 0x383B8000, 0x383BA000, 0x383BC000, 0x383BE000,
1206 0x383C0000, 0x383C2000, 0x383C4000, 0x383C6000, 0x383C8000, 0x383CA000, 0x383CC000, 0x383CE000, 0x383D0000, 0x383D2000, 0x383D4000, 0x383D6000, 0x383D8000, 0x383DA000, 0x383DC000, 0x383DE000,
1207 0x383E0000, 0x383E2000, 0x383E4000, 0x383E6000, 0x383E8000, 0x383EA000, 0x383EC000, 0x383EE000, 0x383F0000, 0x383F2000, 0x383F4000, 0x383F6000, 0x383F8000, 0x383FA000, 0x383FC000, 0x383FE000,
1208 0x38400000, 0x38402000, 0x38404000, 0x38406000, 0x38408000, 0x3840A000, 0x3840C000, 0x3840E000, 0x38410000, 0x38412000, 0x38414000, 0x38416000, 0x38418000, 0x3841A000, 0x3841C000, 0x3841E000,
1209 0x38420000, 0x38422000, 0x38424000, 0x38426000, 0x38428000, 0x3842A000, 0x3842C000, 0x3842E000, 0x38430000, 0x38432000, 0x38434000, 0x38436000, 0x38438000, 0x3843A000, 0x3843C000, 0x3843E000,
1210 0x38440000, 0x38442000, 0x38444000, 0x38446000, 0x38448000, 0x3844A000, 0x3844C000, 0x3844E000, 0x38450000, 0x38452000, 0x38454000, 0x38456000, 0x38458000, 0x3845A000, 0x3845C000, 0x3845E000,
1211 0x38460000, 0x38462000, 0x38464000, 0x38466000, 0x38468000, 0x3846A000, 0x3846C000, 0x3846E000, 0x38470000, 0x38472000, 0x38474000, 0x38476000, 0x38478000, 0x3847A000, 0x3847C000, 0x3847E000,
1212 0x38480000, 0x38482000, 0x38484000, 0x38486000, 0x38488000, 0x3848A000, 0x3848C000, 0x3848E000, 0x38490000, 0x38492000, 0x38494000, 0x38496000, 0x38498000, 0x3849A000, 0x3849C000, 0x3849E000,
1213 0x384A0000, 0x384A2000, 0x384A4000, 0x384A6000, 0x384A8000, 0x384AA000, 0x384AC000, 0x384AE000, 0x384B0000, 0x384B2000, 0x384B4000, 0x384B6000, 0x384B8000, 0x384BA000, 0x384BC000, 0x384BE000,
1214 0x384C0000, 0x384C2000, 0x384C4000, 0x384C6000, 0x384C8000, 0x384CA000, 0x384CC000, 0x384CE000, 0x384D0000, 0x384D2000, 0x384D4000, 0x384D6000, 0x384D8000, 0x384DA000, 0x384DC000, 0x384DE000,
1215 0x384E0000, 0x384E2000, 0x384E4000, 0x384E6000, 0x384E8000, 0x384EA000, 0x384EC000, 0x384EE000, 0x384F0000, 0x384F2000, 0x384F4000, 0x384F6000, 0x384F8000, 0x384FA000, 0x384FC000, 0x384FE000,
1216 0x38500000, 0x38502000, 0x38504000, 0x38506000, 0x38508000, 0x3850A000, 0x3850C000, 0x3850E000, 0x38510000, 0x38512000, 0x38514000, 0x38516000, 0x38518000, 0x3851A000, 0x3851C000, 0x3851E000,
1217 0x38520000, 0x38522000, 0x38524000, 0x38526000, 0x38528000, 0x3852A000, 0x3852C000, 0x3852E000, 0x38530000, 0x38532000, 0x38534000, 0x38536000, 0x38538000, 0x3853A000, 0x3853C000, 0x3853E000,
1218 0x38540000, 0x38542000, 0x38544000, 0x38546000, 0x38548000, 0x3854A000, 0x3854C000, 0x3854E000, 0x38550000, 0x38552000, 0x38554000, 0x38556000, 0x38558000, 0x3855A000, 0x3855C000, 0x3855E000,
1219 0x38560000, 0x38562000, 0x38564000, 0x38566000, 0x38568000, 0x3856A000, 0x3856C000, 0x3856E000, 0x38570000, 0x38572000, 0x38574000, 0x38576000, 0x38578000, 0x3857A000, 0x3857C000, 0x3857E000,
1220 0x38580000, 0x38582000, 0x38584000, 0x38586000, 0x38588000, 0x3858A000, 0x3858C000, 0x3858E000, 0x38590000, 0x38592000, 0x38594000, 0x38596000, 0x38598000, 0x3859A000, 0x3859C000, 0x3859E000,
1221 0x385A0000, 0x385A2000, 0x385A4000, 0x385A6000, 0x385A8000, 0x385AA000, 0x385AC000, 0x385AE000, 0x385B0000, 0x385B2000, 0x385B4000, 0x385B6000, 0x385B8000, 0x385BA000, 0x385BC000, 0x385BE000,
1222 0x385C0000, 0x385C2000, 0x385C4000, 0x385C6000, 0x385C8000, 0x385CA000, 0x385CC000, 0x385CE000, 0x385D0000, 0x385D2000, 0x385D4000, 0x385D6000, 0x385D8000, 0x385DA000, 0x385DC000, 0x385DE000,
1223 0x385E0000, 0x385E2000, 0x385E4000, 0x385E6000, 0x385E8000, 0x385EA000, 0x385EC000, 0x385EE000, 0x385F0000, 0x385F2000, 0x385F4000, 0x385F6000, 0x385F8000, 0x385FA000, 0x385FC000, 0x385FE000,
1224 0x38600000, 0x38602000, 0x38604000, 0x38606000, 0x38608000, 0x3860A000, 0x3860C000, 0x3860E000, 0x38610000, 0x38612000, 0x38614000, 0x38616000, 0x38618000, 0x3861A000, 0x3861C000, 0x3861E000,
1225 0x38620000, 0x38622000, 0x38624000, 0x38626000, 0x38628000, 0x3862A000, 0x3862C000, 0x3862E000, 0x38630000, 0x38632000, 0x38634000, 0x38636000, 0x38638000, 0x3863A000, 0x3863C000, 0x3863E000,
1226 0x38640000, 0x38642000, 0x38644000, 0x38646000, 0x38648000, 0x3864A000, 0x3864C000, 0x3864E000, 0x38650000, 0x38652000, 0x38654000, 0x38656000, 0x38658000, 0x3865A000, 0x3865C000, 0x3865E000,
1227 0x38660000, 0x38662000, 0x38664000, 0x38666000, 0x38668000, 0x3866A000, 0x3866C000, 0x3866E000, 0x38670000, 0x38672000, 0x38674000, 0x38676000, 0x38678000, 0x3867A000, 0x3867C000, 0x3867E000,
1228 0x38680000, 0x38682000, 0x38684000, 0x38686000, 0x38688000, 0x3868A000, 0x3868C000, 0x3868E000, 0x38690000, 0x38692000, 0x38694000, 0x38696000, 0x38698000, 0x3869A000, 0x3869C000, 0x3869E000,
1229 0x386A0000, 0x386A2000, 0x386A4000, 0x386A6000, 0x386A8000, 0x386AA000, 0x386AC000, 0x386AE000, 0x386B0000, 0x386B2000, 0x386B4000, 0x386B6000, 0x386B8000, 0x386BA000, 0x386BC000, 0x386BE000,
1230 0x386C0000, 0x386C2000, 0x386C4000, 0x386C6000, 0x386C8000, 0x386CA000, 0x386CC000, 0x386CE000, 0x386D0000, 0x386D2000, 0x386D4000, 0x386D6000, 0x386D8000, 0x386DA000, 0x386DC000, 0x386DE000,
1231 0x386E0000, 0x386E2000, 0x386E4000, 0x386E6000, 0x386E8000, 0x386EA000, 0x386EC000, 0x386EE000, 0x386F0000, 0x386F2000, 0x386F4000, 0x386F6000, 0x386F8000, 0x386FA000, 0x386FC000, 0x386FE000,
1232 0x38700000, 0x38702000, 0x38704000, 0x38706000, 0x38708000, 0x3870A000, 0x3870C000, 0x3870E000, 0x38710000, 0x38712000, 0x38714000, 0x38716000, 0x38718000, 0x3871A000, 0x3871C000, 0x3871E000,
1233 0x38720000, 0x38722000, 0x38724000, 0x38726000, 0x38728000, 0x3872A000, 0x3872C000, 0x3872E000, 0x38730000, 0x38732000, 0x38734000, 0x38736000, 0x38738000, 0x3873A000, 0x3873C000, 0x3873E000,
1234 0x38740000, 0x38742000, 0x38744000, 0x38746000, 0x38748000, 0x3874A000, 0x3874C000, 0x3874E000, 0x38750000, 0x38752000, 0x38754000, 0x38756000, 0x38758000, 0x3875A000, 0x3875C000, 0x3875E000,
1235 0x38760000, 0x38762000, 0x38764000, 0x38766000, 0x38768000, 0x3876A000, 0x3876C000, 0x3876E000, 0x38770000, 0x38772000, 0x38774000, 0x38776000, 0x38778000, 0x3877A000, 0x3877C000, 0x3877E000,
1236 0x38780000, 0x38782000, 0x38784000, 0x38786000, 0x38788000, 0x3878A000, 0x3878C000, 0x3878E000, 0x38790000, 0x38792000, 0x38794000, 0x38796000, 0x38798000, 0x3879A000, 0x3879C000, 0x3879E000,
1237 0x387A0000, 0x387A2000, 0x387A4000, 0x387A6000, 0x387A8000, 0x387AA000, 0x387AC000, 0x387AE000, 0x387B0000, 0x387B2000, 0x387B4000, 0x387B6000, 0x387B8000, 0x387BA000, 0x387BC000, 0x387BE000,
1238 0x387C0000, 0x387C2000, 0x387C4000, 0x387C6000, 0x387C8000, 0x387CA000, 0x387CC000, 0x387CE000, 0x387D0000, 0x387D2000, 0x387D4000, 0x387D6000, 0x387D8000, 0x387DA000, 0x387DC000, 0x387DE000,
1239 0x387E0000, 0x387E2000, 0x387E4000, 0x387E6000, 0x387E8000, 0x387EA000, 0x387EC000, 0x387EE000, 0x387F0000, 0x387F2000, 0x387F4000, 0x387F6000, 0x387F8000, 0x387FA000, 0x387FC000, 0x387FE000 };
1240 static const bits<float>::type exponent_table[64] = {
1241 0x00000000, 0x00800000, 0x01000000, 0x01800000, 0x02000000, 0x02800000, 0x03000000, 0x03800000, 0x04000000, 0x04800000, 0x05000000, 0x05800000, 0x06000000, 0x06800000, 0x07000000, 0x07800000,
1242 0x08000000, 0x08800000, 0x09000000, 0x09800000, 0x0A000000, 0x0A800000, 0x0B000000, 0x0B800000, 0x0C000000, 0x0C800000, 0x0D000000, 0x0D800000, 0x0E000000, 0x0E800000, 0x0F000000, 0x47800000,
1243 0x80000000, 0x80800000, 0x81000000, 0x81800000, 0x82000000, 0x82800000, 0x83000000, 0x83800000, 0x84000000, 0x84800000, 0x85000000, 0x85800000, 0x86000000, 0x86800000, 0x87000000, 0x87800000,
1244 0x88000000, 0x88800000, 0x89000000, 0x89800000, 0x8A000000, 0x8A800000, 0x8B000000, 0x8B800000, 0x8C000000, 0x8C800000, 0x8D000000, 0x8D800000, 0x8E000000, 0x8E800000, 0x8F000000, 0xC7800000 };
1245 static const unsigned short offset_table[64] = {
1246 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,
1247 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 };
1248 bits<float>::type fbits = mantissa_table[offset_table[value>>10]+(value&0x3FF)] + exponent_table[value>>10];
1249 #endif
1250 float out;
1251 std::memcpy(&out, &fbits, sizeof(float));
1252 return out;
1253 #endif
1254 }
1255
1259 inline double half2float_impl(unsigned int value, double, true_type)
1260 {
1261 #if HALF_ENABLE_F16C_INTRINSICS
1262 return _mm_cvtsd_f64(_mm_cvtps_pd(_mm_cvtph_ps(_mm_cvtsi32_si128(value))));
1263 #else
1264 uint32 hi = static_cast<uint32>(value&0x8000) << 16;
1265 unsigned int abs = value & 0x7FFF;
1266 if(abs)
1267 {
1268 hi |= 0x3F000000 << static_cast<unsigned>(abs>=0x7C00);
1269 for(; abs<0x400; abs<<=1,hi-=0x100000) ;
1270 hi += static_cast<uint32>(abs) << 10;
1271 }
1272 bits<double>::type dbits = static_cast<bits<double>::type>(hi) << 32;
1273 double out;
1274 std::memcpy(&out, &dbits, sizeof(double));
1275 return out;
1276 #endif
1277 }
1278
1283 template<typename T> T half2float_impl(unsigned int value, T, ...)
1284 {
1285 T out;
1286 unsigned int abs = value & 0x7FFF;
1287 if(abs > 0x7C00)
1288 out = (std::numeric_limits<T>::has_signaling_NaN && !(abs&0x200)) ? std::numeric_limits<T>::signaling_NaN() :
1289 std::numeric_limits<T>::has_quiet_NaN ? std::numeric_limits<T>::quiet_NaN() : T();
1290 else if(abs == 0x7C00)
1291 out = std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : std::numeric_limits<T>::max();
1292 else if(abs > 0x3FF)
1293 out = std::ldexp(static_cast<T>((abs&0x3FF)|0x400), (abs>>10)-25);
1294 else
1295 out = std::ldexp(static_cast<T>(abs), -24);
1296 return (value&0x8000) ? -out : out;
1297 }
1298
1303 template<typename T> T half2float(unsigned int value)
1304 {
1305 return half2float_impl(value, T(), bool_type<std::numeric_limits<T>::is_iec559&&sizeof(typename bits<T>::type)==sizeof(T)>());
1306 }
1307
1317 template<std::float_round_style R,bool E,bool I,typename T> T half2int(unsigned int value)
1318 {
1319 unsigned int abs = value & 0x7FFF;
1320 if(abs >= 0x7C00)
1321 {
1323 return (value&0x8000) ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max();
1324 }
1325 if(abs < 0x3800)
1326 {
1328 return (R==std::round_toward_infinity) ? T(~(value>>15)&(abs!=0)) :
1329 (R==std::round_toward_neg_infinity) ? -T(value>0x8000) :
1330 T();
1331 }
1332 int exp = 25 - (abs>>10);
1333 unsigned int m = (value&0x3FF) | 0x400;
1334 int32 i = static_cast<int32>((exp<=0) ? (m<<-exp) : ((m+(
1335 (R==std::round_to_nearest) ? ((1<<(exp-1))-(~(m>>exp)&E)) :
1336 (R==std::round_toward_infinity) ? (((1<<exp)-1)&((value>>15)-1)) :
1337 (R==std::round_toward_neg_infinity) ? (((1<<exp)-1)&-(value>>15)) : 0))>>exp));
1338 if((!std::numeric_limits<T>::is_signed && (value&0x8000)) || (std::numeric_limits<T>::digits<16 &&
1339 ((value&0x8000) ? (-i<std::numeric_limits<T>::min()) : (i>std::numeric_limits<T>::max()))))
1341 else if(I && exp > 0 && (m&((1<<exp)-1)))
1343 return static_cast<T>((value&0x8000) ? -i : i);
1344 }
1345
1349
1355 template<std::float_round_style R> uint32 mulhi(uint32 x, uint32 y)
1356 {
1357 uint32 xy = (x>>16) * (y&0xFFFF), yx = (x&0xFFFF) * (y>>16), c = (xy&0xFFFF) + (yx&0xFFFF) + (((x&0xFFFF)*(y&0xFFFF))>>16);
1358 return (x>>16)*(y>>16) + (xy>>16) + (yx>>16) + (c>>16) +
1359 ((R==std::round_to_nearest) ? ((c>>15)&1) : (R==std::round_toward_infinity) ? ((c&0xFFFF)!=0) : 0);
1360 }
1361
1367 {
1368 #if HALF_ENABLE_CPP11_LONG_LONG
1369 return static_cast<uint32>((static_cast<unsigned long long>(x)*static_cast<unsigned long long>(y)+0x80000000)>>32);
1370 #else
1371 return mulhi<std::round_to_nearest>(x, y);
1372 #endif
1373 }
1374
1380 inline uint32 divide64(uint32 x, uint32 y, int &s)
1381 {
1382 #if HALF_ENABLE_CPP11_LONG_LONG
1383 unsigned long long xx = static_cast<unsigned long long>(x) << 32;
1384 return s = (xx%y!=0), static_cast<uint32>(xx/y);
1385 #else
1386 y >>= 1;
1387 uint32 rem = x, div = 0;
1388 for(unsigned int i=0; i<32; ++i)
1389 {
1390 div <<= 1;
1391 if(rem >= y)
1392 {
1393 rem -= y;
1394 div |= 1;
1395 }
1396 rem <<= 1;
1397 }
1398 return s = rem > 1, div;
1399 #endif
1400 }
1401
1409 template<bool Q,bool R> unsigned int mod(unsigned int x, unsigned int y, int *quo = NULL)
1410 {
1411 unsigned int q = 0;
1412 if(x > y)
1413 {
1414 int absx = x, absy = y, expx = 0, expy = 0;
1415 for(; absx<0x400; absx<<=1,--expx) ;
1416 for(; absy<0x400; absy<<=1,--expy) ;
1417 expx += absx >> 10;
1418 expy += absy >> 10;
1419 int mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400;
1420 for(int d=expx-expy; d; --d)
1421 {
1422 if(!Q && mx == my)
1423 return 0;
1424 if(mx >= my)
1425 {
1426 mx -= my;
1427 q += Q;
1428 }
1429 mx <<= 1;
1430 q <<= static_cast<int>(Q);
1431 }
1432 if(!Q && mx == my)
1433 return 0;
1434 if(mx >= my)
1435 {
1436 mx -= my;
1437 ++q;
1438 }
1439 if(Q)
1440 {
1441 q &= (1<<(std::numeric_limits<int>::digits-1)) - 1;
1442 if(!mx)
1443 return *quo = q, 0;
1444 }
1445 for(; mx<0x400; mx<<=1,--expy) ;
1446 x = (expy>0) ? ((expy<<10)|(mx&0x3FF)) : (mx>>(1-expy));
1447 }
1448 if(R)
1449 {
1450 unsigned int a, b;
1451 if(y < 0x800)
1452 {
1453 a = (x<0x400) ? (x<<1) : (x+0x400);
1454 b = y;
1455 }
1456 else
1457 {
1458 a = x;
1459 b = y - 0x400;
1460 }
1461 if(a > b || (a == b && (q&1)))
1462 {
1463 int exp = (y>>10) + (y<=0x3FF), d = exp - (x>>10) - (x<=0x3FF);
1464 int m = (((y&0x3FF)|((y>0x3FF)<<10))<<1) - (((x&0x3FF)|((x>0x3FF)<<10))<<(1-d));
1465 for(; m<0x800 && exp>1; m<<=1,--exp) ;
1466 x = 0x8000 + ((exp-1)<<10) + (m>>1);
1467 q += Q;
1468 }
1469 }
1470 if(Q)
1471 *quo = q;
1472 return x;
1473 }
1474
1480 template<unsigned int F> uint32 sqrt(uint32 &r, int &exp)
1481 {
1482 int i = exp & 1;
1483 r <<= i;
1484 exp = (exp-i) / 2;
1485 uint32 m = 0;
1486 for(uint32 bit=static_cast<uint32>(1)<<F; bit; bit>>=2)
1487 {
1488 if(r < m+bit)
1489 m >>= 1;
1490 else
1491 {
1492 r -= m + bit;
1493 m = (m>>1) + bit;
1494 }
1495 }
1496 return m;
1497 }
1498
1504 inline uint32 exp2(uint32 m, unsigned int n = 32)
1505 {
1506 static const uint32 logs[] = {
1507 0x80000000, 0x4AE00D1D, 0x2934F098, 0x15C01A3A, 0x0B31FB7D, 0x05AEB4DD, 0x02DCF2D1, 0x016FE50B,
1508 0x00B84E23, 0x005C3E10, 0x002E24CA, 0x001713D6, 0x000B8A47, 0x0005C53B, 0x0002E2A3, 0x00017153,
1509 0x0000B8AA, 0x00005C55, 0x00002E2B, 0x00001715, 0x00000B8B, 0x000005C5, 0x000002E3, 0x00000171,
1510 0x000000B9, 0x0000005C, 0x0000002E, 0x00000017, 0x0000000C, 0x00000006, 0x00000003, 0x00000001 };
1511 if(!m)
1512 return 0x80000000;
1513 uint32 mx = 0x80000000, my = 0;
1514 for(unsigned int i=1; i<n; ++i)
1515 {
1516 uint32 mz = my + logs[i];
1517 if(mz <= m)
1518 {
1519 my = mz;
1520 mx += mx >> i;
1521 }
1522 }
1523 return mx;
1524 }
1525
1531 inline uint32 log2(uint32 m, unsigned int n = 32)
1532 {
1533 static const uint32 logs[] = {
1534 0x80000000, 0x4AE00D1D, 0x2934F098, 0x15C01A3A, 0x0B31FB7D, 0x05AEB4DD, 0x02DCF2D1, 0x016FE50B,
1535 0x00B84E23, 0x005C3E10, 0x002E24CA, 0x001713D6, 0x000B8A47, 0x0005C53B, 0x0002E2A3, 0x00017153,
1536 0x0000B8AA, 0x00005C55, 0x00002E2B, 0x00001715, 0x00000B8B, 0x000005C5, 0x000002E3, 0x00000171,
1537 0x000000B9, 0x0000005C, 0x0000002E, 0x00000017, 0x0000000C, 0x00000006, 0x00000003, 0x00000001 };
1538 if(m == 0x40000000)
1539 return 0;
1540 uint32 mx = 0x40000000, my = 0;
1541 for(unsigned int i=1; i<n; ++i)
1542 {
1543 uint32 mz = mx + (mx>>i);
1544 if(mz <= m)
1545 {
1546 mx = mz;
1547 my += logs[i];
1548 }
1549 }
1550 return my;
1551 }
1552
1558 inline std::pair<uint32,uint32> sincos(uint32 mz, unsigned int n = 31)
1559 {
1560 static const uint32 angles[] = {
1561 0x3243F6A9, 0x1DAC6705, 0x0FADBAFD, 0x07F56EA7, 0x03FEAB77, 0x01FFD55C, 0x00FFFAAB, 0x007FFF55,
1562 0x003FFFEB, 0x001FFFFD, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, 0x00008000,
1563 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080,
1564 0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 };
1565 uint32 mx = 0x26DD3B6A, my = 0;
1566 for(unsigned int i=0; i<n; ++i)
1567 {
1568 uint32 sign = sign_mask(mz);
1569 uint32 tx = mx - (arithmetic_shift(my, i)^sign) + sign;
1570 uint32 ty = my + (arithmetic_shift(mx, i)^sign) - sign;
1571 mx = tx; my = ty; mz -= (angles[i]^sign) - sign;
1572 }
1573 return std::make_pair(my, mx);
1574 }
1575
1582 inline uint32 atan2(uint32 my, uint32 mx, unsigned int n = 31)
1583 {
1584 static const uint32 angles[] = {
1585 0x3243F6A9, 0x1DAC6705, 0x0FADBAFD, 0x07F56EA7, 0x03FEAB77, 0x01FFD55C, 0x00FFFAAB, 0x007FFF55,
1586 0x003FFFEB, 0x001FFFFD, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, 0x00008000,
1587 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080,
1588 0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 };
1589 uint32 mz = 0;
1590 for(unsigned int i=0; i<n; ++i)
1591 {
1592 uint32 sign = sign_mask(my);
1593 uint32 tx = mx + (arithmetic_shift(my, i)^sign) - sign;
1594 uint32 ty = my - (arithmetic_shift(mx, i)^sign) + sign;
1595 mx = tx; my = ty; mz += (angles[i]^sign) - sign;
1596 }
1597 return mz;
1598 }
1599
1604 inline uint32 angle_arg(unsigned int abs, int &k)
1605 {
1606 uint32 m = (abs&0x3FF) | ((abs>0x3FF)<<10);
1607 int exp = (abs>>10) + (abs<=0x3FF) - 15;
1608 if(abs < 0x3A48)
1609 return k = 0, m << (exp+20);
1610 #if HALF_ENABLE_CPP11_LONG_LONG
1611 unsigned long long y = m * 0xA2F9836E4E442, mask = (1ULL<<(62-exp)) - 1, yi = (y+(mask>>1)) & ~mask, f = y - yi;
1612 uint32 sign = -static_cast<uint32>(f>>63);
1613 k = static_cast<int>(yi>>(62-exp));
1614 return (multiply64(static_cast<uint32>((sign ? -f : f)>>(31-exp)), 0xC90FDAA2)^sign) - sign;
1615 #else
1616 uint32 yh = m*0xA2F98 + mulhi<std::round_toward_zero>(m, 0x36E4E442), yl = (m*0x36E4E442) & 0xFFFFFFFF;
1617 uint32 mask = (static_cast<uint32>(1)<<(30-exp)) - 1, yi = (yh+(mask>>1)) & ~mask, sign = -static_cast<uint32>(yi>yh);
1618 k = static_cast<int>(yi>>(30-exp));
1619 uint32 fh = (yh^sign) + (yi^~sign) - ~sign, fl = (yl^sign) - sign;
1620 return (multiply64((exp>-1) ? (((fh<<(1+exp))&0xFFFFFFFF)|((fl&0xFFFFFFFF)>>(31-exp))) : fh, 0xC90FDAA2)^sign) - sign;
1621 #endif
1622 }
1623
1627 inline std::pair<uint32,uint32> atan2_args(unsigned int abs)
1628 {
1629 int exp = -15;
1630 for(; abs<0x400; abs<<=1,--exp) ;
1631 exp += abs >> 10;
1632 uint32 my = ((abs&0x3FF)|0x400) << 5, r = my * my;
1633 int rexp = 2 * exp;
1634 r = 0x40000000 - ((rexp>-31) ? ((r>>-rexp)|((r&((static_cast<uint32>(1)<<-rexp)-1))!=0)) : 1);
1635 for(rexp=0; r<0x40000000; r<<=1,--rexp) ;
1636 uint32 mx = sqrt<30>(r, rexp);
1637 int d = exp - rexp;
1638 if(d < 0)
1639 return std::make_pair((d<-14) ? ((my>>(-d-14))+((my>>(-d-15))&1)) : (my<<(14+d)), (mx<<14)+(r<<13)/mx);
1640 if(d > 0)
1641 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)));
1642 return std::make_pair(my<<13, (mx<<13)+(r<<12)/mx);
1643 }
1644
1650 inline std::pair<uint32,uint32> hyperbolic_args(unsigned int abs, int &exp, unsigned int n = 32)
1651 {
1652 uint32 mx = detail::multiply64(static_cast<uint32>((abs&0x3FF)+((abs>0x3FF)<<10))<<21, 0xB8AA3B29), my;
1653 int e = (abs>>10) + (abs<=0x3FF);
1654 if(e < 14)
1655 {
1656 exp = 0;
1657 mx >>= 14 - e;
1658 }
1659 else
1660 {
1661 exp = static_cast<int>(mx >> (45-e));
1662 mx = (mx<<(e-14)) & 0x7FFFFFFF;
1663 }
1664 mx = exp2(mx, n);
1665 int d = exp << 1, s;
1666 if(mx > 0x80000000)
1667 {
1668 my = divide64(0x80000000, mx, s);
1669 my |= s;
1670 ++d;
1671 }
1672 else
1673 my = mx;
1674 return std::make_pair(mx, (d<31) ? ((my>>d)|((my&((static_cast<uint32>(1)<<d)-1))!=0)) : 1);
1675 }
1676
1688 template<std::float_round_style R> unsigned int exp2_post(uint32 m, int exp, bool esign, unsigned int sign = 0, unsigned int n = 32)
1689 {
1690 if(esign)
1691 {
1692 exp = -exp - (m!=0);
1693 if(exp < -25)
1694 return underflow<R>(sign);
1695 else if(exp == -25)
1696 return rounded<R,false>(sign, 1, m!=0);
1697 }
1698 else if(exp > 15)
1699 return overflow<R>(sign);
1700 if(!m)
1701 return sign | (((exp+=15)>0) ? (exp<<10) : check_underflow(0x200>>-exp));
1702 m = exp2(m, n);
1703 int s = 0;
1704 if(esign)
1705 m = divide64(0x80000000, m, s);
1706 return fixed2half<R,31,false,false,true>(m, exp+14, sign, s);
1707 }
1708
1720 template<std::float_round_style R,uint32 L> unsigned int log2_post(uint32 m, int ilog, int exp, unsigned int sign = 0)
1721 {
1722 uint32 msign = sign_mask(ilog);
1723 m = (((static_cast<uint32>(ilog)<<27)+(m>>4))^msign) - msign;
1724 if(!m)
1725 return 0;
1726 for(; m<0x80000000; m<<=1,--exp) ;
1727 int i = m >= L, s;
1728 exp += i;
1729 m >>= 1 + i;
1730 sign ^= msign & 0x8000;
1731 if(exp < -11)
1732 return underflow<R>(sign);
1733 m = divide64(m, L, s);
1734 return fixed2half<R,30,false,false,true>(m, exp, sign, 1);
1735 }
1736
1745 template<std::float_round_style R> unsigned int hypot_post(uint32 r, int exp)
1746 {
1747 int i = static_cast<int>(r >> 31);
1748 if((exp+=i) > 46)
1749 return overflow<R>();
1750 if(exp < -34)
1751 return underflow<R>();
1752 r = (r>>i) | (r&i);
1753 uint32 m = sqrt<30>(r, exp+=15);
1754 return fixed2half<R,15,false,false,false>(m, exp-1, 0, r!=0);
1755 }
1756
1767 template<std::float_round_style R> unsigned int tangent_post(uint32 my, uint32 mx, int exp, unsigned int sign = 0)
1768 {
1769 int i = my >= mx, s;
1770 exp += i;
1771 if(exp > 29)
1772 return overflow<R>(sign);
1773 if(exp < -11)
1774 return underflow<R>(sign);
1775 uint32 m = divide64(my>>(i+1), mx, s);
1776 return fixed2half<R,30,false,false,true>(m, exp, sign, s);
1777 }
1778
1788 template<std::float_round_style R,bool S> unsigned int area(unsigned int arg)
1789 {
1790 int abs = arg & 0x7FFF, expx = (abs>>10) + (abs<=0x3FF) - 15, expy = -15, ilog;
1791 uint32 mx = static_cast<uint32>((abs&0x3FF)|((abs>0x3FF)<<10)) << 20, my, r;
1792 for(; abs<0x400; abs<<=1,--expy) ;
1793 expy += abs >> 10;
1794 r = ((abs&0x3FF)|0x400) << 5;
1795 r *= r;
1796 int i = static_cast<int>(r >> 31);
1797 expy = 2*expy + i;
1798 r >>= i;
1799 if(S)
1800 {
1801 if(expy < 0)
1802 {
1803 r = 0x40000000 + ((expy>-30) ? ((r>>-expy)|((r&((static_cast<uint32>(1)<<-expy)-1))!=0)) : 1);
1804 expy = 0;
1805 }
1806 else
1807 {
1808 r += 0x40000000 >> expy;
1809 i = static_cast<int>(r >> 31);
1810 r = (r>>i) | (r&i);
1811 expy += i;
1812 }
1813 }
1814 else
1815 {
1816 r -= 0x40000000 >> expy;
1817 for(; r<0x40000000; r<<=1,--expy) ;
1818 }
1819 my = sqrt<30>(r, expy);
1820 my = (my<<15) + (r<<14)/my;
1821 if(S)
1822 {
1823 mx >>= expy - expx;
1824 ilog = expy;
1825 }
1826 else
1827 {
1828 my >>= expx - expy;
1829 ilog = expx;
1830 }
1831 my += mx;
1832 i = static_cast<int>(my >> 31);
1833 static const int G = S && (R==std::round_to_nearest);
1834 return log2_post<R,0xB8AA3B2A>(log2(my>>i, 26+S+G)+(G<<3), ilog+i, 17, arg&(static_cast<unsigned>(S)<<15));
1835 }
1836
1838 struct f31
1839 {
1843 HALF_CONSTEXPR f31(uint32 mant, int e) : m(mant), exp(e) {}
1844
1847 f31(unsigned int abs) : exp(-15)
1848 {
1849 for(; abs<0x400; abs<<=1,--exp) ;
1850 m = static_cast<uint32>((abs&0x3FF)|0x400) << 21;
1851 exp += (abs>>10);
1852 }
1853
1858 friend f31 operator+(f31 a, f31 b)
1859 {
1860 if(b.exp > a.exp)
1861 std::swap(a, b);
1862 int d = a.exp - b.exp;
1863 uint32 m = a.m + ((d<32) ? (b.m>>d) : 0);
1864 int i = (m&0xFFFFFFFF) < a.m;
1865 return f31(((m+i)>>i)|0x80000000, a.exp+i);
1866 }
1867
1872 friend f31 operator-(f31 a, f31 b)
1873 {
1874 int d = a.exp - b.exp, exp = a.exp;
1875 uint32 m = a.m - ((d<32) ? (b.m>>d) : 0);
1876 if(!m)
1877 return f31(0, -32);
1878 for(; m<0x80000000; m<<=1,--exp) ;
1879 return f31(m, exp);
1880 }
1881
1886 friend f31 operator*(f31 a, f31 b)
1887 {
1888 uint32 m = multiply64(a.m, b.m);
1889 int i = static_cast<int>(m >> 31);
1890 return f31(m<<(1-i), a.exp + b.exp + i);
1891 }
1892
1897 friend f31 operator/(f31 a, f31 b)
1898 {
1899 int i = a.m >= b.m, s;
1900 uint32 m = divide64((a.m+i)>>i, b.m, s);
1901 return f31(m, a.exp - b.exp + i - 1);
1902 }
1903
1905 int exp;
1906 };
1907
1918 template<std::float_round_style R,bool C> unsigned int erf(unsigned int arg)
1919 {
1920 unsigned int abs = arg & 0x7FFF, sign = arg & 0x8000;
1921 f31 x(abs), x2 = x * x * f31(0xB8AA3B29, 0), t = f31(0x80000000, 0) / (f31(0x80000000, 0)+f31(0xA7BA054A, -2)*x), t2 = t * t;
1922 f31 e = ((f31(0x87DC2213, 0)*t2+f31(0xB5F0E2AE, 0))*t2+f31(0x82790637, -2)-(f31(0xBA00E2B8, 0)*t2+f31(0x91A98E62, -2))*t) * t /
1923 ((x2.exp<0) ? f31(exp2((x2.exp>-32) ? (x2.m>>-x2.exp) : 0, 30), 0) : f31(exp2((x2.m<<x2.exp)&0x7FFFFFFF, 22), static_cast<int>(x2.m>>(31-x2.exp))));
1924 return (!C || sign) ? fixed2half<R,31,false,true,true>(0x80000000-(e.m>>(C-e.exp)), 14+C, sign&(C-1U)) :
1925 (e.exp<-25) ? underflow<R>() : fixed2half<R,30,false,false,true>(e.m>>1, e.exp+14, 0, e.m&1);
1926 }
1927
1937 template<std::float_round_style R,bool L> unsigned int gamma(unsigned int arg)
1938 {
1939/* static const double p[] ={ 2.50662827563479526904, 225.525584619175212544, -268.295973841304927459, 80.9030806934622512966, -5.00757863970517583837, 0.0114684895434781459556 };
1940 double t = arg + 4.65, s = p[0];
1941 for(unsigned int i=0; i<5; ++i)
1942 s += p[i+1] / (arg+i);
1943 return std::log(s) + (arg-0.5)*std::log(t) - t;
1944*/ static const f31 pi(0xC90FDAA2, 1), lbe(0xB8AA3B29, 0);
1945 unsigned int abs = arg & 0x7FFF, sign = arg & 0x8000;
1946 bool bsign = sign != 0;
1947 f31 z(abs), x = sign ? (z+f31(0x80000000, 0)) : z, t = x + f31(0x94CCCCCD, 2), s =
1948 f31(0xA06C9901, 1) + f31(0xBBE654E2, -7)/(x+f31(0x80000000, 2)) + f31(0xA1CE6098, 6)/(x+f31(0x80000000, 1))
1949 + f31(0xE1868CB7, 7)/x - f31(0x8625E279, 8)/(x+f31(0x80000000, 0)) - f31(0xA03E158F, 2)/(x+f31(0xC0000000, 1));
1950 int i = (s.exp>=2) + (s.exp>=4) + (s.exp>=8) + (s.exp>=16);
1951 s = f31((static_cast<uint32>(s.exp)<<(31-i))+(log2(s.m>>1, 28)>>i), i) / lbe;
1952 if(x.exp != -1 || x.m != 0x80000000)
1953 {
1954 i = (t.exp>=2) + (t.exp>=4) + (t.exp>=8);
1955 f31 l = f31((static_cast<uint32>(t.exp)<<(31-i))+(log2(t.m>>1, 30)>>i), i) / lbe;
1956 s = (x.exp<-1) ? (s-(f31(0x80000000, -1)-x)*l) : (s+(x-f31(0x80000000, -1))*l);
1957 }
1958 s = x.exp ? (s-t) : (t-s);
1959 if(bsign)
1960 {
1961 if(z.exp >= 0)
1962 {
1963 sign &= (L|((z.m>>(31-z.exp))&1)) - 1;
1964 for(z=f31((z.m<<(1+z.exp))&0xFFFFFFFF, -1); z.m<0x80000000; z.m<<=1,--z.exp) ;
1965 }
1966 if(z.exp == -1)
1967 z = f31(0x80000000, 0) - z;
1968 if(z.exp < -1)
1969 {
1970 z = z * pi;
1971 z.m = sincos(z.m>>(1-z.exp), 30).first;
1972 for(z.exp=1; z.m<0x80000000; z.m<<=1,--z.exp) ;
1973 }
1974 else
1975 z = f31(0x80000000, 0);
1976 }
1977 if(L)
1978 {
1979 if(bsign)
1980 {
1981 f31 l(0x92868247, 0);
1982 if(z.exp < 0)
1983 {
1984 uint32 m = log2((z.m+1)>>1, 27);
1985 z = f31(-((static_cast<uint32>(z.exp)<<26)+(m>>5)), 5);
1986 for(; z.m<0x80000000; z.m<<=1,--z.exp) ;
1987 l = l + z / lbe;
1988 }
1989 sign = static_cast<unsigned>(x.exp&&(l.exp<s.exp||(l.exp==s.exp&&l.m<s.m))) << 15;
1990 s = sign ? (s-l) : x.exp ? (l-s) : (l+s);
1991 }
1992 else
1993 {
1994 sign = static_cast<unsigned>(x.exp==0) << 15;
1995 if(s.exp < -24)
1996 return underflow<R>(sign);
1997 if(s.exp > 15)
1998 return overflow<R>(sign);
1999 }
2000 }
2001 else
2002 {
2003 s = s * lbe;
2004 uint32 m;
2005 if(s.exp < 0)
2006 {
2007 m = s.m >> -s.exp;
2008 s.exp = 0;
2009 }
2010 else
2011 {
2012 m = (s.m<<s.exp) & 0x7FFFFFFF;
2013 s.exp = static_cast<int>(s.m>>(31-s.exp));
2014 }
2015 s.m = exp2(m, 27);
2016 if(!x.exp)
2017 s = f31(0x80000000, 0) / s;
2018 if(bsign)
2019 {
2020 if(z.exp < 0)
2021 s = s * z;
2022 s = pi / s;
2023 if(s.exp < -24)
2024 return underflow<R>(sign);
2025 }
2026 else if(z.exp > 0 && !(z.m&((1<<(31-z.exp))-1)))
2027 return ((s.exp+14)<<10) + static_cast<unsigned int>(s.m>>21);
2028 if(s.exp > 15)
2029 return overflow<R>(sign);
2030 }
2031 return fixed2half<R,31,false,false,true>(s.m, s.exp+14, sign);
2032 }
2033
2034
2035 template<typename,typename,std::float_round_style> struct half_caster;
2036 }
2037
2055 class half
2056 {
2057 public:
2060
2065
2069 explicit half(float rhs) : data_(static_cast<detail::uint16>(detail::float2half<round_style>(rhs))) {}
2070
2073 operator float() const { return detail::half2float<float>(data_); }
2074
2079 half& operator=(float rhs) { data_ = static_cast<detail::uint16>(detail::float2half<round_style>(rhs)); return *this; }
2080
2084
2090 half& operator+=(half rhs) { return *this = *this + rhs; }
2091
2097 half& operator-=(half rhs) { return *this = *this - rhs; }
2098
2104 half& operator*=(half rhs) { return *this = *this * rhs; }
2105
2111 half& operator/=(half rhs) { return *this = *this / rhs; }
2112
2117 half& operator+=(float rhs) { return *this = *this + rhs; }
2118
2123 half& operator-=(float rhs) { return *this = *this - rhs; }
2124
2129 half& operator*=(float rhs) { return *this = *this * rhs; }
2130
2135 half& operator/=(float rhs) { return *this = *this / rhs; }
2136
2140
2144 half& operator++() { return *this = *this + half(detail::binary, 0x3C00); }
2145
2149 half& operator--() { return *this = *this + half(detail::binary, 0xBC00); }
2150
2154 half operator++(int) { half out(*this); ++*this; return out; }
2155
2159 half operator--(int) { half out(*this); --*this; return out; }
2161
2162 private:
2164 static const std::float_round_style round_style = (std::float_round_style)(HALF_ROUND_STYLE);
2165
2168 HALF_CONSTEXPR half(detail::binary_t, unsigned int bits) HALF_NOEXCEPT : data_(static_cast<detail::uint16>(bits)) {}
2169
2171 detail::uint16 data_;
2172
2173 #ifndef HALF_DOXYGEN_ONLY
2181 friend half operator+(half, half);
2182 friend half operator-(half, half);
2183 friend half operator*(half, half);
2184 friend half operator/(half, half);
2185 template<typename charT,typename traits> friend std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT,traits>&, half);
2186 template<typename charT,typename traits> friend std::basic_istream<charT,traits>& operator>>(std::basic_istream<charT,traits>&, half&);
2187 friend HALF_CONSTEXPR half fabs(half);
2188 friend half fmod(half, half);
2189 friend half remainder(half, half);
2190 friend half remquo(half, half, int*);
2191 friend half fma(half, half, half);
2194 friend half fdim(half, half);
2195 friend half nanh(const char*);
2196 friend half exp(half);
2197 friend half exp2(half);
2198 friend half expm1(half);
2199 friend half log(half);
2200 friend half log10(half);
2201 friend half log2(half);
2202 friend half log1p(half);
2203 friend half sqrt(half);
2204 friend half rsqrt(half);
2205 friend half cbrt(half);
2206 friend half hypot(half, half);
2207 friend half hypot(half, half, half);
2208 friend half pow(half, half);
2209 friend void sincos(half, half*, half*);
2210 friend half sin(half);
2211 friend half cos(half);
2212 friend half tan(half);
2213 friend half asin(half);
2214 friend half acos(half);
2215 friend half atan(half);
2216 friend half atan2(half, half);
2217 friend half sinh(half);
2218 friend half cosh(half);
2219 friend half tanh(half);
2220 friend half asinh(half);
2221 friend half acosh(half);
2222 friend half atanh(half);
2223 friend half erf(half);
2224 friend half erfc(half);
2225 friend half lgamma(half);
2226 friend half tgamma(half);
2227 friend half ceil(half);
2228 friend half floor(half);
2229 friend half trunc(half);
2230 friend half round(half);
2231 friend long lround(half);
2232 friend half rint(half);
2233 friend long lrint(half);
2234 friend half nearbyint(half);
2235 #ifdef HALF_ENABLE_CPP11_LONG_LONG
2236 friend long long llround(half);
2237 friend long long llrint(half);
2238 #endif
2239 friend half frexp(half, int*);
2240 friend half scalbln(half, long);
2241 friend half modf(half, half*);
2242 friend int ilogb(half);
2243 friend half logb(half);
2244 friend half nextafter(half, half);
2245 friend half nexttoward(half, long double);
2247 friend HALF_CONSTEXPR int fpclassify(half);
2248 friend HALF_CONSTEXPR bool isfinite(half);
2249 friend HALF_CONSTEXPR bool isinf(half);
2250 friend HALF_CONSTEXPR bool isnan(half);
2251 friend HALF_CONSTEXPR bool isnormal(half);
2252 friend HALF_CONSTEXPR bool signbit(half);
2253 friend HALF_CONSTEXPR bool isgreater(half, half);
2254 friend HALF_CONSTEXPR bool isgreaterequal(half, half);
2255 friend HALF_CONSTEXPR bool isless(half, half);
2256 friend HALF_CONSTEXPR bool islessequal(half, half);
2257 friend HALF_CONSTEXPR bool islessgreater(half, half);
2258 template<typename,typename,std::float_round_style> friend struct detail::half_caster;
2259 friend class std::numeric_limits<half>;
2260 #if HALF_ENABLE_CPP11_HASH
2261 friend struct std::hash<half>;
2262 #endif
2263 #if HALF_ENABLE_CPP11_USER_LITERALS
2264 friend half literal::operator "" _h(long double);
2265 #endif
2266 #endif
2267 };
2268
2269#if HALF_ENABLE_CPP11_USER_LITERALS
2270 namespace literal
2271 {
2279 inline half operator "" _h(long double value) { return half(detail::binary, detail::float2half<half::round_style>(value)); }
2280 }
2281#endif
2282
2283 namespace detail
2284 {
2291 template<typename T,typename U,std::float_round_style R=(std::float_round_style)(HALF_ROUND_STYLE)> struct half_caster {};
2292 template<typename U,std::float_round_style R> struct half_caster<half,U,R>
2293 {
2294 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
2295 static_assert(std::is_arithmetic<U>::value, "half_cast from non-arithmetic type not supported");
2296 #endif
2297
2298 static half cast(U arg) { return cast_impl(arg, is_float<U>()); };
2299
2300 private:
2301 static half cast_impl(U arg, true_type) { return half(binary, float2half<R>(arg)); }
2302 static half cast_impl(U arg, false_type) { return half(binary, int2half<R>(arg)); }
2303 };
2304 template<typename T,std::float_round_style R> struct half_caster<T,half,R>
2305 {
2306 #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS
2307 static_assert(std::is_arithmetic<T>::value, "half_cast to non-arithmetic type not supported");
2308 #endif
2309
2310 static T cast(half arg) { return cast_impl(arg, is_float<T>()); }
2311
2312 private:
2313 static T cast_impl(half arg, true_type) { return half2float<T>(arg.data_); }
2314 static T cast_impl(half arg, false_type) { return half2int<R,true,true,T>(arg.data_); }
2315 };
2316 template<std::float_round_style R> struct half_caster<half,half,R>
2317 {
2318 static half cast(half arg) { return arg; }
2319 };
2320 }
2321}
2322
2324namespace std
2325{
2328 template<> class numeric_limits<half_float::half>
2329 {
2330 public:
2333
2336
2339
2341 static HALF_CONSTEXPR_CONST bool is_exact = false;
2342
2344 static HALF_CONSTEXPR_CONST bool is_modulo = false;
2345
2348
2351
2354
2357
2360
2362 static HALF_CONSTEXPR_CONST float_denorm_style has_denorm = denorm_present;
2363
2366
2367 #if HALF_ERRHANDLING_THROWS
2368 static HALF_CONSTEXPR_CONST bool traps = true;
2369 #else
2371 static HALF_CONSTEXPR_CONST bool traps = false;
2372 #endif
2373
2376
2378 static HALF_CONSTEXPR_CONST float_round_style round_style = half_float::half::round_style;
2379
2382
2385
2388
2391
2394
2397
2400
2403
2406
2409
2412
2415
2418 { return half_float::half(half_float::detail::binary, (round_style==std::round_to_nearest) ? 0x3800 : 0x3C00); }
2419
2422
2425
2428
2431 };
2432
2433#if HALF_ENABLE_CPP11_HASH
2438 template<> struct hash<half_float::half>
2439 {
2441 typedef half_float::half argument_type;
2442
2444 typedef size_t result_type;
2445
2449 result_type operator()(argument_type arg) const { return hash<half_float::detail::uint16>()(arg.data_&-static_cast<unsigned>(arg.data_!=0x8000)); }
2450 };
2451#endif
2452}
2453
2454namespace half_float
2455{
2459
2467 {
2468 return !detail::compsignal(x.data_, y.data_) && (x.data_==y.data_ || !((x.data_|y.data_)&0x7FFF));
2469 }
2470
2478 {
2479 return detail::compsignal(x.data_, y.data_) || (x.data_!=y.data_ && ((x.data_|y.data_)&0x7FFF));
2480 }
2481
2489 {
2490 return !detail::compsignal(x.data_, y.data_) &&
2491 ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) < ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15));
2492 }
2493
2501 {
2502 return !detail::compsignal(x.data_, y.data_) &&
2503 ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) > ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15));
2504 }
2505
2513 {
2514 return !detail::compsignal(x.data_, y.data_) &&
2515 ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) <= ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15));
2516 }
2517
2525 {
2526 return !detail::compsignal(x.data_, y.data_) &&
2527 ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) >= ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15));
2528 }
2529
2534
2538 inline HALF_CONSTEXPR half operator+(half arg) { return arg; }
2539
2543 inline HALF_CONSTEXPR half operator-(half arg) { return half(detail::binary, arg.data_^0x8000); }
2544
2553 {
2554 #ifdef HALF_ARITHMETIC_TYPE
2556 #else
2557 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF;
2558 bool sub = ((x.data_^y.data_)&0x8000) != 0;
2559 if(absx >= 0x7C00 || absy >= 0x7C00)
2560 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) : (absy!=0x7C00) ? x.data_ :
2561 (sub && absx==0x7C00) ? detail::invalid() : y.data_);
2562 if(!absx)
2563 return absy ? y : half(detail::binary, (half::round_style==std::round_toward_neg_infinity) ? (x.data_|y.data_) : (x.data_&y.data_));
2564 if(!absy)
2565 return x;
2566 unsigned int sign = ((sub && absy>absx) ? y.data_ : x.data_) & 0x8000;
2567 if(absy > absx)
2568 std::swap(absx, absy);
2569 int exp = (absx>>10) + (absx<=0x3FF), d = exp - (absy>>10) - (absy<=0x3FF), mx = ((absx&0x3FF)|((absx>0x3FF)<<10)) << 3, my;
2570 if(d < 13)
2571 {
2572 my = ((absy&0x3FF)|((absy>0x3FF)<<10)) << 3;
2573 my = (my>>d) | ((my&((1<<d)-1))!=0);
2574 }
2575 else
2576 my = 1;
2577 if(sub)
2578 {
2579 if(!(mx-=my))
2580 return half(detail::binary, static_cast<unsigned>(half::round_style==std::round_toward_neg_infinity)<<15);
2581 for(; mx<0x2000 && exp>1; mx<<=1,--exp) ;
2582 }
2583 else
2584 {
2585 mx += my;
2586 int i = mx >> 14;
2587 if((exp+=i) > 30)
2589 mx = (mx>>i) | (mx&i);
2590 }
2591 return half(detail::binary, detail::rounded<half::round_style,false>(sign+((exp-1)<<10)+(mx>>3), (mx>>2)&1, (mx&0x3)!=0));
2592 #endif
2593 }
2594
2603 {
2604 #ifdef HALF_ARITHMETIC_TYPE
2606 #else
2607 return x + -y;
2608 #endif
2609 }
2610
2619 {
2620 #ifdef HALF_ARITHMETIC_TYPE
2622 #else
2623 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -16;
2624 unsigned int sign = (x.data_^y.data_) & 0x8000;
2625 if(absx >= 0x7C00 || absy >= 0x7C00)
2626 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2627 ((absx==0x7C00 && !absy)||(absy==0x7C00 && !absx)) ? detail::invalid() : (sign|0x7C00));
2628 if(!absx || !absy)
2629 return half(detail::binary, sign);
2630 for(; absx<0x400; absx<<=1,--exp) ;
2631 for(; absy<0x400; absy<<=1,--exp) ;
2632 detail::uint32 m = static_cast<detail::uint32>((absx&0x3FF)|0x400) * static_cast<detail::uint32>((absy&0x3FF)|0x400);
2633 int i = static_cast<int>(m >> 21), s = static_cast<int>(m & i);
2634 exp += (absx>>10) + (absy>>10) + i;
2635 if(exp > 29)
2637 else if(exp < -11)
2640 #endif
2641 }
2642
2652 {
2653 #ifdef HALF_ARITHMETIC_TYPE
2655 #else
2656 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = 14;
2657 unsigned int sign = (x.data_^y.data_) & 0x8000;
2658 if(absx >= 0x7C00 || absy >= 0x7C00)
2659 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2660 (absx==absy) ? detail::invalid() : (sign|((absx==0x7C00) ? 0x7C00 : 0)));
2661 if(!absx)
2662 return half(detail::binary, absy ? sign : detail::invalid());
2663 if(!absy)
2664 return half(detail::binary, detail::pole(sign));
2665 for(; absx<0x400; absx<<=1,--exp) ;
2666 for(; absy<0x400; absy<<=1,++exp) ;
2667 detail::uint32 mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400;
2668 int i = mx < my;
2669 exp += (absx>>10) - (absy>>10) - i;
2670 if(exp > 29)
2672 else if(exp < -11)
2674 mx <<= 12 + i;
2675 my <<= 1;
2677 #endif
2678 }
2679
2684
2690 template<typename charT,typename traits> std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT,traits> &out, half arg)
2691 {
2692 #ifdef HALF_ARITHMETIC_TYPE
2693 return out << detail::half2float<detail::internal_t>(arg.data_);
2694 #else
2695 return out << detail::half2float<float>(arg.data_);
2696 #endif
2697 }
2698
2708 template<typename charT,typename traits> std::basic_istream<charT,traits>& operator>>(std::basic_istream<charT,traits> &in, half &arg)
2709 {
2710 #ifdef HALF_ARITHMETIC_TYPE
2711 detail::internal_t f;
2712 #else
2713 double f;
2714 #endif
2715 if(in >> f)
2717 return in;
2718 }
2719
2724
2729 inline HALF_CONSTEXPR half fabs(half arg) { return half(detail::binary, arg.data_&0x7FFF); }
2730
2735 inline HALF_CONSTEXPR half abs(half arg) { return fabs(arg); }
2736
2743 inline half fmod(half x, half y)
2744 {
2745 unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000;
2746 if(absx >= 0x7C00 || absy >= 0x7C00)
2747 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2748 (absx==0x7C00) ? detail::invalid() : x.data_);
2749 if(!absy)
2751 if(!absx)
2752 return x;
2753 if(absx == absy)
2754 return half(detail::binary, sign);
2755 return half(detail::binary, sign|detail::mod<false,false>(absx, absy));
2756 }
2757
2765 {
2766 unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000;
2767 if(absx >= 0x7C00 || absy >= 0x7C00)
2768 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2769 (absx==0x7C00) ? detail::invalid() : x.data_);
2770 if(!absy)
2772 if(absx == absy)
2773 return half(detail::binary, sign);
2774 return half(detail::binary, sign^detail::mod<false,true>(absx, absy));
2775 }
2776
2784 inline half remquo(half x, half y, int *quo)
2785 {
2786 unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, value = x.data_ & 0x8000;
2787 if(absx >= 0x7C00 || absy >= 0x7C00)
2788 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
2789 (absx==0x7C00) ? detail::invalid() : (*quo = 0, x.data_));
2790 if(!absy)
2792 bool qsign = ((value^y.data_)&0x8000) != 0;
2793 int q = 1;
2794 if(absx != absy)
2795 value ^= detail::mod<true, true>(absx, absy, &q);
2796 return *quo = qsign ? -q : q, half(detail::binary, value);
2797 }
2798
2809 inline half fma(half x, half y, half z)
2810 {
2811 #ifdef HALF_ARITHMETIC_TYPE
2813 #if HALF_ENABLE_CPP11_CMATH && FP_FAST_FMA
2814 return half(detail::binary, detail::float2half<half::round_style>(std::fma(fx, fy, fz)));
2815 #else
2817 #endif
2818 #else
2819 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, exp = -15;
2820 unsigned int sign = (x.data_^y.data_) & 0x8000;
2821 bool sub = ((sign^z.data_)&0x8000) != 0;
2822 if(absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
2823 return (absx>0x7C00 || absy>0x7C00 || absz>0x7C00) ? half(detail::binary, detail::signal(x.data_, y.data_, z.data_)) :
2824 (absx==0x7C00) ? half(detail::binary, (!absy || (sub && absz==0x7C00)) ? detail::invalid() : (sign|0x7C00)) :
2825 (absy==0x7C00) ? half(detail::binary, (!absx || (sub && absz==0x7C00)) ? detail::invalid() : (sign|0x7C00)) : z;
2826 if(!absx || !absy)
2827 return absz ? z : half(detail::binary, (half::round_style==std::round_toward_neg_infinity) ? (z.data_|sign) : (z.data_&sign));
2828 for(; absx<0x400; absx<<=1,--exp) ;
2829 for(; absy<0x400; absy<<=1,--exp) ;
2830 detail::uint32 m = static_cast<detail::uint32>((absx&0x3FF)|0x400) * static_cast<detail::uint32>((absy&0x3FF)|0x400);
2831 int i = static_cast<int>(m >> 21);
2832 exp += (absx>>10) + (absy>>10) + i;
2833 m <<= 3 - i;
2834 if(absz)
2835 {
2836 int expz = 0;
2837 for(; absz<0x400; absz<<=1,--expz) ;
2838 expz += absz >> 10;
2839 detail::uint32 mz = static_cast<detail::uint32>((absz&0x3FF)|0x400) << 13;
2840 if(expz > exp || (expz == exp && mz > m))
2841 {
2842 std::swap(m, mz);
2843 std::swap(exp, expz);
2844 if(sub)
2845 sign = z.data_ & 0x8000;
2846 }
2847 int d = exp - expz;
2848 mz = (d<23) ? ((mz>>d)|((mz&((static_cast<detail::uint32>(1)<<d)-1))!=0)) : 1;
2849 if(sub)
2850 {
2851 m = m - mz;
2852 if(!m)
2853 return half(detail::binary, static_cast<unsigned>(half::round_style==std::round_toward_neg_infinity)<<15);
2854 for(; m<0x800000; m<<=1,--exp) ;
2855 }
2856 else
2857 {
2858 m += mz;
2859 i = static_cast<int>(m >> 24);
2860 m = (m>>i) | (m&i);
2861 exp += i;
2862 }
2863 }
2864 if(exp > 30)
2866 else if(exp < -10)
2869 #endif
2870 }
2871
2879 {
2880 return half(detail::binary, (!isnan(y) && (isnan(x) || (x.data_^(0x8000|(0x8000-(x.data_>>15)))) <
2881 (y.data_^(0x8000|(0x8000-(y.data_>>15)))))) ? detail::select(y.data_, x.data_) : detail::select(x.data_, y.data_));
2882 }
2883
2891 {
2892 return half(detail::binary, (!isnan(y) && (isnan(x) || (x.data_^(0x8000|(0x8000-(x.data_>>15)))) >
2893 (y.data_^(0x8000|(0x8000-(y.data_>>15)))))) ? detail::select(y.data_, x.data_) : detail::select(x.data_, y.data_));
2894 }
2895
2904 inline half fdim(half x, half y)
2905 {
2906 if(isnan(x) || isnan(y))
2907 return half(detail::binary, detail::signal(x.data_, y.data_));
2908 return (x.data_^(0x8000|(0x8000-(x.data_>>15)))) <= (y.data_^(0x8000|(0x8000-(y.data_>>15)))) ? half(detail::binary, 0) : (x-y);
2909 }
2910
2915 inline half nanh(const char *arg)
2916 {
2917 unsigned int value = 0x7FFF;
2918 while(*arg)
2919 value ^= static_cast<unsigned>(*arg++) & 0xFF;
2920 return half(detail::binary, value);
2921 }
2922
2927
2936 inline half exp(half arg)
2937 {
2938 #ifdef HALF_ARITHMETIC_TYPE
2940 #else
2941 int abs = arg.data_ & 0x7FFF, e = (abs>>10) + (abs<=0x3FF), exp;
2942 if(!abs)
2943 return half(detail::binary, 0x3C00);
2944 if(abs >= 0x7C00)
2945 return half(detail::binary, (abs==0x7C00) ? (0x7C00&((arg.data_>>15)-1U)) : detail::signal(arg.data_));
2946 if(abs >= 0x4C80)
2948 detail::uint32 m = detail::multiply64(static_cast<detail::uint32>((abs&0x3FF)+((abs>0x3FF)<<10))<<21, 0xB8AA3B29);
2949 if(e < 14)
2950 {
2951 exp = 0;
2952 m >>= 14 - e;
2953 }
2954 else
2955 {
2956 exp = static_cast<int>(m >> (45-e));
2957 m = (m<<(e-14)) & 0x7FFFFFFF;
2958 }
2959 return half(detail::binary, detail::exp2_post<half::round_style>(m, exp, (arg.data_&0x8000)!=0, 0, 26));
2960 #endif
2961 }
2962
2971 inline half exp2(half arg)
2972 {
2973 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
2975 #else
2976 int abs = arg.data_ & 0x7FFF, e = (abs>>10) + (abs<=0x3FF), exp = (abs&0x3FF) + ((abs>0x3FF)<<10);
2977 if(!abs)
2978 return half(detail::binary, 0x3C00);
2979 if(abs >= 0x7C00)
2980 return half(detail::binary, (abs==0x7C00) ? (0x7C00&((arg.data_>>15)-1U)) : detail::signal(arg.data_));
2981 if(abs >= 0x4E40)
2984 (static_cast<detail::uint32>(exp)<<(6+e))&0x7FFFFFFF, exp>>(25-e), (arg.data_&0x8000)!=0, 0, 28));
2985 #endif
2986 }
2987
2997 inline half expm1(half arg)
2998 {
2999 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3001 #else
3002 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000, e = (abs>>10) + (abs<=0x3FF), exp;
3003 if(!abs)
3004 return arg;
3005 if(abs >= 0x7C00)
3006 return half(detail::binary, (abs==0x7C00) ? (0x7C00+(sign>>1)) : detail::signal(arg.data_));
3007 if(abs >= 0x4A00)
3009 detail::uint32 m = detail::multiply64(static_cast<detail::uint32>((abs&0x3FF)+((abs>0x3FF)<<10))<<21, 0xB8AA3B29);
3010 if(e < 14)
3011 {
3012 exp = 0;
3013 m >>= 14 - e;
3014 }
3015 else
3016 {
3017 exp = static_cast<unsigned int>(m >> (45-e));
3018 m = (m<<(e-14)) & 0x7FFFFFFF;
3019 }
3020 m = detail::exp2(m);
3021 if(sign)
3022 {
3023 int s = 0;
3024 if(m > 0x80000000)
3025 {
3026 ++exp;
3027 m = detail::divide64(0x80000000, m, s);
3028 }
3029 m = 0x80000000 - ((m>>exp)|((m&((static_cast<detail::uint32>(1)<<exp)-1))!=0)|s);
3030 exp = 0;
3031 }
3032 else
3033 m -= (exp<31) ? (0x80000000>>exp) : 1;
3034 for(exp+=14; m<0x80000000 && exp; m<<=1,--exp) ;
3035 if(exp > 29)
3037 return half(detail::binary, detail::rounded<half::round_style,true>(sign+(exp<<10)+static_cast<unsigned int>(m>>21), static_cast<int>((m>>20)&1), (m&0xFFFFF)!=0));
3038 #endif
3039 }
3040
3050 inline half log(half arg)
3051 {
3052 #ifdef HALF_ARITHMETIC_TYPE
3054 #else
3055 int abs = arg.data_ & 0x7FFF, exp = -15;
3056 if(!abs)
3057 return half(detail::binary, detail::pole(0x8000));
3058 if(arg.data_ & 0x8000)
3059 return half(detail::binary, (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3060 if(abs >= 0x7C00)
3061 return (abs==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
3062 for(; abs<0x400; abs<<=1,--exp) ;
3063 exp += abs >> 10;
3065 detail::log2(static_cast<detail::uint32>((abs&0x3FF)|0x400)<<20, 27)+8, exp, 17));
3066 #endif
3067 }
3068
3078 inline half log10(half arg)
3079 {
3080 #ifdef HALF_ARITHMETIC_TYPE
3082 #else
3083 int abs = arg.data_ & 0x7FFF, exp = -15;
3084 if(!abs)
3085 return half(detail::binary, detail::pole(0x8000));
3086 if(arg.data_ & 0x8000)
3087 return half(detail::binary, (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3088 if(abs >= 0x7C00)
3089 return (abs==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
3090 switch(abs)
3091 {
3092 case 0x4900: return half(detail::binary, 0x3C00);
3093 case 0x5640: return half(detail::binary, 0x4000);
3094 case 0x63D0: return half(detail::binary, 0x4200);
3095 case 0x70E2: return half(detail::binary, 0x4400);
3096 }
3097 for(; abs<0x400; abs<<=1,--exp) ;
3098 exp += abs >> 10;
3100 detail::log2(static_cast<detail::uint32>((abs&0x3FF)|0x400)<<20, 27)+8, exp, 16));
3101 #endif
3102 }
3103
3113 inline half log2(half arg)
3114 {
3115 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3117 #else
3118 int abs = arg.data_ & 0x7FFF, exp = -15, s = 0;
3119 if(!abs)
3120 return half(detail::binary, detail::pole(0x8000));
3121 if(arg.data_ & 0x8000)
3122 return half(detail::binary, (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3123 if(abs >= 0x7C00)
3124 return (abs==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
3125 if(abs == 0x3C00)
3126 return half(detail::binary, 0);
3127 for(; abs<0x400; abs<<=1,--exp) ;
3128 exp += (abs>>10);
3129 if(!(abs&0x3FF))
3130 {
3131 unsigned int value = static_cast<unsigned>(exp<0) << 15, m = std::abs(exp) << 6;
3132 for(exp=18; m<0x400; m<<=1,--exp) ;
3133 return half(detail::binary, value+(exp<<10)+m);
3134 }
3135 detail::uint32 ilog = exp, sign = detail::sign_mask(ilog), m =
3136 (((ilog<<27)+(detail::log2(static_cast<detail::uint32>((abs&0x3FF)|0x400)<<20, 28)>>4))^sign) - sign;
3137 if(!m)
3138 return half(detail::binary, 0);
3139 for(exp=14; m<0x8000000 && exp; m<<=1,--exp) ;
3140 for(; m>0xFFFFFFF; m>>=1,++exp)
3141 s |= m & 1;
3143 #endif
3144 }
3145
3156 inline half log1p(half arg)
3157 {
3158 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3160 #else
3161 if(arg.data_ >= 0xBC00)
3162 return half(detail::binary, (arg.data_==0xBC00) ? detail::pole(0x8000) : (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
3163 int abs = arg.data_ & 0x7FFF, exp = -15;
3164 if(!abs || abs >= 0x7C00)
3165 return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3166 for(; abs<0x400; abs<<=1,--exp) ;
3167 exp += abs >> 10;
3168 detail::uint32 m = static_cast<detail::uint32>((abs&0x3FF)|0x400) << 20;
3169 if(arg.data_ & 0x8000)
3170 {
3171 m = 0x40000000 - (m>>-exp);
3172 for(exp=0; m<0x40000000; m<<=1,--exp) ;
3173 }
3174 else
3175 {
3176 if(exp < 0)
3177 {
3178 m = 0x40000000 + (m>>-exp);
3179 exp = 0;
3180 }
3181 else
3182 {
3183 m += 0x40000000 >> exp;
3184 int i = static_cast<int>(m >> 31);
3185 m >>= i;
3186 exp += i;
3187 }
3188 }
3190 #endif
3191 }
3192
3197
3206 inline half sqrt(half arg)
3207 {
3208 #ifdef HALF_ARITHMETIC_TYPE
3210 #else
3211 int abs = arg.data_ & 0x7FFF, exp = 15;
3212 if(!abs || arg.data_ >= 0x7C00)
3213 return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (arg.data_>0x8000) ? detail::invalid() : arg.data_);
3214 for(; abs<0x400; abs<<=1,--exp) ;
3215 detail::uint32 r = static_cast<detail::uint32>((abs&0x3FF)|0x400) << 10, m = detail::sqrt<20>(r, exp+=abs>>10);
3216 return half(detail::binary, detail::rounded<half::round_style,false>((exp<<10)+(m&0x3FF), r>m, r!=0));
3217 #endif
3218 }
3219
3227 inline half rsqrt(half arg)
3228 {
3229 #ifdef HALF_ARITHMETIC_TYPE
3230 return half(detail::binary, detail::float2half<half::round_style>(detail::internal_t(1)/std::sqrt(detail::half2float<detail::internal_t>(arg.data_))));
3231 #else
3232 unsigned int abs = arg.data_ & 0x7FFF, bias = 0x4000;
3233 if(!abs || arg.data_ >= 0x7C00)
3234 return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (arg.data_>0x8000) ?
3235 detail::invalid() : !abs ? detail::pole(arg.data_&0x8000) : 0);
3236 for(; abs<0x400; abs<<=1,bias-=0x400) ;
3237 unsigned int frac = (abs+=bias) & 0x7FF;
3238 if(frac == 0x400)
3239 return half(detail::binary, 0x7A00-(abs>>1));
3240 if((half::round_style == std::round_to_nearest && (frac == 0x3FE || frac == 0x76C)) ||
3241 (half::round_style != std::round_to_nearest && (frac == 0x15A || frac == 0x3FC || frac == 0x401 || frac == 0x402 || frac == 0x67B)))
3242 return pow(arg, half(detail::binary, 0xB800));
3243 detail::uint32 f = 0x17376 - abs, mx = (abs&0x3FF) | 0x400, my = ((f>>1)&0x3FF) | 0x400, mz = my * my;
3244 int expy = static_cast<int>(f>>11) - 31, expx = 32 - (abs>>10), i = static_cast<int>(mz >> 21);
3245 for(mz=0x60000000-(((mz>>i)*mx)>>(expx-2*expy-i)); mz<0x40000000; mz<<=1,--expy) ;
3246 i = static_cast<int>((my*=mz>>10) >> 31);
3247 expy += i;
3248 my = (my>>(20+i)) + 1;
3249 i = static_cast<int>((mz=my*my) >> 21);
3250 for(mz=0x60000000-(((mz>>i)*mx)>>(expx-2*expy-i)); mz<0x40000000; mz<<=1,--expy) ;
3251 i = static_cast<int>((my*=(mz>>10)+1) >> 31);
3253 #endif
3254 }
3255
3264 inline half cbrt(half arg)
3265 {
3266 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3268 #else
3269 int abs = arg.data_ & 0x7FFF, exp = -15;
3270 if(!abs || abs == 0x3C00 || abs >= 0x7C00)
3271 return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3272 for(; abs<0x400; abs<<=1, --exp);
3273 detail::uint32 ilog = exp + (abs>>10), sign = detail::sign_mask(ilog), f, m =
3274 (((ilog<<27)+(detail::log2(static_cast<detail::uint32>((abs&0x3FF)|0x400)<<20, 24)>>4))^sign) - sign;
3275 for(exp=2; m<0x80000000; m<<=1,--exp) ;
3276 m = detail::multiply64(m, 0xAAAAAAAB);
3277 int i = static_cast<int>(m >> 31), s;
3278 exp += i;
3279 m <<= 1 - i;
3280 if(exp < 0)
3281 {
3282 f = m >> -exp;
3283 exp = 0;
3284 }
3285 else
3286 {
3287 f = (m<<exp) & 0x7FFFFFFF;
3288 exp = static_cast<int>(m >> (31-exp));
3289 }
3290 m = detail::exp2(f, (half::round_style==std::round_to_nearest) ? 29 : 26);
3291 if(sign)
3292 {
3293 if(m > 0x80000000)
3294 {
3295 m = detail::divide64(0x80000000, m, s);
3296 ++exp;
3297 }
3298 exp = -exp;
3299 }
3300 return half(detail::binary, (half::round_style==std::round_to_nearest) ?
3302 detail::fixed2half<half::round_style,23,false,false,false>((m+0x80)>>8, exp+14, arg.data_&0x8000));
3303 #endif
3304 }
3305
3315 inline half hypot(half x, half y)
3316 {
3317 #ifdef HALF_ARITHMETIC_TYPE
3318 detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_);
3319 #if HALF_ENABLE_CPP11_CMATH
3320 return half(detail::binary, detail::float2half<half::round_style>(std::hypot(fx, fy)));
3321 #else
3322 return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(fx*fx+fy*fy)));
3323 #endif
3324 #else
3325 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, expx = 0, expy = 0;
3326 if(absx >= 0x7C00 || absy >= 0x7C00)
3327 return half(detail::binary, (absx==0x7C00) ? detail::select(0x7C00, y.data_) :
3328 (absy==0x7C00) ? detail::select(0x7C00, x.data_) : detail::signal(x.data_, y.data_));
3329 if(!absx)
3330 return half(detail::binary, absy ? detail::check_underflow(absy) : 0);
3331 if(!absy)
3333 if(absy > absx)
3334 std::swap(absx, absy);
3335 for(; absx<0x400; absx<<=1,--expx) ;
3336 for(; absy<0x400; absy<<=1,--expy) ;
3337 detail::uint32 mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400;
3338 mx *= mx;
3339 my *= my;
3340 int ix = static_cast<int>(mx >> 21), iy = static_cast<int>(my >> 21);
3341 expx = 2*(expx+(absx>>10)) - 15 + ix;
3342 expy = 2*(expy+(absy>>10)) - 15 + iy;
3343 mx <<= 10 - ix;
3344 my <<= 10 - iy;
3345 int d = expx - expy;
3346 my = (d<30) ? ((my>>d)|((my&((static_cast<detail::uint32>(1)<<d)-1))!=0)) : 1;
3348 #endif
3349 }
3350
3361 inline half hypot(half x, half y, half z)
3362 {
3363 #ifdef HALF_ARITHMETIC_TYPE
3365 return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(fx*fx+fy*fy+fz*fz)));
3366 #else
3367 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, expx = 0, expy = 0, expz = 0;
3368 if(!absx)
3369 return hypot(y, z);
3370 if(!absy)
3371 return hypot(x, z);
3372 if(!absz)
3373 return hypot(x, y);
3374 if(absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
3375 return half(detail::binary, (absx==0x7C00) ? detail::select(0x7C00, detail::select(y.data_, z.data_)) :
3376 (absy==0x7C00) ? detail::select(0x7C00, detail::select(x.data_, z.data_)) :
3377 (absz==0x7C00) ? detail::select(0x7C00, detail::select(x.data_, y.data_)) :
3378 detail::signal(x.data_, y.data_, z.data_));
3379 if(absz > absy)
3380 std::swap(absy, absz);
3381 if(absy > absx)
3382 std::swap(absx, absy);
3383 if(absz > absy)
3384 std::swap(absy, absz);
3385 for(; absx<0x400; absx<<=1,--expx) ;
3386 for(; absy<0x400; absy<<=1,--expy) ;
3387 for(; absz<0x400; absz<<=1,--expz) ;
3388 detail::uint32 mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400, mz = (absz&0x3FF) | 0x400;
3389 mx *= mx;
3390 my *= my;
3391 mz *= mz;
3392 int ix = static_cast<int>(mx >> 21), iy = static_cast<int>(my >> 21), iz = static_cast<int>(mz >> 21);
3393 expx = 2*(expx+(absx>>10)) - 15 + ix;
3394 expy = 2*(expy+(absy>>10)) - 15 + iy;
3395 expz = 2*(expz+(absz>>10)) - 15 + iz;
3396 mx <<= 10 - ix;
3397 my <<= 10 - iy;
3398 mz <<= 10 - iz;
3399 int d = expy - expz;
3400 mz = (d<30) ? ((mz>>d)|((mz&((static_cast<detail::uint32>(1)<<d)-1))!=0)) : 1;
3401 my += mz;
3402 if(my & 0x80000000)
3403 {
3404 my = (my>>1) | (my&1);
3405 if(++expy > expx)
3406 {
3407 std::swap(mx, my);
3408 std::swap(expx, expy);
3409 }
3410 }
3411 d = expx - expy;
3412 my = (d<30) ? ((my>>d)|((my&((static_cast<detail::uint32>(1)<<d)-1))!=0)) : 1;
3414 #endif
3415 }
3416
3427 inline half pow(half x, half y)
3428 {
3429 #ifdef HALF_ARITHMETIC_TYPE
3431 #else
3432 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -15;
3433 if(!absy || x.data_ == 0x3C00)
3434 return half(detail::binary, detail::select(0x3C00, (x.data_==0x3C00) ? y.data_ : x.data_));
3435 bool is_int = absy >= 0x6400 || (absy>=0x3C00 && !(absy&((1<<(25-(absy>>10)))-1)));
3436 unsigned int sign = x.data_ & (static_cast<unsigned>((absy<0x6800)&&is_int&&((absy>>(25-(absy>>10)))&1))<<15);
3437 if(absx >= 0x7C00 || absy >= 0x7C00)
3438 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
3439 (absy==0x7C00) ? ((absx==0x3C00) ? 0x3C00 : (!absx && y.data_==0xFC00) ? detail::pole() :
3440 (0x7C00&-((y.data_>>15)^(absx>0x3C00)))) : (sign|(0x7C00&((y.data_>>15)-1U))));
3441 if(!absx)
3442 return half(detail::binary, (y.data_&0x8000) ? detail::pole(sign) : sign);
3443 if((x.data_&0x8000) && !is_int)
3445 if(x.data_ == 0xBC00)
3446 return half(detail::binary, sign|0x3C00);
3447 switch(y.data_)
3448 {
3449 case 0x3800: return sqrt(x);
3450 case 0x3C00: return half(detail::binary, detail::check_underflow(x.data_));
3451 case 0x4000: return x * x;
3452 case 0xBC00: return half(detail::binary, 0x3C00) / x;
3453 }
3454 for(; absx<0x400; absx<<=1,--exp) ;
3455 detail::uint32 ilog = exp + (absx>>10), msign = detail::sign_mask(ilog), f, m =
3456 (((ilog<<27)+((detail::log2(static_cast<detail::uint32>((absx&0x3FF)|0x400)<<20)+8)>>4))^msign) - msign;
3457 for(exp=-11; m<0x80000000; m<<=1,--exp) ;
3458 for(; absy<0x400; absy<<=1,--exp) ;
3459 m = detail::multiply64(m, static_cast<detail::uint32>((absy&0x3FF)|0x400)<<21);
3460 int i = static_cast<int>(m >> 31);
3461 exp += (absy>>10) + i;
3462 m <<= 1 - i;
3463 if(exp < 0)
3464 {
3465 f = m >> -exp;
3466 exp = 0;
3467 }
3468 else
3469 {
3470 f = (m<<exp) & 0x7FFFFFFF;
3471 exp = static_cast<int>(m >> (31-exp));
3472 }
3473 return half(detail::binary, detail::exp2_post<half::round_style>(f, exp, ((msign&1)^(y.data_>>15))!=0, sign));
3474 #endif
3475 }
3476
3481
3491 inline void sincos(half arg, half *sin, half *cos)
3492 {
3493 #ifdef HALF_ARITHMETIC_TYPE
3494 detail::internal_t f = detail::half2float<detail::internal_t>(arg.data_);
3497 #else
3498 int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15, k;
3499 if(abs >= 0x7C00)
3500 *sin = *cos = half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3501 else if(!abs)
3502 {
3503 *sin = arg;
3504 *cos = half(detail::binary, 0x3C00);
3505 }
3506 else if(abs < 0x2500)
3507 {
3510 }
3511 else
3512 {
3513 if(half::round_style != std::round_to_nearest)
3514 {
3515 switch(abs)
3516 {
3517 case 0x48B7:
3518 *sin = half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x1D07, 1, 1));
3520 return;
3521 case 0x598C:
3522 *sin = half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x3BFF, 1, 1));
3524 return;
3525 case 0x6A64:
3526 *sin = half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x3BFE, 1, 1));
3528 return;
3529 case 0x6D8C:
3530 *sin = half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x0FE6, 1, 1));
3532 return;
3533 }
3534 }
3535 std::pair<detail::uint32,detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
3536 switch(k & 3)
3537 {
3538 case 1: sc = std::make_pair(sc.second, -sc.first); break;
3539 case 2: sc = std::make_pair(-sc.first, -sc.second); break;
3540 case 3: sc = std::make_pair(-sc.second, sc.first); break;
3541 }
3544 }
3545 #endif
3546 }
3547
3556 inline half sin(half arg)
3557 {
3558 #ifdef HALF_ARITHMETIC_TYPE
3560 #else
3561 int abs = arg.data_ & 0x7FFF, k;
3562 if(!abs)
3563 return arg;
3564 if(abs >= 0x7C00)
3565 return half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3566 if(abs < 0x2900)
3568 if(half::round_style != std::round_to_nearest)
3569 switch(abs)
3570 {
3571 case 0x48B7: return half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x1D07, 1, 1));
3572 case 0x6A64: return half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x3BFE, 1, 1));
3573 case 0x6D8C: return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x0FE6, 1, 1));
3574 }
3575 std::pair<detail::uint32,detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
3576 detail::uint32 sign = -static_cast<detail::uint32>(((k>>1)&1)^(arg.data_>>15));
3577 return half(detail::binary, detail::fixed2half<half::round_style,30,true,true,true>((((k&1) ? sc.second : sc.first)^sign) - sign));
3578 #endif
3579 }
3580
3589 inline half cos(half arg)
3590 {
3591 #ifdef HALF_ARITHMETIC_TYPE
3593 #else
3594 int abs = arg.data_ & 0x7FFF, k;
3595 if(!abs)
3596 return half(detail::binary, 0x3C00);
3597 if(abs >= 0x7C00)
3598 return half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3599 if(abs < 0x2500)
3601 if(half::round_style != std::round_to_nearest && abs == 0x598C)
3603 std::pair<detail::uint32,detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
3604 detail::uint32 sign = -static_cast<detail::uint32>(((k>>1)^k)&1);
3605 return half(detail::binary, detail::fixed2half<half::round_style,30,true,true,true>((((k&1) ? sc.first : sc.second)^sign) - sign));
3606 #endif
3607 }
3608
3617 inline half tan(half arg)
3618 {
3619 #ifdef HALF_ARITHMETIC_TYPE
3621 #else
3622 int abs = arg.data_ & 0x7FFF, exp = 13, k;
3623 if(!abs)
3624 return arg;
3625 if(abs >= 0x7C00)
3626 return half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3627 if(abs < 0x2700)
3629 if(half::round_style != std::round_to_nearest)
3630 switch(abs)
3631 {
3632 case 0x658C: return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x07E6, 1, 1));
3633 case 0x7330: return half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x4B62, 1, 1));
3634 }
3635 std::pair<detail::uint32,detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 30);
3636 if(k & 1)
3637 sc = std::make_pair(-sc.second, sc.first);
3638 detail::uint32 signy = detail::sign_mask(sc.first), signx = detail::sign_mask(sc.second);
3639 detail::uint32 my = (sc.first^signy) - signy, mx = (sc.second^signx) - signx;
3640 for(; my<0x80000000; my<<=1,--exp) ;
3641 for(; mx<0x80000000; mx<<=1,++exp) ;
3642 return half(detail::binary, detail::tangent_post<half::round_style>(my, mx, exp, (signy^signx^arg.data_)&0x8000));
3643 #endif
3644 }
3645
3654 inline half asin(half arg)
3655 {
3656 #ifdef HALF_ARITHMETIC_TYPE
3658 #else
3659 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
3660 if(!abs)
3661 return arg;
3662 if(abs >= 0x3C00)
3663 return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (abs>0x3C00) ? detail::invalid() :
3664 detail::rounded<half::round_style,true>(sign|0x3E48, 0, 1));
3665 if(abs < 0x2900)
3667 if(half::round_style != std::round_to_nearest && (abs == 0x2B44 || abs == 0x2DC3))
3669 std::pair<detail::uint32,detail::uint32> sc = detail::atan2_args(abs);
3670 detail::uint32 m = detail::atan2(sc.first, sc.second, (half::round_style==std::round_to_nearest) ? 27 : 26);
3672 #endif
3673 }
3674
3683 inline half acos(half arg)
3684 {
3685 #ifdef HALF_ARITHMETIC_TYPE
3687 #else
3688 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15;
3689 if(!abs)
3691 if(abs >= 0x3C00)
3692 return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (abs>0x3C00) ? detail::invalid() :
3693 sign ? detail::rounded<half::round_style,true>(0x4248, 0, 1) : 0);
3694 std::pair<detail::uint32,detail::uint32> cs = detail::atan2_args(abs);
3695 detail::uint32 m = detail::atan2(cs.second, cs.first, 28);
3696 return half(detail::binary, detail::fixed2half<half::round_style,31,false,true,true>(sign ? (0xC90FDAA2-m) : m, 15, 0, sign));
3697 #endif
3698 }
3699
3708 inline half atan(half arg)
3709 {
3710 #ifdef HALF_ARITHMETIC_TYPE
3712 #else
3713 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
3714 if(!abs)
3715 return arg;
3716 if(abs >= 0x7C00)
3717 return half(detail::binary, (abs==0x7C00) ? detail::rounded<half::round_style,true>(sign|0x3E48, 0, 1) : detail::signal(arg.data_));
3718 if(abs <= 0x2700)
3720 int exp = (abs>>10) + (abs<=0x3FF);
3721 detail::uint32 my = (abs&0x3FF) | ((abs>0x3FF)<<10);
3722 detail::uint32 m = (exp>15) ? detail::atan2(my<<19, 0x20000000>>(exp-15), (half::round_style==std::round_to_nearest) ? 26 : 24) :
3723 detail::atan2(my<<(exp+4), 0x20000000, (half::round_style==std::round_to_nearest) ? 30 : 28);
3725 #endif
3726 }
3727
3738 inline half atan2(half y, half x)
3739 {
3740 #ifdef HALF_ARITHMETIC_TYPE
3742 #else
3743 unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, signx = x.data_ >> 15, signy = y.data_ & 0x8000;
3744 if(absx >= 0x7C00 || absy >= 0x7C00)
3745 {
3746 if(absx > 0x7C00 || absy > 0x7C00)
3747 return half(detail::binary, detail::signal(x.data_, y.data_));
3748 if(absy == 0x7C00)
3749 return half(detail::binary, (absx<0x7C00) ? detail::rounded<half::round_style,true>(signy|0x3E48, 0, 1) :
3750 signx ? detail::rounded<half::round_style,true>(signy|0x40B6, 0, 1) :
3751 detail::rounded<half::round_style,true>(signy|0x3A48, 0, 1));
3752 return (x.data_==0x7C00) ? half(detail::binary, signy) : half(detail::binary, detail::rounded<half::round_style,true>(signy|0x4248, 0, 1));
3753 }
3754 if(!absy)
3755 return signx ? half(detail::binary, detail::rounded<half::round_style,true>(signy|0x4248, 0, 1)) : y;
3756 if(!absx)
3757 return half(detail::binary, detail::rounded<half::round_style,true>(signy|0x3E48, 0, 1));
3758 int d = (absy>>10) + (absy<=0x3FF) - (absx>>10) - (absx<=0x3FF);
3759 if(d > (signx ? 18 : 12))
3760 return half(detail::binary, detail::rounded<half::round_style,true>(signy|0x3E48, 0, 1));
3761 if(signx && d < -11)
3762 return half(detail::binary, detail::rounded<half::round_style,true>(signy|0x4248, 0, 1));
3763 if(!signx && d < ((half::round_style==std::round_toward_zero) ? -15 : -9))
3764 {
3765 for(; absy<0x400; absy<<=1,--d) ;
3766 detail::uint32 mx = ((absx<<1)&0x7FF) | 0x800, my = ((absy<<1)&0x7FF) | 0x800;
3767 int i = my < mx;
3768 d -= i;
3769 if(d < -25)
3771 my <<= 11 + i;
3773 }
3774 detail::uint32 m = detail::atan2( ((absy&0x3FF)|((absy>0x3FF)<<10))<<(19+((d<0) ? d : (d>0) ? 0 : -1)),
3775 ((absx&0x3FF)|((absx>0x3FF)<<10))<<(19-((d>0) ? d : (d<0) ? 0 : 1)));
3776 return half(detail::binary, detail::fixed2half<half::round_style,31,false,true,true>(signx ? (0xC90FDAA2-m) : m, 15, signy, signx));
3777 #endif
3778 }
3779
3784
3793 inline half sinh(half arg)
3794 {
3795 #ifdef HALF_ARITHMETIC_TYPE
3797 #else
3798 int abs = arg.data_ & 0x7FFF, exp;
3799 if(!abs || abs >= 0x7C00)
3800 return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3801 if(abs <= 0x2900)
3803 std::pair<detail::uint32,detail::uint32> mm = detail::hyperbolic_args(abs, exp, (half::round_style==std::round_to_nearest) ? 29 : 27);
3804 detail::uint32 m = mm.first - mm.second;
3805 for(exp+=13; m<0x80000000 && exp; m<<=1,--exp) ;
3806 unsigned int sign = arg.data_ & 0x8000;
3807 if(exp > 29)
3810 #endif
3811 }
3812
3821 inline half cosh(half arg)
3822 {
3823 #ifdef HALF_ARITHMETIC_TYPE
3825 #else
3826 int abs = arg.data_ & 0x7FFF, exp;
3827 if(!abs)
3828 return half(detail::binary, 0x3C00);
3829 if(abs >= 0x7C00)
3830 return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : 0x7C00);
3831 std::pair<detail::uint32,detail::uint32> mm = detail::hyperbolic_args(abs, exp, (half::round_style==std::round_to_nearest) ? 23 : 26);
3832 detail::uint32 m = mm.first + mm.second;
3833 int i = static_cast<int>((~m & 0xFFFFFFFF) >> 31);
3834 m = (m>>i) | (m&i) | 0x80000000;
3835 if((exp+=13+i) > 29)
3838 #endif
3839 }
3840
3849 inline half tanh(half arg)
3850 {
3851 #ifdef HALF_ARITHMETIC_TYPE
3853 #else
3854 int abs = arg.data_ & 0x7FFF, exp;
3855 if(!abs)
3856 return arg;
3857 if(abs >= 0x7C00)
3858 return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (arg.data_-0x4000));
3859 if(abs >= 0x4500)
3860 return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x3BFF, 1, 1));
3861 if(abs < 0x2700)
3863 if(half::round_style != std::round_to_nearest && abs == 0x2D3F)
3865 std::pair<detail::uint32,detail::uint32> mm = detail::hyperbolic_args(abs, exp, 27);
3866 detail::uint32 my = mm.first - mm.second - (half::round_style!=std::round_to_nearest), mx = mm.first + mm.second;
3867 int i = static_cast<int>((~mx&0xFFFFFFFF) >> 31);
3868 for(exp=13; my<0x80000000; my<<=1,--exp) ;
3869 mx = (mx>>i) | 0x80000000;
3870 return half(detail::binary, detail::tangent_post<half::round_style>(my, mx, exp-i, arg.data_&0x8000));
3871 #endif
3872 }
3873
3882 inline half asinh(half arg)
3883 {
3884 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3886 #else
3887 int abs = arg.data_ & 0x7FFF;
3888 if(!abs || abs >= 0x7C00)
3889 return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3890 if(abs <= 0x2900)
3892 if(half::round_style != std::round_to_nearest)
3893 switch(abs)
3894 {
3895 case 0x32D4: return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-13, 1, 1));
3896 case 0x3B5B: return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-197, 1, 1));
3897 }
3899 #endif
3900 }
3901
3910 inline half acosh(half arg)
3911 {
3912 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3914 #else
3915 int abs = arg.data_ & 0x7FFF;
3916 if((arg.data_&0x8000) || abs < 0x3C00)
3917 return half(detail::binary, (abs<=0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3918 if(abs == 0x3C00)
3919 return half(detail::binary, 0);
3920 if(arg.data_ >= 0x7C00)
3921 return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
3923 #endif
3924 }
3925
3935 inline half atanh(half arg)
3936 {
3937 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3939 #else
3940 int abs = arg.data_ & 0x7FFF, exp = 0;
3941 if(!abs)
3942 return arg;
3943 if(abs >= 0x3C00)
3944 return half(detail::binary, (abs==0x3C00) ? detail::pole(arg.data_&0x8000) : (abs<=0x7C00) ? detail::invalid() : detail::signal(arg.data_));
3945 if(abs < 0x2700)
3947 detail::uint32 m = static_cast<detail::uint32>((abs&0x3FF)|((abs>0x3FF)<<10)) << ((abs>>10)+(abs<=0x3FF)+6), my = 0x80000000 + m, mx = 0x80000000 - m;
3948 for(; mx<0x80000000; mx<<=1,++exp) ;
3949 int i = my >= mx, s;
3951 (detail::divide64(my>>i, mx, s)+1)>>1, 27)+0x10, exp+i-1, 16, arg.data_&0x8000));
3952 #endif
3953 }
3954
3959
3968 inline half erf(half arg)
3969 {
3970 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3972 #else
3973 unsigned int abs = arg.data_ & 0x7FFF;
3974 if(!abs || abs >= 0x7C00)
3975 return (abs>=0x7C00) ? half(detail::binary, (abs==0x7C00) ? (arg.data_-0x4000) : detail::signal(arg.data_)) : arg;
3976 if(abs >= 0x4200)
3977 return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x3BFF, 1, 1));
3979 #endif
3980 }
3981
3990 inline half erfc(half arg)
3991 {
3992 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
3994 #else
3995 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
3996 if(abs >= 0x7C00)
3997 return (abs>=0x7C00) ? half(detail::binary, (abs==0x7C00) ? (sign>>1) : detail::signal(arg.data_)) : arg;
3998 if(!abs)
3999 return half(detail::binary, 0x3C00);
4000 if(abs >= 0x4400)
4001 return half(detail::binary, detail::rounded<half::round_style,true>((sign>>1)-(sign>>15), sign>>15, 1));
4003 #endif
4004 }
4005
4015 inline half lgamma(half arg)
4016 {
4017 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
4019 #else
4020 int abs = arg.data_ & 0x7FFF;
4021 if(abs >= 0x7C00)
4022 return half(detail::binary, (abs==0x7C00) ? 0x7C00 : detail::signal(arg.data_));
4023 if(!abs || arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(abs&((1<<(25-(abs>>10)))-1))))
4024 return half(detail::binary, detail::pole());
4025 if(arg.data_ == 0x3C00 || arg.data_ == 0x4000)
4026 return half(detail::binary, 0);
4028 #endif
4029 }
4030
4040 inline half tgamma(half arg)
4041 {
4042 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
4044 #else
4045 unsigned int abs = arg.data_ & 0x7FFF;
4046 if(!abs)
4047 return half(detail::binary, detail::pole(arg.data_));
4048 if(abs >= 0x7C00)
4049 return (arg.data_==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
4050 if(arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(abs&((1<<(25-(abs>>10)))-1))))
4052 if(arg.data_ >= 0xCA80)
4053 return half(detail::binary, detail::underflow<half::round_style>((1-((abs>>(25-(abs>>10)))&1))<<15));
4054 if(arg.data_ <= 0x100 || (arg.data_ >= 0x4900 && arg.data_ < 0x8000))
4056 if(arg.data_ == 0x3C00)
4057 return arg;
4059 #endif
4060 }
4061
4066
4074
4082
4090
4098
4105
4113
4120 inline long lrint(half arg) { return detail::half2int<half::round_style,true,true,long>(arg.data_); }
4121
4128#if HALF_ENABLE_CPP11_LONG_LONG
4134 inline long long llround(half arg) { return detail::half2int<std::round_to_nearest,false,false,long long>(arg.data_); }
4135
4142 inline long long llrint(half arg) { return detail::half2int<half::round_style,true,true,long long>(arg.data_); }
4143#endif
4144
4149
4156 inline half frexp(half arg, int *exp)
4157 {
4158 *exp = 0;
4159 unsigned int abs = arg.data_ & 0x7FFF;
4160 if(abs >= 0x7C00 || !abs)
4161 return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
4162 for(; abs<0x400; abs<<=1,--*exp) ;
4163 *exp += (abs>>10) - 14;
4164 return half(detail::binary, (arg.data_&0x8000)|0x3800|(abs&0x3FF));
4165 }
4166
4176 inline half scalbln(half arg, long exp)
4177 {
4178 unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
4179 if(abs >= 0x7C00 || !abs)
4180 return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
4181 for(; abs<0x400; abs<<=1,--exp) ;
4182 exp += abs >> 10;
4183 if(exp > 30)
4185 else if(exp < -10)
4187 else if(exp > 0)
4188 return half(detail::binary, sign|(exp<<10)|(abs&0x3FF));
4189 unsigned int m = (abs&0x3FF) | 0x400;
4190 return half(detail::binary, detail::rounded<half::round_style,false>(sign|(m>>(1-exp)), (m>>-exp)&1, (m&((1<<-exp)-1))!=0));
4191 }
4192
4202 inline half scalbn(half arg, int exp) { return scalbln(arg, exp); }
4203
4213 inline half ldexp(half arg, int exp) { return scalbln(arg, exp); }
4214
4221 inline half modf(half arg, half *iptr)
4222 {
4223 unsigned int abs = arg.data_ & 0x7FFF;
4224 if(abs > 0x7C00)
4225 {
4226 arg = half(detail::binary, detail::signal(arg.data_));
4227 return *iptr = arg, arg;
4228 }
4229 if(abs >= 0x6400)
4230 return *iptr = arg, half(detail::binary, arg.data_&0x8000);
4231 if(abs < 0x3C00)
4232 return iptr->data_ = arg.data_ & 0x8000, arg;
4233 unsigned int exp = abs >> 10, mask = (1<<(25-exp)) - 1, m = arg.data_ & mask;
4234 iptr->data_ = arg.data_ & ~mask;
4235 if(!m)
4236 return half(detail::binary, arg.data_&0x8000);
4237 for(; m<0x400; m<<=1,--exp) ;
4238 return half(detail::binary, (arg.data_&0x8000)|(exp<<10)|(m&0x3FF));
4239 }
4240
4249 inline int ilogb(half arg)
4250 {
4251 int abs = arg.data_ & 0x7FFF, exp;
4252 if(!abs || abs >= 0x7C00)
4253 {
4255 return !abs ? FP_ILOGB0 : (abs==0x7C00) ? INT_MAX : FP_ILOGBNAN;
4256 }
4257 for(exp=(abs>>10)-15; abs<0x200; abs<<=1,--exp) ;
4258 return exp;
4259 }
4260
4267 inline half logb(half arg)
4268 {
4269 int abs = arg.data_ & 0x7FFF, exp;
4270 if(!abs)
4271 return half(detail::binary, detail::pole(0x8000));
4272 if(abs >= 0x7C00)
4273 return half(detail::binary, (abs==0x7C00) ? 0x7C00 : detail::signal(arg.data_));
4274 for(exp=(abs>>10)-15; abs<0x200; abs<<=1,--exp) ;
4275 unsigned int value = static_cast<unsigned>(exp<0) << 15;
4276 if(exp)
4277 {
4278 unsigned int m = std::abs(exp) << 6;
4279 for(exp=18; m<0x400; m<<=1,--exp) ;
4280 value |= (exp<<10) + m;
4281 }
4282 return half(detail::binary, value);
4283 }
4284
4293 inline half nextafter(half from, half to)
4294 {
4295 int fabs = from.data_ & 0x7FFF, tabs = to.data_ & 0x7FFF;
4296 if(fabs > 0x7C00 || tabs > 0x7C00)
4297 return half(detail::binary, detail::signal(from.data_, to.data_));
4298 if(from.data_ == to.data_ || !(fabs|tabs))
4299 return to;
4300 if(!fabs)
4301 {
4303 return half(detail::binary, (to.data_&0x8000)+1);
4304 }
4305 unsigned int out = from.data_ + (((from.data_>>15)^static_cast<unsigned>(
4306 (from.data_^(0x8000|(0x8000-(from.data_>>15))))<(to.data_^(0x8000|(0x8000-(to.data_>>15))))))<<1) - 1;
4307 detail::raise(FE_OVERFLOW, fabs<0x7C00 && (out&0x7C00)==0x7C00);
4309 return half(detail::binary, out);
4310 }
4311
4320 inline half nexttoward(half from, long double to)
4321 {
4322 int fabs = from.data_ & 0x7FFF;
4323 if(fabs > 0x7C00)
4324 return half(detail::binary, detail::signal(from.data_));
4325 long double lfrom = static_cast<long double>(from);
4326 if(detail::builtin_isnan(to) || lfrom == to)
4327 return half(static_cast<float>(to));
4328 if(!fabs)
4329 {
4331 return half(detail::binary, (static_cast<unsigned>(detail::builtin_signbit(to))<<15)+1);
4332 }
4333 unsigned int out = from.data_ + (((from.data_>>15)^static_cast<unsigned>(lfrom<to))<<1) - 1;
4334 detail::raise(FE_OVERFLOW, (out&0x7FFF)==0x7C00);
4336 return half(detail::binary, out);
4337 }
4338
4344 inline HALF_CONSTEXPR half copysign(half x, half y) { return half(detail::binary, x.data_^((x.data_^y.data_)&0x8000)); }
4345
4350
4360 {
4361 return !(arg.data_&0x7FFF) ? FP_ZERO :
4362 ((arg.data_&0x7FFF)<0x400) ? FP_SUBNORMAL :
4363 ((arg.data_&0x7FFF)<0x7C00) ? FP_NORMAL :
4364 ((arg.data_&0x7FFF)==0x7C00) ? FP_INFINITE :
4365 FP_NAN;
4366 }
4367
4373 inline HALF_CONSTEXPR bool isfinite(half arg) { return (arg.data_&0x7C00) != 0x7C00; }
4374
4380 inline HALF_CONSTEXPR bool isinf(half arg) { return (arg.data_&0x7FFF) == 0x7C00; }
4381
4387 inline HALF_CONSTEXPR bool isnan(half arg) { return (arg.data_&0x7FFF) > 0x7C00; }
4388
4394 inline HALF_CONSTEXPR bool isnormal(half arg) { return ((arg.data_&0x7C00)!=0) & ((arg.data_&0x7C00)!=0x7C00); }
4395
4401 inline HALF_CONSTEXPR bool signbit(half arg) { return (arg.data_&0x8000) != 0; }
4402
4407
4415 {
4416 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);
4417 }
4418
4426 {
4427 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);
4428 }
4429
4436 inline HALF_CONSTEXPR bool isless(half x, half y)
4437 {
4438 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);
4439 }
4440
4448 {
4449 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);
4450 }
4451
4459 {
4460 return x.data_!=y.data_ && ((x.data_|y.data_)&0x7FFF) && !isnan(x) && !isnan(y);
4461 }
4462
4469 inline HALF_CONSTEXPR bool isunordered(half x, half y) { return isnan(x) || isnan(y); }
4470
4475
4489 template<typename T,typename U> T half_cast(U arg) { return detail::half_caster<T,U>::cast(arg); }
4490
4505 template<typename T,std::float_round_style R,typename U> T half_cast(U arg) { return detail::half_caster<T,U,R>::cast(arg); }
4507
4512
4520 inline int feclearexcept(int excepts) { detail::errflags() &= ~excepts; return 0; }
4521
4529 inline int fetestexcept(int excepts) { return detail::errflags() & excepts; }
4530
4540 inline int feraiseexcept(int excepts) { detail::errflags() |= excepts; detail::raise(excepts); return 0; }
4541
4550 inline int fegetexceptflag(int *flagp, int excepts) { *flagp = detail::errflags() & excepts; return 0; }
4551
4561 inline int fesetexceptflag(const int *flagp, int excepts) { detail::errflags() = (detail::errflags()|(*flagp&excepts)) & (*flagp|~excepts); return 0; }
4562
4574 inline void fethrowexcept(int excepts, const char *msg = "")
4575 {
4576 // excepts &= detail::errflags();
4577 // if(excepts & (FE_INVALID|FE_DIVBYZERO))
4578 // throw std::domain_error(msg);
4579 // if(excepts & FE_OVERFLOW)
4580 // throw std::overflow_error(msg);
4581 // if(excepts & FE_UNDERFLOW)
4582 // throw std::underflow_error(msg);
4583 // if(excepts & FE_INEXACT)
4584 // throw std::range_error(msg);
4585 }
4586
4587}
4588
4589
4590#undef HALF_UNUSED_NOERR
4591#undef HALF_CONSTEXPR
4592#undef HALF_CONSTEXPR_CONST
4593#undef HALF_CONSTEXPR_NOERR
4594#undef HALF_NOEXCEPT
4595#undef HALF_NOTHROW
4596#undef HALF_THREAD_LOCAL
4597#undef HALF_TWOS_COMPLEMENT_INT
4598#ifdef HALF_POP_WARNINGS
4599 #pragma warning(pop)
4600 #undef HALF_POP_WARNINGS
4601#endif
4602
4603#endif
Definition half.hpp:2056
half & operator=(float rhs)
Definition half.hpp:2079
friend bool signbit(half)
Definition half.hpp:4401
friend half cosh(half)
Definition half.hpp:3821
friend half erf(half)
Definition half.hpp:3968
friend half tgamma(half)
Definition half.hpp:4040
friend half expm1(half)
Definition half.hpp:2997
friend half copysign(half, half)
Definition half.hpp:4344
friend bool islessgreater(half, half)
Definition half.hpp:4458
half operator++(int)
Definition half.hpp:2154
friend half fmax(half, half)
Definition half.hpp:2878
friend bool isinf(half)
Definition half.hpp:4380
friend bool isnan(half)
Definition half.hpp:4387
friend half fabs(half)
Definition half.hpp:2729
friend half fdim(half, half)
Definition half.hpp:2904
friend half fma(half, half, half)
Definition half.hpp:2809
half & operator+=(float rhs)
Definition half.hpp:2117
friend half log10(half)
Definition half.hpp:3078
half & operator*=(half rhs)
Definition half.hpp:2104
friend half log2(half)
Definition half.hpp:3113
friend bool isless(half, half)
Definition half.hpp:4436
friend bool operator>(half, half)
Definition half.hpp:2500
half & operator*=(float rhs)
Definition half.hpp:2129
friend half modf(half, half *)
Definition half.hpp:4221
friend half sinh(half)
Definition half.hpp:3793
friend half atanh(half)
Definition half.hpp:3935
friend bool isnormal(half)
Definition half.hpp:4394
friend void sincos(half, half *, half *)
Definition half.hpp:3491
friend half acosh(half)
Definition half.hpp:3910
friend half atan2(half, half)
Definition half.hpp:3738
friend bool operator!=(half, half)
Definition half.hpp:2477
friend half log1p(half)
Definition half.hpp:3156
friend int fpclassify(half)
Definition half.hpp:4359
friend half operator-(half)
Definition half.hpp:2543
friend half nextafter(half, half)
Definition half.hpp:4293
friend bool isgreater(half, half)
Definition half.hpp:4414
friend half round(half)
Definition half.hpp:4097
friend half fmod(half, half)
Definition half.hpp:2743
friend long lround(half)
Definition half.hpp:4104
friend half sin(half)
Definition half.hpp:3556
friend bool isgreaterequal(half, half)
Definition half.hpp:4425
friend half floor(half)
Definition half.hpp:4081
half & operator--()
Definition half.hpp:2149
half & operator+=(half rhs)
Definition half.hpp:2090
friend half erfc(half)
Definition half.hpp:3990
friend half log(half)
Definition half.hpp:3050
friend half acos(half)
Definition half.hpp:3683
friend int ilogb(half)
Definition half.hpp:4249
friend half hypot(half, half)
Definition half.hpp:3315
friend bool operator<=(half, half)
Definition half.hpp:2512
friend half cos(half)
Definition half.hpp:3589
half & operator/=(float rhs)
Definition half.hpp:2135
friend bool operator<(half, half)
Definition half.hpp:2488
friend half exp2(half)
Definition half.hpp:2971
friend half asinh(half)
Definition half.hpp:3882
half(float rhs)
Definition half.hpp:2069
friend half logb(half)
Definition half.hpp:4267
friend std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &, half)
Definition half.hpp:2690
friend bool operator>=(half, half)
Definition half.hpp:2524
friend half remquo(half, half, int *)
Definition half.hpp:2784
friend half tanh(half)
Definition half.hpp:3849
friend std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &, half &)
Definition half.hpp:2708
friend half scalbln(half, long)
Definition half.hpp:4176
friend bool operator==(half, half)
Definition half.hpp:2466
friend half tan(half)
Definition half.hpp:3617
half & operator-=(float rhs)
Definition half.hpp:2123
friend half rsqrt(half)
Definition half.hpp:3227
friend half operator*(half, half)
Definition half.hpp:2618
friend half operator/(half, half)
Definition half.hpp:2651
friend half frexp(half, int *)
Definition half.hpp:4156
friend half rint(half)
Definition half.hpp:4112
friend half exp(half)
Definition half.hpp:2936
friend half nearbyint(half)
Definition half.hpp:4127
half & operator-=(half rhs)
Definition half.hpp:2097
friend half nexttoward(half, long double)
Definition half.hpp:4320
friend half trunc(half)
Definition half.hpp:4089
friend bool islessequal(half, half)
Definition half.hpp:4447
half & operator/=(half rhs)
Definition half.hpp:2111
half & operator++()
Definition half.hpp:2144
friend bool isfinite(half)
Definition half.hpp:4373
friend half atan(half)
Definition half.hpp:3708
friend half pow(half, half)
Definition half.hpp:3427
friend half sqrt(half)
Definition half.hpp:3206
friend half nanh(const char *)
Definition half.hpp:2915
half operator--(int)
Definition half.hpp:2159
friend half ceil(half)
Definition half.hpp:4073
friend half cbrt(half)
Definition half.hpp:3264
friend half operator+(half, half)
Definition half.hpp:2552
friend long lrint(half)
Definition half.hpp:4120
half()
Definition half.hpp:2064
friend half asin(half)
Definition half.hpp:3654
friend half lgamma(half)
Definition half.hpp:4015
friend half fmin(half, half)
Definition half.hpp:2890
friend half remainder(half, half)
Definition half.hpp:2764
static const bool has_signaling_NaN
Supports signaling NaNs.
Definition half.hpp:2359
static const bool tinyness_before
Does not support pre-rounding underflow detection.
Definition half.hpp:2375
static const int digits
Significant digits.
Definition half.hpp:2381
static const bool is_specialized
Is template specialization.
Definition half.hpp:2332
static const bool has_infinity
Supports infinity.
Definition half.hpp:2353
static const int max_exponent
One more than largest exponent.
Definition half.hpp:2399
static half_float::half quiet_NaN()
Quiet NaN.
Definition half.hpp:2424
static half_float::half epsilon()
Difference between 1 and next representable value.
Definition half.hpp:2414
static const bool is_integer
Is not an integer type.
Definition half.hpp:2338
static half_float::half max()
Largest finite value.
Definition half.hpp:2411
static const bool is_exact
Is not exact.
Definition half.hpp:2341
static const bool is_modulo
Doesn't provide modulo arithmetic.
Definition half.hpp:2344
static const bool is_iec559
IEEE conformant.
Definition half.hpp:2350
static half_float::half round_error()
Maximum rounding error in ULP (units in the last place).
Definition half.hpp:2417
static half_float::half signaling_NaN()
Signaling NaN.
Definition half.hpp:2427
static const int radix
Number base.
Definition half.hpp:2390
static half_float::half lowest()
Smallest finite value.
Definition half.hpp:2408
static const int digits10
Significant decimal digits.
Definition half.hpp:2384
static const bool is_signed
Supports signed values.
Definition half.hpp:2335
static const int min_exponent
One more than smallest exponent.
Definition half.hpp:2393
static half_float::half infinity()
Positive infinity.
Definition half.hpp:2421
static const int min_exponent10
Smallest normalized representable power of 10.
Definition half.hpp:2396
static half_float::half min()
Smallest positive normal value.
Definition half.hpp:2405
static const int max_exponent10
Largest finitely representable power of 10.
Definition half.hpp:2402
static const bool has_quiet_NaN
Supports quiet NaNs.
Definition half.hpp:2356
static const bool has_denorm_loss
Does not support denormalization detection.
Definition half.hpp:2365
static const float_round_style round_style
Rounding mode.
Definition half.hpp:2378
static const bool traps
Traps only if HALF_ERRHANDLING_THROW_... is acitvated.
Definition half.hpp:2371
static const float_denorm_style has_denorm
Supports subnormal values.
Definition half.hpp:2362
static half_float::half denorm_min()
Smallest positive subnormal value.
Definition half.hpp:2430
static const bool is_bounded
Has a finite set of values.
Definition half.hpp:2347
static const int max_digits10
Required decimal digits to represent all possible values.
Definition half.hpp:2387
#define FP_ILOGBNAN
Definition half.hpp:402
#define HALF_NOEXCEPT
Definition half.hpp:233
#define FP_NAN
Definition half.hpp:411
#define HALF_CONSTEXPR_NOERR
Definition half.hpp:225
#define FP_ZERO
Definition half.hpp:408
#define FP_INFINITE
Definition half.hpp:414
#define FE_UNDERFLOW
Definition half.hpp:424
#define HALF_CONSTEXPR_CONST
Definition half.hpp:224
#define FE_INVALID
Definition half.hpp:421
#define FE_INEXACT
Definition half.hpp:425
#define HALF_THREAD_LOCAL
Definition half.hpp:241
#define HALF_NOTHROW
Definition half.hpp:234
#define FP_ILOGB0
Definition half.hpp:399
#define HALF_UNUSED_NOERR(name)
Definition half.hpp:210
#define FE_DIVBYZERO
Definition half.hpp:422
#define FP_NORMAL
Definition half.hpp:417
#define HALF_CONSTEXPR
Definition half.hpp:223
#define FE_OVERFLOW
Definition half.hpp:423
#define FP_SUBNORMAL
Definition half.hpp:405
#define HALF_ROUND_STYLE
Definition half.hpp:374
#define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
Definition half.hpp:352
Definition half.hpp:452
bool_type< false > false_type
Definition half.hpp:472
unsigned int integral(unsigned int value)
Definition half.hpp:849
uint32 exp2(uint32 m, unsigned int n=32)
Definition half.hpp:1504
bool builtin_signbit(T arg)
Definition half.hpp:578
unsigned int hypot_post(uint32 r, int exp)
Definition half.hpp:1745
bool builtin_isnan(T arg)
Definition half.hpp:562
unsigned short uint16
Unsigned integer of (at least) 16 bits width.
Definition half.hpp:507
unsigned int fixed2half(uint32 m, int exp=14, unsigned int sign=0, int s=0)
Definition half.hpp:884
unsigned int mod(unsigned int x, unsigned int y, int *quo=NULL)
Definition half.hpp:1409
uint32 sqrt(uint32 &r, int &exp)
Definition half.hpp:1480
float half2float_impl(unsigned int value, float, true_type)
Definition half.hpp:1096
std::pair< uint32, uint32 > sincos(uint32 mz, unsigned int n=31)
Definition half.hpp:1558
uint32 multiply64(uint32 x, uint32 y)
Definition half.hpp:1366
int & errflags()
Definition half.hpp:620
unsigned int check_underflow(unsigned int arg)
Definition half.hpp:767
T half2int(unsigned int value)
Definition half.hpp:1317
unsigned int rounded(unsigned int value, int g, int s)
Definition half.hpp:820
const binary_t binary
Tag for binary construction.
Definition half.hpp:536
uint32 mulhi(uint32 x, uint32 y)
Definition half.hpp:1355
bool_type< true > true_type
Definition half.hpp:471
uint32 atan2(uint32 my, uint32 mx, unsigned int n=31)
Definition half.hpp:1582
long int32
Fastest unsigned integer of (at least) 32 bits width.
Definition half.hpp:513
unsigned int float2half(T value)
Definition half.hpp:1064
std::pair< uint32, uint32 > hyperbolic_args(unsigned int abs, int &exp, unsigned int n=32)
Definition half.hpp:1650
bool compsignal(unsigned int x, unsigned int y)
Definition half.hpp:679
unsigned int gamma(unsigned int arg)
Definition half.hpp:1937
void raise(int, bool=true)
Definition half.hpp:625
uint32 arithmetic_shift(uint32 arg, int i)
Definition half.hpp:605
std::pair< uint32, uint32 > atan2_args(unsigned int abs)
Definition half.hpp:1627
uint32 log2(uint32 m, unsigned int n=32)
Definition half.hpp:1531
T half2float(unsigned int value)
Definition half.hpp:1303
unsigned int signal(unsigned int nan)
Definition half.hpp:691
uint32 divide64(uint32 x, uint32 y, int &s)
Definition half.hpp:1380
unsigned int select(unsigned int x, unsigned int)
Definition half.hpp:731
uint32 angle_arg(unsigned int abs, int &k)
Definition half.hpp:1604
unsigned int overflow(unsigned int sign=0)
Definition half.hpp:784
unsigned int log2_post(uint32 m, int ilog, int exp, unsigned int sign=0)
Definition half.hpp:1720
unsigned int area(unsigned int arg)
Definition half.hpp:1788
unsigned long uint32
Fastest unsigned integer of (at least) 32 bits width.
Definition half.hpp:510
unsigned int invalid()
Definition half.hpp:743
unsigned int pole(unsigned int sign=0)
Definition half.hpp:755
unsigned int float2half_impl(float value, true_type)
Definition half.hpp:907
unsigned int underflow(unsigned int sign=0)
Definition half.hpp:800
uint32 sign_mask(uint32 arg)
Definition half.hpp:591
bool builtin_isinf(T arg)
Definition half.hpp:546
unsigned int erf(unsigned int arg)
Definition half.hpp:1918
unsigned int int2half(T value)
Definition half.hpp:1076
unsigned int tangent_post(uint32 my, uint32 mx, int exp, unsigned int sign=0)
Definition half.hpp:1767
unsigned int exp2_post(uint32 m, int exp, bool esign, unsigned int sign=0, unsigned int n=32)
Definition half.hpp:1688
Definition half.hpp:433
half asinh(half arg)
Definition half.hpp:3882
half sinh(half arg)
Definition half.hpp:3793
int feclearexcept(int excepts)
Definition half.hpp:4520
half nextafter(half from, half to)
Definition half.hpp:4293
half atan(half arg)
Definition half.hpp:3708
half hypot(half x, half y)
Definition half.hpp:3315
half fdim(half x, half y)
Definition half.hpp:2904
bool isnan(half arg)
Definition half.hpp:4387
half remquo(half x, half y, int *quo)
Definition half.hpp:2784
int fegetexceptflag(int *flagp, int excepts)
Definition half.hpp:4550
int ilogb(half arg)
Definition half.hpp:4249
half lgamma(half arg)
Definition half.hpp:4015
int fesetexceptflag(const int *flagp, int excepts)
Definition half.hpp:4561
half fma(half x, half y, half z)
Definition half.hpp:2809
bool isinf(half arg)
Definition half.hpp:4380
bool operator<(half x, half y)
Definition half.hpp:2488
half nearbyint(half arg)
Definition half.hpp:4127
half expm1(half arg)
Definition half.hpp:2997
half ldexp(half arg, int exp)
Definition half.hpp:4213
half sin(half arg)
Definition half.hpp:3556
half tanh(half arg)
Definition half.hpp:3849
half rint(half arg)
Definition half.hpp:4112
bool operator>=(half x, half y)
Definition half.hpp:2524
half fabs(half arg)
Definition half.hpp:2729
bool isnormal(half arg)
Definition half.hpp:4394
bool operator==(half x, half y)
Definition half.hpp:2466
int fpclassify(half arg)
Definition half.hpp:4359
bool isunordered(half x, half y)
Definition half.hpp:4469
T half_cast(U arg)
Definition half.hpp:4489
half fmod(half x, half y)
Definition half.hpp:2743
half log(half arg)
Definition half.hpp:3050
half cos(half arg)
Definition half.hpp:3589
half scalbn(half arg, int exp)
Definition half.hpp:4202
half exp2(half arg)
Definition half.hpp:2971
half atanh(half arg)
Definition half.hpp:3935
std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &in, half &arg)
Definition half.hpp:2708
half nexttoward(half from, long double to)
Definition half.hpp:4320
half round(half arg)
Definition half.hpp:4097
half log2(half arg)
Definition half.hpp:3113
bool islessgreater(half x, half y)
Definition half.hpp:4458
half asin(half arg)
Definition half.hpp:3654
half sqrt(half arg)
Definition half.hpp:3206
half trunc(half arg)
Definition half.hpp:4089
bool operator!=(half x, half y)
Definition half.hpp:2477
half erfc(half arg)
Definition half.hpp:3990
bool isgreaterequal(half x, half y)
Definition half.hpp:4425
half abs(half arg)
Definition half.hpp:2735
half tan(half arg)
Definition half.hpp:3617
std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &out, half arg)
Definition half.hpp:2690
half log10(half arg)
Definition half.hpp:3078
half rsqrt(half arg)
Definition half.hpp:3227
half floor(half arg)
Definition half.hpp:4081
half acosh(half arg)
Definition half.hpp:3910
bool signbit(half arg)
Definition half.hpp:4401
half copysign(half x, half y)
Definition half.hpp:4344
half operator+(half arg)
Definition half.hpp:2538
half operator*(half x, half y)
Definition half.hpp:2618
bool operator>(half x, half y)
Definition half.hpp:2500
bool islessequal(half x, half y)
Definition half.hpp:4447
half atan2(half y, half x)
Definition half.hpp:3738
int feraiseexcept(int excepts)
Definition half.hpp:4540
half scalbln(half arg, long exp)
Definition half.hpp:4176
half tgamma(half arg)
Definition half.hpp:4040
half fmin(half x, half y)
Definition half.hpp:2890
long lrint(half arg)
Definition half.hpp:4120
bool operator<=(half x, half y)
Definition half.hpp:2512
half cosh(half arg)
Definition half.hpp:3821
half logb(half arg)
Definition half.hpp:4267
half erf(half arg)
Definition half.hpp:3968
void sincos(half arg, half *sin, half *cos)
Definition half.hpp:3491
half ceil(half arg)
Definition half.hpp:4073
half frexp(half arg, int *exp)
Definition half.hpp:4156
bool isfinite(half arg)
Definition half.hpp:4373
bool isless(half x, half y)
Definition half.hpp:4436
half log1p(half arg)
Definition half.hpp:3156
bool isgreater(half x, half y)
Definition half.hpp:4414
half fmax(half x, half y)
Definition half.hpp:2878
long lround(half arg)
Definition half.hpp:4104
half operator-(half arg)
Definition half.hpp:2543
half acos(half arg)
Definition half.hpp:3683
half pow(half x, half y)
Definition half.hpp:3427
half nanh(const char *arg)
Definition half.hpp:2915
half modf(half arg, half *iptr)
Definition half.hpp:4221
half cbrt(half arg)
Definition half.hpp:3264
void fethrowexcept(int excepts, const char *msg="")
Definition half.hpp:4574
int fetestexcept(int excepts)
Definition half.hpp:4529
half exp(half arg)
Definition half.hpp:2936
half remainder(half x, half y)
Definition half.hpp:2764
half operator/(half x, half y)
Definition half.hpp:2651
Extensions to the C++ standard library.
Definition half.hpp:2325
Tag type for binary construction.
Definition half.hpp:533
unsigned long type
Definition half.hpp:523
Type traits for floating-point bits.
Definition half.hpp:485
unsigned char type
Definition half.hpp:485
Helper for tag dispatching.
Definition half.hpp:470
Conditional type.
Definition half.hpp:466
T type
Definition half.hpp:466
Class for 1.31 unsigned floating-point computation.
Definition half.hpp:1839
friend f31 operator-(f31 a, f31 b)
Definition half.hpp:1872
int exp
exponent.
Definition half.hpp:1905
friend f31 operator*(f31 a, f31 b)
Definition half.hpp:1886
friend f31 operator/(f31 a, f31 b)
Definition half.hpp:1897
f31(uint32 mant, int e)
Definition half.hpp:1843
friend f31 operator+(f31 a, f31 b)
Definition half.hpp:1858
f31(unsigned int abs)
Definition half.hpp:1847
uint32 m
mantissa as 1.31.
Definition half.hpp:1904
static T cast(half arg)
Definition half.hpp:2310
static half cast(U arg)
Definition half.hpp:2298
static half cast(half arg)
Definition half.hpp:2318
Definition half.hpp:2291
Type traits for floating-point types.
Definition half.hpp:475