/* * 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); } }
/* * 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; } }
/* * 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; }
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; } }
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); } }
/* * 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; }
/* * 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; }
/* * 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; } }
/* assume y > x > 0. return y mod x */ static ulong resiu(GEN y, ulong x) { return mpn_mod_1(LIMBS(y), NLIMBS(y), x); }