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