Factorial.java
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.apache.commons.numbers.combinatorics;
- /**
- * <a href="http://mathworld.wolfram.com/Factorial.html">Factorial of a number</a>.
- */
- public final class Factorial {
- /** All long-representable factorials. */
- static final long[] FACTORIALS = {
- 1L, 1L, 2L,
- 6L, 24L, 120L,
- 720L, 5040L, 40320L,
- 362880L, 3628800L, 39916800L,
- 479001600L, 6227020800L, 87178291200L,
- 1307674368000L, 20922789888000L, 355687428096000L,
- 6402373705728000L, 121645100408832000L, 2432902008176640000L
- };
- /** All factorials that can be represented as a double (values up to 170!). */
- private static final double[] DOUBLE_FACTORIALS = {
- 1,
- 1,
- 2,
- 6,
- 24,
- 120,
- 720,
- 5040,
- 40320,
- 362880,
- 3628800,
- 3.99168E7,
- 4.790016E8,
- 6.2270208E9,
- 8.71782912E10,
- 1.307674368E12,
- 2.0922789888E13,
- 3.55687428096E14,
- 6.402373705728E15,
- 1.21645100408832E17,
- 2.43290200817664E18,
- 5.109094217170944E19,
- 1.1240007277776077E21,
- 2.585201673888498E22,
- 6.204484017332394E23,
- 1.5511210043330986E25,
- 4.0329146112660565E26,
- 1.0888869450418352E28,
- 3.0488834461171387E29,
- 8.841761993739702E30,
- 2.6525285981219107E32,
- 8.222838654177922E33,
- 2.631308369336935E35,
- 8.683317618811886E36,
- 2.9523279903960416E38,
- 1.0333147966386145E40,
- 3.7199332678990125E41,
- 1.3763753091226346E43,
- 5.230226174666011E44,
- 2.0397882081197444E46,
- 8.159152832478977E47,
- 3.345252661316381E49,
- 1.40500611775288E51,
- 6.041526306337383E52,
- 2.658271574788449E54,
- 1.1962222086548019E56,
- 5.502622159812089E57,
- 2.5862324151116818E59,
- 1.2413915592536073E61,
- 6.082818640342675E62,
- 3.0414093201713376E64,
- 1.5511187532873822E66,
- 8.065817517094388E67,
- 4.2748832840600255E69,
- 2.308436973392414E71,
- 1.2696403353658276E73,
- 7.109985878048635E74,
- 4.0526919504877214E76,
- 2.3505613312828785E78,
- 1.3868311854568984E80,
- 8.32098711274139E81,
- 5.075802138772248E83,
- 3.146997326038794E85,
- 1.98260831540444E87,
- 1.2688693218588417E89,
- 8.247650592082472E90,
- 5.443449390774431E92,
- 3.647111091818868E94,
- 2.4800355424368305E96,
- 1.711224524281413E98,
- 1.1978571669969892E100,
- 8.504785885678623E101,
- 6.1234458376886085E103,
- 4.4701154615126844E105,
- 3.307885441519386E107,
- 2.48091408113954E109,
- 1.8854947016660504E111,
- 1.4518309202828587E113,
- 1.1324281178206297E115,
- 8.946182130782976E116,
- 7.156945704626381E118,
- 5.797126020747368E120,
- 4.753643337012842E122,
- 3.945523969720659E124,
- 3.314240134565353E126,
- 2.81710411438055E128,
- 2.4227095383672734E130,
- 2.107757298379528E132,
- 1.8548264225739844E134,
- 1.650795516090846E136,
- 1.4857159644817615E138,
- 1.352001527678403E140,
- 1.2438414054641308E142,
- 1.1567725070816416E144,
- 1.087366156656743E146,
- 1.032997848823906E148,
- 9.916779348709496E149,
- 9.619275968248212E151,
- 9.426890448883248E153,
- 9.332621544394415E155,
- 9.332621544394415E157,
- 9.42594775983836E159,
- 9.614466715035127E161,
- 9.90290071648618E163,
- 1.0299016745145628E166,
- 1.081396758240291E168,
- 1.1462805637347084E170,
- 1.226520203196138E172,
- 1.324641819451829E174,
- 1.4438595832024937E176,
- 1.588245541522743E178,
- 1.7629525510902446E180,
- 1.974506857221074E182,
- 2.2311927486598138E184,
- 2.5435597334721877E186,
- 2.925093693493016E188,
- 3.393108684451898E190,
- 3.969937160808721E192,
- 4.684525849754291E194,
- 5.574585761207606E196,
- 6.689502913449127E198,
- 8.094298525273444E200,
- 9.875044200833601E202,
- 1.214630436702533E205,
- 1.506141741511141E207,
- 1.882677176888926E209,
- 2.372173242880047E211,
- 3.0126600184576594E213,
- 3.856204823625804E215,
- 4.974504222477287E217,
- 6.466855489220474E219,
- 8.47158069087882E221,
- 1.1182486511960043E224,
- 1.4872707060906857E226,
- 1.9929427461615188E228,
- 2.6904727073180504E230,
- 3.659042881952549E232,
- 5.012888748274992E234,
- 6.917786472619489E236,
- 9.615723196941089E238,
- 1.3462012475717526E241,
- 1.898143759076171E243,
- 2.695364137888163E245,
- 3.854370717180073E247,
- 5.5502938327393044E249,
- 8.047926057471992E251,
- 1.1749972043909107E254,
- 1.727245890454639E256,
- 2.5563239178728654E258,
- 3.80892263763057E260,
- 5.713383956445855E262,
- 8.62720977423324E264,
- 1.3113358856834524E267,
- 2.0063439050956823E269,
- 3.0897696138473508E271,
- 4.789142901463394E273,
- 7.471062926282894E275,
- 1.1729568794264145E278,
- 1.853271869493735E280,
- 2.9467022724950384E282,
- 4.7147236359920616E284,
- 7.590705053947219E286,
- 1.2296942187394494E289,
- 2.0044015765453026E291,
- 3.287218585534296E293,
- 5.423910666131589E295,
- 9.003691705778438E297,
- 1.503616514864999E300,
- 2.5260757449731984E302,
- 4.269068009004705E304,
- 7.257415615307999E306
- };
- /** Private constructor. */
- private Factorial() {
- // intentionally empty.
- }
- /**
- * Computes the factorial of {@code n}.
- *
- * @param n Argument.
- * @return {@code n!}
- * @throws IllegalArgumentException if {@code n < 0}.
- * @throws IllegalArgumentException if {@code n > 20} (the factorial
- * value is too large to fit in a {@code long}).
- */
- public static long value(int n) {
- if (n < 0 ||
- n > 20) {
- throw new CombinatoricsException(CombinatoricsException.OUT_OF_RANGE,
- n, 0, 20);
- }
- return FACTORIALS[n];
- }
- /**
- * Computes the factorial of {@code n}.
- *
- * <p>The result should be small enough to fit into a {@code double}: The
- * largest {@code n} for which {@code n!} does not exceed
- * {@code Double.MAX_VALUE} is 170. {@code Double.POSITIVE_INFINITY} is
- * returned for {@code n > 170}.
- *
- * @param n Argument.
- * @return {@code n!}
- * @throws IllegalArgumentException if {@code n < 0}.
- * @since 1.1
- */
- public static double doubleValue(int n) {
- if (n < 0) {
- throw new CombinatoricsException(CombinatoricsException.NEGATIVE, n);
- }
- if (n < DOUBLE_FACTORIALS.length) {
- return DOUBLE_FACTORIALS[n];
- }
- return Double.POSITIVE_INFINITY;
- }
- /**
- * Return the factorial of {@code n}.
- *
- * <p>Note: This is an internal method that exposes the tabulated factorials that can
- * be represented as a double. No checks are performed on the argument.
- *
- * @param n Argument (must be in [0, 170])
- * @return n!
- */
- static double uncheckedFactorial(int n) {
- return DOUBLE_FACTORIALS[n];
- }
- }