1 //  Boost pow_test.cpp test file
2 //  Tests the pow function
3 
4 //  (C) Copyright Bruno Lalande 2008.
5 //  Distributed under the Boost Software License, Version 1.0.
6 //  (See accompanying file LICENSE_1_0.txt or copy at
7 //  http://www.boost.org/LICENSE_1_0.txt)
8 
9 #include <cmath>
10 #include <string>
11 #include <iostream>
12 
13 #include <boost/math/concepts/real_concept.hpp>
14 #define BOOST_TEST_MAIN
15 #include <boost/test/unit_test.hpp>
16 #include <boost/test/floating_point_comparison.hpp>
17 
18 #include <boost/typeof/typeof.hpp>
19 #include <boost/type_traits/is_same.hpp>
20 #include <boost/static_assert.hpp>
21 
22 #include <boost/math/special_functions/pow.hpp>
23 
24 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
25 BOOST_TYPEOF_REGISTER_TYPE(boost::math::concepts::real_concept)
26 
27 using namespace boost;
28 using namespace boost::math;
29 
30 template <int N, class T>
test_pow(T base)31 void test_pow(T base)
32 {
33     typedef typename tools::promote_args<T>::type result_type;
34 
35     BOOST_MATH_STD_USING
36 
37     if ((base == 0) && N < 0)
38     {
39        BOOST_CHECK_THROW(math::pow<N>(base), std::overflow_error);
40     }
41     else
42     {
43        BOOST_CHECK_CLOSE(math::pow<N>(base),
44               pow(static_cast<result_type>(base), static_cast<result_type>(N)),
45               boost::math::tools::epsilon<result_type>() * 100 * 400); // 400 eps as a %
46     }
47 }
48 
49 template <int N, class T>
test_with_big_bases()50 void test_with_big_bases()
51 {
52     for (T base = T(); base < T(1000); ++base)
53         test_pow<N>(base);
54 }
55 
56 template <int N, class T>
test_with_small_bases()57 void test_with_small_bases()
58 {
59     T base = 0.9f;
60     for (int i = 0; i < 10; ++i)
61     {
62         base += base/50;
63         test_pow<N>(base);
64     }
65 }
66 
67 template <class T, int Factor>
test_with_small_exponents()68 void test_with_small_exponents()
69 {
70     test_with_big_bases<0, T>();
71     test_with_big_bases<Factor*1, T>();
72     test_with_big_bases<Factor*2, T>();
73     test_with_big_bases<Factor*3, T>();
74     test_with_big_bases<Factor*5, T>();
75     test_with_big_bases<Factor*6, T>();
76     test_with_big_bases<Factor*7, T>();
77     test_with_big_bases<Factor*8, T>();
78     test_with_big_bases<Factor*9, T>();
79     test_with_big_bases<Factor*10, T>();
80     test_with_big_bases<Factor*11, T>();
81     test_with_big_bases<Factor*12, T>();
82 }
83 
84 template <class T, int Factor>
test_with_big_exponents()85 void test_with_big_exponents()
86 {
87     test_with_small_bases<Factor*50, T>();
88     test_with_small_bases<Factor*100, T>();
89     test_with_small_bases<Factor*150, T>();
90     test_with_small_bases<Factor*200, T>();
91     test_with_small_bases<Factor*250, T>();
92     test_with_small_bases<Factor*300, T>();
93     test_with_small_bases<Factor*350, T>();
94     test_with_small_bases<Factor*400, T>();
95     test_with_small_bases<Factor*450, T>();
96     test_with_small_bases<Factor*500, T>();
97 }
98 
99 
test_return_types()100 void test_return_types()
101 {
102     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>('\1')), double>::value));
103     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>(L'\2')), double>::value));
104     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>(3)), double>::value));
105     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>(4u)), double>::value));
106     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>(5ul)), double>::value));
107     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>(6.0f)), float>::value));
108     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>(7.0)), double>::value));
109 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
110     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>(7.0l)), long double>::value));
111 #endif
112 }
113 
114 
115 namespace boost { namespace math { namespace policies {
116 template <class T>
user_overflow_error(const char *,const char *,const T &)117 T user_overflow_error(const char*, const char*, const T&)
118 { return T(123.45); }
119 }}}
120 
121 namespace boost { namespace math { namespace policies {
122 template <class T>
user_indeterminate_result_error(const char *,const char *,const T &)123 T user_indeterminate_result_error(const char*, const char*, const T&)
124 { return T(456.78); }
125 }}}
126 
127 
test_error_policy()128 void test_error_policy()
129 {
130     using namespace policies;
131 
132     BOOST_CHECK(pow<-2>(
133                     0.0,
134                     policy< ::boost::math::policies::overflow_error<user_error> >()
135                 )
136                 == 123.45);
137 
138     BOOST_CHECK(pow<0>(
139                     0.0,
140                     policy< ::boost::math::policies::indeterminate_result_error<user_error> >()
141                 )
142                 == 456.78);
143 }
144 
BOOST_AUTO_TEST_CASE(test_main)145 BOOST_AUTO_TEST_CASE( test_main )
146 {
147     using namespace std;
148 
149     cout << "Testing with integral bases and positive small exponents" << endl;
150     test_with_small_exponents<int, 1>();
151     cout << "Testing with integral bases and negative small exponents" << endl;
152     test_with_small_exponents<int, -1>();
153 
154     cout << "Testing with float precision bases and positive small exponents" << endl;
155     test_with_small_exponents<float, 1>();
156     cout << "Testing with float precision bases and negative small exponents" << endl;
157     test_with_small_exponents<float, -1>();
158 
159     cout << "Testing with float precision bases and positive big exponents" << endl;
160     test_with_big_exponents<float, 1>();
161     cout << "Testing with float precision bases and negative big exponents" << endl;
162     test_with_big_exponents<float, -1>();
163 
164      cout << "Testing with double precision bases and positive small exponents" << endl;
165     test_with_small_exponents<double, 1>();
166     cout << "Testing with double precision bases and negative small exponents" << endl;
167     test_with_small_exponents<double, -1>();
168 
169     cout << "Testing with double precision bases and positive big exponents" << endl;
170     test_with_big_exponents<double, 1>();
171     cout << "Testing with double precision bases and negative big exponents" << endl;
172     test_with_big_exponents<double, -1>();
173 
174 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
175     cout << "Testing with long double precision bases and positive small exponents" << endl;
176     test_with_small_exponents<long double, 1>();
177     cout << "Testing with long double precision bases and negative small exponents" << endl;
178     test_with_small_exponents<long double, -1>();
179 
180     cout << "Testing with long double precision bases and positive big exponents" << endl;
181     test_with_big_exponents<long double, 1>();
182     cout << "Testing with long double precision bases and negative big exponents" << endl;
183     test_with_big_exponents<long double, -1>();
184 
185     cout << "Testing with concepts::real_concept precision bases and positive small exponents" << endl;
186     test_with_small_exponents<boost::math::concepts::real_concept, 1>();
187     cout << "Testing with concepts::real_concept precision bases and negative small exponents" << endl;
188     test_with_small_exponents<boost::math::concepts::real_concept, -1>();
189 
190     cout << "Testing with concepts::real_concept precision bases and positive big exponents" << endl;
191     test_with_big_exponents<boost::math::concepts::real_concept, 1>();
192     cout << "Testing with concepts::real_concept precision bases and negative big exponents" << endl;
193     test_with_big_exponents<boost::math::concepts::real_concept, -1>();
194 #endif
195 
196     test_return_types();
197 
198     test_error_policy();
199 }
200 
201 /*
202 
203   Running 1 test case...
204   Testing with integral bases and positive small exponents
205   Testing with integral bases and negative small exponents
206   Testing with float precision bases and positive small exponents
207   Testing with float precision bases and negative small exponents
208   Testing with float precision bases and positive big exponents
209   Testing with float precision bases and negative big exponents
210   Testing with double precision bases and positive small exponents
211   Testing with double precision bases and negative small exponents
212   Testing with double precision bases and positive big exponents
213   Testing with double precision bases and negative big exponents
214   Testing with long double precision bases and positive small exponents
215   Testing with long double precision bases and negative small exponents
216   Testing with long double precision bases and positive big exponents
217   Testing with long double precision bases and negative big exponents
218   Testing with concepts::real_concept precision bases and positive small exponents
219   Testing with concepts::real_concept precision bases and negative small exponents
220   Testing with concepts::real_concept precision bases and positive big exponents
221   Testing with concepts::real_concept precision bases and negative big exponents
222 
223   *** No errors detected
224 
225   */
226