示例#1
0
文件: pmpq.c 项目: mk8/pgmp
/*
 * Initialize a mpq from the content of a datum
 *
 * NOTE: the function takes a pointer to a const and changes the structure.
 * This allows to define the structure as const in the calling function and
 * avoid the risk to change it inplace, which may corrupt the database data.
 *
 * The structure populated doesn't own the pointed data, so it must not be
 * changed in any way and must not be cleared.
 */
void
mpq_from_pmpq(mpq_srcptr q, const pmpq *pq)
{
    /* discard the const qualifier */
    mpq_ptr wq = (mpq_ptr)q;

    if (pq->num_size != 0) {
        int nalloc = ABS(pq->num_size);

        /* We have data from numer and denom into the datum */
        ALLOC(mpq_numref(wq)) = nalloc;
        SIZ(mpq_numref(wq)) = pq->num_size;
        LIMBS(mpq_numref(wq)) = (mp_limb_t *)pq->data;

        ALLOC(mpq_denref(wq)) = pq->den_size;
        SIZ(mpq_denref(wq)) = pq->den_size;
        LIMBS(mpq_denref(wq)) = (mp_limb_t *)pq->data + nalloc;
    }
    else {
        /* in the datum there is not 1/0,
         * so let's just refer to some static const */
        ALLOC(mpq_numref(wq)) = 1;
        SIZ(mpq_numref(wq)) = 0;
        LIMBS(mpq_numref(wq)) = (mp_limb_t *)(&_pgmp_limb_0);

        ALLOC(mpq_denref(wq)) = 1;
        SIZ(mpq_denref(wq)) = 1;
        LIMBS(mpq_denref(wq)) = (mp_limb_t *)(&_pgmp_limb_1);
    }
}
示例#2
0
文件: pmpz.c 项目: dvarrazzo/pgmp
/*
 * Initialize a mpz from the content of a datum
 *
 * NOTE: the function takes a pointer to a const and changes the structure.
 * This allows to define the structure as const in the calling function and
 * avoid the risk to change it inplace, which may corrupt the database data.
 *
 * The structure populated doesn't own the pointed data, so it must not be
 * changed in any way and must not be cleared.
 */
void
mpz_from_pmpz(mpz_srcptr z, const pmpz *pz)
{
    int nlimbs;
    mpz_ptr wz;

    if (UNLIKELY(0 != (PMPZ_VERSION(pz)))) {
        ereport(ERROR, (
            errcode(ERRCODE_DATA_EXCEPTION),
            errmsg("unsupported mpz version: %d", PMPZ_VERSION(pz))));
    }

    /* discard the const qualifier */
    wz = (mpz_ptr)z;

    nlimbs = (VARSIZE(pz) - PMPZ_HDRSIZE) / sizeof(mp_limb_t);
    if (LIKELY(nlimbs != 0))
    {
        ALLOC(wz) = nlimbs;
        SIZ(wz) = PMPZ_NEGATIVE(pz) ? -nlimbs : nlimbs;
        LIMBS(wz) = (mp_limb_t *)pz->data;
    }
    else
    {
        /* in the datum there is just the varlena header
         * so let's just refer to some static const */
        ALLOC(wz) = 1;
        SIZ(wz) = 0;
        LIMBS(wz) = (mp_limb_t *)&_pgmp_limb_0;
    }
}
示例#3
0
文件: pmpq.c 项目: mk8/pgmp
/*
 * Create a new pmpq structure from the content of a mpq
 */
