1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Factorial</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="../factorials.html" title="Factorials and Binomial Coefficients"> 9<link rel="prev" href="../factorials.html" title="Factorials and Binomial Coefficients"> 10<link rel="next" href="sf_double_factorial.html" title="Double Factorial"> 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="../factorials.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../factorials.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="sf_double_factorial.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.factorials.sf_factorial"></a><a class="link" href="sf_factorial.html" title="Factorial">Factorial</a> 28</h3></div></div></div> 29<h5> 30<a name="math_toolkit.factorials.sf_factorial.h0"></a> 31 <span class="phrase"><a name="math_toolkit.factorials.sf_factorial.synopsis"></a></span><a class="link" href="sf_factorial.html#math_toolkit.factorials.sf_factorial.synopsis">Synopsis</a> 32 </h5> 33<pre class="programlisting"><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">factorials</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 34</pre> 35<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> 36 37<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> 38<span class="identifier">T</span> <span class="identifier">factorial</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span><span class="special">);</span> 39 40<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Chapter 21. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">></span> 41<span class="identifier">T</span> <span class="identifier">factorial</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span><span class="special">,</span> <span class="keyword">const</span> <a class="link" href="../../policy.html" title="Chapter 21. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&);</span> 42 43<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> 44<span class="keyword">constexpr</span> <span class="identifier">T</span> <span class="identifier">unchecked_factorial</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span><span class="special">);</span> 45 46<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> 47<span class="keyword">struct</span> <span class="identifier">max_factorial</span><span class="special">;</span> 48 49<span class="special">}}</span> <span class="comment">// namespaces</span> 50</pre> 51<h5> 52<a name="math_toolkit.factorials.sf_factorial.h1"></a> 53 <span class="phrase"><a name="math_toolkit.factorials.sf_factorial.description"></a></span><a class="link" href="sf_factorial.html#math_toolkit.factorials.sf_factorial.description">Description</a> 54 </h5> 55<div class="important"><table border="0" summary="Important"> 56<tr> 57<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../../doc/src/images/important.png"></td> 58<th align="left">Important</th> 59</tr> 60<tr><td align="left" valign="top"> 61<p> 62 The functions described below are templates where the template argument 63 T CANNOT be deduced from the arguments passed to the function. Therefore 64 if you write something like: 65 </p> 66<p> 67 <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">factorial</span><span class="special">(</span><span class="number">2</span><span class="special">);</span></code> 68 </p> 69<p> 70 You will get a (perhaps perplexing) compiler error, usually indicating 71 that there is no such function to be found. Instead you need to specify 72 the return type explicitly and write: 73 </p> 74<p> 75 <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">factorial</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="number">2</span><span class="special">);</span></code> 76 </p> 77<p> 78 So that the return type is known. 79 </p> 80<p> 81 Furthermore, the template argument must be a real-valued type such as 82 <code class="computeroutput"><span class="keyword">float</span></code> or <code class="computeroutput"><span class="keyword">double</span></code> 83 and not an integer type - that would overflow far too easily for quite 84 small values of parameter <code class="computeroutput"><span class="identifier">i</span></code>! 85 </p> 86<p> 87 The source code <code class="computeroutput"><span class="keyword">static_assert</span></code> 88 and comment just after the will be: 89 </p> 90<pre class="programlisting"><span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(!</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_integral</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span><span class="special">);</span> 91<span class="comment">// factorial<unsigned int>(n) is not implemented</span> 92<span class="comment">// because it would overflow integral type T for too small n</span> 93<span class="comment">// to be useful. Use instead a floating-point type,</span> 94<span class="comment">// and convert to an unsigned type if essential, for example:</span> 95<span class="comment">// unsigned int nfac = static_cast<unsigned int>(factorial<double>(n));</span> 96<span class="comment">// See factorial documentation for more detail.</span> 97</pre> 98</td></tr> 99</table></div> 100<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> 101<span class="identifier">T</span> <span class="identifier">factorial</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span><span class="special">);</span> 102 103<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Chapter 21. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">></span> 104<span class="identifier">T</span> <span class="identifier">factorial</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span><span class="special">,</span> <span class="keyword">const</span> <a class="link" href="../../policy.html" title="Chapter 21. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&);</span> 105</pre> 106<p> 107 Returns <code class="literal">i!</code>. 108 </p> 109<p> 110 The final <a class="link" href="../../policy.html" title="Chapter 21. Policies: Controlling Precision, Error Handling etc">Policy</a> argument is optional and can 111 be used to control the behaviour of the function: how it handles errors, 112 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 113 documentation for more details</a>. 114 </p> 115<p> 116 For <code class="literal">i <= max_factorial<T>::value</code> this is implemented 117 by table lookup, for larger values of <code class="literal">i</code>, this function 118 is implemented in terms of <a class="link" href="../sf_gamma/tgamma.html" title="Gamma">tgamma</a>. 119 </p> 120<p> 121 If <code class="literal">i</code> is so large that the result can not be represented 122 in type T, then calls <a class="link" href="../error_handling.html#math_toolkit.error_handling.overflow_error">overflow_error</a>. 123 </p> 124<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> 125<span class="keyword">constexpr</span> <span class="identifier">T</span> <span class="identifier">unchecked_factorial</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span><span class="special">);</span> 126</pre> 127<p> 128 Returns <code class="literal">i!</code>. 129 </p> 130<p> 131 Internally this function performs table lookup of the result. Further it 132 performs no range checking on the value of i: it is up to the caller to ensure 133 that <code class="literal">i <= max_factorial<T>::value</code>. This function 134 is intended to be used inside inner loops that require fast table lookup 135 of factorials, but requires care to ensure that argument <code class="literal">i</code> 136 never grows too large. 137 </p> 138<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> 139<span class="keyword">struct</span> <span class="identifier">max_factorial</span> 140<span class="special">{</span> 141 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">unsigned</span> <span class="identifier">value</span> <span class="special">=</span> <span class="identifier">X</span><span class="special">;</span> 142<span class="special">};</span> 143</pre> 144<p> 145 This traits class defines the largest value that can be passed to <code class="literal">unchecked_factorial</code>. 146 The member <code class="computeroutput"><span class="identifier">value</span></code> can be used 147 where integral constant expressions are required: for example to define the 148 size of further tables that depend on the factorials. 149 </p> 150<p> 151 This function is <code class="computeroutput"><span class="keyword">constexpr</span></code> only 152 if the compiler supports C++14 constexpr functions. 153 </p> 154<h5> 155<a name="math_toolkit.factorials.sf_factorial.h2"></a> 156 <span class="phrase"><a name="math_toolkit.factorials.sf_factorial.accuracy"></a></span><a class="link" href="sf_factorial.html#math_toolkit.factorials.sf_factorial.accuracy">Accuracy</a> 157 </h5> 158<p> 159 For arguments smaller than <code class="computeroutput"><span class="identifier">max_factorial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span></code> the result should be correctly rounded. 160 For larger arguments the accuracy will be the same as for <a class="link" href="../sf_gamma/tgamma.html" title="Gamma">tgamma</a>. 161 </p> 162<h5> 163<a name="math_toolkit.factorials.sf_factorial.h3"></a> 164 <span class="phrase"><a name="math_toolkit.factorials.sf_factorial.testing"></a></span><a class="link" href="sf_factorial.html#math_toolkit.factorials.sf_factorial.testing">Testing</a> 165 </h5> 166<p> 167 Basic sanity checks and spot values to verify the data tables: the main tests 168 for the <a class="link" href="../sf_gamma/tgamma.html" title="Gamma">tgamma</a> function 169 handle those cases already. 170 </p> 171<h5> 172<a name="math_toolkit.factorials.sf_factorial.h4"></a> 173 <span class="phrase"><a name="math_toolkit.factorials.sf_factorial.implementation"></a></span><a class="link" href="sf_factorial.html#math_toolkit.factorials.sf_factorial.implementation">Implementation</a> 174 </h5> 175<p> 176 The factorial function is table driven for small arguments, and is implemented 177 in terms of <a class="link" href="../sf_gamma/tgamma.html" title="Gamma">tgamma</a> for 178 larger arguments. 179 </p> 180</div> 181<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 182<td align="left"></td> 183<td align="right"><div class="copyright-footer">Copyright © 2006-2019 Nikhar 184 Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, 185 Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Matthew Pulver, Johan 186 Råde, Gautam Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, 187 Daryle Walker and Xiaogang Zhang<p> 188 Distributed under the Boost Software License, Version 1.0. (See accompanying 189 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>) 190 </p> 191</div></td> 192</tr></table> 193<hr> 194<div class="spirit-nav"> 195<a accesskey="p" href="../factorials.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../factorials.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="sf_double_factorial.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 196</div> 197</body> 198</html> 199