remove empty dir
[ghc-hetmet.git] / ghc / rts / gmp / mpz / kronsz.c
1 /* mpz_si_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_si_kronecker (long a, mpz_srcptr b)
32 #else
33 mpz_si_kronecker (a, b)
34      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   b_abs_size = ABSIZ (b);
45   if (b_abs_size == 0)
46     return JACOBI_S0 (a);  /* (a/0) */
47
48   b_ptr = PTR(b);
49   b_low = b_ptr[0];
50
51   /* (0/b) = 1 if b=+/-1, 0 otherwise */
52   if (a == 0)
53     return (b_abs_size == 1) & (b_low == 1);
54
55   /* account for the effect of the sign of b, so can then ignore it */
56   result_bit1 = JACOBI_BSGN_SZ_BIT1 (a, b);
57
58   if ((b_low & 1) == 0)
59     {
60       /* b even */
61
62       if ((a & 1) == 0)
63         return 0;  /* (a/b)=0 if both a,b even */
64
65       /* Require MP_BITS_PER_LIMB even, so that (a/2)^MP_BITS_PER_LIMB = 1,
66          and so that therefore there's no need to account for how many zero
67          limbs are stripped.  */
68       ASSERT ((BITS_PER_MP_LIMB & 1) == 0);
69
70       MPN_STRIP_LOW_ZEROS_NOT_ZERO (b_ptr, b_abs_size);
71       b_low = b_ptr[0];
72
73       if ((b_low & 1) == 0)
74         {
75           /* odd a, even b */
76
77           mp_limb_t  b_shl_bit1;
78
79           count_trailing_zeros (twos, b_low);
80
81           /* b_shl_bit1 is b>>twos, but with only bit 1 guaranteed */
82           if (twos == BITS_PER_MP_LIMB-1)
83             b_shl_bit1 = (b_abs_size == 1) ? 0 : (b_ptr[1] << 1);
84           else
85             b_shl_bit1 = (b_low >> twos);
86
87           result_bit1 ^= JACOBI_ASGN_SU_BIT1 (a, b_shl_bit1);
88           a = ABS(a);
89
90           if (a == 1)
91             return JACOBI_BIT1_TO_PN (result_bit1);  /* (1/b)=1 */
92
93           /* twos (a/2), reciprocity to (b/a), and (b/a) = (b mod a / b) */
94           return mpn_jacobi_base (mpn_mod_1_rshift (b_ptr, b_abs_size,
95                                                     twos, a),
96                                   a,
97                                   result_bit1
98                                   ^ JACOBI_TWOS_U_BIT1 (twos, a)
99                                   ^ JACOBI_RECIP_UU_BIT1 (a, b_shl_bit1));
100         }
101     }
102
103   /* b odd */
104
105   result_bit1 ^= JACOBI_ASGN_SU_BIT1 (a, b_low);
106   a = ABS(a);
107
108   /* (a/1) = 1 for any a */
109   if (b_abs_size == 1 && b_low == 1)
110     return JACOBI_BIT1_TO_PN (result_bit1);
111
112   /* Note a is cast to unsigned because 0x80..00 doesn't fit in a signed. */
113   if ((a & 1) == 0)
114     {
115       count_trailing_zeros (twos, a);
116       a = ((unsigned long) a) >> twos;
117       result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, b_low);
118     }
119
120   if (a == 1)
121     return JACOBI_BIT1_TO_PN (result_bit1);  /* (1/b)=1 */
122
123   /* reciprocity to (b/a), and (b/a) == (b mod a / a) */
124   return mpn_jacobi_base (mpn_mod_1 (b_ptr, b_abs_size, a), a,
125                           result_bit1 ^ JACOBI_RECIP_UU_BIT1 (a, b_low));
126 }