Annotation of OpenXM_contrib/gmp/mpz/kronuz.c, Revision 1.1.1.1
1.1 maekawa 1: /* mpz_ui_kronecker -- Kronecker/Jacobi symbol. */
2:
3: /*
4: Copyright (C) 1999, 2000 Free Software Foundation, Inc.
5:
6: This file is part of the GNU MP Library.
7:
8: The GNU MP Library is free software; you can redistribute it and/or modify
9: it under the terms of the GNU Lesser General Public License as published by
10: the Free Software Foundation; either version 2.1 of the License, or (at your
11: option) any later version.
12:
13: The GNU MP Library is distributed in the hope that it will be useful, but
14: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16: License for more details.
17:
18: You should have received a copy of the GNU Lesser General Public License
19: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
20: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21: MA 02111-1307, USA.
22: */
23:
24: #include "gmp.h"
25: #include "gmp-impl.h"
26: #include "longlong.h"
27:
28:
29: int
30: #if __STDC__
31: mpz_ui_kronecker (unsigned long a, mpz_srcptr b)
32: #else
33: mpz_ui_kronecker (a, b)
34: unsigned long a;
35: mpz_srcptr b;
36: #endif
37: {
38: int b_abs_size;
39: mp_srcptr b_ptr;
40: mp_limb_t b_low;
41: int twos;
42: int result_bit1;
43:
44: /* (a/0) */
45: b_abs_size = ABSIZ (b);
46: if (b_abs_size == 0)
47: return JACOBI_U0 (a);
48:
49: /* (a/-1)=1 when a>=0, so the sign of b is ignored */
50: b_ptr = PTR(b);
51: b_low = b_ptr[0];
52:
53: /* (0/1)=1; (0/-1)=1; (0/b)=0 for b!=+/-1
54: (1/b)=1, for any b */
55: if (a <= 1)
56: return (a == 1) | ((b_abs_size == 1) & (b_low == 1));
57:
58: if (b_low & 1)
59: {
60: /* (a/1) = 1 for any a */
61: if (b_abs_size == 1 && b_low == 1)
62: return 1;
63:
64: count_trailing_zeros (twos, a);
65: a >>= twos;
66: if (a == 1)
67: return JACOBI_TWOS_U (twos, b_low); /* powers of (2/b) only */
68:
69: /* powers of (2/b); reciprocity to (b/a); (b/a) == (b mod a / a) */
70: return mpn_jacobi_base (mpn_mod_1 (b_ptr, b_abs_size, a),
71: a,
72: JACOBI_TWOS_U_BIT1 (twos, b_low)
73: ^ JACOBI_RECIP_UU_BIT1 (b_low, a));
74: }
75:
76: /* b is even; (a/2)=0 if a is even */
77: if ((a & 1) == 0)
78: return 0;
79:
80: /* Require MP_BITS_PER_LIMB even, so (a/2)^MP_BITS_PER_LIMB = 1, and so we
81: don't have to pay attention to how many trailing zero limbs are
82: stripped. */
83: ASSERT ((BITS_PER_MP_LIMB & 1) == 0);
84:
85: MPN_STRIP_LOW_ZEROS_NOT_ZERO (b_ptr, b_abs_size);
86: b_low = b_ptr[0];
87:
88: if (b_low & 1)
89: /* reciprocity to (b/a); (b/a) == (b mod a / a) */
90: return mpn_jacobi_base (mpn_mod_1 (b_ptr, b_abs_size, a),
91: a,
92: JACOBI_RECIP_UU_BIT1 (b_low, a));
93:
94: count_trailing_zeros (twos, b_low);
95:
96: /* reciprocity to get (b/a) */
97: if (twos == BITS_PER_MP_LIMB-1)
98: {
99: if (b_abs_size == 1)
100: {
101: /* b==0x800...00, one limb high bit only, so (a/2)^(BPML-1) */
102: return JACOBI_TWOS_U (BITS_PER_MP_LIMB-1, a);
103: }
104:
105: /* b_abs_size > 1 */
106: result_bit1 = JACOBI_RECIP_UU_BIT1 (a, b_ptr[1] << 1);
107: }
108: else
109: result_bit1 = JACOBI_RECIP_UU_BIT1 (a, b_low >> twos);
110:
111: /* powers of (a/2); reciprocity to (b/a); (b/a) == (b mod a / a) */
112: return mpn_jacobi_base (mpn_mod_1_rshift (b_ptr, b_abs_size, twos, a),
113: a,
114: JACOBI_TWOS_U_BIT1 (twos, a) ^ result_bit1);
115: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>