1
/* mpz_fac_ui(result, n) -- Set RESULT to N!.
3
Copyright 1991, 1993, 1994, 1995, 2000, 2001 Free Software Foundation, Inc.
5
This file is part of the GNU MP Library.
7
The GNU MP Library is free software; you can redistribute it and/or modify
8
it under the terms of the GNU Lesser General Public License as published by
9
the Free Software Foundation; either version 2.1 of the License, or (at your
10
option) any later version.
12
The GNU MP Library is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15
License for more details.
17
You should have received a copy of the GNU Lesser General Public License
18
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
19
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20
MA 02111-1307, USA. */
29
Data tables could be used for results up to 3 or 4 limbs to avoid
30
fiddling around with small quantities.
32
The product accumulation might be worth splitting out into something that
33
could be used elsewhere too.
35
The tree of partial products should be done with TMP_ALLOC, not mpz_init.
36
It should be possible to know a maximum size at each level.
38
Factors of two could be stripped from k to save some multiplying (but not
39
very much). The same could be done with factors of 3, perhaps.
41
The prime factorization of n! is easy to determine, it might be worth
42
using that rather than a simple 1 to n. The powering of primes could do
43
some squaring instead of multiplying. There's probably other ways to use
47
/* for single non-zero limb */
48
#define MPZ_SET_1_NZ(z,n) \
56
/* for single non-zero limb */
57
#define MPZ_INIT_SET_1_NZ(z,n) \
61
PTR(__iz) = __GMP_ALLOCATE_FUNC_LIMBS (1); \
62
MPZ_SET_1_NZ (__iz, n); \
65
/* for src>0 and n>0 */
66
#define MPZ_MUL_1_POS(dst,src,n) \
68
mpz_ptr __dst = (dst); \
69
mpz_srcptr __src = (src); \
70
mp_size_t __size = SIZ(__src); \
74
ASSERT (__size > 0); \
77
MPZ_REALLOC (__dst, __size+1); \
78
__dst_p = PTR(__dst); \
80
__c = mpn_mul_1 (__dst_p, PTR(__src), __size, n); \
81
__dst_p[__size] = __c; \
82
SIZ(__dst) = __size + (__c != 0); \
88
mpz_fac_ui (mpz_ptr result, unsigned long int n)
91
/* Be silly. Just multiply the numbers in ascending order. O(n**2). */
93
mpz_set_ui (result, 1L);
94
for (k = 2; k <= n; k++)
95
mpz_mul_ui (result, result, k);
98
/* Be smarter. Multiply groups of numbers in ascending order until the
99
product doesn't fit in a limb. Multiply these partial product in a
100
balanced binary tree fashion, to make the operand have as equal sizes
101
as possible. When the operands have about the same size, mpn_mul
107
/* Stack of partial products, used to make the computation balanced
108
(i.e. make the sizes of the multiplication operands equal). The
109
topmost position of MP_STACK will contain a one-limb partial product,
110
the second topmost will contain a two-limb partial product, and so
111
on. MP_STACK[0] will contain a partial product with 2**t limbs.
112
To compute n! MP_STACK needs to be less than
113
log(n)**2/log(BITS_PER_MP_LIMB), so 30 is surely enough. */
114
#define MP_STACK_SIZE 30
115
mpz_t mp_stack[MP_STACK_SIZE];
117
/* TOP is an index into MP_STACK, giving the topmost element.
118
TOP_LIMIT_SO_FAR is the largets value it has taken so far. */
119
int top, top_limit_so_far;
121
/* Count of the total number of limbs put on MP_STACK so far. This
122
variable plays an essential role in making the compututation balanced.
124
unsigned int tree_cnt;
126
/* for testing with small limbs */
127
if (MP_LIMB_T_MAX < ULONG_MAX)
128
ASSERT_ALWAYS (n <= MP_LIMB_T_MAX);
130
top = top_limit_so_far = -1;
133
for (k = 2; k <= n; k++)
135
/* Multiply the partial product in P with K. */
136
umul_ppmm (p1, p0, p, (mp_limb_t) k);
138
/* Did we get overflow into the high limb, i.e. is the partial
139
product now more than one limb? */
144
if (tree_cnt % 2 == 0)
148
/* TREE_CNT is even (i.e. we have generated an even number of
149
one-limb partial products), which means that we have a
150
single-limb product on the top of MP_STACK. */
152
MPZ_MUL_1_POS (mp_stack[top], mp_stack[top], p);
154
/* If TREE_CNT is divisable by 4, 8,..., we have two
155
similar-sized partial products with 2, 4,... limbs at
156
the topmost two positions of MP_STACK. Multiply them
157
to form a new partial product with 4, 8,... limbs. */
158
for (i = 4; (tree_cnt & (i - 1)) == 0; i <<= 1)
160
mpz_mul (mp_stack[top - 1],
161
mp_stack[top], mp_stack[top - 1]);
167
/* Put the single-limb partial product in P on the stack.
168
(The next time we get a single-limb product, we will
169
multiply the two together.) */
171
if (top > top_limit_so_far)
173
if (top > MP_STACK_SIZE)
175
/* The stack is now bigger than ever, initialize the top
177
MPZ_INIT_SET_1_NZ (mp_stack[top], p);
181
MPZ_SET_1_NZ (mp_stack[top], p);
184
/* We ignored the last result from umul_ppmm. Put K in P as the
185
first component of the next single-limb partial product. */
189
/* We didn't get overflow in umul_ppmm. Put p0 in P and try
190
with one more value of K. */
194
/* We have partial products in mp_stack[0..top], in descending order.
195
We also have a small partial product in p.
196
Their product is the final result. */
198
MPZ_SET_1_NZ (result, p);
200
MPZ_MUL_1_POS (result, mp_stack[top--], p);
202
mpz_mul (result, result, mp_stack[top--]);
204
/* Free the storage allocated for MP_STACK. */
205
for (top = top_limit_so_far; top >= 0; top--)
206
mpz_clear (mp_stack[top]);