static unsigned long int gcd (unsigned long int a, unsigned long int b) { int an2, bn2, n2; if (a == 0) return b; if (b == 0) return a; count_trailing_zeros (an2, a); a >>= an2; count_trailing_zeros (bn2, b); b >>= bn2; n2 = MIN (an2, bn2); while (a != b) { if (a > b) { a -= b; do a >>= 1; while ((a & 1) == 0); } else /* b > a. */ {
void mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor) { mp_limb_t inverse, s, s_next, c, l, ls, q; unsigned rshift, lshift; mp_limb_t lshift_mask; mp_limb_t divisor_h; ASSERT (size >= 1); ASSERT (divisor != 0); ASSERT (MPN_SAME_OR_SEPARATE_P (dst, src, size)); ASSERT_MPN (src, size); ASSERT_LIMB (divisor); s = *src++; /* src low limb */ size--; if (size == 0) { *dst = s / divisor; return; } if ((divisor & 1) == 0) { count_trailing_zeros (rshift, divisor); divisor >>= rshift; }
static int use_algebraic(const fmpz_t v, const fmpz_t w, slong prec) { fmpz q = *w; int r; if (COEFF_IS_MPZ(q)) return 0; if (q <= 6) return 1; count_trailing_zeros(r, q); q >>= r; if (r >= 4 && prec < (r - 3) * 300) return 0; if (q > 1000) return 0; if (prec < 1500 + 150 * q) return 0; return 1; }
inline int get_and_set_first_available_stream(size_t index) { word_t word = words_[index]; if (word == 0) return -1; int stream = count_trailing_zeros(word); words_[index] ^= (static_cast<word_t>(1) << stream); return stream; }
void mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor) { mp_size_t i; mp_limb_t c, h, l, ls, s, s_next, inverse, dummy; unsigned shift; ASSERT (size >= 1); ASSERT (divisor != 0); ASSERT (MPN_SAME_OR_SEPARATE_P (dst, src, size)); ASSERT_MPN (src, size); ASSERT_LIMB (divisor); s = src[0]; if (size == 1) { dst[0] = s / divisor; return; } if ((divisor & 1) == 0) { count_trailing_zeros (shift, divisor); divisor >>= shift; }
int mpn_divisible_p (mp_srcptr ap, mp_size_t asize, mp_srcptr dp, mp_size_t dsize) { mp_limb_t alow, dlow, dmask; mp_ptr qp, rp; mp_size_t i; TMP_DECL; ASSERT (asize >= 0); ASSERT (asize == 0 || ap[asize-1] != 0); ASSERT (dsize >= 1); ASSERT (dp[dsize-1] != 0); ASSERT_MPN (ap, asize); ASSERT_MPN (dp, dsize); /* When a<d only a==0 is divisible. Notice this test covers all cases of asize==0. */ if (asize < dsize) return (asize == 0); /* Strip low zero limbs from d, requiring a==0 on those. */ for (;;) { alow = *ap; dlow = *dp; if (dlow != 0) break; if (alow != 0) return 0; /* a has fewer low zero limbs than d, so not divisible */ /* a!=0 and d!=0 so won't get to size==0 */ asize--; ASSERT (asize >= 1); dsize--; ASSERT (dsize >= 1); ap++; dp++; } /* a must have at least as many low zero bits as d */ dmask = LOW_ZEROS_MASK (dlow); if ((alow & dmask) != 0) return 0; if (dsize == 1) { if (BELOW_THRESHOLD (asize, MODEXACT_1_ODD_THRESHOLD)) return mpn_mod_1 (ap, asize, dlow) == 0; if ((dlow & 1) == 0) { unsigned twos; count_trailing_zeros (twos, dlow); dlow >>= twos; } return mpn_modexact_1_odd (ap, asize, dlow) == 0; }
Error, error, unsupported BITS_PER_MP_LIMB #endif int mpz_kronecker_ui (mpz_srcptr a, unsigned long b) { mp_srcptr a_ptr = PTR(a); mp_size_t a_size; mp_limb_t a_rem; int result_bit1; a_size = SIZ(a); if (a_size == 0) return JACOBI_0U (b); if (b > GMP_NUMB_MAX) { mp_limb_t blimbs[2]; mpz_t bz; ALLOC(bz) = numberof (blimbs); PTR(bz) = blimbs; mpz_set_ui (bz, b); return mpz_kronecker (a, bz); } if ((b & 1) != 0) { result_bit1 = JACOBI_ASGN_SU_BIT1 (a_size, b); } else { mp_limb_t a_low = a_ptr[0]; int twos; if (b == 0) return JACOBI_LS0 (a_low, a_size); /* (a/0) */ if (! (a_low & 1)) return 0; /* (even/even)=0 */ /* (a/2)=(2/a) for a odd */ count_trailing_zeros (twos, b); b >>= twos; result_bit1 = (JACOBI_TWOS_U_BIT1 (twos, a_low) ^ JACOBI_ASGN_SU_BIT1 (a_size, b)); } if (b == 1) return JACOBI_BIT1_TO_PN (result_bit1); /* (a/1)=1 for any a */ a_size = ABS(a_size); /* (a/b) = (a mod b / b) */ JACOBI_MOD_OR_MODEXACT_1_ODD (result_bit1, a_rem, a_ptr, a_size, b); return mpn_jacobi_base (a_rem, (mp_limb_t) b, result_bit1); }
int __ctzsi2 (unsigned int x) { int ret; count_trailing_zeros (ret, x); return ret; }
int mpz_si_kronecker (long a, mpz_srcptr b) { mp_srcptr b_ptr; mp_limb_t b_low; mp_size_t b_size; mp_size_t b_abs_size; mp_limb_t a_limb, b_rem; unsigned twos; int result_bit1; #if GMP_NUMB_BITS < BITS_PER_ULONG if (a > GMP_NUMB_MAX || a < -GMP_NUMB_MAX) { mp_limb_t alimbs[2]; mpz_t az; ALLOC(az) = numberof (alimbs); PTR(az) = alimbs; mpz_set_si (az, a); return mpz_kronecker (az, b); } #endif b_size = SIZ (b); if (b_size == 0) return JACOBI_S0 (a); /* (a/0) */ /* account for the effect of the sign of b, then ignore it */ result_bit1 = JACOBI_BSGN_SS_BIT1 (a, b_size); b_ptr = PTR(b); b_low = b_ptr[0]; b_abs_size = ABS (b_size); if ((b_low & 1) != 0) { /* b odd */ result_bit1 ^= JACOBI_ASGN_SU_BIT1 (a, b_low); a_limb = (unsigned long) ABS(a); if ((a_limb & 1) == 0) { /* (0/b)=1 for b=+/-1, 0 otherwise */ if (a_limb == 0) return (b_abs_size == 1 && b_low == 1); /* a even, b odd */ count_trailing_zeros (twos, a_limb); a_limb >>= twos; /* (a*2^n/b) = (a/b) * twos(n,a) */ result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, b_low); } }
static unsigned int reduce_octant(fmpz_t v, fmpz_t w, const fmpq_t x) { const fmpz * p = fmpq_numref(x); const fmpz * q = fmpq_denref(x); unsigned int octant; mp_bitcnt_t vval, wval; if (*p > COEFF_MIN / 8 && *p < COEFF_MAX / 8 && *q > 0 && *q < COEFF_MAX / 4) { slong pp, qq, ww, vv, tt; pp = *p; qq = *q; tt = pp * 4; ww = tt / qq; vv = tt - qq * ww; /* compute correct (floor) quotient and remainder */ if (vv < 0) { ww--; vv += qq; } octant = ((ulong) ww) % 8; ww = qq * 4; if (octant % 2 != 0) vv = qq - vv; if (vv != 0) { count_trailing_zeros(vval, vv); count_trailing_zeros(wval, ww); vval = FLINT_MIN(vval, wval); vv >>= vval; ww >>= vval; }
mp_limb_t mpn_gcdext_1 (mp_limb_signed_t *sp, mp_limb_signed_t *tp, mp_limb_t u, mp_limb_t v) { /* Maintain U = t1 u + t0 v V = s1 u + s0 v where U, V are the inputs (without any shared power of two), and the matris has determinant ± 2^{shift}. */ mp_limb_t s0 = 1; mp_limb_t t0 = 0; mp_limb_t s1 = 0; mp_limb_t t1 = 1; mp_limb_t ug; mp_limb_t vg; mp_limb_t ugh; mp_limb_t vgh; unsigned zero_bits; unsigned shift; unsigned i; #if GCDEXT_1_BINARY_METHOD == 2 mp_limb_t det_sign; #endif ASSERT (u > 0); ASSERT (v > 0); count_trailing_zeros (zero_bits, u | v); u >>= zero_bits; v >>= zero_bits; if ((u & 1) == 0) { count_trailing_zeros (shift, u); u >>= shift; t1 <<= shift; }
/* return non zero iff x^y is exact. Assumes x and y are ordinary numbers (neither NaN nor Inf), and y is not zero. */ int mpfr_pow_is_exact (mpfr_srcptr x, mpfr_srcptr y) { mp_exp_t d; unsigned long i, c; mp_limb_t *yp; if ((mpfr_sgn (x) < 0) && (mpfr_isinteger (y) == 0)) return 0; if (mpfr_sgn (y) < 0) return mpfr_cmp_si_2exp (x, MPFR_SIGN(x), MPFR_EXP(x) - 1) == 0; /* compute d such that y = c*2^d with c odd integer */ d = MPFR_EXP(y) - MPFR_PREC(y); /* since y is not zero, necessarily one of the mantissa limbs is not zero, thus we can simply loop until we find a non zero limb */ yp = MPFR_MANT(y); for (i = 0; yp[i] == 0; i++, d += BITS_PER_MP_LIMB); /* now yp[i] is not zero */ count_trailing_zeros (c, yp[i]); d += c; if (d < 0) { mpz_t a; mp_exp_t b; mpz_init (a); b = mpfr_get_z_exp (a, x); /* x = a * 2^b */ c = mpz_scan1 (a, 0); mpz_div_2exp (a, a, c); b += c; /* now a is odd */ while (d != 0) { if (mpz_perfect_square_p (a)) { d++; mpz_sqrt (a, a); } else { mpz_clear (a); return 0; } } mpz_clear (a); } return 1; }
static void bsplit(fmpz_t T, fmpz_t Q, mp_bitcnt_t * Qexp, const slong * xexp, const fmpz * xpow, mp_bitcnt_t r, slong a, slong b) { int cc; if (b - a == 1) { count_trailing_zeros(cc, (2 * a + 2)); fmpz_neg_ui(Q, (2 * a + 2) >> cc); fmpz_mul_ui(Q, Q, 2 * a + 3); *Qexp = 2 * r + cc; fmpz_set(T, xpow); }
int mpz_divisible_ui_p (mpz_srcptr a, unsigned long d) { mp_size_t asize; mp_ptr ap; unsigned twos; asize = SIZ(a); if (UNLIKELY (d == 0)) return (asize == 0); if (asize == 0) /* 0 divisible by any d */ return 1; /* For nails don't try to be clever if d is bigger than a limb, just fake up an mpz_t and go to the main mpz_divisible_p. */ if (d > GMP_NUMB_MAX) { mp_limb_t dlimbs[2]; mpz_t dz; ALLOC(dz) = 2; PTR(dz) = dlimbs; mpz_set_ui (dz, d); return mpz_divisible_p (a, dz); } ap = PTR(a); asize = ABS(asize); /* ignore sign of a */ if (ABOVE_THRESHOLD (asize, BMOD_1_TO_MOD_1_THRESHOLD)) return mpn_mod_1 (ap, asize, (mp_limb_t) d) == 0; if (! (d & 1)) { /* Strip low zero bits to get odd d required by modexact. If d==e*2^n and a is divisible by 2^n and by e, then it's divisible by d. */ if ((ap[0] & LOW_ZEROS_MASK (d)) != 0) return 0; count_trailing_zeros (twos, (mp_limb_t) d); d >>= twos; } return mpn_modexact_1_odd (ap, asize, (mp_limb_t) d) == 0; }
slong fmpr_mul_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) { fmpz xv, yv; fmpz yexp; if (fmpr_is_special(x) || fmpz_is_zero(y)) { if (fmpr_is_zero(x)) { fmpr_zero(z); } else if (fmpz_is_zero(y) && fmpr_is_finite(x)) { fmpr_zero(z); } else if (fmpr_is_inf(x) && !fmpz_is_zero(y)) { if (fmpr_sgn(x) == fmpz_sgn(y)) fmpr_pos_inf(z); else fmpr_neg_inf(z); } else { fmpr_nan(z); } return FMPR_RESULT_EXACT; } xv = *fmpr_manref(x); yv = *y; if (!COEFF_IS_MPZ(xv) && !COEFF_IS_MPZ(yv)) { mp_limb_t ytmp; unsigned int bc; ytmp = FLINT_ABS(yv); count_trailing_zeros(bc, ytmp); ytmp >>= bc; yexp = bc; return _fmpr_mul_1x1(z, FLINT_ABS(xv), fmpr_expref(x), ytmp, &yexp, (xv ^ yv) < 0, prec, rnd); }
int mpz_kronecker_si (mpz_srcptr a, long b) { mp_srcptr a_ptr; mp_size_t a_size; mp_limb_t a_rem, b_limb; int result_bit1; a_size = SIZ(a); if (a_size == 0) return JACOBI_0S (b); #if GMP_NUMB_BITS < BITS_PER_ULONG if (b > GMP_NUMB_MAX || b < -GMP_NUMB_MAX) { mp_limb_t blimbs[2]; mpz_t bz; ALLOC(bz) = numberof (blimbs); PTR(bz) = blimbs; mpz_set_si (bz, b); return mpz_kronecker (a, bz); } #endif result_bit1 = JACOBI_BSGN_SS_BIT1 (a_size, b); b_limb = (unsigned long) ABS (b); a_ptr = PTR(a); if ((b_limb & 1) == 0) { mp_limb_t a_low = a_ptr[0]; int twos; if (b_limb == 0) return JACOBI_LS0 (a_low, a_size); /* (a/0) */ if (! (a_low & 1)) return 0; /* (even/even)=0 */ /* (a/2)=(2/a) for a odd */ count_trailing_zeros (twos, b_limb); b_limb >>= twos; result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, a_low); }
static int mask2cidr(const char *netmask) { struct in_addr addr; if (inet_pton(AF_INET, netmask, &addr) != 1) fatal_printf("%s: not a valid dotted-quad address", netmask); uint32_t mask = ntohl(addr.s_addr); /* To be a *netmask*, the number we get from inet_pton must be of the form 1...10...0, i.e. there must be a single point in the bit representation where it changes from all-1 to all-0. */ int leading_ones = count_leading_zeros(~mask); int trailing_zeros = count_trailing_zeros(mask); if (leading_ones != 32 - trailing_zeros) fatal_printf("%s (%08x: %dlo, %dtz): not a valid netmask", netmask, mask, leading_ones, trailing_zeros); return leading_ones; }
void mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor) { mp_limb_t inverse, lshift_mask, s, sr, s_next, c, h, x, y, q, dummy; unsigned rshift, lshift; ASSERT (size >= 1); ASSERT (divisor != 0); ASSERT (MPN_SAME_OR_SEPARATE_P (dst, src, size)); ASSERT_MPN (src, size); ASSERT_LIMB (divisor); s_next = *src++; /* src[0] */ rshift = 0; lshift_mask = 0; if ((divisor & 1) == 0) { count_trailing_zeros (rshift, divisor); lshift_mask = MP_LIMB_T_MAX; divisor >>= rshift; }
mp_bitcnt_t mpn_scan1 (mp_srcptr up, mp_bitcnt_t starting_bit) { mp_size_t starting_word; mp_limb_t alimb; int cnt; mp_srcptr p; /* Start at the word implied by STARTING_BIT. */ starting_word = starting_bit / GMP_NUMB_BITS; p = up + starting_word; alimb = *p++; /* Mask off any bits before STARTING_BIT in the first limb. */ alimb &= - (mp_limb_t) 1 << (starting_bit % GMP_NUMB_BITS); while (alimb == 0) alimb = *p++; count_trailing_zeros (cnt, alimb); return (p - up - 1) * GMP_NUMB_BITS + cnt; }
unsigned long mpz_scan0 (mpz_srcptr u, unsigned long starting_bit) { mp_srcptr u_ptr = PTR(u); mp_size_t size = SIZ(u); mp_size_t abs_size = ABS(size); mp_srcptr u_end = u_ptr + abs_size; unsigned long starting_limb = starting_bit / GMP_NUMB_BITS; mp_srcptr p = u_ptr + starting_limb; mp_limb_t limb; int cnt; /* When past end, there's an immediate 0 bit for u>=0, or no 0 bits for u<0. Notice this test picks up all cases of u==0 too. */ if (starting_limb >= abs_size) return (size >= 0 ? starting_bit : ULONG_MAX); limb = *p; if (size >= 0) { /* Mask to 1 all bits before starting_bit, thus ignoring them. */ limb |= (CNST_LIMB(1) << (starting_bit % GMP_NUMB_BITS)) - 1; /* Search for a limb which isn't all ones. If the end is reached then the zero bit immediately past the end is returned. */ while (limb == GMP_NUMB_MAX) { p++; if (p == u_end) return (unsigned long) abs_size * GMP_NUMB_BITS; limb = *p; } /* Now seek low 1 bit. */ limb = ~limb; } else { mp_srcptr q; /* If there's a non-zero limb before ours then we're in the ones complement region. Search from *(p-1) downwards since that might give better cache locality, and since a non-zero in the middle of a number is perhaps a touch more likely than at the end. */ q = p; while (q != u_ptr) { q--; if (*q != 0) goto inverted; } /* Adjust so ~limb implied by searching for 1 bit below becomes -limb. If limb==0 here then this isn't the beginning of twos complement inversion, but that doesn't matter because limb==0 is a zero bit immediately (-1 is all ones for below). */ limb--; inverted: /* Now seeking a 1 bit. */ /* Mask to 0 all bits before starting_bit, thus ignoring them. */ limb &= (MP_LIMB_T_MAX << (starting_bit % GMP_NUMB_BITS)); if (limb == 0) { /* If the high limb is zero after masking, then no 1 bits past starting_bit. */ p++; if (p == u_end) return ULONG_MAX; /* Search further for a non-zero limb. The high limb is non-zero, if nothing else. */ for (;;) { limb = *p; if (limb != 0) break; p++; ASSERT (p < u_end); } } } ASSERT (limb != 0); count_trailing_zeros (cnt, limb); return (p - u_ptr) * GMP_NUMB_BITS + cnt; }
void mpq_set_f (mpq_ptr q, mpf_srcptr f) { mp_size_t fexp = EXP(f); mp_ptr fptr = PTR(f); mp_size_t fsize = SIZ(f); mp_size_t abs_fsize = ABS(fsize); mp_limb_t flow; if (fsize == 0) { /* set q=0 */ SIZ(NUM(q)) = 0; SIZ(DEN(q)) = 1; PTR(DEN(q))[0] = 1; return; } /* strip low zero limbs from f */ flow = *fptr; MPN_STRIP_LOW_ZEROS_NOT_ZERO (fptr, abs_fsize, flow); if (fexp >= abs_fsize) { /* radix point is to the right of the limbs, no denominator */ mp_ptr num_ptr; num_ptr = MPZ_NEWALLOC (mpq_numref (q), fexp); MPN_ZERO (num_ptr, fexp - abs_fsize); MPN_COPY (num_ptr + fexp - abs_fsize, fptr, abs_fsize); SIZ(NUM(q)) = fsize >= 0 ? fexp : -fexp; SIZ(DEN(q)) = 1; PTR(DEN(q))[0] = 1; } else { /* radix point is within or to the left of the limbs, use denominator */ mp_ptr num_ptr, den_ptr; mp_size_t den_size; den_size = abs_fsize - fexp; num_ptr = MPZ_NEWALLOC (mpq_numref (q), abs_fsize); den_ptr = MPZ_NEWALLOC (mpq_denref (q), den_size+1); if (flow & 1) { /* no powers of two to strip from numerator */ MPN_COPY (num_ptr, fptr, abs_fsize); MPN_ZERO (den_ptr, den_size); den_ptr[den_size] = 1; } else { /* right shift numerator, adjust denominator accordingly */ int shift; den_size--; count_trailing_zeros (shift, flow); mpn_rshift (num_ptr, fptr, abs_fsize, shift); abs_fsize -= (num_ptr[abs_fsize-1] == 0); MPN_ZERO (den_ptr, den_size); den_ptr[den_size] = GMP_LIMB_HIGHBIT >> (shift-1); } SIZ(NUM(q)) = fsize >= 0 ? abs_fsize : -abs_fsize; SIZ(DEN(q)) = den_size + 1; } }
void mpz_gcd (mpz_ptr g, mpz_srcptr u, mpz_srcptr v) { mpir_ui g_zero_bits, u_zero_bits, v_zero_bits; mp_size_t g_zero_limbs, u_zero_limbs, v_zero_limbs; mp_ptr tp; mp_ptr up; mp_size_t usize; mp_ptr vp; mp_size_t vsize; mp_size_t gsize; TMP_DECL; up = PTR(u); usize = ABSIZ (u); vp = PTR(v); vsize = ABSIZ (v); /* GCD(0, V) == V. */ if (usize == 0) { SIZ (g) = vsize; if (g == v) return; MPZ_REALLOC (g, vsize); MPN_COPY (PTR (g), vp, vsize); return; } /* GCD(U, 0) == U. */ if (vsize == 0) { SIZ (g) = usize; if (g == u) return; MPZ_REALLOC (g, usize); MPN_COPY (PTR (g), up, usize); return; } if (usize == 1) { SIZ (g) = 1; PTR (g)[0] = mpn_gcd_1 (vp, vsize, up[0]); return; } if (vsize == 1) { SIZ(g) = 1; PTR (g)[0] = mpn_gcd_1 (up, usize, vp[0]); return; } TMP_MARK; /* Eliminate low zero bits from U and V and move to temporary storage. */ while (*up == 0) up++; u_zero_limbs = up - PTR(u); usize -= u_zero_limbs; count_trailing_zeros (u_zero_bits, *up); tp = up; up = TMP_ALLOC_LIMBS (usize); if (u_zero_bits != 0) { mpn_rshift (up, tp, usize, u_zero_bits); usize -= up[usize - 1] == 0; } else MPN_COPY (up, tp, usize); while (*vp == 0) vp++; v_zero_limbs = vp - PTR (v); vsize -= v_zero_limbs; count_trailing_zeros (v_zero_bits, *vp); tp = vp; vp = TMP_ALLOC_LIMBS (vsize); if (v_zero_bits != 0) { mpn_rshift (vp, tp, vsize, v_zero_bits); vsize -= vp[vsize - 1] == 0; } else MPN_COPY (vp, tp, vsize); if (u_zero_limbs > v_zero_limbs) { g_zero_limbs = v_zero_limbs; g_zero_bits = v_zero_bits; } else if (u_zero_limbs < v_zero_limbs) { g_zero_limbs = u_zero_limbs; g_zero_bits = u_zero_bits; } else /* Equal. */ { g_zero_limbs = u_zero_limbs; g_zero_bits = MIN (u_zero_bits, v_zero_bits); } /* Call mpn_gcd. The 2nd argument must not have more bits than the 1st. */ vsize = (usize < vsize || (usize == vsize && up[usize-1] < vp[vsize-1])) ? mpn_gcd (vp, vp, vsize, up, usize) : mpn_gcd (vp, up, usize, vp, vsize); /* Here G <-- V << (g_zero_limbs*GMP_LIMB_BITS + g_zero_bits). */ gsize = vsize + g_zero_limbs; if (g_zero_bits != 0) { mp_limb_t cy_limb; gsize += (vp[vsize - 1] >> (GMP_NUMB_BITS - g_zero_bits)) != 0; MPZ_REALLOC (g, gsize); MPN_ZERO (PTR (g), g_zero_limbs); tp = PTR(g) + g_zero_limbs; cy_limb = mpn_lshift (tp, vp, vsize, g_zero_bits); if (cy_limb != 0) tp[vsize] = cy_limb; }
int mpz_ui_kronecker (unsigned long a, mpz_srcptr b) { mp_srcptr b_ptr; mp_limb_t b_low; int b_abs_size; mp_limb_t b_rem; int twos; int result_bit1; /* (a/-1)=1 when a>=0, so the sign of b is ignored */ b_abs_size = ABSIZ (b); if (b_abs_size == 0) return JACOBI_U0 (a); /* (a/0) */ if (a > GMP_NUMB_MAX) { mp_limb_t alimbs[2]; mpz_t az; ALLOC(az) = numberof (alimbs); PTR(az) = alimbs; mpz_set_ui (az, a); return mpz_kronecker (az, b); } b_ptr = PTR(b); b_low = b_ptr[0]; result_bit1 = 0; if (! (b_low & 1)) { /* (0/b)=0 for b!=+/-1; and (even/even)=0 */ if (! (a & 1)) return 0; /* a odd, b even Establish shifted b_low with valid bit1 for the RECIP below. Zero limbs stripped are accounted for, but zero bits on b_low are not because they remain in {b_ptr,b_abs_size} for JACOBI_MOD_OR_MODEXACT_1_ODD. */ JACOBI_STRIP_LOW_ZEROS (result_bit1, a, b_ptr, b_abs_size, b_low); if (! (b_low & 1)) { if (UNLIKELY (b_low == GMP_NUMB_HIGHBIT)) { /* need b_ptr[1] to get bit1 in b_low */ if (b_abs_size == 1) { /* (a/0x80...00) == (a/2)^(NUMB-1) */ if ((GMP_NUMB_BITS % 2) == 0) { /* JACOBI_STRIP_LOW_ZEROS does nothing to result_bit1 when GMP_NUMB_BITS is even, so it's still 0. */ ASSERT (result_bit1 == 0); result_bit1 = JACOBI_TWO_U_BIT1 (a); } return JACOBI_BIT1_TO_PN (result_bit1); } /* b_abs_size > 1 */ b_low = b_ptr[1] << 1; } else { count_trailing_zeros (twos, b_low); b_low >>= twos; } } } else { if (a == 0) /* (0/b)=1 for b=+/-1, 0 otherwise */
int main (int argc, char *argv[]) { mp_limb_t bb, h, l, bb_inv; int i, j; for (i = 2; i < numberof (mp_bases); i++) { if (POW2_P (i)) { count_trailing_zeros (j, i); if (mp_bases[i].big_base != (mp_limb_t) j) { printf ("mp_bases[%d].big_base (trailing zeros) wrong\n", i); abort (); } } else { bb = 1; for (j = 0; j < mp_bases[i].chars_per_limb; j++) { umul_ppmm (h, bb, bb, i); if (h != 0 || (bb & GMP_NAIL_MASK) != 0) { printf ("mp_bases[%d].chars_per_limb overflow\n", i); abort (); } } umul_ppmm (h, l, bb, i); if (h == 0 && (l & GMP_NAIL_MASK) == 0) { printf ("mp_bases[%d].chars_per_limb too small\n", i); abort (); } if (mp_bases[i].big_base != bb) { printf ("mp_bases[%d].big_base wrong\n", i); abort (); } invert_limb (bb_inv, bb << refmpn_count_leading_zeros (bb)); if (mp_bases[i].big_base_inverted != bb_inv) { printf ("mp_bases[%d].big_base_inverted wrong\n", i); abort (); } } } if (MP_BASES_CHARS_PER_LIMB_10 != mp_bases[10].chars_per_limb) { printf ("MP_BASES_CHARS_PER_LIMB_10 not the same as mp_bases[10].chars_per_limb\n"); abort (); } if (MP_BASES_BIG_BASE_10 != mp_bases[10].big_base) { printf ("MP_BASES_BIG_BASE_10 not the same as mp_bases[10].big_base\n"); abort (); } if (MP_BASES_BIG_BASE_INVERTED_10 != mp_bases[10].big_base_inverted) { printf ("MP_BASES_BIG_BASE_INVERTED_10 not the same as mp_bases[10].big_base_inverted\n"); abort (); } if (MP_BASES_NORMALIZATION_STEPS_10 != refmpn_count_leading_zeros (MP_BASES_BIG_BASE_10)) { printf ("MP_BASES_NORMALIZATION_STEPS_10 wrong\n"); abort (); } exit (0); }
/* mpz/gcd.c: Calculate the greatest common divisor of two integers. Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU MP Library. The GNU MP Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. The GNU MP Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ #include "gmp.h" #include "gmp-impl.h" #include "longlong.h" #ifdef BERKELEY_MP #include "mp.h" #endif void #ifndef BERKELEY_MP mpz_gcd (mpz_ptr g, mpz_srcptr u, mpz_srcptr v) #else /* BERKELEY_MP */ gcd (mpz_srcptr u, mpz_srcptr v, mpz_ptr g) #endif /* BERKELEY_MP */ { unsigned long int g_zero_bits, u_zero_bits, v_zero_bits; mp_size_t g_zero_limbs, u_zero_limbs, v_zero_limbs; mp_ptr tp; mp_ptr up = u->_mp_d; mp_size_t usize = ABS (u->_mp_size); mp_ptr vp = v->_mp_d; mp_size_t vsize = ABS (v->_mp_size); mp_size_t gsize; TMP_DECL; /* GCD(0, V) == V. */ if (usize == 0) { g->_mp_size = vsize; if (g == v) return; if (g->_mp_alloc < vsize) _mpz_realloc (g, vsize); MPN_COPY (g->_mp_d, vp, vsize); return; } /* GCD(U, 0) == U. */ if (vsize == 0) { g->_mp_size = usize; if (g == u) return; if (g->_mp_alloc < usize) _mpz_realloc (g, usize); MPN_COPY (g->_mp_d, up, usize); return; } if (usize == 1) { g->_mp_size = 1; g->_mp_d[0] = mpn_gcd_1 (vp, vsize, up[0]); return; } if (vsize == 1) { g->_mp_size = 1; g->_mp_d[0] = mpn_gcd_1 (up, usize, vp[0]); return; } TMP_MARK; /* Eliminate low zero bits from U and V and move to temporary storage. */ while (*up == 0) up++; u_zero_limbs = up - u->_mp_d; usize -= u_zero_limbs; count_trailing_zeros (u_zero_bits, *up); tp = up; up = TMP_ALLOC_LIMBS (usize); if (u_zero_bits != 0) { mpn_rshift (up, tp, usize, u_zero_bits); usize -= up[usize - 1] == 0; } else MPN_COPY (up, tp, usize); while (*vp == 0) vp++; v_zero_limbs = vp - v->_mp_d; vsize -= v_zero_limbs; count_trailing_zeros (v_zero_bits, *vp); tp = vp; vp = TMP_ALLOC_LIMBS (vsize); if (v_zero_bits != 0) { mpn_rshift (vp, tp, vsize, v_zero_bits); vsize -= vp[vsize - 1] == 0; } else MPN_COPY (vp, tp, vsize); if (u_zero_limbs > v_zero_limbs) { g_zero_limbs = v_zero_limbs; g_zero_bits = v_zero_bits; } else if (u_zero_limbs < v_zero_limbs) { g_zero_limbs = u_zero_limbs; g_zero_bits = u_zero_bits; } else /* Equal. */ { g_zero_limbs = u_zero_limbs; g_zero_bits = MIN (u_zero_bits, v_zero_bits); } /* Call mpn_gcd. The 2nd argument must not have more bits than the 1st. */ vsize = (usize < vsize || (usize == vsize && up[usize-1] < vp[vsize-1])) ? mpn_gcd (vp, vp, vsize, up, usize) : mpn_gcd (vp, up, usize, vp, vsize); /* Here G <-- V << (g_zero_limbs*GMP_LIMB_BITS + g_zero_bits). */ gsize = vsize + g_zero_limbs; if (g_zero_bits != 0) { mp_limb_t cy_limb; gsize += (vp[vsize - 1] >> (GMP_NUMB_BITS - g_zero_bits)) != 0; if (g->_mp_alloc < gsize) _mpz_realloc (g, gsize); MPN_ZERO (g->_mp_d, g_zero_limbs); tp = g->_mp_d + g_zero_limbs; cy_limb = mpn_lshift (tp, vp, vsize, g_zero_bits); if (cy_limb != 0) tp[vsize] = cy_limb; }
int mpz_congruent_p (mpz_srcptr a, mpz_srcptr c, mpz_srcptr d) { mp_size_t asize, csize, dsize, sign; mp_srcptr ap, cp, dp; mp_ptr xp; mp_limb_t alow, clow, dlow, dmask, r; int result; TMP_DECL; dsize = SIZ(d); if (UNLIKELY (dsize == 0)) return (mpz_cmp (a, c) == 0); dsize = ABS(dsize); dp = PTR(d); if (ABSIZ(a) < ABSIZ(c)) MPZ_SRCPTR_SWAP (a, c); asize = SIZ(a); csize = SIZ(c); sign = (asize ^ csize); asize = ABS(asize); ap = PTR(a); if (csize == 0) return mpn_divisible_p (ap, asize, dp, dsize); csize = ABS(csize); cp = PTR(c); alow = ap[0]; clow = cp[0]; dlow = dp[0]; /* Check a==c mod low zero bits of dlow. This might catch a few cases of a!=c quickly, and it helps the csize==1 special cases below. */ dmask = LOW_ZEROS_MASK (dlow) & GMP_NUMB_MASK; alow = (sign >= 0 ? alow : -alow); if (((alow-clow) & dmask) != 0) return 0; if (csize == 1) { if (dsize == 1) { cong_1: if (sign < 0) NEG_MOD (clow, clow, dlow); if (ABOVE_THRESHOLD (asize, BMOD_1_TO_MOD_1_THRESHOLD)) { r = mpn_mod_1 (ap, asize, dlow); if (clow < dlow) return r == clow; else return r == (clow % dlow); } if ((dlow & 1) == 0) { /* Strip low zero bits to get odd d required by modexact. If d==e*2^n then a==c mod d if and only if both a==c mod e and a==c mod 2^n, the latter having been done above. */ unsigned twos; count_trailing_zeros (twos, dlow); dlow >>= twos; } r = mpn_modexact_1c_odd (ap, asize, dlow, clow); return r == 0 || r == dlow; }
mp_bitcnt_t mpz_scan1 (mpz_srcptr u, mp_bitcnt_t starting_bit) { mp_srcptr u_ptr = PTR(u); mp_size_t size = SIZ(u); mp_size_t abs_size = ABS(size); mp_srcptr u_end = u_ptr + abs_size; mp_size_t starting_limb = starting_bit / GMP_NUMB_BITS; mp_srcptr p = u_ptr + starting_limb; mp_limb_t limb; int cnt; /* Past the end there's no 1 bits for u>=0, or an immediate 1 bit for u<0. Notice this test picks up any u==0 too. */ if (starting_limb >= abs_size) return (size >= 0 ? ULONG_MAX : starting_bit); limb = *p; if (size >= 0) { /* Mask to 0 all bits before starting_bit, thus ignoring them. */ limb &= (MP_LIMB_T_MAX << (starting_bit % GMP_NUMB_BITS)); if (limb == 0) { /* If it's the high limb which is zero after masking, then there's no 1 bits after starting_bit. */ p++; if (p == u_end) return ULONG_MAX; /* Otherwise search further for a non-zero limb. The high limb is non-zero, if nothing else. */ for (;;) { limb = *p; if (limb != 0) break; p++; ASSERT (p < u_end); } } } else { mp_srcptr q; /* If there's a non-zero limb before ours then we're in the ones complement region. Search from *(p-1) downwards since that might give better cache locality, and since a non-zero in the middle of a number is perhaps a touch more likely than at the end. */ q = p; while (q != u_ptr) { q--; if (*q != 0) goto inverted; } if (limb == 0) { /* Skip zero limbs, to find the start of twos complement. The high limb is non-zero, if nothing else. This search is necessary so the -limb is applied at the right spot. */ do { p++; ASSERT (p < u_end); limb = *p; } while (limb == 0); /* Apply twos complement, and look for a 1 bit in that. Since limb!=0 here, also have (-limb)!=0 so there's certainly a 1 bit. */ limb = -limb; goto got_limb; } /* Adjust so ~limb implied by searching for 0 bit becomes -limb. */ limb--; inverted: /* Now seeking a 0 bit. */ /* Mask to 1 all bits before starting_bit, thus ignoring them. */ limb |= (CNST_LIMB(1) << (starting_bit % GMP_NUMB_BITS)) - 1; /* Search for a limb which is not all ones. If the end is reached then the zero immediately past the end is the result. */ while (limb == GMP_NUMB_MAX) { p++; if (p == u_end) return (mp_bitcnt_t)abs_size * GMP_NUMB_BITS; limb = *p; } /* Now seeking low 1 bit. */ limb = ~limb; } got_limb: ASSERT (limb != 0); count_trailing_zeros (cnt, limb); return (mp_bitcnt_t)((p - u_ptr) * GMP_NUMB_BITS + cnt); }
choke me #endif void mpq_set_d (mpq_ptr dest, double d) { int negative; mp_exp_t exp; mp_limb_t tp[LIMBS_PER_DOUBLE]; mp_ptr np, dp; mp_size_t nn, dn; int c; negative = d < 0; d = ABS (d); exp = __gmp_extract_double (tp, d); /* There are two main version of the conversion. The `then' arm handles things that have a fractional part, while the `else' part handles only integers. */ #if BITS_PER_MP_LIMB == 32 if (exp <= 1 || (exp == 2 && tp[0] != 0)) #else if (exp <= 1) #endif { if (d == 0.0) { SIZ(&(dest->_mp_num)) = 0; SIZ(&(dest->_mp_den)) = 1; PTR(&(dest->_mp_den))[0] = 1; return; } dn = -exp; if (dest->_mp_num._mp_alloc < 3) _mpz_realloc (&(dest->_mp_num), 3); np = PTR(&(dest->_mp_num)); #if BITS_PER_MP_LIMB == 32 if ((tp[0] | tp[1]) == 0) np[0] = tp[2], nn = 1; else if (tp[0] == 0) np[1] = tp[2], np[0] = tp[1], nn = 2; else np[2] = tp[2], np[1] = tp[1], np[0] = tp[0], nn = 3; #else if (tp[0] == 0) np[0] = tp[1], nn = 1; else np[1] = tp[1], np[0] = tp[0], nn = 2; #endif dn += nn + 1; if (dest->_mp_den._mp_alloc < dn) _mpz_realloc (&(dest->_mp_den), dn); dp = PTR(&(dest->_mp_den)); MPN_ZERO (dp, dn - 1); dp[dn - 1] = 1; count_trailing_zeros (c, np[0] | dp[0]); if (c != 0) { mpn_rshift (np, np, nn, c); nn -= np[nn - 1] == 0; mpn_rshift (dp, dp, dn, c); dn -= dp[dn - 1] == 0; } SIZ(&(dest->_mp_den)) = dn; SIZ(&(dest->_mp_num)) = negative ? -nn : nn; } else { nn = exp; if (dest->_mp_num._mp_alloc < nn) _mpz_realloc (&(dest->_mp_num), nn); np = PTR(&(dest->_mp_num)); #if BITS_PER_MP_LIMB == 32 switch (nn) { default: MPN_ZERO (np, nn - 3); np += nn - 3; /* fall through */ case 3: np[2] = tp[2], np[1] = tp[1], np[0] = tp[0]; break; case 2: np[1] = tp[2], np[0] = tp[1]; break; } #else switch (nn) { default: MPN_ZERO (np, nn - 2); np += nn - 2; /* fall through */ case 2: np[1] = tp[1], np[0] = tp[0]; break; } #endif dp = PTR(&(dest->_mp_den)); dp[0] = 1; SIZ(&(dest->_mp_den)) = 1; SIZ(&(dest->_mp_num)) = negative ? -nn : nn; } }
int mpz_congruent_ui_p (mpz_srcptr a, unsigned long cu, unsigned long du) { mp_srcptr ap; mp_size_t asize; mp_limb_t c, d, r; if (UNLIKELY (du == 0)) return (mpz_cmp_ui (a, cu) == 0); asize = SIZ(a); if (asize == 0) { if (cu < du) return cu == 0; else return (cu % du) == 0; } /* For nails don't try to be clever if c or d is bigger than a limb, just fake up some mpz_t's and go to the main mpz_congruent_p. */ if (du > GMP_NUMB_MAX || cu > GMP_NUMB_MAX) { mp_limb_t climbs[2], dlimbs[2]; mpz_t cz, dz; ALLOC(cz) = 2; PTR(cz) = climbs; ALLOC(dz) = 2; PTR(dz) = dlimbs; mpz_set_ui (cz, cu); mpz_set_ui (dz, du); return mpz_congruent_p (a, cz, dz); } /* NEG_MOD works on limbs, so convert ulong to limb */ c = cu; d = du; if (asize < 0) { asize = -asize; NEG_MOD (c, c, d); } ap = PTR (a); if (ABOVE_THRESHOLD (asize, BMOD_1_TO_MOD_1_THRESHOLD)) { r = mpn_mod_1 (ap, asize, d); if (c < d) return r == c; else return r == (c % d); } if ((d & 1) == 0) { /* Strip low zero bits to get odd d required by modexact. If d==e*2^n then a==c mod d if and only if both a==c mod 2^n and a==c mod e. */ unsigned twos; if ((ap[0]-c) & LOW_ZEROS_MASK (d)) return 0; count_trailing_zeros (twos, d); d >>= twos; }
choke me #endif void mpq_set_d (mpq_ptr dest, double d) { int negative; mp_exp_t exp; mp_limb_t tp[LIMBS_PER_DOUBLE]; mp_ptr np, dp; mp_size_t nn, dn; int c; DOUBLE_NAN_INF_ACTION (d, __gmp_invalid_operation (), __gmp_invalid_operation ()); negative = d < 0; d = ABS (d); exp = __gmp_extract_double (tp, d); /* There are two main version of the conversion. The `then' arm handles numbers with a fractional part, while the `else' arm handles integers. */ #if LIMBS_PER_DOUBLE == 4 if (exp <= 1 || (exp == 2 && (tp[0] | tp[1]) != 0)) #endif #if LIMBS_PER_DOUBLE == 3 if (exp <= 1 || (exp == 2 && tp[0] != 0)) #endif #if LIMBS_PER_DOUBLE == 2 if (exp <= 1) #endif { if (d == 0.0) { SIZ(NUM(dest)) = 0; SIZ(DEN(dest)) = 1; PTR(DEN(dest))[0] = 1; return; } #if LIMBS_PER_DOUBLE == 4 np = MPZ_NEWALLOC (NUM(dest), 4); if ((tp[0] | tp[1] | tp[2]) == 0) np[0] = tp[3], nn = 1; else if ((tp[0] | tp[1]) == 0) np[1] = tp[3], np[0] = tp[2], nn = 2; else if (tp[0] == 0) np[2] = tp[3], np[1] = tp[2], np[0] = tp[1], nn = 3; else np[3] = tp[3], np[2] = tp[2], np[1] = tp[1], np[0] = tp[0], nn = 4; #endif #if LIMBS_PER_DOUBLE == 3 np = MPZ_NEWALLOC (NUM(dest), 3); if ((tp[0] | tp[1]) == 0) np[0] = tp[2], nn = 1; else if (tp[0] == 0) np[1] = tp[2], np[0] = tp[1], nn = 2; else np[2] = tp[2], np[1] = tp[1], np[0] = tp[0], nn = 3; #endif #if LIMBS_PER_DOUBLE == 2 np = MPZ_NEWALLOC (NUM(dest), 2); if (tp[0] == 0) np[0] = tp[1], nn = 1; else np[1] = tp[1], np[0] = tp[0], nn = 2; #endif dn = nn + 1 - exp; ASSERT (dn > 0); /* -exp >= -1; nn >= 1*/ dp = MPZ_NEWALLOC (DEN(dest), dn); MPN_ZERO (dp, dn - 1); dp[dn - 1] = 1; count_trailing_zeros (c, np[0] | dp[0]); if (c != 0) { mpn_rshift (np, np, nn, c); nn -= np[nn - 1] == 0; --dn; dp[dn - 1] = CNST_LIMB(1) << (GMP_LIMB_BITS - c); } SIZ(DEN(dest)) = dn; } else { nn = exp; np = MPZ_NEWALLOC (NUM(dest), nn); switch (nn) { default: MPN_ZERO (np, nn - LIMBS_PER_DOUBLE); np += nn - LIMBS_PER_DOUBLE; /* fall through */ #if LIMBS_PER_DOUBLE == 2 case 2: np[1] = tp[1], np[0] = tp[0]; break; #endif #if LIMBS_PER_DOUBLE == 3 case 3: np[2] = tp[2], np[1] = tp[1], np[0] = tp[0]; break; case 2: np[1] = tp[2], np[0] = tp[1]; break; #endif #if LIMBS_PER_DOUBLE == 4 case 4: np[3] = tp[3], np[2] = tp[2], np[1] = tp[1], np[0] = tp[0]; break; case 3: np[2] = tp[3], np[1] = tp[2], np[0] = tp[1]; break; case 2: np[1] = tp[3], np[0] = tp[2]; break; #endif } *PTR(DEN(dest)) = 1; SIZ(DEN(dest)) = 1; } SIZ(NUM(dest)) = negative ? -nn : nn; }