~yade-dev/yade/0.80

« back to all changes in this revision

Viewing changes to extra/floating_point_utilities_v3/boost/math/fpclassify.hpp

  • Committer: Anton Gladky
  • Date: 2012-05-02 21:50:42 UTC
  • Revision ID: gladky.anton@gmail.com-20120502215042-v1fa9r65usqe7kfk
0.80.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// fpclassify.hpp
 
2
 
 
3
#ifndef BOOST_MATH_FPCLASSIFY_HPP
 
4
#define BOOST_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
#include <cmath>
 
42
 
 
43
#ifndef FP_INFINITE
 
44
#   define FP_INFINITE 0
 
45
#   define FP_NAN 1
 
46
#   define FP_NORMAL 2
 
47
#   define FP_SUBNORMAL 3
 
48
#   define FP_ZERO 4
 
49
#endif
 
50
 
 
51
#include "detail/fp_traits.hpp"
 
52
 
 
53
namespace boost {
 
54
namespace math {
 
55
    
 
56
//------------------------------------------------------------------------------
 
57
 
 
58
template<class T> bool (isfinite)(T x)
 
59
{
 
60
    typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
 
61
    traits::init();
 
62
 
 
63
    BOOST_DEDUCED_TYPENAME traits::bits a;
 
64
    traits::get_bits(x,a);
 
65
    a &= traits::exponent;
 
66
    return a != traits::exponent;
 
67
}
 
68
 
 
69
//------------------------------------------------------------------------------
 
70
 
 
71
template<class T> bool (isnormal)(T x)
 
72
{
 
73
    typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
 
74
    traits::init();
 
75
 
 
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);
 
80
}
 
81
 
 
82
//------------------------------------------------------------------------------
 
83
 
 
84
namespace detail {
 
85
 
 
86
    template<class T> bool isinf_impl(T x, all_bits)
 
87
    {
 
88
        typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
 
89
 
 
90
        BOOST_DEDUCED_TYPENAME traits::bits a;
 
91
        traits::get_bits(x,a);
 
92
        a &= traits::exponent | traits::mantissa;
 
93
        return a == traits::exponent;
 
94
    }
 
95
 
 
96
    template<class T> bool isinf_impl(T x, not_all_bits)
 
97
    {
 
98
        typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
 
99
 
 
100
        BOOST_DEDUCED_TYPENAME traits::bits a;
 
101
        traits::get_bits(x,a);
 
102
        a &= traits::exponent | traits::mantissa;
 
103
        if(a != traits::exponent)
 
104
            return false;
 
105
 
 
106
        traits::set_bits(x,0);
 
107
        return x == 0;
 
108
    }
 
109
 
 
110
}   // namespace detail
 
111
 
 
112
template<class T> bool (isinf)(T x)
 
113
{
 
114
    typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
 
115
    traits::init();
 
116
    return detail::isinf_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
 
117
}
 
118
 
 
119
//------------------------------------------------------------------------------
 
120
 
 
121
namespace detail {
 
122
 
 
123
    template<class T> bool isnan_impl(T x, all_bits)
 
124
    {
 
125
        typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
 
126
        traits::init();
 
127
 
 
128
        BOOST_DEDUCED_TYPENAME traits::bits a;
 
129
        traits::get_bits(x,a);
 
130
        a &= traits::exponent | traits::mantissa;
 
131
        return a > traits::exponent;
 
132
    }
 
133
 
 
134
    template<class T> bool isnan_impl(T x, not_all_bits)
 
135
    {
 
136
        typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
 
137
        traits::init();
 
138
 
 
139
        BOOST_DEDUCED_TYPENAME traits::bits a;
 
140
        traits::get_bits(x,a);
 
141
 
 
142
        a &= traits::exponent | traits::mantissa;
 
143
        if(a < traits::exponent)
 
144
            return false;
 
145
 
 
146
        a &= traits::mantissa;
 
147
        traits::set_bits(x,a);
 
148
        return x != 0;
 
149
    }
 
150
 
 
151
}   // namespace detail
 
152
 
 
153
template<class T> bool (isnan)(T x)
 
154
{
 
155
    typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
 
156
    traits::init();
 
157
    return detail::isnan_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
 
158
}
 
159
 
 
160
//------------------------------------------------------------------------------
 
161
 
 
162
namespace detail {
 
163
 
 
164
    template<class T> int fpclassify_impl(T x, all_bits)
 
165
    {
 
166
        typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
 
167
 
 
168
        BOOST_DEDUCED_TYPENAME traits::bits a;
 
169
        traits::get_bits(x,a);
 
170
        a &= traits::exponent | traits::flag | traits::mantissa;
 
171
 
 
172
        if(a <= traits::mantissa) {
 
173
            if(a == 0)
 
174
                return FP_ZERO;
 
175
            else
 
176
                return FP_SUBNORMAL;
 
177
        }
 
178
 
 
179
        if(a < traits::exponent)
 
180
            return FP_NORMAL;
 
181
 
 
182
        a &= traits::mantissa;
 
183
        if(a == 0)
 
184
            return FP_INFINITE;
 
185
 
 
186
        return FP_NAN;
 
187
    }
 
188
 
 
189
    template<class T> int fpclassify_impl(T x, not_all_bits)
 
190
    {
 
191
        typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
 
192
 
 
193
        BOOST_DEDUCED_TYPENAME traits::bits a;
 
194
        traits::get_bits(x,a); 
 
195
        a &= traits::exponent | traits::flag | traits::mantissa;
 
196
 
 
197
        if(a <= traits::mantissa) {
 
198
            if(x == 0)
 
199
                return FP_ZERO;
 
200
            else
 
201
                return FP_SUBNORMAL;
 
202
        }
 
203
            
 
204
        if(a < traits::exponent)
 
205
            return FP_NORMAL;
 
206
 
 
207
        a &= traits::mantissa;
 
208
        traits::set_bits(x,a);
 
209
        if(x == 0)
 
210
            return FP_INFINITE;
 
211
        
 
212
        return FP_NAN;
 
213
    }
 
214
 
 
215
}   // namespace detail
 
216
 
 
217
template<class T> int (fpclassify)(T x)
 
218
{
 
219
    typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
 
220
    traits::init();
 
221
    return detail::fpclassify_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
 
222
}
 
223
 
 
224
//------------------------------------------------------------------------------
 
225
 
 
226
}   // namespace math
 
227
}   // namespace boost
 
228
 
 
229
#endif