constants_eg1.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // Copyright Paul Bristow 2013.
  2. // Copyright John Maddock 2010.
  3. // Use, modification and distribution are subject to the
  4. // Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt
  6. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. /*! \brief Examples of using the enhanced math constants.
  8. \details This allows for access to constants via functions like @c pi(),
  9. and also via namespaces, @c using @c namespace boost::math::double_constants;
  10. called simply @c pi.
  11. */
  12. #include <boost/math/constants/constants.hpp>
  13. #include <iostream>
  14. using std::cout;
  15. using std::endl;
  16. #include <limits>
  17. using std::numeric_limits;
  18. /*! \brief Examples of a template function using constants.
  19. \details This example shows using of constants from function calls like @c pi(),
  20. rather than the 'cute' plain @c pi use in non-template applications.
  21. \tparam Real radius parameter that can be a built-in like float, double,
  22. or a user-defined type like multiprecision.
  23. \returns Area = pi * radius ^ 2
  24. */
  25. //[math_constants_eg1
  26. template<class Real>
  27. Real area(Real r)
  28. {
  29. using namespace boost::math::constants;
  30. return pi<Real>() * r * r;
  31. }
  32. //] [/math_constants_eg1]
  33. int main()
  34. {
  35. { // Boost.Math constants using function calls like pi().
  36. // using namespace boost::math::constants;
  37. using boost::math::constants::pi;
  38. using boost::math::constants::one_div_two_pi;
  39. #ifdef BOOST_NO_CXX11_NUMERIC_LIMITS
  40. std::size_t max_digits10 = 2 + std::numeric_limits<double>::digits * 3010/10000;
  41. #else
  42. std::size_t max_digits10 = std::numeric_limits<double>::max_digits10;
  43. #endif
  44. std::cout.precision(max_digits10);
  45. cout << "double pi = boost::math::double_constants::pi = " << pi<double>() << endl;
  46. // double pi = boost::math::double_constants::pi = 3.1415926535897931
  47. double r = 1.234567890123456789;
  48. double d = pi<double>() * r * r;
  49. cout << "d = " << d << ", r = " << r << endl;
  50. float rf = 0.987654321987654321f;
  51. float pif = boost::math::constants::pi<float>();
  52. cout << "pidf = boost::math::constants::pi() = " << pif << endl;
  53. // pidf = boost::math::float_constants::pi = 3.1415927410125732
  54. //float df = pi * rf * rf; // conversion from 'const double' to 'float', possible loss of data.
  55. float df = pif * rf * rf;
  56. cout << "df = " << df << ", rf = " << rf << endl;
  57. cout << "one_div_two_pi " << one_div_two_pi<double>() << endl;
  58. using boost::math::constants::one_div_two_pi;
  59. cout << "one_div_root_two_pi " << one_div_two_pi<double>() << endl;
  60. }
  61. { // Boost math new constants using namespace selected values, like pi.
  62. //using namespace boost::math::float_constants;
  63. using namespace boost::math::double_constants;
  64. double my2pi = two_pi; // Uses boost::math::double_constants::two_pi;
  65. cout << "double my2pi = " << my2pi << endl;
  66. using boost::math::float_constants::e;
  67. float my_e = e;
  68. cout << "float my_e " << my_e << endl;
  69. double my_pi = boost::math::double_constants::pi;
  70. cout << "double my_pi = boost::math::double_constants::pi = " << my_pi << endl;
  71. // If you try to use two namespaces, this may, of course, create ambiguity:
  72. // it is not too difficult to do this inadvertently.
  73. using namespace boost::math::float_constants;
  74. //cout << pi << endl; // error C2872: 'pi' : ambiguous symbol.
  75. }
  76. {
  77. //[math_constants_ambiguity
  78. // If you use more than one namespace, this will, of course, create ambiguity:
  79. using namespace boost::math::double_constants;
  80. using namespace boost::math::constants;
  81. //double my_pi = pi(); // error C2872: 'pi' : ambiguous symbol
  82. //double my_pi2 = pi; // Context does not allow for disambiguation of overloaded function
  83. // It is also possible to create ambiguity inadvertently,
  84. // perhaps in other peoples code,
  85. // by making the scope of a namespace declaration wider than necessary,
  86. // therefore is it prudent to avoid this risk by localising the scope of such definitions.
  87. //] [/math_constants_ambiguity]
  88. }
  89. { // You can, of course, use both methods of access if both are fully qualified, for examples:
  90. //cout.precision(std::numeric_limits<double>::max_digits10);// Ideally.
  91. cout.precision(2 + std::numeric_limits<double>::digits * 3010/10000); // If no max_digits10.
  92. double my_pi1 = boost::math::constants::pi<double>();
  93. double my_pid = boost::math::double_constants::pi;
  94. cout << "boost::math::constants::pi<double>() = " << my_pi1 << endl
  95. << "boost::math::double_constants::pi = " << my_pid << endl;
  96. // cout.precision(std::numeric_limits<float>::max_digits10); // Ideally.
  97. cout.precision(2 + std::numeric_limits<double>::digits * 3010/10000); // If no max_digits10.
  98. float my_pif = boost::math::float_constants::pi;
  99. cout << "boost::math::float_constants::pi = " << my_pif << endl;
  100. }
  101. { // Use with templates
  102. // \warning it is important to be very careful with the type provided as parameter.
  103. // For example, naively providing an @b integer instead of a floating-point type can be disastrous.
  104. // cout << "Area = " << area(2) << endl; // warning : 'return' : conversion from 'double' to 'int', possible loss of data
  105. // Failure to heed this warning can lead to very wrong answers!
  106. // Area = 12 !! = 3 * 2 * 2
  107. //[math_constants_template_integer_type
  108. //cout << "Area = " << area(2) << endl; // Area = 12!
  109. cout << "Area = " << area(2.) << endl; // Area = 12.566371
  110. // You can also avoid this by being explicit about the type of @c area.
  111. cout << "Area = " << area<double>(2) << endl;
  112. //] [/math_constants_template_integer_type]
  113. }
  114. /*
  115. {
  116. using boost::math::constants::pi;
  117. //double my_pi3 = pi<double>(); // OK
  118. //double my_pi4 = pi<>(); cannot find template type.
  119. //double my_pi4 = pi(); // Can't find a function.
  120. }
  121. */
  122. } // int main()
  123. /*[constants_eq1_output
  124. Output:
  125. double pi = boost::math::double_constants::pi = 3.1415926535897931
  126. d = 4.7882831840285398, r = 1.2345678901234567
  127. pidf = boost::math::constants::pi() = 3.1415927410125732
  128. df = 3.0645015239715576, rf = 0.98765432834625244
  129. one_div_two_pi 0.15915494309189535
  130. one_div_root_two_pi 0.15915494309189535
  131. double my2pi = 6.2831853071795862
  132. float my_e 2.7182817459106445
  133. double my_pi = boost::math::double_constants::pi = 3.1415926535897931
  134. boost::math::constants::pi<double>() = 3.1415926535897931
  135. boost::math::double_constants::pi = 3.1415926535897931
  136. boost::math::float_constants::pi = 3.1415927410125732
  137. Area = 12.566370614359172
  138. Area = 12.566370614359172
  139. ] [/constants_eq1_output]
  140. */