pow_test.cpp 8.0 KB

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