Esempio n. 1
0
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.  */
	{
Esempio n. 2
0
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;
    }
Esempio n. 3
0
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;
}
Esempio n. 4
0
 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;
 }
Esempio n. 5
0
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;
    }
Esempio n. 6
0
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;
    }
Esempio n. 7
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);
}
Esempio n. 8
0
File: ctzsi2.c Progetto: knz/slcore
int
__ctzsi2 (unsigned int x)
{
  int ret;

  count_trailing_zeros (ret, x);

  return ret;
}
Esempio n. 9
0
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);
	}
    }
Esempio n. 10
0
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;
        }
Esempio n. 11
0
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;
    }
Esempio n. 12
0
File: pow.c Progetto: mahdiz/mpclib
/* 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;
}
Esempio n. 13
0
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);
    }
Esempio n. 14
0
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;
}
Esempio n. 15
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);
    }
Esempio n. 16
0
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);
    }
Esempio n. 17
0
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;
}
Esempio n. 18
0
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;
    }
Esempio n. 19
0
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;
}
Esempio n. 20
0
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;
}
Esempio n. 21
0
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;
    }
}
Esempio n. 22
0
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 */
Esempio n. 24
0
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);
}
Esempio n. 25
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;
    }
Esempio n. 26
0
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;
	}
Esempio n. 27
0
File: scan1.c Progetto: gnooth/xcl
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);
}
Esempio n. 28
0
  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;
    }
}
Esempio n. 29
0
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;
    }
Esempio n. 30
0
  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;
}