Exemple #1
0
void
mpf_reldiff (mpf_t rdiff, mpf_srcptr x, mpf_srcptr y)
{
  if (UNLIKELY (SIZ(x) == 0))
    {
      mpf_set_ui (rdiff, (unsigned long int) (mpf_sgn (y) != 0));
    }
  else
    {
      mp_size_t dprec;
      mpf_t d;
      TMP_DECL;

      TMP_MARK;
      dprec = PREC(rdiff) + ABSIZ(x);
      ASSERT (PREC(rdiff)+1 == dprec - ABSIZ(x) + 1);

      PREC(d) = dprec;
      PTR(d) = TMP_ALLOC_LIMBS (dprec + 1);

      mpf_sub (d, x, y);
      SIZ(d) = ABSIZ(d);
      mpf_div (rdiff, d, x);

      TMP_FREE;
    }
}
Exemple #2
0
void
mpz_divexact (mpz_ptr quot, mpz_srcptr num, mpz_srcptr den)
{
  mp_ptr qp;
  mp_size_t qn;
  mp_srcptr np, dp;
  mp_size_t nn, dn;
  TMP_DECL;

#if WANT_ASSERT
  {
    mpz_t  rem;
    mpz_init (rem);
    mpz_tdiv_r (rem, num, den);
    ASSERT (SIZ(rem) == 0);
    mpz_clear (rem);
  }
#endif

  nn = ABSIZ (num);
  dn = ABSIZ (den);

  if (nn < dn)
    {
      /* This special case avoids segfaults below when the function is
	 incorrectly called with |N| < |D|, N != 0.  It also handles the
	 well-defined case N = 0.  */
      SIZ(quot) = 0;
      return;
    }

  qn = nn - dn + 1;

  TMP_MARK;

  if (quot == num || quot == den)
    qp = TMP_ALLOC_LIMBS (qn);
  else
    qp = MPZ_REALLOC (quot, qn);

  np = PTR(num);
  dp = PTR(den);

  mpn_divexact (qp, np, nn, dp, dn);
  MPN_NORMALIZE (qp, qn);

  if (qp != PTR(quot))
    MPN_COPY (MPZ_REALLOC (quot, qn), qp, qn);

  SIZ(quot) = (SIZ(num) ^ SIZ(den)) >= 0 ? qn : -qn;

  TMP_FREE;
}
Exemple #3
0
void
check_print (mpf_srcptr src, mpf_srcptr got, mpf_srcptr want)
{
  mp_trace_base = 16;
  mpf_trace ("src ", src);
  mpf_trace ("got ", got);
  mpf_trace ("want", want);

  printf ("got  size=%d exp=%ld\n", SIZ(got), EXP(got));
  mpn_trace ("     limbs=", PTR(got), (mp_size_t) ABSIZ(got));

  printf ("want size=%d exp=%ld\n", SIZ(want), EXP(want));
  mpn_trace ("     limbs=", PTR(want), (mp_size_t) ABSIZ(want));
}
Exemple #4
0
int
_mpq_cmp_si (mpq_srcptr q, long n, unsigned long d)
{
  /* need canonical sign to get right result */
  ASSERT (SIZ(DEN(q)) > 0);

  if (SIZ(NUM(q)) >= 0)
    {
      if (n >= 0)
        return _mpq_cmp_ui (q, n, d);            /* >=0 cmp >=0 */
      else
        return 1;                                /* >=0 cmp <0 */
    }
  else
    {
      if (n >= 0)
        return -1;                               /* <0 cmp >=0 */
      else
        {
          mpq_t  qabs;
          SIZ(NUM(qabs)) = ABSIZ(NUM(q));
          PTR(NUM(qabs)) = PTR(NUM(q));
          SIZ(DEN(qabs)) = SIZ(DEN(q));
          PTR(DEN(qabs)) = PTR(DEN(q));

          return - _mpq_cmp_ui (qabs, NEG_CAST (unsigned long, n), d);    /* <0 cmp <0 */
        }
    }
}
Exemple #5
0
size_t
mpz_sizeinbase (mpz_srcptr x, int base)
{
  size_t  result;
  MPN_SIZEINBASE (result, PTR(x), ABSIZ(x), base);
  return result;
}
Exemple #6
0
int
mpz_divisible_2exp_p (mpz_srcptr a, unsigned long d)
{
  unsigned long  i, dlimbs, dbits;
  mp_ptr         ap;
  mp_limb_t      dmask;
  mp_size_t      asize;

  asize = ABSIZ(a);
  dlimbs = d / GMP_NUMB_BITS;

  /* if d covers the whole of a, then only a==0 is divisible */
  if (asize <= dlimbs)
    return asize == 0;

  /* whole limbs must be zero */
  ap = PTR(a);
  for (i = 0; i < dlimbs; i++)
    if (ap[i] != 0)
      return 0;

  /* left over bits must be zero */
  dbits = d % GMP_NUMB_BITS;
  dmask = (CNST_LIMB(1) << dbits) - 1;
  return (ap[dlimbs] & dmask) == 0;
}
Exemple #7
0
void
mpz_realloc2 (mpz_ptr m, mp_bitcnt_t bits)
{
  mp_size_t new_alloc;

  bits -= (bits != 0);		/* Round down, except if 0 */
  new_alloc = 1 + bits / GMP_NUMB_BITS;

  if (sizeof (unsigned long) > sizeof (int)) /* param vs _mp_size field */
    {
      if (UNLIKELY (new_alloc > INT_MAX))
	{
	  fprintf (stderr, "gmp: overflow in mpz type\n");
	  abort ();
	}
    }

  PTR(m) = __GMP_REALLOCATE_FUNC_LIMBS (PTR(m), ALLOC(m), new_alloc);
  ALLOC(m) = new_alloc;

  /* Don't create an invalid number; if the current value doesn't fit after
     reallocation, clear it to 0.  */
  if (ABSIZ(m) > new_alloc)
    SIZ(m) = 0;
}
Exemple #8
0
/* Convert an mpz_t to an mpfr_exp_t, restricted to
   the interval [MPFR_EXP_MIN,MPFR_EXP_MAX]. */
