View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.numbers.combinatorics;
19  
20  /**
21   * <a href="http://mathworld.wolfram.com/Factorial.html">Factorial of a number</a>.
22   */
23  public final class Factorial {
24  
25      /** All long-representable factorials. */
26      static final long[] FACTORIALS = {
27                         1L,                  1L,                   2L,
28                         6L,                 24L,                 120L,
29                       720L,               5040L,               40320L,
30                    362880L,            3628800L,            39916800L,
31                 479001600L,         6227020800L,         87178291200L,
32             1307674368000L,     20922789888000L,     355687428096000L,
33          6402373705728000L, 121645100408832000L, 2432902008176640000L
34      };
35  
36      /** All factorials that can be represented as a double (values up to 170!). */
37      private static final double[] DOUBLE_FACTORIALS = {
38          1,
39          1,
40          2,
41          6,
42          24,
43          120,
44          720,
45          5040,
46          40320,
47          362880,
48          3628800,
49          3.99168E7,
50          4.790016E8,
51          6.2270208E9,
52          8.71782912E10,
53          1.307674368E12,
54          2.0922789888E13,
55          3.55687428096E14,
56          6.402373705728E15,
57          1.21645100408832E17,
58          2.43290200817664E18,
59          5.109094217170944E19,
60          1.1240007277776077E21,
61          2.585201673888498E22,
62          6.204484017332394E23,
63          1.5511210043330986E25,
64          4.0329146112660565E26,
65          1.0888869450418352E28,
66          3.0488834461171387E29,
67          8.841761993739702E30,
68          2.6525285981219107E32,
69          8.222838654177922E33,
70          2.631308369336935E35,
71          8.683317618811886E36,
72          2.9523279903960416E38,
73          1.0333147966386145E40,
74          3.7199332678990125E41,
75          1.3763753091226346E43,
76          5.230226174666011E44,
77          2.0397882081197444E46,
78          8.159152832478977E47,
79          3.345252661316381E49,
80          1.40500611775288E51,
81          6.041526306337383E52,
82          2.658271574788449E54,
83          1.1962222086548019E56,
84          5.502622159812089E57,
85          2.5862324151116818E59,
86          1.2413915592536073E61,
87          6.082818640342675E62,
88          3.0414093201713376E64,
89          1.5511187532873822E66,
90          8.065817517094388E67,
91          4.2748832840600255E69,
92          2.308436973392414E71,
93          1.2696403353658276E73,
94          7.109985878048635E74,
95          4.0526919504877214E76,
96          2.3505613312828785E78,
97          1.3868311854568984E80,
98          8.32098711274139E81,
99          5.075802138772248E83,
100         3.146997326038794E85,
101         1.98260831540444E87,
102         1.2688693218588417E89,
103         8.247650592082472E90,
104         5.443449390774431E92,
105         3.647111091818868E94,
106         2.4800355424368305E96,
107         1.711224524281413E98,
108         1.1978571669969892E100,
109         8.504785885678623E101,
110         6.1234458376886085E103,
111         4.4701154615126844E105,
112         3.307885441519386E107,
113         2.48091408113954E109,
114         1.8854947016660504E111,
115         1.4518309202828587E113,
116         1.1324281178206297E115,
117         8.946182130782976E116,
118         7.156945704626381E118,
119         5.797126020747368E120,
120         4.753643337012842E122,
121         3.945523969720659E124,
122         3.314240134565353E126,
123         2.81710411438055E128,
124         2.4227095383672734E130,
125         2.107757298379528E132,
126         1.8548264225739844E134,
127         1.650795516090846E136,
128         1.4857159644817615E138,
129         1.352001527678403E140,
130         1.2438414054641308E142,
131         1.1567725070816416E144,
132         1.087366156656743E146,
133         1.032997848823906E148,
134         9.916779348709496E149,
135         9.619275968248212E151,
136         9.426890448883248E153,
137         9.332621544394415E155,
138         9.332621544394415E157,
139         9.42594775983836E159,
140         9.614466715035127E161,
141         9.90290071648618E163,
142         1.0299016745145628E166,
143         1.081396758240291E168,
144         1.1462805637347084E170,
145         1.226520203196138E172,
146         1.324641819451829E174,
147         1.4438595832024937E176,
148         1.588245541522743E178,
149         1.7629525510902446E180,
150         1.974506857221074E182,
151         2.2311927486598138E184,
152         2.5435597334721877E186,
153         2.925093693493016E188,
154         3.393108684451898E190,
155         3.969937160808721E192,
156         4.684525849754291E194,
157         5.574585761207606E196,
158         6.689502913449127E198,
159         8.094298525273444E200,
160         9.875044200833601E202,
161         1.214630436702533E205,
162         1.506141741511141E207,
163         1.882677176888926E209,
164         2.372173242880047E211,
165         3.0126600184576594E213,
166         3.856204823625804E215,
167         4.974504222477287E217,
168         6.466855489220474E219,
169         8.47158069087882E221,
170         1.1182486511960043E224,
171         1.4872707060906857E226,
172         1.9929427461615188E228,
173         2.6904727073180504E230,
174         3.659042881952549E232,
175         5.012888748274992E234,
176         6.917786472619489E236,
177         9.615723196941089E238,
178         1.3462012475717526E241,
179         1.898143759076171E243,
180         2.695364137888163E245,
181         3.854370717180073E247,
182         5.5502938327393044E249,
183         8.047926057471992E251,
184         1.1749972043909107E254,
185         1.727245890454639E256,
186         2.5563239178728654E258,
187         3.80892263763057E260,
188         5.713383956445855E262,
189         8.62720977423324E264,
190         1.3113358856834524E267,
191         2.0063439050956823E269,
192         3.0897696138473508E271,
193         4.789142901463394E273,
194         7.471062926282894E275,
195         1.1729568794264145E278,
196         1.853271869493735E280,
197         2.9467022724950384E282,
198         4.7147236359920616E284,
199         7.590705053947219E286,
200         1.2296942187394494E289,
201         2.0044015765453026E291,
202         3.287218585534296E293,
203         5.423910666131589E295,
204         9.003691705778438E297,
205         1.503616514864999E300,
206         2.5260757449731984E302,
207         4.269068009004705E304,
208         7.257415615307999E306
209     };
210 
211     /** Private constructor. */
212     private Factorial() {
213         // intentionally empty.
214     }
215 
216     /**
217      * Computes the factorial of {@code n}.
218      *
219      * @param n Argument.
220      * @return {@code n!}
221      * @throws IllegalArgumentException if {@code n < 0}.
222      * @throws IllegalArgumentException if {@code n > 20} (the factorial
223      * value is too large to fit in a {@code long}).
224      */
225     public static long value(int n) {
226         if (n < 0 ||
227             n > 20) {
228             throw new CombinatoricsException(CombinatoricsException.OUT_OF_RANGE,
229                                              n, 0, 20);
230         }
231 
232         return FACTORIALS[n];
233     }
234 
235     /**
236      * Computes the factorial of {@code n}.
237      *
238      * <p>The result should be small enough to fit into a {@code double}: The
239      * largest {@code n} for which {@code n!} does not exceed
240      * {@code Double.MAX_VALUE} is 170. {@code Double.POSITIVE_INFINITY} is
241      * returned for {@code n > 170}.
242      *
243      * @param n Argument.
244      * @return {@code n!}
245      * @throws IllegalArgumentException if {@code n < 0}.
246      * @since 1.1
247      */
248     public static double doubleValue(int n) {
249         if (n < 0) {
250             throw new CombinatoricsException(CombinatoricsException.NEGATIVE, n);
251         }
252         if (n < DOUBLE_FACTORIALS.length) {
253             return DOUBLE_FACTORIALS[n];
254         }
255         return Double.POSITIVE_INFINITY;
256     }
257 
258     /**
259      * Return the factorial of {@code n}.
260      *
261      * <p>Note: This is an internal method that exposes the tabulated factorials that can
262      * be represented as a double. No checks are performed on the argument.
263      *
264      * @param n Argument (must be in [0, 170])
265      * @return n!
266      */
267     static double uncheckedFactorial(int n) {
268         return DOUBLE_FACTORIALS[n];
269     }
270 }