Chris@16
|
1 // Copyright John Maddock 2010.
|
Chris@16
|
2 // Use, modification and distribution are subject to the
|
Chris@16
|
3 // Boost Software License, Version 1.0. (See accompanying file
|
Chris@16
|
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5
|
Chris@16
|
6 #ifdef _MSC_VER
|
Chris@16
|
7 # pragma once
|
Chris@16
|
8 #endif
|
Chris@16
|
9
|
Chris@16
|
10 #ifndef BOOST_MATH_CONSTANTS_INFO_INCLUDED
|
Chris@16
|
11 #define BOOST_MATH_CONSTANTS_INFO_INCLUDED
|
Chris@16
|
12
|
Chris@16
|
13 #include <boost/math/constants/constants.hpp>
|
Chris@16
|
14 #include <iostream>
|
Chris@16
|
15 #include <iomanip>
|
Chris@16
|
16 #include <typeinfo>
|
Chris@16
|
17
|
Chris@16
|
18 namespace boost{ namespace math{ namespace constants{
|
Chris@16
|
19
|
Chris@16
|
20 namespace detail{
|
Chris@16
|
21
|
Chris@16
|
22 template <class T>
|
Chris@16
|
23 const char* nameof(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
|
Chris@16
|
24 {
|
Chris@16
|
25 return typeid(T).name();
|
Chris@16
|
26 }
|
Chris@16
|
27 template <>
|
Chris@16
|
28 const char* nameof<float>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(float))
|
Chris@16
|
29 {
|
Chris@16
|
30 return "float";
|
Chris@16
|
31 }
|
Chris@16
|
32 template <>
|
Chris@16
|
33 const char* nameof<double>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(double))
|
Chris@16
|
34 {
|
Chris@16
|
35 return "double";
|
Chris@16
|
36 }
|
Chris@16
|
37 template <>
|
Chris@16
|
38 const char* nameof<long double>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(long double))
|
Chris@16
|
39 {
|
Chris@16
|
40 return "long double";
|
Chris@16
|
41 }
|
Chris@16
|
42
|
Chris@16
|
43 }
|
Chris@16
|
44
|
Chris@16
|
45 template <class T, class Policy>
|
Chris@16
|
46 void print_info_on_type(std::ostream& os = std::cout BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(Policy))
|
Chris@16
|
47 {
|
Chris@16
|
48 using detail::nameof;
|
Chris@16
|
49 #ifdef BOOST_MSVC
|
Chris@16
|
50 #pragma warning(push)
|
Chris@16
|
51 #pragma warning(disable:4127)
|
Chris@16
|
52 #endif
|
Chris@16
|
53 os <<
|
Chris@16
|
54 "Information on the Implementation and Handling of \n"
|
Chris@16
|
55 "Mathematical Constants for Type " << nameof<T>() <<
|
Chris@16
|
56 "\n\n"
|
Chris@16
|
57 "Checking for std::numeric_limits<" << nameof<T>() << "> specialisation: " <<
|
Chris@16
|
58 (std::numeric_limits<T>::is_specialized ? "yes" : "no") << std::endl;
|
Chris@16
|
59 if(std::numeric_limits<T>::is_specialized)
|
Chris@16
|
60 {
|
Chris@16
|
61 os <<
|
Chris@16
|
62 "std::numeric_limits<" << nameof<T>() << ">::digits reports that the radix is " << std::numeric_limits<T>::radix << ".\n";
|
Chris@16
|
63 if (std::numeric_limits<T>::radix == 2)
|
Chris@16
|
64 {
|
Chris@16
|
65 os <<
|
Chris@16
|
66 "std::numeric_limits<" << nameof<T>() << ">::digits reports that the precision is \n" << std::numeric_limits<T>::digits << " binary digits.\n";
|
Chris@16
|
67 }
|
Chris@16
|
68 else if (std::numeric_limits<T>::radix == 10)
|
Chris@16
|
69 {
|
Chris@16
|
70 os <<
|
Chris@16
|
71 "std::numeric_limits<" << nameof<T>() << ">::digits reports that the precision is \n" << std::numeric_limits<T>::digits10 << " decimal digits.\n";
|
Chris@16
|
72 os <<
|
Chris@16
|
73 "std::numeric_limits<" << nameof<T>() << ">::digits reports that the precision is \n"
|
Chris@16
|
74 << std::numeric_limits<T>::digits * 1000L /301L << " binary digits.\n"; // divide by log2(10) - about 3 bits per decimal digit.
|
Chris@16
|
75 }
|
Chris@16
|
76 else
|
Chris@16
|
77 {
|
Chris@16
|
78 os << "Unknown radix = " << std::numeric_limits<T>::radix << "\n";
|
Chris@16
|
79 }
|
Chris@16
|
80 }
|
Chris@16
|
81 typedef typename boost::math::policies::precision<T, Policy>::type precision_type;
|
Chris@16
|
82 if(precision_type::value)
|
Chris@16
|
83 {
|
Chris@16
|
84 if (std::numeric_limits<T>::radix == 2)
|
Chris@16
|
85 {
|
Chris@16
|
86 os <<
|
Chris@16
|
87 "boost::math::policies::precision<" << nameof<T>() << ", " << nameof<Policy>() << " reports that the compile time precision is \n" << precision_type::value << " binary digits.\n";
|
Chris@16
|
88 }
|
Chris@16
|
89 else if (std::numeric_limits<T>::radix == 10)
|
Chris@16
|
90 {
|
Chris@16
|
91 os <<
|
Chris@16
|
92 "boost::math::policies::precision<" << nameof<T>() << ", " << nameof<Policy>() << " reports that the compile time precision is \n" << precision_type::value << " binary digits.\n";
|
Chris@16
|
93 }
|
Chris@16
|
94 else
|
Chris@16
|
95 {
|
Chris@16
|
96 os << "Unknown radix = " << std::numeric_limits<T>::radix << "\n";
|
Chris@16
|
97 }
|
Chris@16
|
98 }
|
Chris@16
|
99 else
|
Chris@16
|
100 {
|
Chris@16
|
101 os <<
|
Chris@16
|
102 "boost::math::policies::precision<" << nameof<T>() << ", Policy> \n"
|
Chris@16
|
103 "reports that there is no compile type precision available.\n"
|
Chris@16
|
104 "boost::math::tools::digits<" << nameof<T>() << ">() \n"
|
Chris@16
|
105 "reports that the current runtime precision is \n" <<
|
Chris@16
|
106 boost::math::tools::digits<T>() << " binary digits.\n";
|
Chris@16
|
107 }
|
Chris@16
|
108
|
Chris@16
|
109 typedef typename construction_traits<T, Policy>::type construction_type;
|
Chris@16
|
110
|
Chris@16
|
111 switch(construction_type::value)
|
Chris@16
|
112 {
|
Chris@16
|
113 case 0:
|
Chris@16
|
114 os <<
|
Chris@16
|
115 "No compile time precision is available, the construction method \n"
|
Chris@16
|
116 "will be decided at runtime and results will not be cached \n"
|
Chris@16
|
117 "- this may lead to poor runtime performance.\n"
|
Chris@16
|
118 "Current runtime precision indicates that\n";
|
Chris@16
|
119 if(boost::math::tools::digits<T>() > max_string_digits)
|
Chris@16
|
120 {
|
Chris@16
|
121 os << "the constant will be recalculated on each call.\n";
|
Chris@16
|
122 }
|
Chris@16
|
123 else
|
Chris@16
|
124 {
|
Chris@16
|
125 os << "the constant will be constructed from a string on each call.\n";
|
Chris@16
|
126 }
|
Chris@16
|
127 break;
|
Chris@16
|
128 case 1:
|
Chris@16
|
129 os <<
|
Chris@16
|
130 "The constant will be constructed from a float.\n";
|
Chris@16
|
131 break;
|
Chris@16
|
132 case 2:
|
Chris@16
|
133 os <<
|
Chris@16
|
134 "The constant will be constructed from a double.\n";
|
Chris@16
|
135 break;
|
Chris@16
|
136 case 3:
|
Chris@16
|
137 os <<
|
Chris@16
|
138 "The constant will be constructed from a long double.\n";
|
Chris@16
|
139 break;
|
Chris@16
|
140 case 4:
|
Chris@16
|
141 os <<
|
Chris@16
|
142 "The constant will be constructed from a string (and the result cached).\n";
|
Chris@16
|
143 break;
|
Chris@16
|
144 default:
|
Chris@16
|
145 os <<
|
Chris@16
|
146 "The constant will be calculated (and the result cached).\n";
|
Chris@16
|
147 break;
|
Chris@16
|
148 }
|
Chris@16
|
149 os << std::endl;
|
Chris@16
|
150 #ifdef BOOST_MSVC
|
Chris@16
|
151 #pragma warning(pop)
|
Chris@16
|
152 #endif
|
Chris@16
|
153 }
|
Chris@16
|
154
|
Chris@16
|
155 template <class T>
|
Chris@16
|
156 void print_info_on_type(std::ostream& os = std::cout BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
|
Chris@16
|
157 {
|
Chris@16
|
158 print_info_on_type<T, boost::math::policies::policy<> >(os);
|
Chris@16
|
159 }
|
Chris@16
|
160
|
Chris@16
|
161 }}} // namespaces
|
Chris@16
|
162
|
Chris@16
|
163 #endif // BOOST_MATH_CONSTANTS_INFO_INCLUDED
|