// Boost pow_test.cpp test file // Tests the pow function // (C) Copyright Bruno Lalande 2008. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include #include #include #include #include #include #include #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() BOOST_TYPEOF_REGISTER_TYPE(boost::math::concepts::real_concept) using namespace boost; using namespace boost::math; template void test_pow(T base) { typedef typename tools::promote_args::type result_type; BOOST_MATH_STD_USING if ((base == 0) && N < 0) { BOOST_CHECK_THROW(math::pow(base), std::overflow_error); } else { BOOST_CHECK_CLOSE(math::pow(base), pow(static_cast(base), static_cast(N)), boost::math::tools::epsilon() * 100 * 200); // 200 eps as a % } } template void test_with_big_bases() { for (T base = T(); base < T(1000); ++base) test_pow(base); } template void test_with_small_bases() { T base = 0.9f; for (int i = 0; i < 10; ++i) { base += base/50; test_pow(base); } } template void test_with_small_exponents() { test_with_big_bases<0, T>(); test_with_big_bases(); test_with_big_bases(); test_with_big_bases(); test_with_big_bases(); test_with_big_bases(); test_with_big_bases(); test_with_big_bases(); test_with_big_bases(); test_with_big_bases(); test_with_big_bases(); test_with_big_bases(); } template void test_with_big_exponents() { test_with_small_bases(); test_with_small_bases(); test_with_small_bases(); test_with_small_bases(); test_with_small_bases(); test_with_small_bases(); test_with_small_bases(); test_with_small_bases(); test_with_small_bases(); test_with_small_bases(); } void test_return_types() { BOOST_STATIC_ASSERT((is_same('\1')), double>::value)); BOOST_STATIC_ASSERT((is_same(L'\2')), double>::value)); BOOST_STATIC_ASSERT((is_same(3)), double>::value)); BOOST_STATIC_ASSERT((is_same(4u)), double>::value)); BOOST_STATIC_ASSERT((is_same(5ul)), double>::value)); BOOST_STATIC_ASSERT((is_same(6.0f)), float>::value)); BOOST_STATIC_ASSERT((is_same(7.0)), double>::value)); #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS BOOST_STATIC_ASSERT((is_same(7.0l)), long double>::value)); #endif } namespace boost { namespace math { namespace policies { template T user_overflow_error(const char*, const char*, const T&) { return T(123.45); } }}} namespace boost { namespace math { namespace policies { template T user_indeterminate_result_error(const char*, const char*, const T&) { return T(456.78); } }}} void test_error_policy() { using namespace policies; BOOST_CHECK(pow<-2>( 0.0, policy< ::boost::math::policies::overflow_error >() ) == 123.45); BOOST_CHECK(pow<0>( 0.0, policy< ::boost::math::policies::indeterminate_result_error >() ) == 456.78); } int test_main(int, char* []) { using namespace std; cout << "Testing with integral bases and positive small exponents" << endl; test_with_small_exponents(); cout << "Testing with integral bases and negative small exponents" << endl; test_with_small_exponents(); cout << "Testing with float precision bases and positive small exponents" << endl; test_with_small_exponents(); cout << "Testing with float precision bases and negative small exponents" << endl; test_with_small_exponents(); cout << "Testing with float precision bases and positive big exponents" << endl; test_with_big_exponents(); cout << "Testing with float precision bases and negative big exponents" << endl; test_with_big_exponents(); cout << "Testing with double precision bases and positive small exponents" << endl; test_with_small_exponents(); cout << "Testing with double precision bases and negative small exponents" << endl; test_with_small_exponents(); cout << "Testing with double precision bases and positive big exponents" << endl; test_with_big_exponents(); cout << "Testing with double precision bases and negative big exponents" << endl; test_with_big_exponents(); #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS cout << "Testing with long double precision bases and positive small exponents" << endl; test_with_small_exponents(); cout << "Testing with long double precision bases and negative small exponents" << endl; test_with_small_exponents(); cout << "Testing with long double precision bases and positive big exponents" << endl; test_with_big_exponents(); cout << "Testing with long double precision bases and negative big exponents" << endl; test_with_big_exponents(); cout << "Testing with concepts::real_concept precision bases and positive small exponents" << endl; test_with_small_exponents(); cout << "Testing with concepts::real_concept precision bases and negative small exponents" << endl; test_with_small_exponents(); cout << "Testing with concepts::real_concept precision bases and positive big exponents" << endl; test_with_big_exponents(); cout << "Testing with concepts::real_concept precision bases and negative big exponents" << endl; test_with_big_exponents(); #endif test_return_types(); test_error_policy(); return 0; }