mpfr_exp_t
mpfr_ubf_zexp2exp (mpz_ptr ez)
{
  mp_size_t n;
  mpfr_eexp_t e;
  mpfr_t d;
  int inex;
  MPFR_SAVE_EXPO_DECL (expo);

  n = ABSIZ (ez); /* limb size of ez */
  if (n == 0)
    return 0;

  MPFR_SAVE_EXPO_MARK (expo);
  mpfr_init2 (d, n * GMP_NUMB_BITS);
  MPFR_DBGRES (inex = mpfr_set_z (d, ez, MPFR_RNDN));
  MPFR_ASSERTD (inex == 0);
  e = mpfr_get_exp_t (d, MPFR_RNDZ);
  mpfr_clear (d);
  MPFR_SAVE_EXPO_FREE (expo);
  if (MPFR_UNLIKELY (e < MPFR_EXP_MIN))
    return MPFR_EXP_MIN;
  if (MPFR_UNLIKELY (e > MPFR_EXP_MAX))
    return MPFR_EXP_MAX;
  return e;
}
Exemple #9
0
void
mpz_combit (mpz_ptr d, unsigned long int bit_index)
{
  mp_size_t dsize = ABSIZ(d);
  mp_ptr dp = LIMBS(d);
  
  mp_size_t limb_index = bit_index / GMP_NUMB_BITS;
  mp_limb_t bit = ((mp_limb_t) 1 << (bit_index % GMP_NUMB_BITS));

  if (limb_index >= dsize)
    {
      MPZ_REALLOC(d, limb_index + 1);
      dp = LIMBS(d);
      
      MPN_ZERO(dp + dsize, limb_index + 1 - dsize);
      dsize = limb_index + 1;
    }
    
  if (SIZ(d) >= 0)
    {
      dp[limb_index] ^= bit;
      MPN_NORMALIZE (dp, dsize);
      SIZ(d) = dsize;
    }
  else
    {
      mp_limb_t x = -dp[limb_index];
      mp_size_t i;

      /* non-zero limb below us means ones-complement */
      for (i = limb_index-1; i >= 0; i--)
        if (dp[i] != 0)
          {
            x--;  /* change twos comp to ones comp */
            break;
          }

      if (x & bit)
	{
          mp_limb_t  c;

	  /* Clearing the bit increases the magitude. We might need a carry. */
	  MPZ_REALLOC(d, dsize + 1);
	  dp = LIMBS(d);

          __GMPN_ADD_1 (c, dp+limb_index, dp+limb_index,
                        dsize - limb_index, bit);
          dp[dsize] = c;
          dsize += c;
        }
      else
	/* Setting the bit decreases the magnitude */
	mpn_sub_1(dp+limb_index, dp+limb_index, dsize + limb_index, bit);

      MPN_NORMALIZE (dp, dsize);
      SIZ(d) = -dsize;
    }
}
Exemple #10
0
int
mpz_cmpabs (mpz_srcptr u, mpz_srcptr v)
{
  mp_size_t  usize, vsize, dsize;
  mp_srcptr  up, vp;
  int        cmp;

  usize = ABSIZ (u);
  vsize = ABSIZ (v);
  dsize = usize - vsize;
  if (dsize != 0)
    return dsize;

  up = PTR(u);
  vp = PTR(v);
  MPN_CMP (cmp, up, vp, usize);
  return cmp;
}
Exemple #11
0
int
mpz_invert (mpz_ptr inverse, mpz_srcptr x, mpz_srcptr n)
{
  mpz_t gcd, tmp;
  mp_size_t xsize, nsize, size;
  TMP_DECL;

  xsize = ABSIZ (x);
  nsize = ABSIZ (n);

  /* No inverse exists if the leftside operand is 0.  Likewise, no
     inverse exists if the mod operand is 1.  */
  if (xsize == 0 || (nsize == 1 && (PTR (n))[0] == 1))
    return 0;

  size = MAX (xsize, nsize) + 1;
  TMP_MARK;

  MPZ_TMP_INIT (gcd, size);
  MPZ_TMP_INIT (tmp, size);
  mpz_gcdext (gcd, tmp, (mpz_ptr) 0, x, n);

  /* If no inverse existed, return with an indication of that.  */
  if (!MPZ_EQUAL_1_P (gcd))
    {
      TMP_FREE;
      return 0;
    }

  /* Make sure we return a positive inverse.  */
  if (SIZ (tmp) < 0)
    {
      if (SIZ (n) < 0)
	mpz_sub (inverse, tmp, n);
      else
	mpz_add (inverse, tmp, n);
    }
  else
    mpz_set (inverse, tmp);

  TMP_FREE;
  return 1;
}
Exemple #12
0
void
dump_abort (int i, char *s,
            mpz_t op1, mpz_t op2, mpz_t product, mpz_t ref_product)
{
  mp_size_t b, e;
  fprintf (stderr, "ERROR: %s in test %d\n", s, i);
  fprintf (stderr, "op1          = "); debug_mp (op1);
  fprintf (stderr, "op2          = "); debug_mp (op2);
  fprintf (stderr, "    product  = "); debug_mp (product);
  fprintf (stderr, "ref_product  = "); debug_mp (ref_product);
  for (b = 0; b < ABSIZ(ref_product); b++)
    if (PTR(ref_product)[b] != PTR(product)[b])
      break;
  for (e = ABSIZ(ref_product) - 1; e >= 0; e--)
    if (PTR(ref_product)[e] != PTR(product)[e])
      break;
  printf ("ERRORS in %ld--%ld\n", b, e);
  abort();
}
Exemple #13
0
void
hexdump (mpf_t x)
{
  mp_size_t i;
  for (i = ABSIZ(x) - 1; i >= 0; i--)
    {
      gmp_printf ("%0*MX", SZ, PTR(x)[i]);
      if (i != 0)
	printf (" ");
    }
}
Exemple #14
0
/* this function is useful in debug mode to print non-normalized residues */
static void
mpresn_print (mpres_t x, mpmod_t n)
{
  mp_size_t m, xn;

  xn = SIZ(x);
  m = ABSIZ(x);
  MPN_NORMALIZE(PTR(x), m);
  SIZ(x) = xn >= 0 ? m : -m;
  gmp_printf ("%Zd\n", x);
  SIZ(x) = xn;
}
Exemple #15
0
void
check_one (mpf_ptr got, mpq_srcptr q)
{
  mpf_t  n, d;

  mpf_set_q (got, q);

  PTR(n) = PTR(&q->_mp_num);
  SIZ(n) = SIZ(&q->_mp_num);
  EXP(n) = ABSIZ(&q->_mp_num);

  PTR(d) = PTR(&q->_mp_den);
  SIZ(d) = SIZ(&q->_mp_den);
  EXP(d) = ABSIZ(&q->_mp_den);

  if (! refmpf_validate_division ("mpf_set_q", got, n, d))
    {
      mp_trace_base = -16;
      mpq_trace ("   q", q);
      abort ();
    }
}
Exemple #16
0
unsigned long
refmpz_scan (mpz_srcptr z, unsigned long i, int sought)
{
  unsigned long  z_bits = (unsigned long) ABSIZ(z) * GMP_NUMB_BITS;

  do
    {
      if (mpz_tstbit (z, i) == sought)
        return i;
      i++;
    }
  while (i <= z_bits);

  return ULONG_MAX;
}
Exemple #17
0
void
check_one (mpf_srcptr src, mpf_srcptr trunc, mpf_srcptr ceil, mpf_srcptr floor)
{
  mpf_t  got;

  mpf_init2 (got, mpf_get_prec (trunc));
  ASSERT_ALWAYS (PREC(got) == PREC(trunc));
  ASSERT_ALWAYS (PREC(got) == PREC(ceil));
  ASSERT_ALWAYS (PREC(got) == PREC(floor));

#define CHECK_SEP(name, fun, want)              \
  mpf_set_ui (got, 54321L); /* initial junk */  \
  fun (got, src);                               \
  MPF_CHECK_FORMAT (got);                       \
  if (mpf_cmp (got, want) != 0)                 \
    {                                           \
	printf ("%s wrong\n", name);            \
	check_print (src, got, want);           \
	abort ();                               \
    }

  CHECK_SEP ("mpf_trunc", mpf_trunc, trunc);
  CHECK_SEP ("mpf_ceil",  mpf_ceil,  ceil);
  CHECK_SEP ("mpf_floor", mpf_floor, floor);

#define CHECK_INPLACE(name, fun, want)  \
  mpf_set (got, src);                   \
  fun (got, got);                       \
  MPF_CHECK_FORMAT (got);               \
  if (mpf_cmp (got, want) != 0)         \
    {                                   \
	printf ("%s wrong\n", name);    \
	check_print (src, got, want);   \
	abort ();                       \
    }

  CHECK_INPLACE ("mpf_trunc", mpf_trunc, trunc);

  /* Can't do these unconditionally in case truncation by mpf_set strips
     some low non-zero limbs which would have rounded the result.  */
  if (ABSIZ(src) <= PREC(trunc)+1)
    {
      CHECK_INPLACE ("mpf_ceil",  mpf_ceil,  ceil);
      CHECK_INPLACE ("mpf_floor", mpf_floor, floor);
    }

  mpf_clear (got);
}
/* this function is useful in debug mode to print residues */
static void
mpres_print (mpres_t x, char* name, mpmod_t n)
{
  mp_size_t m, xn;
  mpres_t t;
  mpres_init(t, n);
  mpz_set_ui(t, 1);
  mpres_mul (t, x, t, n);

  xn = SIZ(t);
  m = ABSIZ(t);
  MPN_NORMALIZE(PTR(t), m);
  SIZ(t) = xn >= 0 ? m : -m;
  gmp_printf ("%s=%Zd\n", name, t);
  SIZ(t) = xn;
  mpres_clear (t, n);
}
void
mpz_tdiv_r_2exp (mpz_ptr res, mpz_srcptr in, mp_bitcnt_t cnt)
{
  mp_size_t in_size = ABSIZ (in);
  mp_size_t res_size;
  mp_size_t limb_cnt = cnt / GMP_NUMB_BITS;
  mp_srcptr in_ptr = PTR (in);

  if (in_size > limb_cnt)
    {
      /* The input operand is (probably) greater than 2**CNT.  */
      mp_limb_t x;

      x = in_ptr[limb_cnt] & (((mp_limb_t) 1 << cnt % GMP_NUMB_BITS) - 1);
      if (x != 0)
	{
	  res_size = limb_cnt + 1;
	  MPZ_REALLOC (res, res_size);

	  PTR (res)[limb_cnt] = x;
	}
      else
	{
	  res_size = limb_cnt;
	  MPN_NORMALIZE (in_ptr, res_size);

	  MPZ_REALLOC (res, res_size);

	  limb_cnt = res_size;
	}
    }
  else
    {
      /* The input operand is smaller than 2**CNT.  We perform a no-op,
	 apart from that we might need to copy IN to RES.  */
      res_size = in_size;
      MPZ_REALLOC (res, res_size);

      limb_cnt = res_size;
    }

  if (res != in)
    MPN_COPY (PTR (res), PTR (in), limb_cnt);
  SIZ (res) = SIZ (in) >= 0 ? res_size : -res_size;
}
Exemple #20
0
void *
_mpz_realloc (mpz_ptr m, mp_size_t new_alloc)
{
  mp_ptr mp;

  /* Never allocate zero space. */
  new_alloc = MAX (new_alloc, 1);

  mp = __GMP_REALLOCATE_FUNC_LIMBS (PTR(m), ALLOC(m), new_alloc);
  PTR(m) = mp;
  ALLOC(m) = new_alloc;

  /* Don't create an invalid number; if the current value doesn't fit after
     reallocation, clear it to 0.  */
  if (ABSIZ(m) > new_alloc)
    SIZ(m) = 0;

  return (void *) mp;
}
Exemple #21
0
void
mpq_abs (mpq_ptr dst, mpq_srcptr src)
{
  mp_size_t  num_abs_size = ABSIZ(NUM(src));

  if (dst != src)
    {
      mp_size_t  den_size = SIZ(DEN(src));
      mp_ptr dp;

      dp = MPZ_NEWALLOC (NUM(dst), num_abs_size);
      MPN_COPY (dp, PTR(NUM(src)), num_abs_size);

      dp = MPZ_NEWALLOC (DEN(dst), den_size);
      SIZ(DEN(dst)) = den_size;
      MPN_COPY (dp, PTR(DEN(src)), den_size);
    }

  SIZ(NUM(dst)) = num_abs_size;
}
Exemple #22
0
void
gmp_randinit_lc (gmp_randstate_t rstate,
		 mpz_srcptr a,
		 unsigned long int c,
		 mpz_srcptr m)
{
  /* FIXME: Not finished.  We don't handle this in _gmp_rand() yet. */
  abort ();

  mpz_init_set_ui (rstate->_mp_seed, 1);
  _mpz_realloc (rstate->_mp_seed, ABSIZ (m));

  /* Allocate algorithm specific data. */
  rstate->_mp_algdata._mp_lc = (__gmp_randata_lc *)
    (*__gmp_allocate_func) (sizeof (__gmp_randata_lc));

  mpz_init_set (rstate->_mp_algdata._mp_lc->_mp_a, a);
  rstate->_mp_algdata._mp_lc->_mp_c = c;
  mpz_init_set (rstate->_mp_algdata._mp_lc->_mp_m, m);

  rstate->_mp_alg = GMP_RAND_ALG_LC;
}
Exemple #23
0
void *
_mpz_realloc (mpz_ptr m, mp_size_t new_alloc)
{
  mp_ptr mp;

  /* Never allocate zero space. */
  new_alloc = MAX (new_alloc, 1);

  if (sizeof (mp_size_t) == sizeof (int))
    {
      if (UNLIKELY (new_alloc > ULONG_MAX / GMP_NUMB_BITS))
	{
	  fprintf (stderr, "gmp: overflow in mpz type\n");
	  abort ();
	}
    }
  else
    {
      if (UNLIKELY (new_alloc > INT_MAX))
	{
	  fprintf (stderr, "gmp: overflow in mpz type\n");
	  abort ();
	}
    }

  mp = __GMP_REALLOCATE_FUNC_LIMBS (PTR(m), ALLOC(m), new_alloc);
  PTR(m) = mp;
  ALLOC(m) = (int) new_alloc; // (int) added by PM

  /* Don't create an invalid number; if the current value doesn't fit after
     reallocation, clear it to 0.  */
  if (ABSIZ(m) > new_alloc)
    SIZ(m) = 0;

  return (void *) mp;
}
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 */
Exemple #25
0
int
mpz_congruent_2exp_p (mpz_srcptr a, mpz_srcptr c, mp_bitcnt_t d)
{
  mp_size_t      i, dlimbs;
  unsigned       dbits;
  mp_ptr         ap, cp;
  mp_limb_t      dmask, alimb, climb, sum;
  mp_size_t      asize_signed, csize_signed, asize, csize;

  if (ABSIZ(a) < ABSIZ(c))
    MPZ_SRCPTR_SWAP (a, c);

  dlimbs = d / GMP_NUMB_BITS;
  dbits = d % GMP_NUMB_BITS;
  dmask = (CNST_LIMB(1) << dbits) - 1;

  ap = PTR(a);
  cp = PTR(c);

  asize_signed = SIZ(a);
  asize = ABS(asize_signed);

  csize_signed = SIZ(c);
  csize = ABS(csize_signed);

  if (csize_signed == 0)
    goto a_zeros;

  if ((asize_signed ^ csize_signed) >= 0)
    {
      /* same signs, direct comparison */

      /* a==c for limbs in common */
      if (mpn_cmp (ap, cp, MIN (csize, dlimbs)) != 0)
        return 0;

      /* if that's all of dlimbs, then a==c for remaining bits */
      if (csize > dlimbs)
        return ((ap[dlimbs]-cp[dlimbs]) & dmask) == 0;

    a_zeros:
      /* a remains, need all zero bits */

      /* if d covers all of a and c, then must be exactly equal */
      if (asize <= dlimbs)
        return asize == csize;

      /* whole limbs zero */
      for (i = csize; i < dlimbs; i++)
        if (ap[i] != 0)
          return 0;

      /* partial limb zero */
      return (ap[dlimbs] & dmask) == 0;
    }
  else
    {
      /* different signs, negated comparison */

      /* common low zero limbs, stopping at first non-zeros, which must
         match twos complement */
      i = 0;
      for (;;)
        {
          ASSERT (i < csize);  /* always have a non-zero limb on c */
          alimb = ap[i];
          climb = cp[i];
          sum = (alimb + climb) & GMP_NUMB_MASK;

          if (i >= dlimbs)
            return (sum & dmask) == 0;
          i++;

          /* require both zero, or first non-zeros as twos-complements */
          if (sum != 0)
            return 0;

          if (alimb != 0)
            break;
        }

      /* further limbs matching as ones-complement */
      for (;;)
        {
          if (i >= csize)
            break;

          alimb = ap[i];
          climb = cp[i];
          sum = (alimb + climb + 1) & GMP_NUMB_MASK;

          if (i >= dlimbs)
            return (sum & dmask) == 0;

          if (sum != 0)
            return 0;

          i++;
        }

      /* no more c, so require all 1 bits in a */

      if (asize < dlimbs)
        return 0;   /* not enough a */

      /* whole limbs */
      for ( ; i < dlimbs; i++)
        if (ap[i] != GMP_NUMB_MAX)
          return 0;

      /* if only whole limbs, no further fetches from a */
      if (dbits == 0)
        return 1;

      /* need enough a */
      if (asize == dlimbs)
        return 0;

      return ((ap[dlimbs]+1) & dmask) == 0;
    }
}
void
check_z (void)
{
  static const struct {
    const char  *fmt;
    const char  *z;
    const char  *want;
  } data[] = {
    { "%Zd", "0",    "0" },
    { "%Zd", "1",    "1" },
    { "%Zd", "123",  "123" },
    { "%Zd", "-1",   "-1" },
    { "%Zd", "-123", "-123" },

    { "%+Zd", "0",      "+0" },
    { "%+Zd", "123",  "+123" },
    { "%+Zd", "-123", "-123" },

    { "%Zx",  "123",   "7b" },
    { "%ZX",  "123",   "7B" },
    { "%Zx", "-123",  "-7b" },
    { "%ZX", "-123",  "-7B" },
    { "%Zo",  "123",  "173" },
    { "%Zo", "-123", "-173" },

    { "%#Zx",    "0",     "0" },
    { "%#ZX",    "0",     "0" },
    { "%#Zx",  "123",  "0x7b" },
    { "%#ZX",  "123",  "0X7B" },
    { "%#Zx", "-123", "-0x7b" },
    { "%#ZX", "-123", "-0X7B" },

    { "%#Zo",    "0",     "0" },
    { "%#Zo",  "123",  "0173" },
    { "%#Zo", "-123", "-0173" },

    { "%10Zd",      "0", "         0" },
    { "%10Zd",    "123", "       123" },
    { "%10Zd",   "-123", "      -123" },

    { "%-10Zd",     "0", "0         " },
    { "%-10Zd",   "123", "123       " },
    { "%-10Zd",  "-123", "-123      " },

    { "%+10Zd",   "123", "      +123" },
    { "%+-10Zd",  "123", "+123      " },
    { "%+10Zd",  "-123", "      -123" },
    { "%+-10Zd", "-123", "-123      " },

    { "%08Zd",    "0", "00000000" },
    { "%08Zd",  "123", "00000123" },
    { "%08Zd", "-123", "-0000123" },

    { "%+08Zd",    "0", "+0000000" },
    { "%+08Zd",  "123", "+0000123" },
    { "%+08Zd", "-123", "-0000123" },

    { "%#08Zx",    "0", "00000000" },
    { "%#08Zx",  "123", "0x00007b" },
    { "%#08Zx", "-123", "-0x0007b" },

    { "%+#08Zx",    "0", "+0000000" },
    { "%+#08Zx",  "123", "+0x0007b" },
    { "%+#08Zx", "-123", "-0x0007b" },

    { "%.0Zd", "0", "" },
    { "%.1Zd", "0", "0" },
    { "%.2Zd", "0", "00" },
    { "%.3Zd", "0", "000" },
  };

  int        i, j;
  mpz_t      z;
  char       *nfmt;
  mp_size_t  nsize, zeros;

  mpz_init (z);

  for (i = 0; i < numberof (data); i++)
    {
      mpz_set_str_or_abort (z, data[i].z, 0);

      /* don't try negatives or forced sign in hex or octal */
      if (mpz_fits_slong_p (z)
	  && ! (hex_or_octal_p (data[i].fmt)
		&& (strchr (data[i].fmt, '+') != NULL || mpz_sgn(z) < 0)))
	{
	  check_plain (data[i].want, data[i].fmt, mpz_get_si (z));
	}

      check_one (data[i].want, data[i].fmt, z);

      /* Same again, with %N and possibly some high zero limbs */
      nfmt = __gmp_allocate_strdup (data[i].fmt);
      for (j = 0; nfmt[j] != '\0'; j++)
	if (nfmt[j] == 'Z')
	  nfmt[j] = 'N';
      for (zeros = 0; zeros <= 3; zeros++)
	{
	  nsize = ABSIZ(z)+zeros;
	  MPZ_REALLOC (z, nsize);
	  nsize = (SIZ(z) >= 0 ? nsize : -nsize);
	  refmpn_zero (PTR(z)+ABSIZ(z), zeros);
	  check_one (data[i].want, nfmt, PTR(z), nsize);
	}
      __gmp_free_func (nfmt, strlen(nfmt)+1);
    }

  mpz_clear (z);
}
Exemple #27
0
void
mpz_powm_sec (mpz_ptr r, mpz_srcptr b, mpz_srcptr e, mpz_srcptr m)
{
  mp_size_t n;
  mp_ptr rp, tp;
  mp_srcptr bp, ep, mp;
  mp_size_t rn, bn, es, en;
  TMP_DECL;

  n = ABSIZ(m);

  mp = PTR(m);

  if (UNLIKELY ((n == 0) || (mp[0] % 2 == 0)))
    DIVIDE_BY_ZERO;

  es = SIZ(e);
  if (UNLIKELY (es <= 0))
    {
      if (es == 0)
	{
	  /* b^0 mod m,  b is anything and m is non-zero.
	     Result is 1 mod m, i.e., 1 or 0 depending on if m = 1.  */
	  SIZ(r) = n != 1 || mp[0] != 1;
	  PTR(r)[0] = 1;
	  return;
	}
      DIVIDE_BY_ZERO;
    }
  en = es;

  bn = ABSIZ(b);

  if (UNLIKELY (bn == 0))
    {
      SIZ(r) = 0;
      return;
    }

  TMP_MARK;
  tp = TMP_ALLOC_LIMBS (n + mpn_sec_powm_itch (bn, en * GMP_NUMB_BITS, n));

  rp = tp;  tp += n;

  bp = PTR(b);
  ep = PTR(e);

  mpn_sec_powm (rp, bp, bn, ep, en * GMP_NUMB_BITS, mp, n, tp);

  rn = n;

  MPN_NORMALIZE (rp, rn);

  if ((ep[0] & 1) && SIZ(b) < 0 && rn != 0)
    {
      mpn_sub (rp, PTR(m), n, rp, rn);
      rn = n;
      MPN_NORMALIZE (rp, rn);
    }

  MPZ_REALLOC (r, rn);
  SIZ(r) = rn;
  MPN_COPY (PTR(r), rp, rn);

  TMP_FREE;
}
Exemple #28
0
void
mpz_urandomm (mpz_ptr rop, gmp_randstate_t rstate, mpz_srcptr n)
{
  mp_ptr rp, np, nlast;
  mp_size_t nbits, size;
  int count;
  int pow2;
  int cmp;
  TMP_DECL;

  size = ABSIZ (n);
  if (size == 0)
    DIVIDE_BY_ZERO;

  nlast = &PTR (n)[size - 1];

  /* Detect whether n is a power of 2.  */
  pow2 = POW2_P (*nlast);
  if (pow2 != 0)
    for (np = PTR (n); np < nlast; np++)
      if (*np != 0)
	{
	  pow2 = 0;		/* Mark n as `not a power of two'.  */
	  break;
	}

  count_leading_zeros (count, *nlast);
  nbits = size * GMP_NUMB_BITS - (count - GMP_NAIL_BITS) - pow2;
  if (nbits == 0)		/* nbits == 0 means that n was == 1.  */
    {
      SIZ (rop) = 0;
      return;
    }

  TMP_MARK;
  np = PTR (n);
  if (rop == n)
    {
      mp_ptr tp;
      tp = TMP_ALLOC_LIMBS (size);
      MPN_COPY (tp, np, size);
      np = tp;
    }

  /* Here the allocated size can be one too much if n is a power of
     (2^GMP_NUMB_BITS) but it's convenient for using mpn_cmp below.  */
  rp = MPZ_REALLOC (rop, size);
  /* Clear last limb to prevent the case in which size is one too much.  */
  rp[size - 1] = 0;

  count = MAX_URANDOMM_ITER;	/* Set iteration count limit.  */
  do
    {
      _gmp_rand (rp, rstate, nbits);
      MPN_CMP (cmp, rp, np, size);
    }
  while (cmp >= 0 && --count != 0);

  if (count == 0)
    /* Too many iterations; return result mod n == result - n */
    mpn_sub_n (rp, rp, np, size);

  MPN_NORMALIZE (rp, size);
  SIZ (rop) = size;
  TMP_FREE;
}
Exemple #29
0
void
mpz_powm_ui (mpz_ptr r, mpz_srcptr b, unsigned long int el, mpz_srcptr m)
{
  mp_ptr xp, tp, qp, mp, bp;
  mp_size_t xn, tn, mn, bn;
  int m_zero_cnt;
  int c;
  mp_limb_t e;
  TMP_DECL;

  mp = PTR(m);
  mn = ABSIZ(m);
  if (mn == 0)
    DIVIDE_BY_ZERO;

  if (el == 0)
    {
      /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0
	 depending on if MOD equals 1.  */
      SIZ(r) = (mn == 1 && mp[0] == 1) ? 0 : 1;
      PTR(r)[0] = 1;
      return;
    }

  TMP_MARK;

  /* Normalize m (i.e. make its most significant bit set) as required by
     division functions below.  */
  count_leading_zeros (m_zero_cnt, mp[mn - 1]);
  m_zero_cnt -= GMP_NAIL_BITS;
  if (m_zero_cnt != 0)
    {
      mp_ptr new_mp = TMP_ALLOC_LIMBS (mn);
      mpn_lshift (new_mp, mp, mn, m_zero_cnt);
      mp = new_mp;
    }

  bn = ABSIZ(b);
  bp = PTR(b);
  if (bn > mn)
    {
      /* Reduce possibly huge base.  Use a function call to reduce, since we
	 don't want the quotient allocation to live until function return.  */
      mp_ptr new_bp = TMP_ALLOC_LIMBS (mn);
      reduce (new_bp, bp, bn, mp, mn);
      bp = new_bp;
      bn = mn;
      /* Canonicalize the base, since we are potentially going to multiply with
	 it quite a few times.  */
      MPN_NORMALIZE (bp, bn);
    }

  if (bn == 0)
    {
      SIZ(r) = 0;
      TMP_FREE;
      return;
    }

  tp = TMP_ALLOC_LIMBS (2 * mn + 1);
  xp = TMP_ALLOC_LIMBS (mn);

  qp = TMP_ALLOC_LIMBS (mn + 1);

  MPN_COPY (xp, bp, bn);
  xn = bn;

  e = el;
  count_leading_zeros (c, e);
  e = (e << c) << 1;		/* shift the exp bits to the left, lose msb */
  c = BITS_PER_MP_LIMB - 1 - c;

  /* Main loop. */

  /* If m is already normalized (high bit of high limb set), and b is the
     same size, but a bigger value, and e==1, then there's no modular
     reductions done and we can end up with a result out of range at the
     end. */
  if (c == 0)
    {
      if (xn == mn && mpn_cmp (xp, mp, mn) >= 0)
        mpn_sub_n (xp, xp, mp, mn);
      goto finishup;
    }

  while (c != 0)
    {
      mpn_sqr_n (tp, xp, xn);
      tn = 2 * xn; tn -= tp[tn - 1] == 0;
      if (tn < mn)
	{
	  MPN_COPY (xp, tp, tn);
	  xn = tn;
	}
      else
	{
	  mpn_tdiv_qr (qp, xp, 0L, tp, tn, mp, mn);
	  xn = mn;
	}

      if ((mp_limb_signed_t) e < 0)
	{
	  mpn_mul (tp, xp, xn, bp, bn);
	  tn = xn + bn; tn -= tp[tn - 1] == 0;
	  if (tn < mn)
	    {
	      MPN_COPY (xp, tp, tn);
	      xn = tn;
	    }
	  else
	    {
	      mpn_tdiv_qr (qp, xp, 0L, tp, tn, mp, mn);
	      xn = mn;
	    }
	}
      e <<= 1;
      c--;
    }

 finishup:
  /* We shifted m left m_zero_cnt steps.  Adjust the result by reducing
     it with the original MOD.  */
  if (m_zero_cnt != 0)
    {
      mp_limb_t cy;
      cy = mpn_lshift (tp, xp, xn, m_zero_cnt);
      tp[xn] = cy; xn += cy != 0;

      if (xn < mn)
	{
	  MPN_COPY (xp, tp, xn);
	}
      else
	{
	  mpn_tdiv_qr (qp, xp, 0L, tp, xn, mp, mn);
	  xn = mn;
	}
      mpn_rshift (xp, xp, xn, m_zero_cnt);
    }
  MPN_NORMALIZE (xp, xn);

  if ((el & 1) != 0 && SIZ(b) < 0 && xn != 0)
    {
      mp = PTR(m);			/* want original, unnormalized m */
      mpn_sub (xp, mp, mn, xp, xn);
      xn = mn;
      MPN_NORMALIZE (xp, xn);
    }
  MPZ_REALLOC (r, xn);
  SIZ (r) = xn;
  MPN_COPY (PTR(r), xp, xn);

  TMP_FREE;
}
Exemple #30
0
void
mpz_gcdext (mpz_ptr g, mpz_ptr s, mpz_ptr t, mpz_srcptr a, mpz_srcptr b)
{
  mp_size_t asize, bsize;
  mp_ptr tmp_ap, tmp_bp;
  mp_size_t gsize, ssize, tmp_ssize;
  mp_ptr gp, tmp_gp, tmp_sp;
  TMP_DECL;

  /* mpn_gcdext requires that Usize >= Vsize.  Therefore, we often
     have to swap U and V.  The computed cofactor will be the
     "smallest" one, which is faster to produce.  The wanted one will
     be computed here; this is needed anyway when both are requested.  */

  asize = ABSIZ (a);
  bsize = ABSIZ (b);

  if (asize < bsize)
    {
      MPZ_SRCPTR_SWAP (a, b);
      MP_SIZE_T_SWAP (asize, bsize);
      MPZ_PTR_SWAP (s, t);
    }

  if (bsize == 0)
    {
      /* g = |a|, s = sgn(a), t = 0. */
      ssize = SIZ (a) >= 0 ? (asize != 0) : -1;

      gp = MPZ_REALLOC (g, asize);
      MPN_COPY (gp, PTR (a), asize);
      SIZ (g) = asize;

      if (t != NULL)
	SIZ (t) = 0;
      if (s != NULL)
	{
	  SIZ (s) = ssize;
	  PTR (s)[0] = 1;
	}
      return;
    }

  TMP_MARK;

  TMP_ALLOC_LIMBS_2 (tmp_ap, asize, tmp_bp, bsize);
  MPN_COPY (tmp_ap, PTR (a), asize);
  MPN_COPY (tmp_bp, PTR (b), bsize);

  TMP_ALLOC_LIMBS_2 (tmp_gp, bsize, tmp_sp, bsize + 1);

  gsize = mpn_gcdext (tmp_gp, tmp_sp, &tmp_ssize, tmp_ap, asize, tmp_bp, bsize);

  ssize = ABS (tmp_ssize);
  tmp_ssize = SIZ (a) >= 0 ? tmp_ssize : -tmp_ssize;

  if (t != NULL)
    {
      mpz_t x;
      __mpz_struct gtmp, stmp;

      PTR (&gtmp) = tmp_gp;
      SIZ (&gtmp) = gsize;

      PTR (&stmp) = tmp_sp;
      SIZ (&stmp) = tmp_ssize;

      MPZ_TMP_INIT (x, ssize + asize + 1);
      mpz_mul (x, &stmp, a);
      mpz_sub (x, &gtmp, x);
      mpz_divexact (t, x, b);
    }

  if (s != NULL)
    {
      mp_ptr sp;

      sp = MPZ_REALLOC (s, ssize);
      MPN_COPY (sp, tmp_sp, ssize);
      SIZ (s) = tmp_ssize;
    }

  gp = MPZ_REALLOC (g, gsize);
  MPN_COPY (gp, tmp_gp, gsize);
  SIZ (g) = gsize;

  TMP_FREE;
}