Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Compile Time Power of a Runtime Base

The pow function effectively computes the compile-time integral power of a run-time base.

Synopsis

#include <boost/math/special_functions/pow.hpp>

namespace boost { namespace math {

template <int N, typename T>
calculated-result-type pow(T base);

template <int N, typename T, class Policy>
calculated-result-type pow(T base, const Policy& policy);

}}
Rationale and Usage

Computing the power of a number with an exponent that is known at compile time is a common need for programmers. In such cases, the usual method is to avoid the overhead implied by the pow, powf and powl C functions by hardcoding an expression such as:

// Hand-written 8th power of a 'base' variable
double result = base*base*base*base*base*base*base*base;

However, this kind of expression is not really readable (knowing the value of the exponent involves counting the number of occurrences of base), error-prone (it's easy to forget an occurrence), syntactically bulky, and non-optimal in terms of performance.

The pow function of Boost.Math helps writing this kind expression along with solving all the problems listed above:

// 8th power of a 'base' variable using math::pow
double result = pow<8>(base);

The expression is now shorter, easier to read, safer, and even faster. Indeed, pow will compute the expression such that only log2(N) products are made for a power of N. For instance in the example above, the resulting expression will be the same as if we had written this, with only one computation of each identical subexpression:

// Internal effect of pow<8>(base)
double result = ((base*base)*(base*base))*((base*base)*(base*base));

Only 3 different products were actually computed.

Return Type

The return type of these functions is computed using the result type calculation rules. For example:

Policies

The final Policy argument is optional and can be used to control the behaviour of the function: how it handles errors, what level of precision to use etc. Refer to the policy documentation for more details.

Error Handling

Two cases of errors can occur when using pow:

The default overflow error policy is throw_on_error. A call like pow<-2>(0) will thus throw a std::overflow_error exception. As shown in the link given above, other error handling policies can be used:

The default indeterminate result error policy is ignore_error, which for this function returns 1 since it's the most commonly chosen result for a power of 0. Here again, other error handling policies can be used:

Here is an example of error handling customization where we want to specify the result that has to be returned in case of error. We will thus use the user_error policy, by passing as second argument an instance of an overflow_error policy templated with user_error:

// First we open the boost::math::policies namespace and define the `user_overflow_error`
// by making it return the value we want in case of error (-1 here)

namespace boost { namespace math { namespace policies {
template <class T>
T user_overflow_error(const char*, const char*, const T&)
{ return -1; }
}}}


// Then we invoke pow and indicate that we want to use the user_error policy
using boost::math::policies;
double result = pow<-5>(base, policy<overflow_error<user_error> >());

// We can now test the returned value and treat the special case if needed:
if (result == -1)
{
    // there was an error, do something...
}

Another way is to redefine the default overflow_error policy by using the BOOST_MATH_OVERFLOW_ERROR_POLICY macro. Once the user_overflow_error function is defined as above, we can achieve the same result like this:

// Redefine the default error_overflow policy
#define BOOST_MATH_OVERFLOW_ERROR_POLICY user_error
#include <boost/math/special_functions/pow.hpp>

// From this point, passing a policy in argument is no longer needed, a call like this one
// will return -1 in case of error:

double result = pow<-5>(base);
Acknowledgements

Bruno Lalande submitted this addition to Boost.Math.

Thanks to Joaquín López Muñoz and Scott McMurray for their help in improving the implementation.

References

D.E. Knuth, The Art of Computer Programming, Vol. 2: Seminumerical Algorithms, 2nd ed., Addison-Wesley, Reading, MA, 1981


PrevUpHomeNext