• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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">&lt;</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">&gt;</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">&lt;</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">&gt;</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">&lt;</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">&gt;</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">&amp;</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">&lt;</span><span class="number">8</span><span class="special">&gt;(</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&lt;8&gt;(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">&lt;-</span><span class="number">2</span><span class="special">&gt;(</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&amp;)</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">&lt;-</span><span class="number">5</span><span class="special">&gt;(</span><span class="identifier">base</span><span class="special">,</span> <span class="identifier">policy</span><span class="special">&lt;</span><span class="identifier">overflow_error</span><span class="special">&lt;</span><span class="identifier">user_error</span><span class="special">&gt;</span> <span class="special">&gt;());</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">&lt;</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">&gt;</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">&lt;-</span><span class="number">5</span><span class="special">&gt;(</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