[section pow]
This function effectively computes the compile-time integral power of a run-time base.
[section 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 the expression:
``
// 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.
[endsect]
[section Return type]
The return type depends on the type T of the argument passed to `pow`:
* If T is a `float`, the return type is a `float`.
* If T is a `long double`, the return type is a `long double`.
* Otherwise, the return type is a `double`.
[endsect]
[section Error handling]
In the case where `pow` is called with a null base and a negative exponent, an error occurs since
this operation is a division by 0 (it equals to 1/0). The error raised is an overflow error
following the [@sf_and_dist/html/math_toolkit/main_overview/error_handling.html general policies of
error handling in Boost.Math].
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:
* `errno_on_error`: Sets `::errno` to `EDOM and` returns `std::numeric_limits::quiet_NaN()`.
* `ignore_error`: Returns `std::numeric_limits::quiet_NaN()`.
* `user_error`: Returns the result of `boost::math::policies::user_pole_error`: this function must
be defined by the user.
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
T user_overflow_error(const char*, const char*, const T&)
{ return 123.456; }
}}}
// Then we invoque pow and indicate that we want to use the user_error policy
using boost::math::policies;
double result = pow<-5>(base, policy >());
// 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 errno_on_error
// 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);
``
[endsect]
[section Header File]
This function can be used by including [@../../boost/math/pow.hpp ].
[endsect]
[section Synopsis]
Here is the synopsis of `pow`. As explained above, the return type depends on the type of the
argument. The second overload allows to specify a different error handling policy (see section
"Error Handling").
``
namespace boost { namespace math {
template
pow(T base);
template
pow(T base, const Policy& policy);
}}
``
[endsect]
[section Acknowledgements]
Thanks to Joaquín López Muñoz and Scott McMurray for their help in improving the implementation.
[endsect]
[section References]
D.E. Knuth, ['The Art of Computer Programming, Vol. 2: Seminumerical Algorithms], 2nd ed., Addison-Wesley, Reading, MA, 1981
[endsect]
[endsect]