]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/math/test/test_classify.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / math / test / test_classify.cpp
1 // Copyright John Maddock 2006.
2 // Copyright Paul A. Bristow 2007
3 // Use, modification and distribution are subject to the
4 // Boost Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7 #include <pch.hpp>
8
9 #include <cmath>
10 #include <math.h>
11 #include <boost/limits.hpp>
12 #include <boost/math/concepts/real_concept.hpp>
13 #include <boost/math/special_functions/fpclassify.hpp>
14 #define BOOST_TEST_MAIN
15 #include <boost/test/unit_test.hpp>
16 #include <iostream>
17 #include <iomanip>
18
19 #ifdef _MSC_VER
20 #pragma warning(disable: 4127 4146) // conditional expression is constant
21 #endif
22
23 const char* method_name(const boost::math::detail::native_tag&)
24 {
25 return "Native";
26 }
27
28 const char* method_name(const boost::math::detail::generic_tag<true>&)
29 {
30 return "Generic (with numeric limits)";
31 }
32
33 const char* method_name(const boost::math::detail::generic_tag<false>&)
34 {
35 return "Generic (without numeric limits)";
36 }
37
38 const char* method_name(const boost::math::detail::ieee_tag&)
39 {
40 return "IEEE std";
41 }
42
43 const char* method_name(const boost::math::detail::ieee_copy_all_bits_tag&)
44 {
45 return "IEEE std, copy all bits";
46 }
47
48 const char* method_name(const boost::math::detail::ieee_copy_leading_bits_tag&)
49 {
50 return "IEEE std, copy leading bits";
51 }
52
53 template <class T>
54 void test_classify(T t, const char* type)
55 {
56 std::cout << "Testing type " << type << std::endl;
57
58 typedef typename boost::math::detail::fp_traits<T>::type traits;
59 typedef typename traits::method method;
60
61 std::cout << "Evaluation method = " << method_name(method()) << std::endl;
62
63 t = 2;
64 T u = 2;
65 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_NORMAL);
66 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_NORMAL);
67 BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
68 BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
69 BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
70 BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
71 BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
72 BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
73 BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), true);
74 BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), true);
75 if(std::numeric_limits<T>::is_specialized)
76 {
77 t = (std::numeric_limits<T>::max)();
78 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_NORMAL);
79 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_NORMAL);
80 BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
81 BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
82 BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
83 BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
84 BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
85 BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
86 BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), true);
87 BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), true);
88 t = (std::numeric_limits<T>::min)();
89 if(t != 0)
90 {
91 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_NORMAL);
92 BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
93 BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
94 BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
95 BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), true);
96 if(!std::numeric_limits<T>::is_integer)
97 {
98 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_NORMAL);
99 BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
100 BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
101 BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), true);
102 BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
103 }
104 }
105 }
106 if(std::numeric_limits<T>::has_denorm)
107 {
108 t = (std::numeric_limits<T>::min)();
109 t /= 2;
110 if(t != 0)
111 {
112 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_SUBNORMAL);
113 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_SUBNORMAL);
114 BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
115 BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
116 BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
117 BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
118 BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
119 BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
120 BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
121 BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
122 }
123 t = std::numeric_limits<T>::denorm_min();
124 if((t != 0) && (t < (std::numeric_limits<T>::min)()))
125 {
126 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_SUBNORMAL);
127 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_SUBNORMAL);
128 BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
129 BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
130 BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
131 BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
132 BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
133 BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
134 BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
135 BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
136 }
137 }
138 else
139 {
140 std::cout << "Denormalised forms not tested" << std::endl;
141 }
142 t = 0;
143 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_ZERO);
144 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_ZERO);
145 BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
146 BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
147 BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
148 BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
149 BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
150 BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
151 BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
152 BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
153 t /= -u; // create minus zero if it exists
154 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_ZERO);
155 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_ZERO);
156 BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
157 BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
158 BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
159 BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
160 BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
161 BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
162 BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
163 BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
164 // infinity:
165 if(std::numeric_limits<T>::has_infinity)
166 {
167 // At least one std::numeric_limits<T>::infinity)() returns zero
168 // (Compaq true64 cxx), hence the check.
169 t = (std::numeric_limits<T>::infinity)();
170 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_INFINITE);
171 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_INFINITE);
172 BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), false);
173 BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), false);
174 BOOST_CHECK_EQUAL((::boost::math::isinf)(t), true);
175 BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), true);
176 BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
177 BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
178 BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
179 BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
180 #if !defined(BOOST_BORLANDC) && !(defined(__DECCXX) && !defined(_IEEE_FP))
181 // divide by zero on Borland triggers a C++ exception :-(
182 // divide by zero on Compaq CXX triggers a C style signal :-(
183 t = 2;
184 u = 0;
185 t /= u;
186 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_INFINITE);
187 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_INFINITE);
188 BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), false);
189 BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), false);
190 BOOST_CHECK_EQUAL((::boost::math::isinf)(t), true);
191 BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), true);
192 BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
193 BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
194 BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
195 BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
196 t = -2;
197 t /= u;
198 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_INFINITE);
199 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_INFINITE);
200 BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), false);
201 BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), false);
202 BOOST_CHECK_EQUAL((::boost::math::isinf)(t), true);
203 BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), true);
204 BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
205 BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
206 BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
207 BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
208 #else
209 std::cout << "Infinities from divide by zero not tested" << std::endl;
210 #endif
211 }
212 else
213 {
214 std::cout << "Infinity not tested" << std::endl;
215 }
216 #ifndef BOOST_BORLANDC
217 // NaN's:
218 // Note that Borland throws an exception if we even try to obtain a Nan
219 // by calling std::numeric_limits<T>::quiet_NaN() !!!!!!!
220 if(std::numeric_limits<T>::has_quiet_NaN)
221 {
222 t = std::numeric_limits<T>::quiet_NaN();
223 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_NAN);
224 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_NAN);
225 BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), false);
226 BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), false);
227 BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
228 BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
229 BOOST_CHECK_EQUAL((::boost::math::isnan)(t), true);
230 BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), true);
231 BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
232 BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
233 }
234 else
235 {
236 std::cout << "Quiet NaN's not tested" << std::endl;
237 }
238 if(std::numeric_limits<T>::has_signaling_NaN)
239 {
240 t = std::numeric_limits<T>::signaling_NaN();
241 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_NAN);
242 BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_NAN);
243 BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), false);
244 BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), false);
245 BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
246 BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
247 BOOST_CHECK_EQUAL((::boost::math::isnan)(t), true);
248 BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), true);
249 BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
250 BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
251 }
252 else
253 {
254 std::cout << "Signaling NaN's not tested" << std::endl;
255 }
256 #endif
257 }
258
259 BOOST_AUTO_TEST_CASE( test_main )
260 {
261 BOOST_MATH_CONTROL_FP;
262 // start by printing some information:
263 #ifdef isnan
264 std::cout << "Platform has isnan macro." << std::endl;
265 #endif
266 #ifdef fpclassify
267 std::cout << "Platform has fpclassify macro." << std::endl;
268 #endif
269 #ifdef BOOST_HAS_FPCLASSIFY
270 std::cout << "Platform has FP_NORMAL macro." << std::endl;
271 #endif
272 std::cout << "FP_ZERO: " << (int)FP_ZERO << std::endl;
273 std::cout << "FP_NORMAL: " << (int)FP_NORMAL << std::endl;
274 std::cout << "FP_INFINITE: " << (int)FP_INFINITE << std::endl;
275 std::cout << "FP_NAN: " << (int)FP_NAN << std::endl;
276 std::cout << "FP_SUBNORMAL: " << (int)FP_SUBNORMAL << std::endl;
277
278 // then run the tests:
279 test_classify(float(0), "float");
280 test_classify(double(0), "double");
281 // long double support for fpclassify is considered "core" so we always test it
282 // even when long double support is turned off via BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
283 test_classify((long double)(0), "long double");
284 test_classify((boost::math::concepts::real_concept)(0), "real_concept");
285
286 // We should test with integer types as well:
287 test_classify(int(0), "int");
288 test_classify(unsigned(0), "unsigned");
289 }
290
291 /*
292 Autorun "i:\Boost-sandbox\math_toolkit\libs\math\test\MSVC80\debug\test_classify.exe"
293 Running 1 test case...
294 FP_ZERO: 0
295 FP_NORMAL: 1
296 FP_INFINITE: 2
297 FP_NAN: 3
298 FP_SUBNORMAL: 4
299 Testing type float
300 Testing type double
301 Testing type long double
302 Testing type real_concept
303 Denormalised forms not tested
304 Infinity not tested
305 Quiet NaN's not tested
306 Signaling NaN's not tested
307 Test suite "Test Program" passed with:
308 79 assertions out of 79 passed
309 1 test case out of 1 passed
310 Test case "test_main_caller( argc, argv )" passed with:
311 79 assertions out of 79 passed
312
313 */