1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Compile Time Power of a Runtime Base</title> 5<link rel="stylesheet" href="../../math.css" type="text/css"> 6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> 7<link rel="home" href="../../index.html" title="Math Toolkit 2.12.0"> 8<link rel="up" href="../powers.html" title="Basic Functions"> 9<link rel="prev" href="hypot.html" title="hypot"> 10<link rel="next" href="../sinc.html" title="Sinus Cardinal and Hyperbolic Sinus Cardinal Functions"> 11</head> 12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> 13<table cellpadding="2" width="100%"><tr> 14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td> 15<td align="center"><a href="../../../../../../index.html">Home</a></td> 16<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td> 17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> 18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> 19<td align="center"><a href="../../../../../../more/index.htm">More</a></td> 20</tr></table> 21<hr> 22<div class="spirit-nav"> 23<a accesskey="p" href="hypot.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../powers.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../sinc.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 24</div> 25<div class="section"> 26<div class="titlepage"><div><div><h3 class="title"> 27<a name="math_toolkit.powers.ct_pow"></a><a class="link" href="ct_pow.html" title="Compile Time Power of a Runtime Base">Compile Time Power of a Runtime 28 Base</a> 29</h3></div></div></div> 30<p> 31 The <code class="computeroutput"><span class="identifier">pow</span></code> function effectively 32 computes the compile-time integral power of a run-time base. 33 </p> 34<h5> 35<a name="math_toolkit.powers.ct_pow.h0"></a> 36 <span class="phrase"><a name="math_toolkit.powers.ct_pow.synopsis"></a></span><a class="link" href="ct_pow.html#math_toolkit.powers.ct_pow.synopsis">Synopsis</a> 37 </h5> 38<p> 39 <a href="../../../../../../boost/math/special_functions/pow.hpp" target="_top"><code class="computeroutput"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">special_functions</span><span class="special">/</span><span class="identifier">pow</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code></a> 40 </p> 41<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">math</span> <span class="special">{</span> 42 43<span class="keyword">template</span> <span class="special"><</span><span class="keyword">int</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> 44<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">pow</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">base</span><span class="special">);</span> 45 46<span class="keyword">template</span> <span class="special"><</span><span class="keyword">int</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Policy</span><span class="special">></span> 47<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">pow</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">base</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Policy</span><span class="special">&</span> <span class="identifier">policy</span><span class="special">);</span> 48 49<span class="special">}}</span> 50</pre> 51<h5> 52<a name="math_toolkit.powers.ct_pow.h1"></a> 53 <span class="phrase"><a name="math_toolkit.powers.ct_pow.rationale_and_usage"></a></span><a class="link" href="ct_pow.html#math_toolkit.powers.ct_pow.rationale_and_usage">Rationale 54 and Usage</a> 55 </h5> 56<p> 57 Computing the power of a number with an exponent that is known at compile 58 time is a common need for programmers. In such cases, the usual method is 59 to avoid the overhead implied by the <code class="computeroutput"><span class="identifier">pow</span></code>, 60 <code class="computeroutput"><span class="identifier">powf</span></code> and <code class="computeroutput"><span class="identifier">powl</span></code> 61 C functions by hardcoding an expression such as: 62 </p> 63<pre class="programlisting"><span class="comment">// Hand-written 8th power of a 'base' variable</span> 64<span class="keyword">double</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">;</span> 65</pre> 66<p> 67 However, this kind of expression is not really readable (knowing the value 68 of the exponent involves counting the number of occurrences of <span class="emphasis"><em>base</em></span>), 69 error-prone (it's easy to forget an occurrence), syntactically bulky, and 70 non-optimal in terms of performance. 71 </p> 72<p> 73 The <code class="computeroutput"><span class="identifier">pow</span></code> function of Boost.Math 74 helps writing this kind expression along with solving all the problems listed 75 above: 76 </p> 77<pre class="programlisting"><span class="comment">// 8th power of a 'base' variable using math::pow</span> 78<span class="keyword">double</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">pow</span><span class="special"><</span><span class="number">8</span><span class="special">>(</span><span class="identifier">base</span><span class="special">);</span> 79</pre> 80<p> 81 The expression is now shorter, easier to read, safer, and even faster. Indeed, 82 <code class="computeroutput"><span class="identifier">pow</span></code> will compute the expression 83 such that only log2(N) products are made for a power of N. For instance in 84 the example above, the resulting expression will be the same as if we had 85 written this, with only one computation of each identical subexpression: 86 </p> 87<pre class="programlisting"><span class="comment">// Internal effect of pow<8>(base)</span> 88<span class="keyword">double</span> <span class="identifier">result</span> <span class="special">=</span> <span class="special">((</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">)*(</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">))*((</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">)*(</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">));</span> 89</pre> 90<p> 91 Only 3 different products were actually computed. 92 </p> 93<h5> 94<a name="math_toolkit.powers.ct_pow.h2"></a> 95 <span class="phrase"><a name="math_toolkit.powers.ct_pow.return_type"></a></span><a class="link" href="ct_pow.html#math_toolkit.powers.ct_pow.return_type">Return 96 Type</a> 97 </h5> 98<p> 99 The return type of these functions is computed using the <a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>result 100 type calculation rules</em></span></a>. For example: 101 </p> 102<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 103<li class="listitem"> 104 If T is a <code class="computeroutput"><span class="keyword">float</span></code>, the return 105 type is a <code class="computeroutput"><span class="keyword">float</span></code>. 106 </li> 107<li class="listitem"> 108 If T is a <code class="computeroutput"><span class="keyword">long</span> <span class="keyword">double</span></code>, 109 the return type is a <code class="computeroutput"><span class="keyword">long</span> <span class="keyword">double</span></code>. 110 </li> 111<li class="listitem"> 112 Otherwise, the return type is a <code class="computeroutput"><span class="keyword">double</span></code>. 113 </li> 114</ul></div> 115<h5> 116<a name="math_toolkit.powers.ct_pow.h3"></a> 117 <span class="phrase"><a name="math_toolkit.powers.ct_pow.policies"></a></span><a class="link" href="ct_pow.html#math_toolkit.powers.ct_pow.policies">Policies</a> 118 </h5> 119<p> 120 The final <a class="link" href="../../policy.html" title="Chapter 21. Policies: Controlling Precision, Error Handling etc">Policy</a> argument is optional and can 121 be used to control the behaviour of the function: how it handles errors, 122 what level of precision to use etc. Refer to the <a class="link" href="../../policy.html" title="Chapter 21. Policies: Controlling Precision, Error Handling etc">policy 123 documentation for more details</a>. 124 </p> 125<h5> 126<a name="math_toolkit.powers.ct_pow.h4"></a> 127 <span class="phrase"><a name="math_toolkit.powers.ct_pow.error_handling"></a></span><a class="link" href="ct_pow.html#math_toolkit.powers.ct_pow.error_handling">Error 128 Handling</a> 129 </h5> 130<p> 131 Two cases of errors can occur when using <code class="computeroutput"><span class="identifier">pow</span></code>: 132 </p> 133<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 134<li class="listitem"> 135 In case of null base and negative exponent, an <a class="link" href="../error_handling.html#math_toolkit.error_handling.overflow_error">overflow_error</a> 136 occurs since this operation is a division by 0 (it equals to 1/0). 137 </li> 138<li class="listitem"> 139 In case of null base and null exponent, an <a class="link" href="../error_handling.html#math_toolkit.error_handling.indeterminate_result_error">indeterminate_result_error</a> 140 occurs since the result of this operation is indeterminate. Those errors 141 follow the <a class="link" href="../error_handling.html" title="Error Handling">general policies 142 of error handling in Boost.Math</a>. 143 </li> 144</ul></div> 145<p> 146 The default overflow error policy is <code class="computeroutput"><span class="identifier">throw_on_error</span></code>. 147 A call like <code class="computeroutput"><span class="identifier">pow</span><span class="special"><-</span><span class="number">2</span><span class="special">>(</span><span class="number">0</span><span class="special">)</span></code> will thus throw a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">overflow_error</span></code> 148 exception. As shown in the link given above, other error handling policies 149 can be used: 150 </p> 151<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 152<li class="listitem"> 153 <code class="computeroutput"><span class="identifier">errno_on_error</span></code>: Sets 154 <code class="computeroutput"><span class="special">::</span><span class="identifier">errno</span></code> 155 to <code class="computeroutput"><span class="identifier">ERANGE</span></code> and returns 156 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">infinity</span><span class="special">()</span></code>. 157 </li> 158<li class="listitem"> 159 <code class="computeroutput"><span class="identifier">ignore_error</span></code>: Returns 160 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">infinity</span><span class="special">()</span></code>. 161 </li> 162<li class="listitem"> 163 <code class="computeroutput"><span class="identifier">user_error</span></code>: Returns the 164 result of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">::</span><span class="identifier">user_overflow_error</span></code>: this function 165 must be defined by the user. 166 </li> 167</ul></div> 168<p> 169 The default indeterminate result error policy is <code class="computeroutput"><span class="identifier">ignore_error</span></code>, 170 which for this function returns 1 since it's the most commonly chosen result 171 for a power of 0. Here again, other error handling policies can be used: 172 </p> 173<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 174<li class="listitem"> 175 <code class="computeroutput"><span class="identifier">throw_on_error</span></code>: Throws 176 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">domain_error</span></code> 177 </li> 178<li class="listitem"> 179 <code class="computeroutput"><span class="identifier">errno_on_error</span></code>: Sets 180 <code class="computeroutput"><span class="special">::</span><span class="identifier">errno</span></code> 181 to <code class="computeroutput"><span class="identifier">EDOM</span></code> and returns 1. 182 </li> 183<li class="listitem"> 184 <code class="computeroutput"><span class="identifier">user_error</span></code>: Returns the 185 result of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">::</span><span class="identifier">user_indeterminate_result_error</span></code>: this 186 function must be defined by the user. 187 </li> 188</ul></div> 189<p> 190 Here is an example of error handling customization where we want to specify 191 the result that has to be returned in case of error. We will thus use the 192 <code class="computeroutput"><span class="identifier">user_error</span></code> policy, by passing 193 as second argument an instance of an overflow_error policy templated with 194 <code class="computeroutput"><span class="identifier">user_error</span></code>: 195 </p> 196<pre class="programlisting"><span class="comment">// First we open the boost::math::policies namespace and define the `user_overflow_error`</span> 197<span class="comment">// by making it return the value we want in case of error (-1 here)</span> 198 199<span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">math</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">policies</span> <span class="special">{</span> 200<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> 201<span class="identifier">T</span> <span class="identifier">user_overflow_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&)</span> 202<span class="special">{</span> <span class="keyword">return</span> <span class="special">-</span><span class="number">1</span><span class="special">;</span> <span class="special">}</span> 203<span class="special">}}}</span> 204 205 206<span class="comment">// Then we invoke pow and indicate that we want to use the user_error policy</span> 207<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">;</span> 208<span class="keyword">double</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">pow</span><span class="special"><-</span><span class="number">5</span><span class="special">>(</span><span class="identifier">base</span><span class="special">,</span> <span class="identifier">policy</span><span class="special"><</span><span class="identifier">overflow_error</span><span class="special"><</span><span class="identifier">user_error</span><span class="special">></span> <span class="special">>());</span> 209 210<span class="comment">// We can now test the returned value and treat the special case if needed:</span> 211<span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">)</span> 212<span class="special">{</span> 213 <span class="comment">// there was an error, do something...</span> 214<span class="special">}</span> 215</pre> 216<p> 217 Another way is to redefine the default <code class="computeroutput"><span class="identifier">overflow_error</span></code> 218 policy by using the BOOST_MATH_OVERFLOW_ERROR_POLICY macro. Once the <code class="computeroutput"><span class="identifier">user_overflow_error</span></code> function is defined 219 as above, we can achieve the same result like this: 220 </p> 221<pre class="programlisting"><span class="comment">// Redefine the default error_overflow policy</span> 222<span class="preprocessor">#define</span> <span class="identifier">BOOST_MATH_OVERFLOW_ERROR_POLICY</span> <span class="identifier">user_error</span> 223<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">special_functions</span><span class="special">/</span><span class="identifier">pow</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 224 225<span class="comment">// From this point, passing a policy in argument is no longer needed, a call like this one</span> 226<span class="comment">// will return -1 in case of error:</span> 227 228<span class="keyword">double</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">pow</span><span class="special"><-</span><span class="number">5</span><span class="special">>(</span><span class="identifier">base</span><span class="special">);</span> 229</pre> 230<h5> 231<a name="math_toolkit.powers.ct_pow.h5"></a> 232 <span class="phrase"><a name="math_toolkit.powers.ct_pow.acknowledgements"></a></span><a class="link" href="ct_pow.html#math_toolkit.powers.ct_pow.acknowledgements">Acknowledgements</a> 233 </h5> 234<p> 235 Bruno Lalande submitted this addition to Boost.Math. 236 </p> 237<p> 238 Thanks to Joaquín López Muñoz and Scott McMurray for their help in 239improving the implementation. 240 </p> 241<h5> 242<a name="math_toolkit.powers.ct_pow.h6"></a> 243 <span class="phrase"><a name="math_toolkit.powers.ct_pow.references"></a></span><a class="link" href="ct_pow.html#math_toolkit.powers.ct_pow.references">References</a> 244 </h5> 245<p> 246 D.E. Knuth, <span class="emphasis"><em>The Art of Computer Programming, Vol. 2: Seminumerical 247 Algorithms</em></span>, 2nd ed., Addison-Wesley, Reading, MA, 1981 248 </p> 249</div> 250<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 251<td align="left"></td> 252<td align="right"><div class="copyright-footer">Copyright © 2006-2019 Nikhar 253 Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, 254 Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Matthew Pulver, Johan 255 Råde, Gautam Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, 256 Daryle Walker and Xiaogang Zhang<p> 257 Distributed under the Boost Software License, Version 1.0. (See accompanying 258 file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) 259 </p> 260</div></td> 261</tr></table> 262<hr> 263<div class="spirit-nav"> 264<a accesskey="p" href="hypot.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../powers.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../sinc.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 265</div> 266</body> 267</html> 268