gen-fac_ui.c
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:4k
源码类别:

数学计算

开发平台:

Unix_Linux

  1. /* Generate mpz_fac_ui data.
  2. Copyright 2002 Free Software Foundation, Inc.
  3. This file is part of the GNU MP Library.
  4. The GNU MP Library is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or (at your
  7. option) any later version.
  8. The GNU MP Library is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  11. License for more details.
  12. You should have received a copy of the GNU Lesser General Public License
  13. along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include "dumbmp.c"
  17. /* sets x=y*(y+2)*(y+4)*....*(y+2*(z-1)) */
  18. void
  19. odd_products (mpz_t x, mpz_t y, int z)
  20. {
  21.   mpz_t t;
  22.   mpz_init_set (t, y);
  23.   mpz_set_ui (x, 1);
  24.   for (; z != 0; z--)
  25.     {
  26.       mpz_mul (x, x, t);
  27.       mpz_add_ui (t, t, 2);
  28.     }
  29.   mpz_clear (t);
  30.   return;
  31. }
  32. /* returns 0 on success */
  33. int
  34. gen_consts (int numb, int nail, int limb)
  35. {
  36.   mpz_t x, y, z, t;
  37.   unsigned long a, b, first = 1;
  38.   printf ("/* This file is automatically generated by gen-fac_ui.c */nn");
  39.   printf ("#if GMP_NUMB_BITS != %dn", numb);
  40.   printf ("Error , error this data is for %d GMP_NUMB_BITS onlyn", numb);
  41.   printf ("#endifn");
  42.   printf ("#if GMP_LIMB_BITS != %dn", limb);
  43.   printf ("Error , error this data is for %d GMP_LIMB_BITS onlyn", limb);
  44.   printf ("#endifn");
  45.   printf
  46.     ("/* This table is 0!,1!,2!,3!,...,n! where n! has <= GMP_NUMB_BITS bits */n");
  47.   printf
  48.     ("#define ONE_LIMB_FACTORIAL_TABLE CNST_LIMB(0x1),CNST_LIMB(0x1),CNST_LIMB(0x2),");
  49.   mpz_init_set_ui (x, 2);
  50.   for (b = 3;; b++)
  51.     {
  52.       mpz_mul_ui (x, x, b); /* so b!=a       */
  53.       if (mpz_sizeinbase (x, 2) > numb)
  54. break;
  55.       if (first)
  56. {
  57.   first = 0;
  58. }
  59.       else
  60. {
  61.   printf ("),");
  62. }
  63.       printf ("CNST_LIMB(0x");
  64.       mpz_out_str (stdout, 16, x);
  65.     }
  66.   printf (")n");
  67.   mpz_set_ui (x, 1);
  68.   mpz_mul_2exp (x, x, limb + 1); /* x=2^(limb+1)        */
  69.   mpz_init (y);
  70.   mpz_set_ui (y, 10000);
  71.   mpz_mul (x, x, y); /* x=2^(limb+1)*10^4     */
  72.   mpz_set_ui (y, 27182); /* exp(1)*10^4      */
  73.   mpz_tdiv_q (x, x, y); /* x=2^(limb+1)/exp(1)        */
  74.   printf ("n/* is 2^(GMP_LIMB_BITS+1)/exp(1) */n");
  75.   printf ("#define FAC2OVERE CNST_LIMB(0x");
  76.   mpz_out_str (stdout, 16, x);
  77.   printf (")n");
  78.   printf
  79.     ("n/* FACMULn is largest odd x such that x*(x+2)*...*(x+2(n-1))<=2^GMP_NUMB_BITS-1 */nn");
  80.   mpz_init (z);
  81.   mpz_init (t);
  82.   for (a = 2; a <= 4; a++)
  83.     {
  84.       mpz_set_ui (x, 1);
  85.       mpz_mul_2exp (x, x, numb);
  86.       mpz_root (x, x, a);
  87.       /* so x is approx sol       */
  88.       if (mpz_even_p (x))
  89. mpz_sub_ui (x, x, 1);
  90.       mpz_set_ui (y, 1);
  91.       mpz_mul_2exp (y, y, numb);
  92.       mpz_sub_ui (y, y, 1);
  93.       /* decrement x until we are <= real sol     */
  94.       do
  95. {
  96.   mpz_sub_ui (x, x, 2);
  97.   odd_products (t, x, a);
  98.   if (mpz_cmp (t, y) <= 0)
  99.     break;
  100. }
  101.       while (1);
  102.       /* increment x until > real sol     */
  103.       do
  104. {
  105.   mpz_add_ui (x, x, 2);
  106.   odd_products (t, x, a);
  107.   if (mpz_cmp (t, y) > 0)
  108.     break;
  109. }
  110.       while (1);
  111.       /* dec once to get real sol */
  112.       mpz_sub_ui (x, x, 2);
  113.       printf ("#define FACMUL%lu CNST_LIMB(0x", a);
  114.       mpz_out_str (stdout, 16, x);
  115.       printf (")n");
  116.     }
  117.   return 0;
  118. }
  119. int
  120. main (int argc, char *argv[])
  121. {
  122.   int nail_bits, limb_bits, numb_bits;
  123.   if (argc != 3)
  124.     {
  125.       fprintf (stderr, "Usage: gen-fac_ui limbbits nailbitsn");
  126.       exit (1);
  127.     }
  128.   limb_bits = atoi (argv[1]);
  129.   nail_bits = atoi (argv[2]);
  130.   numb_bits = limb_bits - nail_bits;
  131.   if (limb_bits < 0 || nail_bits < 0 || numb_bits < 0)
  132.     {
  133.       fprintf (stderr, "Invalid limb/nail bits %d,%dn", limb_bits,
  134.        nail_bits);
  135.       exit (1);
  136.     }
  137.   gen_consts (numb_bits, nail_bits, limb_bits);
  138.   return 0;
  139. }