]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/spirit/home/support/detail/math/fpclassify.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / spirit / home / support / detail / math / fpclassify.hpp
1 // fpclassify.hpp
2
3 #ifndef BOOST_SPIRIT_MATH_FPCLASSIFY_HPP
4 #define BOOST_SPIRIT_MATH_FPCLASSIFY_HPP
5
6 // Copyright (c) 2006 Johan Rade
7
8 // Distributed under the Boost Software License, Version 1.0.
9 // (See accompanying file LICENSE_1_0.txt
10 // or copy at http://www.boost.org/LICENSE_1_0.txt)
11
12 /*
13 The following algorithm is used:
14
15 If all exponent bits, the flag bit (if there is one),
16 and all mantissa bits are 0, then the number is zero.
17
18 If all exponent bits and the flag bit (if there is one) are 0,
19 and at least one mantissa bit is 1, then the number is subnormal.
20
21 If all exponent bits are 1 and all mantissa bits are 0,
22 then the number is infinity.
23
24 If all exponent bits are 1 and at least one mantissa bit is 1,
25 then the number is a not-a-number.
26
27 Otherwise the number is normal.
28
29 (Note that the binary representation of infinity
30 has flag bit 0 for Motorola 68K extended double precision,
31 and flag bit 1 for Intel extended double precision.)
32
33 To get the bits, the four or eight most significant bytes are copied
34 into an uint32_t or uint64_t and bit masks are applied.
35 This covers all the exponent bits and the flag bit (if there is one),
36 but not always all the mantissa bits.
37 Some of the functions below have two implementations,
38 depending on whether all the mantissa bits are copied or not.
39 */
40
41 #if defined(_MSC_VER)
42 #pragma once
43 #endif
44
45 #include <cmath>
46
47 #ifndef FP_INFINITE
48 # define FP_INFINITE 0
49 # define FP_NAN 1
50 # define FP_NORMAL 2
51 # define FP_SUBNORMAL 3
52 # define FP_ZERO 4
53 #endif
54
55 #include <boost/spirit/home/support/detail/math/detail/fp_traits.hpp>
56
57 namespace boost {
58 namespace spirit {
59 namespace math {
60
61 //------------------------------------------------------------------------------
62
63 template<class T> bool (isfinite)(T x)
64 {
65 typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
66 traits::init();
67
68 BOOST_DEDUCED_TYPENAME traits::bits a;
69 traits::get_bits(x,a);
70 a &= traits::exponent;
71 return a != traits::exponent;
72 }
73
74 //------------------------------------------------------------------------------
75
76 template<class T> bool (isnormal)(T x)
77 {
78 typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
79 traits::init();
80
81 BOOST_DEDUCED_TYPENAME traits::bits a;
82 traits::get_bits(x,a);
83 a &= traits::exponent | traits::flag;
84 return (a != 0) && (a < traits::exponent);
85 }
86
87 //------------------------------------------------------------------------------
88
89 namespace detail {
90
91 template<class T> bool isinf_impl(T x, all_bits)
92 {
93 typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
94
95 BOOST_DEDUCED_TYPENAME traits::bits a;
96 traits::get_bits(x,a);
97 a &= traits::exponent | traits::mantissa;
98 return a == traits::exponent;
99 }
100
101 template<class T> bool isinf_impl(T x, not_all_bits)
102 {
103 typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
104
105 BOOST_DEDUCED_TYPENAME traits::bits a;
106 traits::get_bits(x,a);
107 a &= traits::exponent | traits::mantissa;
108 if(a != traits::exponent)
109 return false;
110
111 traits::set_bits(x,0);
112 return x == 0;
113 }
114
115 } // namespace detail
116
117 template<class T> bool (isinf)(T x)
118 {
119 typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
120 traits::init();
121 return detail::isinf_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
122 }
123
124 //------------------------------------------------------------------------------
125
126 namespace detail {
127
128 template<class T> bool isnan_impl(T x, all_bits)
129 {
130 typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
131 traits::init();
132
133 BOOST_DEDUCED_TYPENAME traits::bits a;
134 traits::get_bits(x,a);
135 a &= traits::exponent | traits::mantissa;
136 return a > traits::exponent;
137 }
138
139 template<class T> bool isnan_impl(T x, not_all_bits)
140 {
141 typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
142 traits::init();
143
144 BOOST_DEDUCED_TYPENAME traits::bits a;
145 traits::get_bits(x,a);
146
147 a &= traits::exponent | traits::mantissa;
148 if(a < traits::exponent)
149 return false;
150
151 a &= traits::mantissa;
152 traits::set_bits(x,a);
153 return x != 0;
154 }
155
156 } // namespace detail
157
158 template<class T> bool (isnan)(T x)
159 {
160 typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
161 traits::init();
162 return detail::isnan_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
163 }
164
165 //------------------------------------------------------------------------------
166
167 namespace detail {
168
169 template<class T> int fpclassify_impl(T x, all_bits)
170 {
171 typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
172
173 BOOST_DEDUCED_TYPENAME traits::bits a;
174 traits::get_bits(x,a);
175 a &= traits::exponent | traits::flag | traits::mantissa;
176
177 if(a <= traits::mantissa) {
178 if(a == 0)
179 return FP_ZERO;
180 else
181 return FP_SUBNORMAL;
182 }
183
184 if(a < traits::exponent)
185 return FP_NORMAL;
186
187 a &= traits::mantissa;
188 if(a == 0)
189 return FP_INFINITE;
190
191 return FP_NAN;
192 }
193
194 template<class T> int fpclassify_impl(T x, not_all_bits)
195 {
196 typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
197
198 BOOST_DEDUCED_TYPENAME traits::bits a;
199 traits::get_bits(x,a);
200 a &= traits::exponent | traits::flag | traits::mantissa;
201
202 if(a <= traits::mantissa) {
203 if(x == 0)
204 return FP_ZERO;
205 else
206 return FP_SUBNORMAL;
207 }
208
209 if(a < traits::exponent)
210 return FP_NORMAL;
211
212 a &= traits::mantissa;
213 traits::set_bits(x,a);
214 if(x == 0)
215 return FP_INFINITE;
216
217 return FP_NAN;
218 }
219
220 } // namespace detail
221
222 template<class T> int (fpclassify)(T x)
223 {
224 typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
225 traits::init();
226 return detail::fpclassify_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
227 }
228
229 //------------------------------------------------------------------------------
230
231 } // namespace math
232 } // namespace spirit
233 } // namespace boost
234
235 #endif