X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fgmp%2Fmpz%2Ffac_ui.c;fp=rts%2Fgmp%2Fmpz%2Ffac_ui.c;h=0000000000000000000000000000000000000000;hb=fdf1cd0399158308769fcb2ab7e46e215a68d865;hp=85f40f271ca64382c6356cef458a2ad60087e719;hpb=e552cfc427d2734b9a9629f2ab1d22f493e775f6;p=ghc-hetmet.git diff --git a/rts/gmp/mpz/fac_ui.c b/rts/gmp/mpz/fac_ui.c deleted file mode 100644 index 85f40f2..0000000 --- a/rts/gmp/mpz/fac_ui.c +++ /dev/null @@ -1,157 +0,0 @@ -/* mpz_fac_ui(result, n) -- Set RESULT to N!. - -Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc. - -This file is part of the GNU MP Library. - -The GNU MP Library is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 of the License, or (at your -option) any later version. - -The GNU MP Library is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with the GNU MP Library; see the file COPYING.LIB. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, -MA 02111-1307, USA. */ - -#ifdef DBG -#include -#endif - -#include "gmp.h" -#include "gmp-impl.h" -#include "longlong.h" - -void -#if __STDC__ -mpz_fac_ui (mpz_ptr result, unsigned long int n) -#else -mpz_fac_ui (result, n) - mpz_ptr result; - unsigned long int n; -#endif -{ -#if SIMPLE_FAC - - /* Be silly. Just multiply the numbers in ascending order. O(n**2). */ - - unsigned long int k; - - mpz_set_ui (result, 1L); - - for (k = 2; k <= n; k++) - mpz_mul_ui (result, result, k); -#else - - /* Be smarter. Multiply groups of numbers in ascending order until the - product doesn't fit in a limb. Multiply these partial product in a - balanced binary tree fashion, to make the operand have as equal sizes - as possible. When the operands have about the same size, mpn_mul - becomes faster. */ - - unsigned long int p, k; - mp_limb_t p1, p0; - - /* Stack of partial products, used to make the computation balanced - (i.e. make the sizes of the multiplication operands equal). The - topmost position of MP_STACK will contain a one-limb partial product, - the second topmost will contain a two-limb partial product, and so - on. MP_STACK[0] will contain a partial product with 2**t limbs. - To compute n! MP_STACK needs to be less than - log(n)**2/log(BITS_PER_MP_LIMB), so 30 is surely enough. */ -#define MP_STACK_SIZE 30 - mpz_t mp_stack[MP_STACK_SIZE]; - - /* TOP is an index into MP_STACK, giving the topmost element. - TOP_LIMIT_SO_FAR is the largets value it has taken so far. */ - int top, top_limit_so_far; - - /* Count of the total number of limbs put on MP_STACK so far. This - variable plays an essential role in making the compututation balanced. - See below. */ - unsigned int tree_cnt; - - top = top_limit_so_far = -1; - tree_cnt = 0; - p = 1; - for (k = 2; k <= n; k++) - { - /* Multiply the partial product in P with K. */ - umul_ppmm (p1, p0, (mp_limb_t) p, (mp_limb_t) k); - - /* Did we get overflow into the high limb, i.e. is the partial - product now more than one limb? */ - if (p1 != 0) - { - tree_cnt++; - - if (tree_cnt % 2 == 0) - { - mp_size_t i; - - /* TREE_CNT is even (i.e. we have generated an even number of - one-limb partial products), which means that we have a - single-limb product on the top of MP_STACK. */ - - mpz_mul_ui (mp_stack[top], mp_stack[top], p); - - /* If TREE_CNT is divisable by 4, 8,..., we have two - similar-sized partial products with 2, 4,... limbs at - the topmost two positions of MP_STACK. Multiply them - to form a new partial product with 4, 8,... limbs. */ - for (i = 4; (tree_cnt & (i - 1)) == 0; i <<= 1) - { - mpz_mul (mp_stack[top - 1], - mp_stack[top], mp_stack[top - 1]); - top--; - } - } - else - { - /* Put the single-limb partial product in P on the stack. - (The next time we get a single-limb product, we will - multiply the two together.) */ - top++; - if (top > top_limit_so_far) - { - if (top > MP_STACK_SIZE) - abort(); - /* The stack is now bigger than ever, initialize the top - element. */ - mpz_init_set_ui (mp_stack[top], p); - top_limit_so_far++; - } - else - mpz_set_ui (mp_stack[top], p); - } - - /* We ignored the last result from umul_ppmm. Put K in P as the - first component of the next single-limb partial product. */ - p = k; - } - else - /* We didn't get overflow in umul_ppmm. Put p0 in P and try - with one more value of K. */ - p = p0; /* bogus if long != mp_limb_t */ - } - - /* We have partial products in mp_stack[0..top], in descending order. - We also have a small partial product in p. - Their product is the final result. */ - if (top < 0) - mpz_set_ui (result, p); - else - mpz_mul_ui (result, mp_stack[top--], p); - while (top >= 0) - mpz_mul (result, result, mp_stack[top--]); - - /* Free the storage allocated for MP_STACK. */ - for (top = top_limit_so_far; top >= 0; top--) - mpz_clear (mp_stack[top]); -#endif -}