Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

563676 views
1
/* Generate mpz_fac_ui data.
2
3
Copyright 2002 Free Software Foundation, Inc.
4
5
This file is part of the GNU MP Library.
6
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.
11
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.
16
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., 51 Franklin Street, Fifth Floor, Boston,
20
MA 02110-1301, USA. */
21
22
#include <stdio.h>
23
#include <stdlib.h>
24
25
#include "dumbmp.c"
26
27
28
/* sets x=y*(y+2)*(y+4)*....*(y+2*(z-1)) */
29
void
30
odd_products (mpz_t x, mpz_t y, int z)
31
{
32
mpz_t t;
33
34
mpz_init_set (t, y);
35
mpz_set_ui (x, 1);
36
for (; z != 0; z--)
37
{
38
mpz_mul (x, x, t);
39
mpz_add_ui (t, t, 2);
40
}
41
mpz_clear (t);
42
return;
43
}
44
45
/* returns 0 on success */
46
int
47
gen_consts (int numb, int nail, int limb)
48
{
49
mpz_t x, y, z, t;
50
unsigned long a, b, first = 1;
51
52
printf ("/* This file is automatically generated by gen-fac_ui.c */\n\n");
53
printf ("#if GMP_NUMB_BITS != %d\n", numb);
54
printf ("Error , error this data is for %d GMP_NUMB_BITS only\n", numb);
55
printf ("#endif\n");
56
printf ("#if GMP_LIMB_BITS != %d\n", limb);
57
printf ("Error , error this data is for %d GMP_LIMB_BITS only\n", limb);
58
printf ("#endif\n");
59
60
printf
61
("/* This table is 0!,1!,2!,3!,...,n! where n! has <= GMP_NUMB_BITS bits */\n");
62
printf
63
("#define ONE_LIMB_FACTORIAL_TABLE CNST_LIMB(0x1),CNST_LIMB(0x1),CNST_LIMB(0x2),");
64
mpz_init_set_ui (x, 2);
65
for (b = 3;; b++)
66
{
67
mpz_mul_ui (x, x, b); /* so b!=a */
68
if (mpz_sizeinbase (x, 2) > numb)
69
break;
70
if (first)
71
{
72
first = 0;
73
}
74
else
75
{
76
printf ("),");
77
}
78
printf ("CNST_LIMB(0x");
79
mpz_out_str (stdout, 16, x);
80
}
81
printf (")\n");
82
83
84
mpz_set_ui (x, 1);
85
mpz_mul_2exp (x, x, limb + 1); /* x=2^(limb+1) */
86
mpz_init (y);
87
mpz_set_ui (y, 10000);
88
mpz_mul (x, x, y); /* x=2^(limb+1)*10^4 */
89
mpz_set_ui (y, 27182); /* exp(1)*10^4 */
90
mpz_tdiv_q (x, x, y); /* x=2^(limb+1)/exp(1) */
91
printf ("\n/* is 2^(GMP_LIMB_BITS+1)/exp(1) */\n");
92
printf ("#define FAC2OVERE CNST_LIMB(0x");
93
mpz_out_str (stdout, 16, x);
94
printf (")\n");
95
96
97
printf
98
("\n/* FACMULn is largest odd x such that x*(x+2)*...*(x+2(n-1))<=2^GMP_NUMB_BITS-1 */\n\n");
99
mpz_init (z);
100
mpz_init (t);
101
for (a = 2; a <= 4; a++)
102
{
103
mpz_set_ui (x, 1);
104
mpz_mul_2exp (x, x, numb);
105
mpz_root (x, x, a);
106
/* so x is approx sol */
107
if (mpz_even_p (x))
108
mpz_sub_ui (x, x, 1);
109
mpz_set_ui (y, 1);
110
mpz_mul_2exp (y, y, numb);
111
mpz_sub_ui (y, y, 1);
112
/* decrement x until we are <= real sol */
113
do
114
{
115
mpz_sub_ui (x, x, 2);
116
odd_products (t, x, a);
117
if (mpz_cmp (t, y) <= 0)
118
break;
119
}
120
while (1);
121
/* increment x until > real sol */
122
do
123
{
124
mpz_add_ui (x, x, 2);
125
odd_products (t, x, a);
126
if (mpz_cmp (t, y) > 0)
127
break;
128
}
129
while (1);
130
/* dec once to get real sol */
131
mpz_sub_ui (x, x, 2);
132
printf ("#define FACMUL%lu CNST_LIMB(0x", a);
133
mpz_out_str (stdout, 16, x);
134
printf (")\n");
135
}
136
137
return 0;
138
}
139
140
int
141
main (int argc, char *argv[])
142
{
143
int nail_bits, limb_bits, numb_bits;
144
145
if (argc != 3)
146
{
147
fprintf (stderr, "Usage: gen-fac_ui limbbits nailbits\n");
148
exit (1);
149
}
150
limb_bits = atoi (argv[1]);
151
nail_bits = atoi (argv[2]);
152
numb_bits = limb_bits - nail_bits;
153
if (limb_bits < 0 || nail_bits < 0 || numb_bits < 0)
154
{
155
fprintf (stderr, "Invalid limb/nail bits %d,%d\n", limb_bits,
156
nail_bits);
157
exit (1);
158
}
159
gen_consts (numb_bits, nail_bits, limb_bits);
160
return 0;
161
}
162
163