Skip to main content

malachite_nz/natural/arithmetic/
factorial.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MP Library.
4//
5//      `limb_apprsqrt`, `mpz_2multiswing_1`, `mpz_oddfac_1`, `mpz_fac_ui`, and `mpz_2fac_ui`
6//      contributed to the GNU project by Marco Bodrato.
7//
8//      Copyright © 1991-2018 Free Software Foundation, Inc.
9//
10// This file is part of Malachite.
11//
12// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
13// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
14// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
15
16use crate::natural::arithmetic::mul::product_of_limbs::limbs_product;
17use crate::natural::arithmetic::mul::{
18    limbs_mul_greater_to_out, limbs_mul_greater_to_out_scratch_len,
19};
20use crate::natural::arithmetic::square::{limbs_square_to_out, limbs_square_to_out_scratch_len};
21use crate::natural::{Natural, bit_to_limb_count_floor};
22use crate::platform::{
23    Limb, NTH_ROOT_NUMB_MASK_TABLE, ODD_DOUBLEFACTORIAL_TABLE_LIMIT, ODD_DOUBLEFACTORIAL_TABLE_MAX,
24    ODD_FACTORIAL_TABLE_LIMIT, ONE_LIMB_ODD_DOUBLEFACTORIAL_TABLE, ONE_LIMB_ODD_FACTORIAL_TABLE,
25    TABLE_2N_MINUS_POPC_2N, TABLE_LIMIT_2N_MINUS_POPC_2N,
26};
27use alloc::vec::Vec;
28use malachite_base::fail_on_untested_path;
29use malachite_base::num::arithmetic::traits::{
30    DoubleFactorial, Factorial, Gcd, Multifactorial, Parity, Pow, PowerOf2, Square, Subfactorial,
31    XMulYToZZ,
32};
33use malachite_base::num::basic::integers::PrimitiveInt;
34use malachite_base::num::basic::traits::One;
35use malachite_base::num::conversion::traits::{ConvertibleFrom, ExactFrom, WrappingFrom};
36#[cfg(feature = "32_bit_limbs")]
37use malachite_base::num::factorization::prime_sieve::limbs_prime_sieve_u32;
38#[cfg(not(feature = "32_bit_limbs"))]
39use malachite_base::num::factorization::prime_sieve::limbs_prime_sieve_u64;
40use malachite_base::num::factorization::prime_sieve::{id_to_n, limbs_prime_sieve_size, n_to_bit};
41use malachite_base::num::logic::traits::{BitAccess, CountOnes, NotAssign, SignificantBits};
42
43pub_test! {subfactorial_naive(n: u64) -> Natural {
44    let mut f = Natural::ONE;
45    let mut b = true;
46    for i in 1..=n {
47        f *= Natural::from(i);
48        if b {
49            f -= Natural::ONE;
50        } else {
51            f += Natural::ONE;
52        }
53        b.not_assign();
54    }
55    f
56}}
57
58// Returns an approximation of the square root of x.
59//
60// It gives:
61// ```
62// limb_apprsqrt(x) ^ 2 <= x < (limb_apprsqrt(x) + 1) ^ 2
63// ```
64// or
65// ```
66// x <= limb_apprsqrt(x) ^ 2 <= x * 9 / 8
67// ```
68//
69// This is equivalent to `limb_apprsqrt` in `mpz/oddfac_1.c`, GMP 6.2.1.
70fn limbs_approx_sqrt(x: u64) -> u64 {
71    assert!(x > 2);
72    let s = x.significant_bits() >> 1;
73    (u64::power_of_2(s) + (x >> s)) >> 1
74}
75
76pub(crate) const fn bit_to_n(bit: u64) -> u64 {
77    (bit * 3 + 4) | 1
78}
79
80// `limbs_2_multiswing_odd` computes the odd part of the 2-multiswing factorial of the parameter n.
81// The result x is an odd positive integer so that multiswing(n, 2) = x * 2 ^ a.
82//
83// The algorithm is described by Peter Luschny in "Divide, Swing and Conquer the Factorial!".
84//
85// The pointer sieve points to `limbs_prime_sieve_size(n)` limbs containing a bit array where primes
86// are marked as 0. Enough limbs must be pointed by `factors`.
87//
88// # Worst-case complexity
89// $T(n) = O(n (\log n)^2 \log\log n)$
90//
91// $M(n) = O(n \log n)$
92//
93// where $T$ is time, $M$ is additional memory, and $n$ is `n`.
94//
95// This is equivalent to `mpz_2multiswing_1` from `mpz/oddfac_1.c`, GMP 6.2.1, where `x_and_sieve`
96// is provided as a single slice, allowing the sieve to be overwritten.
97#[allow(clippy::useless_conversion)]
98fn limbs_2_multiswing_odd(
99    x_and_sieve: &mut [Limb],
100    x_len: usize,
101    mut n: Limb,
102    factors: &mut [Limb],
103) -> usize {
104    assert!(n > 25);
105    let mut prod = if n.odd() { n } else { 1 };
106    n.clear_bit(0);
107    let max_prod = Limb::MAX / (n - 1);
108    // Handle prime = 3 separately
109    let mut j = 0;
110    if prod > max_prod {
111        factors[j] = prod;
112        j += 1;
113        prod = 1;
114    }
115    let mut q = n;
116    while q >= 3 {
117        q /= 3;
118        if q.odd() {
119            prod *= 3;
120        }
121    }
122    let limb_n = n;
123    let n = u64::exact_from(n);
124    // Swing primes from 5 to n / 3
125    let mut s = limbs_approx_sqrt(n);
126    assert!(s >= 5);
127    s = n_to_bit(s);
128    assert!(bit_to_n(s + 1).square() > n);
129    assert!(s < n_to_bit(n / 3));
130    let start = const { n_to_bit(5) };
131    let mut index = bit_to_limb_count_floor(start);
132    let mut mask = Limb::power_of_2(start & Limb::WIDTH_MASK);
133    let sieve = &mut x_and_sieve[x_len..];
134    for i in start + 1..=s + 1 {
135        if sieve[index] & mask == 0 {
136            let prime = Limb::exact_from(id_to_n(i));
137            if prod > max_prod {
138                factors[j] = prod;
139                j += 1;
140                prod = 1;
141            }
142            let mut q = limb_n;
143            while q >= prime {
144                q /= prime;
145                if q.odd() {
146                    prod *= prime;
147                }
148            }
149        }
150        mask <<= 1;
151        if mask == 0 {
152            mask = 1;
153            index += 1;
154        }
155    }
156    assert!(max_prod <= const { Limb::MAX / 3 });
157    let l_max_prod = max_prod * 3;
158    for i in s + 2..=n_to_bit(n / 3) + 1 {
159        if sieve[index] & mask == 0 {
160            let prime = Limb::exact_from(id_to_n(i));
161            if (limb_n / prime).odd() {
162                if prod > l_max_prod {
163                    factors[j] = prod;
164                    j += 1;
165                    prod = prime;
166                } else {
167                    prod *= prime;
168                }
169            }
170        }
171        mask <<= 1;
172        if mask == 0 {
173            mask = 1;
174            index += 1;
175        }
176    }
177    // Store primes from (n + 1) / 2 to n
178    let start = n_to_bit(n >> 1) + 1;
179    let mut index = bit_to_limb_count_floor(start);
180    let mut mask = Limb::power_of_2(start & Limb::WIDTH_MASK);
181    for i in start + 1..=n_to_bit(n) + 1 {
182        if sieve[index] & mask == 0 {
183            let prime = Limb::exact_from(id_to_n(i));
184            if prod > max_prod {
185                factors[j] = prod;
186                j += 1;
187                prod = prime;
188            } else {
189                prod *= prime;
190            }
191        }
192        mask <<= 1;
193        if mask == 0 {
194            mask = 1;
195            index += 1;
196        }
197    }
198    if j != 0 {
199        factors[j] = prod;
200        j += 1;
201        match limbs_product(&mut x_and_sieve[..x_len], &mut factors[..j]) {
202            (size, None) => size,
203            (size, Some(new_x_and_sieve)) => {
204                x_and_sieve[..size].copy_from_slice(&new_x_and_sieve[..size]);
205                size
206            }
207        }
208    } else {
209        // not triggered by the first billion inputs
210        fail_on_untested_path("limbs_2_multiswing_odd, j == 0");
211        x_and_sieve[0] = prod;
212        1
213    }
214}
215
216pub(crate) const FAC_DSC_THRESHOLD: usize = 236;
217
218const fn clb2(x: usize) -> usize {
219    let floor_log_base_2 = (usize::WIDTH as usize - x.leading_zeros() as usize) - 1;
220    if x.is_power_of_two() {
221        floor_log_base_2
222    } else {
223        floor_log_base_2 + 1
224    }
225}
226
227const FACTORS_PER_LIMB: usize =
228    (Limb::WIDTH << 1) as usize / (clb2(FAC_DSC_THRESHOLD * FAC_DSC_THRESHOLD - 1) + 1) - 1;
229
230// n ^ log <= Limb::MAX: a limb can store log factors less than n.
231//
232// This is equivalent to log_n_max, `gmp-impl.h`, GMP 6.2.1.
233pub(crate) fn log_n_max(n: Limb) -> u64 {
234    // NTH_ROOT_NUMB_MASK_TABLE[0] is Limb::MAX, so a match will always be found
235    u64::wrapping_from(
236        NTH_ROOT_NUMB_MASK_TABLE
237            .iter()
238            .rposition(|&x| n <= x)
239            .unwrap(),
240    ) + 1
241}
242
243// `limbs_odd_factorial` computes the odd part of the factorial of the parameter n, i.e. n! = x * 2
244// ^ a, where x is the returned value: an odd positive integer.
245//
246// If `double` is `true`, a square is skipped in the DSC part, e.g. if n is odd, n >
247// FAC_DSC_THRESHOLD and `double` is true, x is set to n!!.
248//
249// If n is too small, `double` is ignored, and an assert can be triggered.
250//
251// TODO: FAC_DSC_THRESHOLD is used here with two different roles:
252// - to decide when prime factorisation is needed,
253// - to stop the recursion, once sieving is done.
254// Maybe two thresholds can do a better job.
255//
256// # Worst-case complexity
257// $T(n) = O(n (\log n)^2 \log\log n)$
258//
259// $M(n) = O(n \log n)$
260//
261// where $T$ is time, $M$ is additional memory, and $n$ is `n`.
262//
263// This is equivalent to `mpz_oddfac_1` from `mpz/oddfac_1.c`, GMP 6.2.1.
264
265pub_crate_test! {
266#[allow(clippy::redundant_comparisons)]
267limbs_odd_factorial(n: usize, double: bool) -> Vec<Limb> {
268    assert!(Limb::convertible_from(n));
269    if double {
270        assert!(n > ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 1 && n >= FAC_DSC_THRESHOLD);
271    }
272    if n <= ODD_FACTORIAL_TABLE_LIMIT {
273        vec![ONE_LIMB_ODD_FACTORIAL_TABLE[n]]
274    } else if n <= ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 1 {
275        let (hi, lo) = Limb::x_mul_y_to_zz(
276            ONE_LIMB_ODD_DOUBLEFACTORIAL_TABLE[(n - 1) >> 1],
277            ONE_LIMB_ODD_FACTORIAL_TABLE[n >> 1],
278        );
279        vec![lo, hi]
280    } else {
281        // Compute the number of recursive steps for the DSC algorithm
282        let mut m = n;
283        let mut s = 0;
284        while m >= FAC_DSC_THRESHOLD {
285            m >>= 1;
286            s += 1;
287        }
288        let mut factors = vec![0; m / FACTORS_PER_LIMB + 1];
289        assert!(m >= FACTORS_PER_LIMB);
290        const LIMIT_P1: usize = ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 1;
291        assert!(m > LIMIT_P1);
292        let mut j = 0;
293        let mut prod = 1;
294        let mut max_prod = const { Limb::MAX / (FAC_DSC_THRESHOLD * FAC_DSC_THRESHOLD) as Limb };
295        assert!(m > LIMIT_P1);
296        loop {
297            factors[j] = ODD_DOUBLEFACTORIAL_TABLE_MAX;
298            j += 1;
299            let mut diff = (m - ODD_DOUBLEFACTORIAL_TABLE_LIMIT) & const { 2usize.wrapping_neg() };
300            if diff & 2 != 0 {
301                let f = (ODD_DOUBLEFACTORIAL_TABLE_LIMIT + diff) as Limb;
302                if prod > max_prod {
303                    factors[j] = prod;
304                    j += 1;
305                    prod = f;
306                } else {
307                    prod *= f;
308                }
309                diff -= 2;
310            }
311            if diff != 0 {
312                let mut fac = (ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 2)
313                    * (ODD_DOUBLEFACTORIAL_TABLE_LIMIT + diff);
314                loop {
315                    let f = fac as Limb;
316                    if prod > max_prod {
317                        factors[j] = prod;
318                        j += 1;
319                        prod = f;
320                    } else {
321                        prod *= f;
322                    }
323                    diff -= 4;
324                    fac += diff << 1;
325                    if diff == 0 {
326                        break;
327                    }
328                }
329            }
330            max_prod <<= 2;
331            m >>= 1;
332            if m <= LIMIT_P1 {
333                break;
334            }
335        }
336        factors[j] = prod;
337        j += 1;
338        factors[j] = ONE_LIMB_ODD_DOUBLEFACTORIAL_TABLE[(m - 1) >> 1];
339        j += 1;
340        factors[j] = ONE_LIMB_ODD_FACTORIAL_TABLE[m >> 1];
341        j += 1;
342        let mut out = Vec::new();
343        let (out_size, new_out) = limbs_product(&mut out, &mut factors[..j]);
344        out = new_out.unwrap();
345        out.truncate(out_size);
346        if s != 0 {
347            // Use the algorithm described by Peter Luschny in "Divide, Swing and Conquer the
348            // Factorial!".
349            let mut size = (n >> Limb::LOG_WIDTH) + 4;
350            let n_m_1 = u64::exact_from(n - 1);
351            assert!(limbs_prime_sieve_size::<Limb>(n_m_1) < size - (size >> 1));
352            // 2-multiswing(n) < 2^(n - 1) * sqrt(n / pi) < 2 ^ (n + Limb::WIDTH); One more can be
353            // overwritten by mul, another for the sieve.
354            let mut swing_and_sieve = vec![0; size];
355            // Put the sieve on the second half; it will be overwritten by the last
356            // `limbs_2_multiswing_odd`.
357            let sieve_offset = (size >> 1) + 1;
358            let ss_len = swing_and_sieve.len() - 1;
359            #[cfg(feature = "32_bit_limbs")]
360            let count = limbs_prime_sieve_u32(&mut swing_and_sieve[sieve_offset..ss_len], n_m_1);
361            #[cfg(not(feature = "32_bit_limbs"))]
362            let count = limbs_prime_sieve_u64(&mut swing_and_sieve[sieve_offset..ss_len], n_m_1);
363            size = usize::exact_from((count + 1) / log_n_max(Limb::exact_from(n)) + 1);
364            let mut factors = vec![0; size];
365            let mut out_len = out.len();
366            for i in (0..s).rev() {
367                let ns = limbs_2_multiswing_odd(
368                    &mut swing_and_sieve,
369                    sieve_offset,
370                    Limb::exact_from(n >> i),
371                    &mut factors,
372                );
373                let mut square;
374                if double && i == 0 {
375                    size = out_len;
376                    square = vec![0; size];
377                    square[..out_len].copy_from_slice(&out[..out_len]);
378                } else {
379                    size = out_len << 1;
380                    square = vec![0; size];
381                    let mut square_scratch = vec![0; limbs_square_to_out_scratch_len(out_len)];
382                    limbs_square_to_out(&mut square, &out[..out_len], &mut square_scratch);
383                    if square[size - 1] == 0 {
384                        size -= 1;
385                    }
386                }
387                out_len = size + ns;
388                out.resize(out_len, 0);
389                assert!(ns <= size);
390                // n != n$ * floor(n / 2)! ^ 2
391                let mut mul_scratch = vec![0; limbs_mul_greater_to_out_scratch_len(size, ns)];
392                if limbs_mul_greater_to_out(
393                    &mut out,
394                    &square[..size],
395                    &swing_and_sieve[..ns],
396                    &mut mul_scratch,
397                ) == 0
398                {
399                    out_len -= 1;
400                }
401            }
402        }
403        if *out.last().unwrap() == 0 {
404            out.pop();
405        }
406        out
407    }
408}}
409
410const FAC_ODD_THRESHOLD: Limb = 24;
411
412#[cfg(feature = "32_bit_limbs")]
413const SMALL_FACTORIAL_LIMIT: u64 = 13;
414#[cfg(not(feature = "32_bit_limbs"))]
415const SMALL_FACTORIAL_LIMIT: u64 = 21;
416
417impl Factorial for Natural {
418    /// Computes the factorial of a number.
419    ///
420    /// $$
421    /// f(n) = n! = 1 \times 2 \times 3 \times \cdots \times n.
422    /// $$
423    ///
424    /// $n! = O(\sqrt{n}(n/e)^n)$.
425    ///
426    /// # Worst-case complexity
427    /// $T(n) = O(n (\log n)^2 \log\log n)$
428    ///
429    /// $M(n) = O(n \log n)$
430    ///
431    /// where $T$ is time, $M$ is additional memory, and $n$ is `n`.
432    ///
433    /// # Examples
434    /// ```
435    /// use malachite_base::num::arithmetic::traits::Factorial;
436    /// use malachite_nz::natural::Natural;
437    ///
438    /// assert_eq!(Natural::factorial(0), 1);
439    /// assert_eq!(Natural::factorial(1), 1);
440    /// assert_eq!(Natural::factorial(2), 2);
441    /// assert_eq!(Natural::factorial(3), 6);
442    /// assert_eq!(Natural::factorial(4), 24);
443    /// assert_eq!(Natural::factorial(5), 120);
444    /// assert_eq!(
445    ///     Natural::factorial(100).to_string(),
446    ///     "9332621544394415268169923885626670049071596826438162146859296389521759999322991560894\
447    ///     1463976156518286253697920827223758251185210916864000000000000000000000000"
448    /// );
449    /// ```
450    ///
451    /// This is equivalent to `mpz_fac_ui` from `mpz/fac_ui.c`, GMP 6.2.1.
452    #[allow(clippy::useless_conversion)]
453    fn factorial(n: u64) -> Self {
454        assert!(Limb::convertible_from(n));
455        if n < SMALL_FACTORIAL_LIMIT {
456            Self::from(Limb::factorial(n))
457        } else if n < u64::from(FAC_ODD_THRESHOLD) {
458            let mut factors =
459                vec![0; usize::wrapping_from(n - SMALL_FACTORIAL_LIMIT) / FACTORS_PER_LIMB + 2];
460            factors[0] = Limb::factorial(SMALL_FACTORIAL_LIMIT - 1);
461            let mut j = 1;
462            let n = Limb::wrapping_from(n);
463            let mut prod = n;
464            const MAX_PROD: Limb = Limb::MAX / (FAC_ODD_THRESHOLD | 1);
465            const LIMB_SMALL_FACTORIAL_LIMIT: Limb = SMALL_FACTORIAL_LIMIT as Limb;
466            for i in (LIMB_SMALL_FACTORIAL_LIMIT..n).rev() {
467                if prod > MAX_PROD {
468                    factors[j] = prod;
469                    j += 1;
470                    prod = i;
471                } else {
472                    prod *= i;
473                }
474            }
475            factors[j] = prod;
476            j += 1;
477            let mut xs = Vec::new();
478            let new_xs = limbs_product(&mut xs, &mut factors[..j]).1;
479            xs = new_xs.unwrap();
480            Self::from_owned_limbs_asc(xs)
481        } else {
482            let count = if n <= TABLE_LIMIT_2N_MINUS_POPC_2N {
483                u64::from(TABLE_2N_MINUS_POPC_2N[usize::exact_from((n >> 1) - 1)])
484            } else {
485                n - CountOnes::count_ones(n)
486            };
487            Self::from_owned_limbs_asc(limbs_odd_factorial(usize::exact_from(n), false)) << count
488        }
489    }
490}
491
492const FAC_2DSC_THRESHOLD: Limb = ((FAC_DSC_THRESHOLD << 1) | (FAC_DSC_THRESHOLD & 1)) as Limb;
493
494impl DoubleFactorial for Natural {
495    /// Computes the double factorial of a number.
496    ///
497    /// $$
498    /// f(n) = n!! = n \times (n - 2) \times (n - 4) \times \cdots \times i,
499    /// $$
500    /// where $i$ is 1 if $n$ is odd and $2$ if $n$ is even.
501    ///
502    /// $n!! = O(\sqrt{n}(n/e)^{n/2})$.
503    ///
504    /// # Worst-case complexity
505    /// $T(n) = O(n (\log n)^2 \log\log n)$
506    ///
507    /// $M(n) = O(n \log n)$
508    ///
509    /// # Examples
510    /// ```
511    /// use malachite_base::num::arithmetic::traits::DoubleFactorial;
512    /// use malachite_nz::natural::Natural;
513    ///
514    /// assert_eq!(Natural::double_factorial(0), 1);
515    /// assert_eq!(Natural::double_factorial(1), 1);
516    /// assert_eq!(Natural::double_factorial(2), 2);
517    /// assert_eq!(Natural::double_factorial(3), 3);
518    /// assert_eq!(Natural::double_factorial(4), 8);
519    /// assert_eq!(Natural::double_factorial(5), 15);
520    /// assert_eq!(Natural::double_factorial(6), 48);
521    /// assert_eq!(Natural::double_factorial(7), 105);
522    /// assert_eq!(
523    ///     Natural::double_factorial(99).to_string(),
524    ///     "2725392139750729502980713245400918633290796330545803413734328823443106201171875"
525    /// );
526    /// assert_eq!(
527    ///     Natural::double_factorial(100).to_string(),
528    ///     "34243224702511976248246432895208185975118675053719198827915654463488000000000000"
529    /// );
530    /// ```
531    ///
532    /// This is equivalent to `mpz_2fac_ui` from `mpz/2fac_ui.c`, GMP 6.2.1.
533    fn double_factorial(n: u64) -> Self {
534        assert!(Limb::convertible_from(n));
535        if n.even() {
536            // n is even, n = 2k, (2k)!! = k! 2^k
537            let half_n = usize::wrapping_from(n >> 1);
538            let count = if n <= TABLE_LIMIT_2N_MINUS_POPC_2N && n != 0 {
539                u64::from(TABLE_2N_MINUS_POPC_2N[half_n - 1])
540            } else {
541                n - CountOnes::count_ones(n)
542            };
543            Self::from_owned_limbs_asc(limbs_odd_factorial(half_n, false)) << count
544        } else if n <= u64::wrapping_from(ODD_DOUBLEFACTORIAL_TABLE_LIMIT) {
545            Self::from(ONE_LIMB_ODD_DOUBLEFACTORIAL_TABLE[usize::wrapping_from(n >> 1)])
546        } else if n < u64::wrapping_from(FAC_2DSC_THRESHOLD) {
547            let mut factors = vec![0; usize::exact_from(n) / (FACTORS_PER_LIMB << 1) + 1];
548            factors[0] = ODD_DOUBLEFACTORIAL_TABLE_MAX;
549            let mut j = 1;
550            let mut n = Limb::wrapping_from(n);
551            let mut prod = n;
552            let max_prod = Limb::MAX / FAC_2DSC_THRESHOLD;
553            const LIMIT: Limb = ODD_DOUBLEFACTORIAL_TABLE_LIMIT as Limb + 2;
554            while n > LIMIT {
555                n -= 2;
556                if prod > max_prod {
557                    factors[j] = prod;
558                    j += 1;
559                    prod = n;
560                } else {
561                    prod *= n;
562                }
563            }
564            factors[j] = prod;
565            j += 1;
566            let mut xs = Vec::new();
567            let new_xs = limbs_product(&mut xs, &mut factors[..j]).1;
568            xs = new_xs.unwrap();
569            Self::from_owned_limbs_asc(xs)
570        } else {
571            Self::from_owned_limbs_asc(limbs_odd_factorial(usize::exact_from(n), true))
572        }
573    }
574}
575
576impl Multifactorial for Natural {
577    /// Computes a multifactorial of a number.
578    ///
579    /// $$
580    /// f(n, m) = n!^{(m)} = n \times (n - m) \times (n - 2m) \times \cdots \times i.
581    /// $$
582    /// If $n$ is divisible by $m$, then $i$ is $m$; otherwise, $i$ is the remainder when $n$ is
583    /// divided by $m$.
584    ///
585    /// $n!^{(m)} = O(\sqrt{n}(n/e)^{n/m})$.
586    ///
587    /// # Worst-case complexity
588    /// $T(n, m) = O(n (\log n)^2 \log\log n)$
589    ///
590    /// $M(n, m) = O(n \log n)$
591    ///
592    /// # Examples
593    /// ```
594    /// use malachite_base::num::arithmetic::traits::Multifactorial;
595    /// use malachite_nz::natural::Natural;
596    ///
597    /// assert_eq!(Natural::multifactorial(0, 1), 1);
598    /// assert_eq!(Natural::multifactorial(1, 1), 1);
599    /// assert_eq!(Natural::multifactorial(2, 1), 2);
600    /// assert_eq!(Natural::multifactorial(3, 1), 6);
601    /// assert_eq!(Natural::multifactorial(4, 1), 24);
602    /// assert_eq!(Natural::multifactorial(5, 1), 120);
603    ///
604    /// assert_eq!(Natural::multifactorial(0, 2), 1);
605    /// assert_eq!(Natural::multifactorial(1, 2), 1);
606    /// assert_eq!(Natural::multifactorial(2, 2), 2);
607    /// assert_eq!(Natural::multifactorial(3, 2), 3);
608    /// assert_eq!(Natural::multifactorial(4, 2), 8);
609    /// assert_eq!(Natural::multifactorial(5, 2), 15);
610    /// assert_eq!(Natural::multifactorial(6, 2), 48);
611    /// assert_eq!(Natural::multifactorial(7, 2), 105);
612    ///
613    /// assert_eq!(Natural::multifactorial(0, 3), 1);
614    /// assert_eq!(Natural::multifactorial(1, 3), 1);
615    /// assert_eq!(Natural::multifactorial(2, 3), 2);
616    /// assert_eq!(Natural::multifactorial(3, 3), 3);
617    /// assert_eq!(Natural::multifactorial(4, 3), 4);
618    /// assert_eq!(Natural::multifactorial(5, 3), 10);
619    /// assert_eq!(Natural::multifactorial(6, 3), 18);
620    /// assert_eq!(Natural::multifactorial(7, 3), 28);
621    /// assert_eq!(Natural::multifactorial(8, 3), 80);
622    /// assert_eq!(Natural::multifactorial(9, 3), 162);
623    ///
624    /// assert_eq!(
625    ///     Natural::multifactorial(100, 3).to_string(),
626    ///     "174548867015437739741494347897360069928419328000000000"
627    /// );
628    /// ```
629    fn multifactorial(mut n: u64, mut m: u64) -> Self {
630        assert_ne!(m, 0);
631        assert!(Limb::convertible_from(n));
632        assert!(Limb::convertible_from(m));
633        if n < 3 || n - 3 < m - 1 {
634            // n < 3 || n - 1 <= m
635            if n == 0 { Self::ONE } else { Self::from(n) }
636        } else {
637            // 0 < m < n - 1 < Limb::MAX
638            let gcd = n.gcd(m);
639            if gcd > 1 {
640                n /= gcd;
641                m /= gcd;
642            }
643            if m <= 2 {
644                // fac or 2fac
645                if m == 1 {
646                    match gcd {
647                        gcd if gcd > 2 => Self::from(gcd).pow(n) * Self::factorial(n),
648                        2 => Self::double_factorial(n << 1),
649                        _ => Self::factorial(n),
650                    }
651                } else if gcd > 1 {
652                    // m == 2
653                    Self::from(gcd).pow((n >> 1) + 1) * Self::double_factorial(n)
654                } else {
655                    Self::double_factorial(n)
656                }
657            } else {
658                // m >= 3, gcd(n,m) = 1
659                let reduced_n = n / m + 1;
660                let mut n = Limb::exact_from(n);
661                let m = Limb::exact_from(m);
662                let mut j = 0;
663                let mut prod = n;
664                n -= m;
665                let max_prod = Limb::MAX / n;
666                let mut factors = vec![0; usize::exact_from(reduced_n / log_n_max(n) + 2)];
667                while n > m {
668                    if prod > max_prod {
669                        factors[j] = prod;
670                        j += 1;
671                        prod = n;
672                    } else {
673                        prod *= n;
674                    }
675                    n -= m;
676                }
677                factors[j] = n;
678                j += 1;
679                factors[j] = prod;
680                j += 1;
681                let mut xs = Vec::new();
682                let new_xs = limbs_product(&mut xs, &mut factors[..j]).1;
683                xs = new_xs.unwrap();
684                let x = Self::from_owned_limbs_asc(xs);
685                if gcd == 1 {
686                    x
687                } else {
688                    Self::from(gcd).pow(reduced_n) * x
689                }
690            }
691        }
692    }
693}
694
695impl Subfactorial for Natural {
696    /// Computes the subfactorial of a number.
697    ///
698    /// The subfactorial of $n$ counts the number of derangements of a set of size $n$; a
699    /// derangement is a permutation with no fixed points.
700    ///
701    /// $$
702    /// f(n) = \\ !n = \lfloor n!/e \rfloor.
703    /// $$
704    ///
705    /// $!n = O(n!) = O(\sqrt{n}(n/e)^n)$.
706    ///
707    /// # Worst-case complexity
708    /// $T(n) = O(n^2)$
709    ///
710    /// $M(n) = O(n)$
711    ///
712    /// # Examples
713    /// ```
714    /// use malachite_base::num::arithmetic::traits::Subfactorial;
715    /// use malachite_nz::natural::Natural;
716    ///
717    /// assert_eq!(Natural::subfactorial(0), 1);
718    /// assert_eq!(Natural::subfactorial(1), 0);
719    /// assert_eq!(Natural::subfactorial(2), 1);
720    /// assert_eq!(Natural::subfactorial(3), 2);
721    /// assert_eq!(Natural::subfactorial(4), 9);
722    /// assert_eq!(Natural::subfactorial(5), 44);
723    /// assert_eq!(
724    ///     Natural::subfactorial(100).to_string(),
725    ///     "3433279598416380476519597752677614203236578380537578498354340028268518079332763243279\
726    ///     1396429850988990237345920155783984828001486412574060553756854137069878601"
727    /// );
728    /// ```
729    #[inline]
730    fn subfactorial(n: u64) -> Self {
731        subfactorial_naive(n)
732    }
733}