3 #ifndef BOOST_SPIRIT_MATH_FPCLASSIFY_HPP
4 #define BOOST_SPIRIT_MATH_FPCLASSIFY_HPP
6 // Copyright (c) 2006 Johan Rade
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)
13 The following algorithm is used:
15 If all exponent bits, the flag bit (if there is one),
16 and all mantissa bits are 0, then the number is zero.
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.
21 If all exponent bits are 1 and all mantissa bits are 0,
22 then the number is infinity.
24 If all exponent bits are 1 and at least one mantissa bit is 1,
25 then the number is a not-a-number.
27 Otherwise the number is normal.
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.)
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.
48 # define FP_INFINITE 0
51 # define FP_SUBNORMAL 3
55 #include <boost/spirit/home/support/detail/math/detail/fp_traits.hpp>
61 //------------------------------------------------------------------------------
63 template<class T> bool (isfinite)(T x)
65 typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
68 BOOST_DEDUCED_TYPENAME traits::bits a;
69 traits::get_bits(x,a);
70 a &= traits::exponent;
71 return a != traits::exponent;
74 //------------------------------------------------------------------------------
76 template<class T> bool (isnormal)(T x)
78 typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
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);
87 //------------------------------------------------------------------------------
91 template<class T> bool isinf_impl(T x, all_bits)
93 typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
95 BOOST_DEDUCED_TYPENAME traits::bits a;
96 traits::get_bits(x,a);
97 a &= traits::exponent | traits::mantissa;
98 return a == traits::exponent;
101 template<class T> bool isinf_impl(T x, not_all_bits)
103 typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
105 BOOST_DEDUCED_TYPENAME traits::bits a;
106 traits::get_bits(x,a);
107 a &= traits::exponent | traits::mantissa;
108 if(a != traits::exponent)
111 traits::set_bits(x,0);
115 } // namespace detail
117 template<class T> bool (isinf)(T x)
119 typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
121 return detail::isinf_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
124 //------------------------------------------------------------------------------
128 template<class T> bool isnan_impl(T x, all_bits)
130 typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
133 BOOST_DEDUCED_TYPENAME traits::bits a;
134 traits::get_bits(x,a);
135 a &= traits::exponent | traits::mantissa;
136 return a > traits::exponent;
139 template<class T> bool isnan_impl(T x, not_all_bits)
141 typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
144 BOOST_DEDUCED_TYPENAME traits::bits a;
145 traits::get_bits(x,a);
147 a &= traits::exponent | traits::mantissa;
148 if(a < traits::exponent)
151 a &= traits::mantissa;
152 traits::set_bits(x,a);
156 } // namespace detail
158 template<class T> bool (isnan)(T x)
160 typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
162 return detail::isnan_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
165 //------------------------------------------------------------------------------
169 template<class T> int fpclassify_impl(T x, all_bits)
171 typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
173 BOOST_DEDUCED_TYPENAME traits::bits a;
174 traits::get_bits(x,a);
175 a &= traits::exponent | traits::flag | traits::mantissa;
177 if(a <= traits::mantissa) {
184 if(a < traits::exponent)
187 a &= traits::mantissa;
194 template<class T> int fpclassify_impl(T x, not_all_bits)
196 typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
198 BOOST_DEDUCED_TYPENAME traits::bits a;
199 traits::get_bits(x,a);
200 a &= traits::exponent | traits::flag | traits::mantissa;
202 if(a <= traits::mantissa) {
209 if(a < traits::exponent)
212 a &= traits::mantissa;
213 traits::set_bits(x,a);
220 } // namespace detail
222 template<class T> int (fpclassify)(T x)
224 typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
226 return detail::fpclassify_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
229 //------------------------------------------------------------------------------
232 } // namespace spirit