pmpq *
pmpq_from_mpq(mpq_srcptr q)
{
    pmpq *res;
    int nsize = SIZ(mpq_numref(q));

    if (LIKELY(0 != nsize))
    {
        int nalloc = ABS(nsize);
        int dsize = SIZ(mpq_denref(q));

        res = (pmpq *)palloc(
            PMPQ_HDRSIZE + (nalloc + dsize) * sizeof(mp_limb_t));
        res->num_size = nsize;
        res->den_size = dsize;

        SET_VARSIZE(res,
            PMPQ_HDRSIZE + (nalloc + dsize) * sizeof(mp_limb_t));
        memcpy(&(res->data), LIMBS(mpq_numref(q)),
            nalloc * sizeof(mp_limb_t));
        memcpy(&(res->data) + nalloc, LIMBS(mpq_denref(q)),
            dsize * sizeof(mp_limb_t));
    }
    else
    {
        res = (pmpq *)palloc0(PMPQ_HDRSIZE);
        SET_VARSIZE(res, PMPQ_HDRSIZE);
    }

    return res;
}
示例#4
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;
    }
}
示例#5
0
文件: gcd.c 项目: jkeuffer/pari
GEN
gcdii(GEN a, GEN b)
{
  long v, w;
  pari_sp av;
  GEN t;

  switch (absi_cmp(a,b))
  {
    case 0: return absi(a);
    case -1: swap(a,b);
  }
  if (!signe(b)) return absi(a);
  /* here |a|>|b|>0. Try single precision first */
  if (lgefint(a)==3)
    return igcduu((ulong)a[2], (ulong)b[2]);
  if (lgefint(b)==3)
  {
    ulong u = resiu(a,(ulong)b[2]);
    if (!u) return absi(b);
    return igcduu((ulong)b[2], u);
  }
  /* larger than gcd: "avma=av" gerepile (erasing t) is valid */
  av = avma; (void)new_chunk(lgefint(b)+1); /* HACK */
  t = remii(a,b);
  if (!signe(t)) { avma=av; return absi(b); }

  a = b; b = t;
  v = vali(a); a = shifti(a,-v); setabssign(a);
  w = vali(b); b = shifti(b,-w); setabssign(b);
  if (w < v) v = w;
  switch(absi_cmp(a,b))
  {
    case  0: avma=av; a=shifti(a,v); return a;
    case -1: swap(a,b);
  }
  if (is_pm1(b)) { avma=av; return int2n(v); }
 {
  /* general case */
  /*This serve two purposes: 1) mpn_gcd destroy its input and need an extra
   * limb 2) this allows us to use icopy instead of gerepile later.  NOTE: we
   * must put u before d else the final icopy could fail.
   */
  GEN res= cgeti(lgefint(a)+1);
  GEN ca = icopy_ef(a,lgefint(a)+1);
  GEN cb = icopy_ef(b,lgefint(b)+1);
  long l = mpn_gcd(LIMBS(res), LIMBS(ca), NLIMBS(ca), LIMBS(cb), NLIMBS(cb));
  res[1] = evalsigne(1)|evallgefint(l+2);
  avma=av;
  return shifti(res,v);
  }
}
示例#6
0
文件: pmpz.c 项目: dvarrazzo/pgmp
/*
 * Create a pmpz structure from the content of a mpz.
 *
 * The function relies on the limbs being allocated using the GMP custom
 * allocator: such allocator leaves PGMP_MAX_HDRSIZE bytes *before* the
 * returned pointer. We scrubble that area prepending the pmpz header.
 */
pmpz *
pmpz_from_mpz(mpz_srcptr z)
{
    pmpz *res;
    int size = SIZ(z);

    res = (pmpz *)((char *)LIMBS(z) - PMPZ_HDRSIZE);

    if (LIKELY(0 != size))
    {
        size_t slimbs;
        int sign;

        if (size > 0) {
            slimbs = size * sizeof(mp_limb_t);
            sign = 0;
        }
        else {
            slimbs = -size * sizeof(mp_limb_t);
            sign = PMPZ_SIGN_MASK;
        }

        SET_VARSIZE(res, PMPZ_HDRSIZE + slimbs);
        res->mdata = sign;          /* implicit version: 0 */
    }
    else
    {
        /* In the zero representation there are no limbs */
        SET_VARSIZE(res, PMPZ_HDRSIZE);
        res->mdata = 0;             /* version: 0 */
    }

    return res;
}
示例#7
0
文件: pmpz.c 项目: mk8/pgmp
/*
 * Create a new pmpz structure from the content of a mpz
 */
pmpz *
pmpz_from_mpz(mpz_srcptr z)
{
    pmpz *res;
    int size = SIZ(z);

    if (LIKELY(0 != size))
    {
        size_t slimbs;
        if (size > 0) {
            slimbs = size * sizeof(mp_limb_t);
        }
        else {
            slimbs = -size * sizeof(mp_limb_t);
        }

        res = (pmpz *)palloc(PMPZ_HDRSIZE + slimbs);
        SET_VARSIZE(res, PMPZ_HDRSIZE + slimbs);
        res->size = size;
        memcpy(&(res->data), LIMBS(z), slimbs);
    }
    else
    {
        res = (pmpz *)palloc0(PMPZ_HDRSIZE);
        SET_VARSIZE(res, PMPZ_HDRSIZE);
    }

    return res;
}
示例#8
0
文件: pmpz.c 项目: mk8/pgmp
/*
 * Initialize a mpz from the content of a datum
 *
 * NOTE: the function takes a pointer to a const and changes the structure.
 * This allows to define the structure as const in the calling function and
 * avoid the risk to change it inplace, which may corrupt the database data.
 *
 * The structure populated doesn't own the pointed data, so it must not be
 * changed in any way and must not be cleared.
 */
void
mpz_from_pmpz(mpz_srcptr z, const pmpz *pz)
{
    /* discard the const qualifier */
    mpz_ptr wz = (mpz_ptr)z;

    if (LIKELY(pz->size != 0))
    {
        ALLOC(wz) = ABS(pz->size);
        SIZ(wz) = pz->size;
        LIMBS(wz) = (mp_limb_t *)pz->data;
    }
    else
    {
        /* in the datum there is just the varlena header
         * so let's just refer to some static const */
        ALLOC(wz) = 1;
        SIZ(wz) = 0;
        LIMBS(wz) = (mp_limb_t *)&_pgmp_limb_0;
    }
}
示例#9
0
文件: gcd.c 项目: jkeuffer/pari
/* assume y > x > 0. return y mod x */
static ulong
resiu(GEN y, ulong x)
{
  return mpn_mod_1(LIMBS(y), NLIMBS(y), x);
}