multiprecision (/sandbox/big_number/) - pow function

I am using the multiprecision library from /sandbox/big_number compiling with boost 1.49.0. Specifically, I am using cpp_int. I can successfully compile and run the following example: #include <boost/multiprecision/cpp_int.hpp> using namespace boost::multiprecision; cpp_int u = 1; for(unsigned i = 1; i <= 100; ++i) u *= i; std::cout << u << std::endl; // prints 100! which I obtained from: https://svn.boost.org/svn/boost/sandbox/big_number/libs/multiprecision/doc/h... When I add the following code: cpp_int x; x = pow( u, 2 ); I receive the following compiler error (g++ 4.1.2): ./boost/boost/multiprecision/detail/functions/pow.hpp: In function ‘void boost::multiprecision::default_ops::eval_pow(T&, const T&, const U&) [with T = boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> >, U = int]’: ./boost/boost/multiprecision/detail/default_ops.hpp:1250: instantiated from ‘void boost::multiprecision::detail::pow_funct<Backend>::operator()(Backend&, const Backend&, const Arithmetic&) const [with Arithmetic = int, Backend = boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> >]’ ./boost/boost/multiprecision/mp_number.hpp:1089: instantiated from ‘void boost::multiprecision::mp_number<Backend, ExpressionTemplates>::do_assign_function_2(const F&, const Exp1&, const Exp2&, const boost::multiprecision::detail::terminal&, const boost::multiprecision::detail::terminal&) [with F = boost::multiprecision::detail::pow_funct<boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> > >, Exp1 = boost::multiprecision::detail::mp_exp<boost::multiprecision::detail::terminal, boost::multiprecision::mp_number<boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> >, true>, void, void>, Exp2 = boost::multiprecision::detail::mp_exp<boost::multiprecision::detail::terminal, int, void, void>, Backend = boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> >, bool ExpressionTemplates = true]’ ./boost/boost/multiprecision/mp_number.hpp:1084: instantiated from ‘void boost::multiprecision::mp_number<Backend, ExpressionTemplates>::do_assign_function(const Exp&, const mpl_::int_<3>&) [with Exp = boost::multiprecision::detail::mp_exp<boost::multiprecision::detail::function, boost::multiprecision::detail::pow_funct<boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> > >, boost::multiprecision::mp_number<boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> >, true>, int>, Backend = boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> >, bool ExpressionTemplates = true]’ ./boost/boost/multiprecision/mp_number.hpp:973: instantiated from ‘void boost::multiprecision::mp_number<Backend, ExpressionTemplates>::do_assign(const Exp&, const boost::multiprecision::detail::function&) [with Exp = boost::multiprecision::detail::mp_exp<boost::multiprecision::detail::function, boost::multiprecision::detail::pow_funct<boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> > >, boost::multiprecision::mp_number<boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> >, true>, int>, Backend = boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> >, bool ExpressionTemplates = true]’ ./boost/boost/multiprecision/mp_number.hpp:570: instantiated from ‘void boost::multiprecision::mp_number<Backend, ExpressionTemplates>::do_assign(const boost::multiprecision::detail::mp_exp<tag, Arg1, Arg2, Arg3>&, const mpl_::true_&) [with tag = boost::multiprecision::detail::function, Arg1 = boost::multiprecision::detail::pow_funct<boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> > >, Arg2 = boost::multiprecision::mp_number<boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> >, true>, Arg3 = int, Backend = boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> >, bool ExpressionTemplates = true]’ ./boost/boost/multiprecision/mp_number.hpp:95: instantiated from ‘boost::multiprecision::mp_number<Backend, ExpressionTemplates>& boost::multiprecision::mp_number<Backend, ExpressionTemplates>::operator=(const boost::multiprecision::detail::mp_exp<tag, Arg1, Arg2, Arg3>&) [with tag = boost::multiprecision::detail::function, Arg1 = boost::multiprecision::detail::pow_funct<boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> > >, Arg2 = boost::multiprecision::mp_number<boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> >, true>, Arg3 = int, Backend = boost::multiprecision::backends::cpp_int_backend<0u, true, std::allocator<unsigned int> >, bool ExpressionTemplates = true]’ vcp_translator_test.cpp:24: instantiated from here ./boost/boost/multiprecision/detail/functions/pow.hpp:89: error: invalid application of ‘sizeof’ to incomplete type ‘boost::STATIC_ASSERTION_FAILURE<false>’ Different invocations of pow with the arbitrary precision argument as the base, exponent, or both yield different compiler errors, but all of them seem to be broken. Am I doing something wrong? Is there some other fast way to achieve exponentiation with this library? Thanks, Ryan

./boost/boost/multiprecision/detail/functions/pow.hpp:89: error: invalid application of ‘sizeof’ to incomplete type ‘boost::STATIC_ASSERTION_FAILURE<false>’
That's a truly horrible error message: in my defence, compilers that implement static_assert give the rather better: 1>m:\data\boost\sandbox\big_number\boost\multiprecision\detail\functions\pow.hpp(89): error C2338: The pow function is only valid for floating point types. In other words I haven't implemented pow for integer types, I guess as other libraries like GMP do so I should follow suit, though I admit to being a bit conflicted on this as the results get real big real fast with exponentiation. If I get some time later I'll see if I can improve those error messages, and maybe extend pow to integers. Thanks for the report, John.

Different invocations of pow with the arbitrary precision argument as the base, exponent, or both yield different compiler errors, but all of them seem to be broken. Am I doing something wrong? Is there some other fast way to achieve exponentiation with this library?
Well it took longer than I expected, but: * Calling an unsupported function now yields an error earlier without the horrid backtrace. * The functions pow and powm (modular exponentiation) are now supported for integer types - the former requires an unsigned integer for the exponent and is probably dangerous (too easy to create values that take "forever" to compute), while the latter is safe and accepts both integers and multiprecision types for the exponent and modulus. HTH, John.
participants (2)
-
John Maddock
-
Ryan Lichtenwalter