# <span class='text-muted'>046.</span> Use GAMMA to compute factorials

<span style='font-size: small;' class='text-muted'>topic: {ref}`math-intrinsic-functions`</span>

Why does Fortran not have a factorial function?
It does, as for positive whole values of $n$,
the [gamma function](https://en.wikipedia.org/wiki/Gamma_function)
simplifies to the factorial function for $n-1$.
That is,
```
n! == gamma(n+1)
```

```{literalinclude} ../../src/factorial.f90
:language: fortran
:caption: factorial.f90 | <a href="https://github.com/zmoon/FortranTipBrowser/blob/main/src/factorial.f90" target="_blank" title="See this source on GitHub"><i class="fab fa-github"></i></a> | <a href="https://github.com/Beliavsky/FortranTip/blob/main/factorial.f90" target="_blank" title="See the original source on Beliavsky/FortranTip GitHub"><i class="fab fa-github"></i><sub>0</sub></a> | <a href="https://godbolt.org/#g:!((g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:fortran,selection:(endColumn:1,endLineNumber:15,positionColumn:1,positionLineNumber:15,selectionStartColumn:1,selectionStartLineNumber:15,startColumn:1,startLineNumber:15),source:'program+factorial%0A+++use,+intrinsic+::+iso_fortran_env,+only:+wp+%3D%3E+real64%0A%0A+++integer,+parameter+::+n(*)+%3D+%5B0,+1,+5,+11,+170%5D%0A+++integer++++++++++++::+j%0A%0A+++do+j+%3D+1,+size(n)%0A++++++print+!'(*(g0,1x))!',+!'factorial+of!',+n(j),+!'+is+!',+%26%0A+++++++++product(%5B(real(i,+kind%3Dwp),+i%3D1,+n(j))%5D),+%26%0A+++++++++!'+or+!',+%26%0A+++++++++gamma(real(n(j)+%2B+1,+kind%3Dwp))%0A+++end+do%0A+++print+*,+huge(0._wp)%0A%0Aend+program+factorial%0A'),l:'5',n:'0',o:'Fortran+source+%231',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:gfortran112,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'0',intel:'0',libraryCode:'0',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:fortran,libs:!(),options:'',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1,tree:'1'),l:'5',n:'0',o:'x86-64+gfortran+11.2+(Fortran,+Editor+%231,+Compiler+%231)',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',m:62.300683371298405,n:'0',o:'',t:'0'),(g:!((h:output,i:(compiler:1,editor:1,fontScale:14,fontUsePx:'0',tree:'1',wrap:'1'),l:'5',n:'0',o:'Output+of+x86-64+gfortran+11.2+(Compiler+%231)',t:'0')),header:(),l:'4',m:37.699316628701595,n:'0',o:'',s:0,t:'0')),l:'3',n:'0',o:'',t:'0')),version:4" target="_blank" title="Open in Godbolt Compiler Explorer"><img src="https://raw.githubusercontent.com/compiler-explorer/compiler-explorer/main/views/resources/site-logo.svg" alt="Godbolt Compiler Explorer logo" width="55.11" height="16.7" class="align-text-bottom" /></a> | <a href="https://play.fortran-lang.org/?code=program%20factorial%0A%20%20%20use%2C%20intrinsic%20%3A%3A%20iso_fortran_env%2C%20only%3A%20wp%20%3D%3E%20real64%0A%0A%20%20%20integer%2C%20parameter%20%3A%3A%20n%28%2A%29%20%3D%20%5B0%2C%201%2C%205%2C%2011%2C%20170%5D%0A%20%20%20integer%20%20%20%20%20%20%20%20%20%20%20%20%3A%3A%20j%0A%0A%20%20%20do%20j%20%3D%201%2C%20size%28n%29%0A%20%20%20%20%20%20print%20%27%28%2A%28g0%2C1x%29%29%27%2C%20%27factorial%20of%27%2C%20n%28j%29%2C%20%27%20is%20%27%2C%20%26%0A%20%20%20%20%20%20%20%20%20product%28%5B%28real%28i%2C%20kind%3Dwp%29%2C%20i%3D1%2C%20n%28j%29%29%5D%29%2C%20%26%0A%20%20%20%20%20%20%20%20%20%27%20or%20%27%2C%20%26%0A%20%20%20%20%20%20%20%20%20gamma%28real%28n%28j%29%20%2B%201%2C%20kind%3Dwp%29%29%0A%20%20%20end%20do%0A%20%20%20print%20%2A%2C%20huge%280._wp%29%0A%0Aend%20program%20factorial%0A" target="_blank" title="Open in Fortran Playground"><img src="https://raw.githubusercontent.com/fortran-lang/playground/main/frontend/src/fortran-logo.png" alt="Fortran logo" height="15.5" class="align-text-bottom" /></a>
```

```{code-block} text
:caption: Output[^gfortran-version]

factorial of 0  is  1.0000000000000000  or  1.0000000000000000
factorial of 1  is  1.0000000000000000  or  1.0000000000000000
factorial of 5  is  120.00000000000000  or  120.00000000000000
factorial of 11  is  39916800.000000000  or  39916800.000000000
factorial of 170  is  0.72574156153079940E+307  or  0.72574156153079990E+307
   1.7976931348623157E+308

```

[^gfortran-version]: Compiled using `GNU Fortran (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0` with no flags

Intrinsic function
[`gamma`](https://gcc.gnu.org/onlinedocs/gfortran/GAMMA.html)
was added in the F2008 standard.

We can see that $170!$ is close to the real64 limit.
$171!$ [would be](https://www.wolframalpha.com/input?i=171%21) too large.

Also used above:
* implied `do` loop for computing the array passed to `product`
* assumed-size array (`n(*)`) -- the size is "assumed" from the size of the
  array literal on the right-hand side of the equals sign
* `g0` edit descriptor and `*` infinite repeat count -- see Tip 041

```{note}
Thanks to [@urbanjost](https://github.com/urbanjost)
[for this tip and code](https://github.com/Beliavsky/FortranTip/issues/19).
```

---

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Why does Fortran not have a factorial function? It does, as for positive whole values of X the Gamma function simplifies to the factorial function for (X-1).<br>That is,<br><br>x! == gamma(x+1)<br><br>Thanks to urbanjost for tip! <a href="https://t.co/fTAPvhKEpr">pic.twitter.com/fTAPvhKEpr</a></p>&mdash; FortranTip (@fortrantip) <a href="https://twitter.com/fortrantip/status/1474357943667671060?ref_src=twsrc%5Etfw">December 24, 2021</a></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>