如何理解阶乘增长的速度
阶乘的增长速度很快就会超过指数增长,下表给出了一些精确值和近似量级。
| n | n! | 近似量级 |
|---|---|---|
| 0 | 1 | 1 |
| 5 | 120 | 1.2 × 10² |
| 10 | 3,628,800 | 3.6 × 10⁶ |
| 15 | 1,307,674,368,000 | 1.3 × 10¹² |
| 18 | 6,402,373,705,728,000 | 6.4 × 10¹⁵ |
| 20 | 2,432,902,008,176,640,000 | 2.4 × 10¹⁸ |
- 18!(约 6.40 × 10¹⁵)是仍低于安全整数上限的最大阶乘,因为 JavaScript 的 Number.MAX_SAFE_INTEGER 为 2⁵³ − 1 ≈ 9.007 × 10¹⁵;因此本计算器只在 n = 18 及以下时显示精确值。越过这个上限之后,阶乘仍能作为双精度浮点数精确表示,一直到 22!,因为每个阶乘都含有大量因数 2;23! 才是第一个会被舍入的阶乘。
- 对于 n 从 19 到 170,只会显示科学记数法的近似值(以及 ln(n!)),因为精确整数所需的精度已经超出了不借助大整数库的标准浮点运算所能支持的范围。
- 当 n 超过 170 时,n! 会超过标准双精度浮点数所能表示的最大值(约 1.8 × 10³⁰⁸)并溢出为无穷大,因此本计算器把 n 的上限设为 170。
什么是阶乘?
非负整数 n 的阶乘,记作 n!,定义为从 1 到 n 所有正整数的乘积:n! = n × (n − 1) × (n − 2) × ... × 2 × 1。例如,5! = 5 × 4 × 3 × 2 × 1 = 120。按定义,0! = 1(空乘积,即乘法单位元),这是组合数学中通用的标准约定。
阶乘的增长速度极快——比 n 的指数函数还要快得多。10! = 3,628,800,而 20! 就已经超过 24 万亿亿(2.43 × 10¹⁸),比自大爆炸以来经过的秒数还要多。正是由于这种爆炸式的增长,较大的 n 通常用科学记数法表示阶乘,超过一定范围后再显示精确的整数值就不再实际。
阶乘是组合数学的基础:它给出了把 n 个不同物体按顺序排列的方式数(排列数),也出现在用于计算无序选取方式数(组合数)的二项式系数公式的分母中。此外,阶乘还出现在概率论、微积分(泰勒级数的系数)以及许多闭式组合恒等式中。
如何使用本阶乘计算器
- 输入一个介于 0 到 170 之间的整数 n(170! 已经非常接近标准双精度浮点数在溢出为无穷大之前所能表示的最大阶乘)。
- 查看以科学记数法给出的结果,无论 n 大小,该结果都会显示。
- 当 n ≤ 18 时,还会显示 n! 的精确整数值,因为更大的阶乘超出了标准双精度运算能精确表示的整数范围(2⁵³ ≈ 9.007 × 10¹⁵)。
- 查看 n! 的自然对数(在不发生溢出的情况下处理非常大的阶乘时很有用),以及 n! 精确十进制表示中末尾零的个数。
阶乘、末尾零个数及 ln(n!) 的计算方法
阶乘的定义性递推关系是 n! = n × (n − 1)!,基准情形为 0! = 1。举例说明:5! = 5 × 4! = 5 × 4 × 3! = 5 × 4 × 3 × 2! = 5 × 4 × 3 × 2 × 1! = 5 × 4 × 3 × 2 × 1 × 0! = 120 × 1 = 120。
对于较大的 n,自然对数 ln(n!) 是通过求和 Σ ln(k)(k 从 2 到 n)计算的,这样可以避免直接相乘原始阶乘所导致的溢出。科学记数法结果则由这个和通过以 10 为底的对数推出:log₁₀(n!) = ln(n!) ÷ ln(10),整数部分给出指数,小数部分(用 10^x 换算回来)给出尾数。
n! 末尾零的个数等于 10 能整除 n! 的次数;由于 10 = 2 × 5,且在阶乘中因数 2 的个数总是多于因数 5 的个数,这个问题就归结为用勒让德公式统计因数 5 的个数:末尾零个数 = ⌊n/5⌋ + ⌊n/25⌋ + ⌊n/125⌋ + ...。以 10! 为例:⌊10/5⌋ = 2,⌊10/25⌋ = 0,所以 10! 有 2 个末尾零——这与 10! = 3,628,800 相符。
常见错误
- 忘记 0! = 1 而不是 0——这是一条标准的数学约定(空乘积等于 1),对于组合公式在边界情形下能正确成立至关重要。
- 以为标准运算能对任意大的 n 精确计算阶乘——超过 n = 22 之后,精确整数值就会超出双精度浮点数在不产生舍入误差的情况下所能表示的范围。
- 把 n!(阶乘)和 nⁿ(n 的 n 次方)混淆——阶乘是把从 n 递减到 1 的一串整数相乘,而乘方是把 n 自身相乘 n 次;这两者的增长速度不同,很快就会明显拉开差距(5! = 120,而 5⁵ = 3125)。
- 输入负数或非整数——在这种初等意义下,阶乘只对非负整数有定义(伽玛函数把这一概念推广到了非整数,但那是另一个更高级的公式)。
常见问题
n 的阶乘是什么?
n 的阶乘(n!)是从 1 到 n 所有正整数的乘积。例如,5! = 5 × 4 × 3 × 2 × 1 = 120。按定义,0! = 1。
为什么 0! 等于 1?
按照数学约定,0! 被定义为 1,表示「空乘积」(零个因数相乘),按惯例等于乘法单位元 1。这一定义使排列数、组合数等组合公式在边界情形下也能保持一致——例如,把零个物体排列的方式恰好只有 1 种。
阶乘增长有多快?
阶乘的增长速度比 n 的指数函数还要快。10! 约为 360 万,但 20! 就已经超过 2.4 × 10¹⁸(2.4 万亿亿)。正是这种超指数的增长速度,使得即使 n 只是中等大小,阶乘也常常需要用科学记数法表示,也让阶乘常被用作数学中极快增长的例子。
100! 有多少个末尾零?
用勒让德公式(求和 ⌊100/5ⁱ⌋)计算,100! 有 ⌊100/5⌋ + ⌊100/25⌋ = 20 + 4 = 24 个末尾零。末尾零来自乘积中 10 = 2 × 5 这一因数,由于阶乘中因数 2 总是比因数 5 多,只需统计因数 5 的个数即可得到末尾零的数量。
计算器能精确计算的最大阶乘是多少?
在标准双精度浮点运算(JavaScript 及大多数计算器所使用)中,18! 是仍低于安全整数上限的最大阶乘,因为 18! ≈ 6.40 × 10¹⁵ 小于 2⁵³ − 1 ≈ 9.007 × 10¹⁵,而 19! 已经超过这个上限。不过越过该上限之后,阶乘仍能作为双精度浮点数精确表示,一直到 22!,因为每个阶乘都含有大量因数 2;23! 才是第一个会被舍入的阶乘。更大的阶乘通常以科学记数法表示。
参考文献
- NIST Digital Library of Mathematical Functions (DLMF), §5.1 Gamma Function: Factorial Function. dlmf.nist.gov.
- Rosen KH. Discrete Mathematics and Its Applications. 8th ed. McGraw-Hill, 2018. (Factorials and combinatorics.)
- Graham RL, Knuth DE, Patashnik O. Concrete Mathematics. 2nd ed. Addison-Wesley, 1994. (Legendre's formula for factors in n!.)