1
/* Reference mpz functions.
3
Copyright 1997, 1999, 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. */
22
/* always do assertion checking */
26
#include <stdlib.h> /* for free */
33
/* Change this to "#define TRACE(x) x" for some traces. */
38
refmpz_hamdist (mpz_srcptr x, mpz_srcptr y)
44
if ((SIZ(x) < 0 && SIZ(y) >= 0)
45
|| (SIZ(y) < 0 && SIZ(x) >= 0))
48
tsize = MAX (ABSIZ(x), ABSIZ(y));
50
xp = refmpn_malloc_limbs (tsize);
51
refmpn_zero (xp, tsize);
52
refmpn_copy (xp, PTR(x), ABSIZ(x));
54
yp = refmpn_malloc_limbs (tsize);
55
refmpn_zero (yp, tsize);
56
refmpn_copy (yp, PTR(y), ABSIZ(y));
59
refmpn_neg_n (xp, xp, tsize);
62
refmpn_neg_n (yp, yp, tsize);
64
ret = refmpn_hamdist (xp, yp, tsize);
72
/* (0/b), with mpz b; is 1 if b=+/-1, 0 otherwise */
73
#define JACOBI_0Z(b) JACOBI_0LS (PTR(b)[0], SIZ(b))
75
/* (a/b) effect due to sign of b: mpz/mpz */
76
#define JACOBI_BSGN_ZZ_BIT1(a, b) JACOBI_BSGN_SS_BIT1 (SIZ(a), SIZ(b))
78
/* (a/b) effect due to sign of a: mpz/unsigned-mpz, b odd;
79
is (-1/b) if a<0, or +1 if a>=0 */
80
#define JACOBI_ASGN_ZZU_BIT1(a, b) JACOBI_ASGN_SU_BIT1 (SIZ(a), PTR(b)[0])
83
refmpz_kronecker (mpz_srcptr a_orig, mpz_srcptr b_orig)
89
if (mpz_sgn (b_orig) == 0)
90
return JACOBI_Z0 (a_orig); /* (a/0) */
92
if (mpz_sgn (a_orig) == 0)
93
return JACOBI_0Z (b_orig); /* (0/b) */
95
if (mpz_even_p (a_orig) && mpz_even_p (b_orig))
98
if (mpz_cmp_ui (b_orig, 1) == 0)
101
mpz_init_set (a, a_orig);
102
mpz_init_set (b, b_orig);
106
result_bit1 ^= JACOBI_BSGN_ZZ_BIT1 (a, b);
111
twos = mpz_scan1 (b, 0L);
112
mpz_tdiv_q_2exp (b, b, twos);
113
result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, PTR(a)[0]);
118
result_bit1 ^= JACOBI_N1B_BIT1 (PTR(b)[0]);
123
twos = mpz_scan1 (a, 0L);
124
mpz_tdiv_q_2exp (a, a, twos);
125
result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, PTR(b)[0]);
130
ASSERT (mpz_odd_p (a));
131
ASSERT (mpz_odd_p (b));
132
ASSERT (mpz_sgn (a) > 0);
133
ASSERT (mpz_sgn (b) > 0);
135
TRACE (printf ("top\n");
137
mpz_trace (" b", b));
139
if (mpz_cmp (a, b) < 0)
141
TRACE (printf ("swap\n"));
143
result_bit1 ^= JACOBI_RECIP_UU_BIT1 (PTR(a)[0], PTR(b)[0]);
146
if (mpz_cmp_ui (b, 1) == 0)
150
TRACE (printf ("sub\n");
151
mpz_trace (" a", a));
152
if (mpz_sgn (a) == 0)
155
twos = mpz_scan1 (a, 0L);
156
mpz_fdiv_q_2exp (a, a, twos);
157
TRACE (printf ("twos %lu\n", twos);
158
mpz_trace (" a", a));
159
result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, PTR(b)[0]);
164
return JACOBI_BIT1_TO_PN (result_bit1);
172
/* Same as mpz_kronecker, but ignoring factors of 2 on b */
174
refmpz_jacobi (mpz_srcptr a, mpz_srcptr b)
177
mpz_init_set (b_odd, b);
178
if (mpz_sgn (b_odd) != 0)
179
mpz_fdiv_q_2exp (b_odd, b_odd, mpz_scan1 (b_odd, 0L));
180
return refmpz_kronecker (a, b_odd);
184
refmpz_legendre (mpz_srcptr a, mpz_srcptr b)
186
return refmpz_jacobi (a, b);
191
refmpz_kronecker_ui (mpz_srcptr a, unsigned long b)
195
mpz_init_set_ui (bz, b);
196
ret = refmpz_kronecker (a, bz);
202
refmpz_kronecker_si (mpz_srcptr a, long b)
206
mpz_init_set_si (bz, b);
207
ret = refmpz_kronecker (a, bz);
213
refmpz_ui_kronecker (unsigned long a, mpz_srcptr b)
217
mpz_init_set_ui (az, a);
218
ret = refmpz_kronecker (az, b);
224
refmpz_si_kronecker (long a, mpz_srcptr b)
228
mpz_init_set_si (az, a);
229
ret = refmpz_kronecker (az, b);
236
refmpz_pow_ui (mpz_ptr w, mpz_srcptr b, unsigned long e)
241
mpz_init_set_ui (t, 1L);
247
for (i = 2; i <= e; i <<= 1)