]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/config/test/math_info.cpp
1 // (C) Copyright John Maddock 2005.
2 // Use, modification and distribution are subject to the
3 // Boost Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 // See http://www.boost.org/libs/config/test for most recent version.
9 // This test prints out informative information about <math.h>, <float.h>
10 // and <limits>. Note that this file does require a correctly configured
11 // Boost setup, and so can't be folded into config_info which is designed
12 // to function without Boost.Confg support. Each test is documented in
16 #include <boost/limits.hpp>
24 #include <boost/type_traits/alignment_of.hpp>
26 #ifdef BOOST_NO_STDC_NAMESPACE
27 namespace std
{ using ::strcmp
; using ::pow
; using ::fabs
; using ::sqrt
; using ::sin
; using ::atan2
; }
30 static unsigned int indent
= 4;
31 static unsigned int width
= 40;
33 void print_macro(const char* name
, const char* value
)
35 // if name == value+1 then then macro is not defined,
36 // in which case we don't print anything:
37 if(0 != std::strcmp(name
, value
+1))
39 for(unsigned i
= 0; i
< indent
; ++i
) std::cout
.put(' ');
40 std::cout
<< std::setw(width
);
41 std::cout
.setf(std::istream::left
, std::istream::adjustfield
);
46 std::cout
<< value
<< "\n";
50 // macro is defined but has no value:
51 std::cout
<< " [no value]\n";
56 #define PRINT_MACRO(X) print_macro(#X, BOOST_STRINGIZE(=X))
59 void print_expression(const char* expression
, T val
)
61 for(unsigned i
= 0; i
< indent
; ++i
) std::cout
.put(' ');
62 std::cout
<< std::setw(width
);
63 std::cout
.setf(std::istream::left
, std::istream::adjustfield
);
64 std::cout
<< std::setprecision(std::numeric_limits
<T
>::digits10
+2);
65 std::cout
<< expression
<< "=" << val
<< std::endl
;
68 #define PRINT_EXPRESSION(E) print_expression(#E, E);
72 void print_limits(T
, const char* name
)
75 // Output general information on numeric_limits, as well as
76 // probing known and supected problems.
79 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
80 "std::numeric_limits information for type " << name
<< std::endl
;
82 " is_specialized = " << std::numeric_limits
<T
>::is_specialized
<< std::endl
;
84 " min" "() = " << std::setprecision(std::numeric_limits
<T
>::digits10
+ 2) << (std::numeric_limits
<T
>::min
)() << std::endl
;
86 " max" "() = " << std::setprecision(std::numeric_limits
<T
>::digits10
+ 2) << (std::numeric_limits
<T
>::max
)() << std::endl
;
88 " digits = " << std::numeric_limits
<T
>::digits
<< std::endl
;
90 " digits10 = " << std::numeric_limits
<T
>::digits10
<< std::endl
;
92 " is_signed = " << std::numeric_limits
<T
>::is_signed
<< std::endl
;
94 " is_integer = " << std::numeric_limits
<T
>::is_integer
<< std::endl
;
96 " is_exact = " << std::numeric_limits
<T
>::is_exact
<< std::endl
;
98 " radix = " << std::numeric_limits
<T
>::radix
<< std::endl
;
101 " epsilon() = " << std::setprecision(std::numeric_limits
<T
>::digits10
+ 2) << (std::numeric_limits
<T
>::epsilon
)() << std::endl
;
103 " round_error() = " << std::setprecision(std::numeric_limits
<T
>::digits10
+ 2) << (std::numeric_limits
<T
>::round_error
)() << std::endl
;
106 " min_exponent = " << std::numeric_limits
<T
>::min_exponent
<< std::endl
;
108 " min_exponent10 = " << std::numeric_limits
<T
>::min_exponent10
<< std::endl
;
110 " max_exponent = " << std::numeric_limits
<T
>::max_exponent
<< std::endl
;
112 " max_exponent10 = " << std::numeric_limits
<T
>::max_exponent10
<< std::endl
;
114 " has_infinity = " << std::numeric_limits
<T
>::has_infinity
<< std::endl
;
116 " has_quiet_NaN = " << std::numeric_limits
<T
>::has_quiet_NaN
<< std::endl
;
118 " has_signaling_NaN = " << std::numeric_limits
<T
>::has_signaling_NaN
<< std::endl
;
120 " has_denorm = " << std::numeric_limits
<T
>::has_denorm
<< std::endl
;
122 " has_denorm_loss = " << std::numeric_limits
<T
>::has_denorm_loss
<< std::endl
;
125 " infinity() = " << std::setprecision(std::numeric_limits
<T
>::digits10
+ 2) << (std::numeric_limits
<T
>::infinity
)() << std::endl
;
127 " quiet_NaN() = " << std::setprecision(std::numeric_limits
<T
>::digits10
+ 2) << (std::numeric_limits
<T
>::quiet_NaN
)() << std::endl
;
129 " signaling_NaN() = " << std::setprecision(std::numeric_limits
<T
>::digits10
+ 2) << (std::numeric_limits
<T
>::signaling_NaN
)() << std::endl
;
131 " denorm_min() = " << std::setprecision(std::numeric_limits
<T
>::digits10
+ 2) << (std::numeric_limits
<T
>::denorm_min
)() << std::endl
;
135 " is_iec559 = " << std::numeric_limits
<T
>::is_iec559
<< std::endl
;
137 " is_bounded = " << std::numeric_limits
<T
>::is_bounded
<< std::endl
;
139 " is_modulo = " << std::numeric_limits
<T
>::is_modulo
<< std::endl
;
141 " traps = " << std::numeric_limits
<T
>::traps
<< std::endl
;
143 " tinyness_before = " << std::numeric_limits
<T
>::tinyness_before
<< std::endl
;
145 " round_style = " << std::numeric_limits
<T
>::round_style
<< std::endl
<< std::endl
;
147 if(std::numeric_limits
<T
>::is_exact
== 0)
149 bool r
= std::numeric_limits
<T
>::epsilon() == std::pow(static_cast<T
>(std::numeric_limits
<T
>::radix
), 1-std::numeric_limits
<T
>::digits
);
151 std::cout
<< "Epsilon has sane value of std::pow(std::numeric_limits<T>::radix, 1-std::numeric_limits<T>::digits)." << std::endl
;
153 std::cout
<< "CAUTION: epsilon does not have a sane value." << std::endl
;
154 std::cout
<< std::endl
;
157 " sizeof(" << name
<< ") = " << sizeof(T
) << std::endl
;
159 " alignment_of<" << name
<< "> = " << boost::alignment_of
<T
>::value
<< std::endl
<< std::endl
;
163 bool is_same_type(T, T)
167 bool is_same_type(float, float)
169 bool is_same_type(double, double)
171 bool is_same_type(long double, long double)
173 template <class T
, class U
>
174 bool is_same_type(T
, U
)
180 // We need this to test whether abs has been overloaded for
181 // the floating point types or not:
184 #if !BOOST_WORKAROUND(BOOST_MSVC, == 1300) && \
185 !defined(_LIBCPP_VERSION)
196 void test_overloads(T
, const char* name
)
199 // Probe known and suspected problems with the std lib Math functions.
202 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
203 "Math function overload information for type " << name
<< std::endl
;
206 // Are the math functions overloaded for type T,
207 // or do we just get double versions?
209 bool r
= is_same_type(std::fabs(T(0)), T(0));
210 r
&= is_same_type(std::sqrt(T(0)), T(0));
211 r
&= is_same_type(std::sin(T(0)), T(0));
213 std::cout
<< "The Math functions are overloaded for type " << name
<< std::endl
;
215 std::cout
<< "CAUTION: The Math functions are NOT overloaded for type " << name
<< std::endl
;
218 // Check that a few of the functions work OK, we do this because if these
219 // are implemented as double precision internally then we can get
220 // overflow or underflow when passing arguments of other types.
222 r
= (std::fabs((std::numeric_limits
<T
>::max
)()) == (std::numeric_limits
<T
>::max
)());
223 r
&= (std::fabs(-(std::numeric_limits
<T
>::max
)()) == (std::numeric_limits
<T
>::max
)());
224 r
&= (std::fabs((std::numeric_limits
<T
>::min
)()) == (std::numeric_limits
<T
>::min
)());
225 r
&= (std::fabs(-(std::numeric_limits
<T
>::min
)()) == (std::numeric_limits
<T
>::min
)());
227 std::cout
<< "std::fabs looks OK for type " << name
<< std::endl
;
229 std::cout
<< "CAUTION: std::fabs is broken for type " << name
<< std::endl
;
232 // abs not overloaded for real arguments with VC6 (and others?)
234 r
= (std::abs((std::numeric_limits
<T
>::max
)()) == (std::numeric_limits
<T
>::max
)());
235 r
&= (std::abs(-(std::numeric_limits
<T
>::max
)()) == (std::numeric_limits
<T
>::max
)());
236 r
&= (std::abs((std::numeric_limits
<T
>::min
)()) == (std::numeric_limits
<T
>::min
)());
237 r
&= (std::abs(-(std::numeric_limits
<T
>::min
)()) == (std::numeric_limits
<T
>::min
)());
239 std::cout
<< "std::abs looks OK for type " << name
<< std::endl
;
241 std::cout
<< "CAUTION: std::abs is broken for type " << name
<< std::endl
;
244 // std::sqrt on FreeBSD converts long double arguments to double leading to
245 // overflow/underflow:
247 r
= (std::sqrt((std::numeric_limits
<T
>::max
)()) < (std::numeric_limits
<T
>::max
)());
249 std::cout
<< "std::sqrt looks OK for type " << name
<< std::endl
;
251 std::cout
<< "CAUTION: std::sqrt is broken for type " << name
<< std::endl
;
254 // Sanity check for atan2: verify that it returns arguments in the correct
255 // range and not just atan(x/y).
257 static const T half_pi
= static_cast<T
>(1.57079632679489661923132169163975144L);
259 T val
= std::atan2(T(-1), T(-1));
261 val
= std::atan2(T(1), T(-1));
263 val
= std::atan2(T(1), T(1));
264 r
&= (val
> 0) && (val
< half_pi
);
265 val
= std::atan2(T(-1), T(1));
266 r
&= (val
< 0) && (val
> -half_pi
);
268 std::cout
<< "std::atan2 looks OK for type " << name
<< std::endl
;
270 std::cout
<< "CAUTION: std::atan2 is broken for type " << name
<< std::endl
;
278 // Start by printing the values of the macros from float.h
281 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
282 "Macros from <math.h>" << std::endl
;
284 #ifdef BOOST_BORLANDC
285 // Turn off hardware exceptions so we don't just abort
286 // when calling numeric_limits members.
287 _control87(MCW_EM
,MCW_EM
);
290 PRINT_EXPRESSION(HUGE_VAL
);
292 PRINT_EXPRESSION(HUGE_VALF
);
295 PRINT_EXPRESSION(HUGE_VALL
);
298 PRINT_EXPRESSION(INFINITY
);
302 PRINT_MACRO(FP_INFINITE
);
304 PRINT_MACRO(FP_NORMAL
);
305 PRINT_MACRO(FP_SUBNORMAL
);
306 PRINT_MACRO(FP_ZERO
);
307 PRINT_MACRO(FP_FAST_FMA
);
308 PRINT_MACRO(FP_FAST_FMAF
);
309 PRINT_MACRO(FP_FAST_FMAL
);
310 PRINT_MACRO(FP_ILOGB0
);
311 PRINT_MACRO(FP_ILOGBNAN
);
312 PRINT_MACRO(MATH_ERRNO
);
313 PRINT_MACRO(MATH_ERREXCEPT
);
315 PRINT_EXPRESSION(FLT_MIN_10_EXP
);
316 PRINT_EXPRESSION(FLT_DIG
);
317 PRINT_EXPRESSION(FLT_MIN_EXP
);
318 PRINT_EXPRESSION(FLT_EPSILON
);
319 PRINT_EXPRESSION(FLT_RADIX
);
320 PRINT_EXPRESSION(FLT_MANT_DIG
);
321 PRINT_EXPRESSION(FLT_ROUNDS
);
322 PRINT_EXPRESSION(FLT_MAX
);
323 PRINT_EXPRESSION(FLT_MAX_10_EXP
);
324 PRINT_EXPRESSION(FLT_MAX_EXP
);
325 PRINT_EXPRESSION(FLT_MIN
);
326 PRINT_EXPRESSION(DBL_DIG
);
327 PRINT_EXPRESSION(DBL_MIN_EXP
);
328 PRINT_EXPRESSION(DBL_EPSILON
);
329 PRINT_EXPRESSION(DBL_MANT_DIG
);
330 PRINT_EXPRESSION(DBL_MAX
);
331 PRINT_EXPRESSION(DBL_MIN
);
332 PRINT_EXPRESSION(DBL_MAX_10_EXP
);
333 PRINT_EXPRESSION(DBL_MAX_EXP
);
334 PRINT_EXPRESSION(DBL_MIN_10_EXP
);
335 PRINT_EXPRESSION(LDBL_MAX_10_EXP
);
336 PRINT_EXPRESSION(LDBL_MAX_EXP
);
337 PRINT_EXPRESSION(LDBL_MIN
);
338 PRINT_EXPRESSION(LDBL_MIN_10_EXP
);
339 PRINT_EXPRESSION(LDBL_DIG
);
340 PRINT_EXPRESSION(LDBL_MIN_EXP
);
341 PRINT_EXPRESSION(LDBL_EPSILON
);
342 PRINT_EXPRESSION(LDBL_MANT_DIG
);
343 PRINT_EXPRESSION(LDBL_MAX
);
345 std::cout
<< std::endl
;
348 // print out numeric_limits info:
350 print_limits(float(0), "float");
351 print_limits(double(0), "double");
352 print_limits((long double)(0), "long double");
355 // print out function overload information:
357 test_overloads(float(0), "float");
358 test_overloads(double(0), "double");
359 test_overloads((long double)(0), "long double");