Factorial.java

  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. package org.apache.commons.numbers.combinatorics;

  18. /**
  19.  * <a href="http://mathworld.wolfram.com/Factorial.html">Factorial of a number</a>.
  20.  */
  21. public final class Factorial {

  22.     /** All long-representable factorials. */
  23.     static final long[] FACTORIALS = {
  24.                        1L,                  1L,                   2L,
  25.                        6L,                 24L,                 120L,
  26.                      720L,               5040L,               40320L,
  27.                   362880L,            3628800L,            39916800L,
  28.                479001600L,         6227020800L,         87178291200L,
  29.            1307674368000L,     20922789888000L,     355687428096000L,
  30.         6402373705728000L, 121645100408832000L, 2432902008176640000L
  31.     };

  32.     /** All factorials that can be represented as a double (values up to 170!). */
  33.     private static final double[] DOUBLE_FACTORIALS = {
  34.         1,
  35.         1,
  36.         2,
  37.         6,
  38.         24,
  39.         120,
  40.         720,
  41.         5040,
  42.         40320,
  43.         362880,
  44.         3628800,
  45.         3.99168E7,
  46.         4.790016E8,
  47.         6.2270208E9,
  48.         8.71782912E10,
  49.         1.307674368E12,
  50.         2.0922789888E13,
  51.         3.55687428096E14,
  52.         6.402373705728E15,
  53.         1.21645100408832E17,
  54.         2.43290200817664E18,
  55.         5.109094217170944E19,
  56.         1.1240007277776077E21,
  57.         2.585201673888498E22,
  58.         6.204484017332394E23,
  59.         1.5511210043330986E25,
  60.         4.0329146112660565E26,
  61.         1.0888869450418352E28,
  62.         3.0488834461171387E29,
  63.         8.841761993739702E30,
  64.         2.6525285981219107E32,
  65.         8.222838654177922E33,
  66.         2.631308369336935E35,
  67.         8.683317618811886E36,
  68.         2.9523279903960416E38,
  69.         1.0333147966386145E40,
  70.         3.7199332678990125E41,
  71.         1.3763753091226346E43,
  72.         5.230226174666011E44,
  73.         2.0397882081197444E46,
  74.         8.159152832478977E47,
  75.         3.345252661316381E49,
  76.         1.40500611775288E51,
  77.         6.041526306337383E52,
  78.         2.658271574788449E54,
  79.         1.1962222086548019E56,
  80.         5.502622159812089E57,
  81.         2.5862324151116818E59,
  82.         1.2413915592536073E61,
  83.         6.082818640342675E62,
  84.         3.0414093201713376E64,
  85.         1.5511187532873822E66,
  86.         8.065817517094388E67,
  87.         4.2748832840600255E69,
  88.         2.308436973392414E71,
  89.         1.2696403353658276E73,
  90.         7.109985878048635E74,
  91.         4.0526919504877214E76,
  92.         2.3505613312828785E78,
  93.         1.3868311854568984E80,
  94.         8.32098711274139E81,
  95.         5.075802138772248E83,
  96.         3.146997326038794E85,
  97.         1.98260831540444E87,
  98.         1.2688693218588417E89,
  99.         8.247650592082472E90,
  100.         5.443449390774431E92,
  101.         3.647111091818868E94,
  102.         2.4800355424368305E96,
  103.         1.711224524281413E98,
  104.         1.1978571669969892E100,
  105.         8.504785885678623E101,
  106.         6.1234458376886085E103,
  107.         4.4701154615126844E105,
  108.         3.307885441519386E107,
  109.         2.48091408113954E109,
  110.         1.8854947016660504E111,
  111.         1.4518309202828587E113,
  112.         1.1324281178206297E115,
  113.         8.946182130782976E116,
  114.         7.156945704626381E118,
  115.         5.797126020747368E120,
  116.         4.753643337012842E122,
  117.         3.945523969720659E124,
  118.         3.314240134565353E126,
  119.         2.81710411438055E128,
  120.         2.4227095383672734E130,
  121.         2.107757298379528E132,
  122.         1.8548264225739844E134,
  123.         1.650795516090846E136,
  124.         1.4857159644817615E138,
  125.         1.352001527678403E140,
  126.         1.2438414054641308E142,
  127.         1.1567725070816416E144,
  128.         1.087366156656743E146,
  129.         1.032997848823906E148,
  130.         9.916779348709496E149,
  131.         9.619275968248212E151,
  132.         9.426890448883248E153,
  133.         9.332621544394415E155,
  134.         9.332621544394415E157,
  135.         9.42594775983836E159,
  136.         9.614466715035127E161,
  137.         9.90290071648618E163,
  138.         1.0299016745145628E166,
  139.         1.081396758240291E168,
  140.         1.1462805637347084E170,
  141.         1.226520203196138E172,
  142.         1.324641819451829E174,
  143.         1.4438595832024937E176,
  144.         1.588245541522743E178,
  145.         1.7629525510902446E180,
  146.         1.974506857221074E182,
  147.         2.2311927486598138E184,
  148.         2.5435597334721877E186,
  149.         2.925093693493016E188,
  150.         3.393108684451898E190,
  151.         3.969937160808721E192,
  152.         4.684525849754291E194,
  153.         5.574585761207606E196,
  154.         6.689502913449127E198,
  155.         8.094298525273444E200,
  156.         9.875044200833601E202,
  157.         1.214630436702533E205,
  158.         1.506141741511141E207,
  159.         1.882677176888926E209,
  160.         2.372173242880047E211,
  161.         3.0126600184576594E213,
  162.         3.856204823625804E215,
  163.         4.974504222477287E217,
  164.         6.466855489220474E219,
  165.         8.47158069087882E221,
  166.         1.1182486511960043E224,
  167.         1.4872707060906857E226,
  168.         1.9929427461615188E228,
  169.         2.6904727073180504E230,
  170.         3.659042881952549E232,
  171.         5.012888748274992E234,
  172.         6.917786472619489E236,
  173.         9.615723196941089E238,
  174.         1.3462012475717526E241,
  175.         1.898143759076171E243,
  176.         2.695364137888163E245,
  177.         3.854370717180073E247,
  178.         5.5502938327393044E249,
  179.         8.047926057471992E251,
  180.         1.1749972043909107E254,
  181.         1.727245890454639E256,
  182.         2.5563239178728654E258,
  183.         3.80892263763057E260,
  184.         5.713383956445855E262,
  185.         8.62720977423324E264,
  186.         1.3113358856834524E267,
  187.         2.0063439050956823E269,
  188.         3.0897696138473508E271,
  189.         4.789142901463394E273,
  190.         7.471062926282894E275,
  191.         1.1729568794264145E278,
  192.         1.853271869493735E280,
  193.         2.9467022724950384E282,
  194.         4.7147236359920616E284,
  195.         7.590705053947219E286,
  196.         1.2296942187394494E289,
  197.         2.0044015765453026E291,
  198.         3.287218585534296E293,
  199.         5.423910666131589E295,
  200.         9.003691705778438E297,
  201.         1.503616514864999E300,
  202.         2.5260757449731984E302,
  203.         4.269068009004705E304,
  204.         7.257415615307999E306
  205.     };

  206.     /** Private constructor. */
  207.     private Factorial() {
  208.         // intentionally empty.
  209.     }

  210.     /**
  211.      * Computes the factorial of {@code n}.
  212.      *
  213.      * @param n Argument.
  214.      * @return {@code n!}
  215.      * @throws IllegalArgumentException if {@code n < 0}.
  216.      * @throws IllegalArgumentException if {@code n > 20} (the factorial
  217.      * value is too large to fit in a {@code long}).
  218.      */
  219.     public static long value(int n) {
  220.         if (n < 0 ||
  221.             n > 20) {
  222.             throw new CombinatoricsException(CombinatoricsException.OUT_OF_RANGE,
  223.                                              n, 0, 20);
  224.         }

  225.         return FACTORIALS[n];
  226.     }

  227.     /**
  228.      * Computes the factorial of {@code n}.
  229.      *
  230.      * <p>The result should be small enough to fit into a {@code double}: The
  231.      * largest {@code n} for which {@code n!} does not exceed
  232.      * {@code Double.MAX_VALUE} is 170. {@code Double.POSITIVE_INFINITY} is
  233.      * returned for {@code n > 170}.
  234.      *
  235.      * @param n Argument.
  236.      * @return {@code n!}
  237.      * @throws IllegalArgumentException if {@code n < 0}.
  238.      * @since 1.1
  239.      */
  240.     public static double doubleValue(int n) {
  241.         if (n < 0) {
  242.             throw new CombinatoricsException(CombinatoricsException.NEGATIVE, n);
  243.         }
  244.         if (n < DOUBLE_FACTORIALS.length) {
  245.             return DOUBLE_FACTORIALS[n];
  246.         }
  247.         return Double.POSITIVE_INFINITY;
  248.     }

  249.     /**
  250.      * Return the factorial of {@code n}.
  251.      *
  252.      * <p>Note: This is an internal method that exposes the tabulated factorials that can
  253.      * be represented as a double. No checks are performed on the argument.
  254.      *
  255.      * @param n Argument (must be in [0, 170])
  256.      * @return n!
  257.      */
  258.     static double uncheckedFactorial(int n) {
  259.         return DOUBLE_FACTORIALS[n];
  260.     }
  261. }