3
#ifndef BOOST_MATH_FPCLASSIFY_HPP
4
#define BOOST_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.
44
# define FP_INFINITE 0
47
# define FP_SUBNORMAL 3
51
#include "detail/fp_traits.hpp"
56
//------------------------------------------------------------------------------
58
template<class T> bool (isfinite)(T x)
60
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
63
BOOST_DEDUCED_TYPENAME traits::bits a;
64
traits::get_bits(x,a);
65
a &= traits::exponent;
66
return a != traits::exponent;
69
//------------------------------------------------------------------------------
71
template<class T> bool (isnormal)(T x)
73
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
76
BOOST_DEDUCED_TYPENAME traits::bits a;
77
traits::get_bits(x,a);
78
a &= traits::exponent | traits::flag;
79
return (a != 0) && (a < traits::exponent);
82
//------------------------------------------------------------------------------
86
template<class T> bool isinf_impl(T x, all_bits)
88
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
90
BOOST_DEDUCED_TYPENAME traits::bits a;
91
traits::get_bits(x,a);
92
a &= traits::exponent | traits::mantissa;
93
return a == traits::exponent;
96
template<class T> bool isinf_impl(T x, not_all_bits)
98
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
100
BOOST_DEDUCED_TYPENAME traits::bits a;
101
traits::get_bits(x,a);
102
a &= traits::exponent | traits::mantissa;
103
if(a != traits::exponent)
106
traits::set_bits(x,0);
110
} // namespace detail
112
template<class T> bool (isinf)(T x)
114
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
116
return detail::isinf_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
119
//------------------------------------------------------------------------------
123
template<class T> bool isnan_impl(T x, all_bits)
125
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
128
BOOST_DEDUCED_TYPENAME traits::bits a;
129
traits::get_bits(x,a);
130
a &= traits::exponent | traits::mantissa;
131
return a > traits::exponent;
134
template<class T> bool isnan_impl(T x, not_all_bits)
136
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
139
BOOST_DEDUCED_TYPENAME traits::bits a;
140
traits::get_bits(x,a);
142
a &= traits::exponent | traits::mantissa;
143
if(a < traits::exponent)
146
a &= traits::mantissa;
147
traits::set_bits(x,a);
151
} // namespace detail
153
template<class T> bool (isnan)(T x)
155
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
157
return detail::isnan_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
160
//------------------------------------------------------------------------------
164
template<class T> int fpclassify_impl(T x, all_bits)
166
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
168
BOOST_DEDUCED_TYPENAME traits::bits a;
169
traits::get_bits(x,a);
170
a &= traits::exponent | traits::flag | traits::mantissa;
172
if(a <= traits::mantissa) {
179
if(a < traits::exponent)
182
a &= traits::mantissa;
189
template<class T> int fpclassify_impl(T x, not_all_bits)
191
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
193
BOOST_DEDUCED_TYPENAME traits::bits a;
194
traits::get_bits(x,a);
195
a &= traits::exponent | traits::flag | traits::mantissa;
197
if(a <= traits::mantissa) {
204
if(a < traits::exponent)
207
a &= traits::mantissa;
208
traits::set_bits(x,a);
215
} // namespace detail
217
template<class T> int (fpclassify)(T x)
219
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
221
return detail::fpclassify_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
224
//------------------------------------------------------------------------------