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