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