info.hpp 5.4 KB

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