void mpz_tdiv_r_2exp (mpz_ptr res, mpz_srcptr in, mp_bitcnt_t cnt) { mp_size_t in_size = ABS (in->_mp_size); mp_size_t res_size; mp_size_t limb_cnt = cnt / GMP_NUMB_BITS; mp_srcptr in_ptr = in->_mp_d; 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; if (res->_mp_alloc < res_size) _mpz_realloc (res, res_size); res->_mp_d[limb_cnt] = x; } else { res_size = limb_cnt; MPN_NORMALIZE (in_ptr, res_size); if (res->_mp_alloc < 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; if (res->_mp_alloc < res_size) _mpz_realloc (res, res_size); limb_cnt = res_size; } if (res != in) MPN_COPY (res->_mp_d, in->_mp_d, limb_cnt); res->_mp_size = in->_mp_size >= 0 ? res_size : -res_size; }
void mpz_mul_si(mpz_ptr prod, mpz_srcptr mult, long int small_mult) { mp_size_t size = mult->_mp_size; mp_size_t sign_product = size; mp_limb_t cy; mp_size_t prod_size; mp_ptr prod_ptr; if(size == 0 || small_mult == 0) { prod->_mp_size = 0; return; } size = ABS(size); prod_size = size + 1; if(prod->_mp_alloc < prod_size) { _mpz_realloc(prod, prod_size); } prod_ptr = prod->_mp_d; cy = mpn_mul_1(prod_ptr, mult->_mp_d, size, (mp_limb_t)ABS(small_mult)); if(cy != 0) { prod_ptr[size] = cy; size++; } prod->_mp_size = ((sign_product < 0) ^ (small_mult < 0)) ? -size : size; }
static inline void setlen1 (MP_INT *r, int max) { mp_limb_t *lp = r->_mp_d; mp_limb_t *nz = lp; mp_limb_t *end = lp + max; for (;;) { mp_limb_t lv; if (lp == end) goto carryout; lv = *lp + 1; *lp++ = lv; if (lv) { nz = lp; break; } } while (lp < end) if (*lp++) nz = lp; r->_mp_size = r->_mp_d - nz; return; carryout: r->_mp_size = - ++max; if (max > r->_mp_alloc) _mpz_realloc(r, max); r->_mp_d[max-1] = 1; }
mpz_ptr _pari_to_gmp(GEN pnum, mpz_ptr *gnum_ptr) { mpz_ptr gnum; long length = lgef(pnum) - 2; long sign = signe(pnum); GEN pptr; mp_limb_t *gptr; if (*gnum_ptr == NULL) { *gnum_ptr = (mpz_ptr) IMP_MemAllocFnc(sizeof(__mpz_struct)); gnum = *gnum_ptr; mpz_init(gnum); } else gnum = *gnum_ptr; gnum->_mp_size = (sign < 0 ? -length : length); _mpz_realloc(gnum, length); gnum->_mp_alloc = length; gptr = gnum->_mp_d; pnum++; pptr = pnum + length; for (; pptr > pnum; gptr++, pptr--) *gptr = *pptr; return gnum; }
int bignum2mpz(const BIGNUM *bn, mpz_t g) { bn_check_top(bn); if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) && (BN_BITS2 == GMP_NUMB_BITS)) { /* The common case */ if(!_mpz_realloc (g, bn->top)) return 0; memcpy(&g->_mp_d[0], &bn->d[0], bn->top * sizeof(bn->d[0])); g->_mp_size = bn->top; if(bn->neg) g->_mp_size = -g->_mp_size; return 1; } else { char *tmpchar = BN_bn2hex(bn); if(!tmpchar) return 0; OPENSSL_free(tmpchar); return 0; } }
/* Most often limb sizes will be the same. If not, we use hex conversion * which is neat, but extremely inefficient. */ static int bn2gmp(const BIGNUM *bn, mpz_t g) { bn_check_top(bn); if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) && (BN_BITS2 == GMP_NUMB_BITS)) { /* The common case */ if(!_mpz_realloc (g, bn->top)) return 0; TINYCLR_SSL_MEMCPY(&g->_mp_d[0], &bn->d[0], bn->top * sizeof(bn->d[0])); g->_mp_size = bn->top; if(bn->neg) g->_mp_size = -g->_mp_size; return 1; } else { int toret; char *tmpchar = BN_bn2hex(bn); if(!tmpchar) return 0; toret = (mpz_set_str(g, tmpchar, 16) == 0 ? 1 : 0); OPENSSL_free(tmpchar); return toret; } }
void mpq_inv (MP_RAT *dest, const MP_RAT *src) { mp_size_t num_size = src->_mp_num._mp_size; mp_size_t den_size = src->_mp_den._mp_size; if (num_size == 0) DIVIDE_BY_ZERO; if (num_size < 0) { num_size = -num_size; den_size = -den_size; } dest->_mp_den._mp_size = num_size; dest->_mp_num._mp_size = den_size; /* If dest == src we may just swap the numerator and denominator, but we have to ensure the new denominator is positive. */ if (dest == src) { mp_size_t alloc = dest->_mp_num._mp_alloc; mp_ptr limb_ptr = dest->_mp_num._mp_d; dest->_mp_num._mp_alloc = dest->_mp_den._mp_alloc; dest->_mp_num._mp_d = dest->_mp_den._mp_d; dest->_mp_den._mp_alloc = alloc; dest->_mp_den._mp_d = limb_ptr; } else { den_size = ABS (den_size); if (dest->_mp_num._mp_alloc < den_size) _mpz_realloc (&(dest->_mp_num), den_size); if (dest->_mp_den._mp_alloc < num_size) _mpz_realloc (&(dest->_mp_den), num_size); MPN_COPY (dest->_mp_num._mp_d, src->_mp_den._mp_d, den_size); MPN_COPY (dest->_mp_den._mp_d, src->_mp_num._mp_d, num_size); } }
void mpq_set (MP_RAT *dest, const MP_RAT *src) { mp_size_t num_size, den_size; mp_size_t abs_num_size; num_size = src->_mp_num._mp_size; abs_num_size = ABS (num_size); if (dest->_mp_num._mp_alloc < abs_num_size) _mpz_realloc (&(dest->_mp_num), abs_num_size); MPN_COPY (dest->_mp_num._mp_d, src->_mp_num._mp_d, abs_num_size); dest->_mp_num._mp_size = num_size; den_size = src->_mp_den._mp_size; if (dest->_mp_den._mp_alloc < den_size) _mpz_realloc (&(dest->_mp_den), den_size); MPN_COPY (dest->_mp_den._mp_d, src->_mp_den._mp_d, den_size); dest->_mp_den._mp_size = den_size; }
void mpq_set_num (MP_RAT *dest, const MP_INT *num) { mp_size_t size = num->_mp_size; mp_size_t abs_size = ABS (size); if (dest->_mp_num._mp_alloc < abs_size) _mpz_realloc (&(dest->_mp_num), abs_size); MPN_COPY (dest->_mp_num._mp_d, num->_mp_d, abs_size); dest->_mp_num._mp_size = size; }
void mpq_get_num (MP_INT *num, const MP_RAT *src) { mp_size_t size = src->_mp_num._mp_size; mp_size_t abs_size = ABS (size); if (num->_mp_alloc < abs_size) _mpz_realloc (num, abs_size); MPN_COPY (num->_mp_d, src->_mp_num._mp_d, abs_size); num->_mp_size = size; }
void mpq_set_den (MP_RAT *dest, const MP_INT *den) { mp_size_t size = den->_mp_size; mp_size_t abs_size = ABS (size); if (dest->_mp_den._mp_alloc < abs_size) _mpz_realloc (&(dest->_mp_den), abs_size); MPN_COPY (dest->_mp_den._mp_d, den->_mp_d, abs_size); dest->_mp_den._mp_size = size; }
void mpz_random2 (mpz_ptr x, mp_size_t size) { mp_size_t abs_size; abs_size = ABS (size); if (abs_size != 0) { if (x->_mp_alloc < abs_size) _mpz_realloc (x, abs_size); mpn_random2 (x->_mp_d, abs_size); } x->_mp_size = size; }
void mpz_mul_2exp (mpz_ptr w, mpz_srcptr u, unsigned long int cnt) { mp_size_t usize = u->_mp_size; mp_size_t abs_usize = ABS (usize); mp_size_t wsize; mp_size_t limb_cnt; mp_ptr wp; mp_limb_t wlimb; if (usize == 0) { w->_mp_size = 0; return; } limb_cnt = cnt / GMP_NUMB_BITS; wsize = abs_usize + limb_cnt + 1; if (w->_mp_alloc < wsize) _mpz_realloc (w, wsize); wp = w->_mp_d; wsize = abs_usize + limb_cnt; cnt %= GMP_NUMB_BITS; if (cnt != 0) { wlimb = mpn_lshift (wp + limb_cnt, u->_mp_d, abs_usize, cnt); if (wlimb != 0) { wp[wsize] = wlimb; wsize++; } } else { MPN_COPY_DECR (wp + limb_cnt, u->_mp_d, abs_usize); } /* Zero all whole limbs at low end. Do it here and not before calling mpn_lshift, not to lose for U == W. */ MPN_ZERO (wp, limb_cnt); w->_mp_size = usize >= 0 ? wsize : -wsize; }
void FUNCTION (ARGUMENTS) { mp_ptr wp, up; mp_size_t usize, size; usize = u->_mp_size; size = ABS (usize); if (w->_mp_alloc < size) _mpz_realloc (w, size); wp = w->_mp_d; up = u->_mp_d; MPN_COPY (wp, up, size); w->_mp_size = usize; }
void mpz_abs (mpz_ptr w, mpz_srcptr u) { mp_ptr wp, up; mp_size_t size; size = ABS (u->_mp_size); if (u != w) { if (w->_mp_alloc < size) _mpz_realloc (w, size); wp = w->_mp_d; up = u->_mp_d; MPN_COPY (wp, up, size); } w->_mp_size = size; }
static void fp_to_mpz(mpz_ptr z, element_ptr e) { eptr ep = (eptr)e->data; if (!ep->flag) mpz_set_ui(z, 0); else { // x is stored as xR. // We must divide out R to convert to standard representation. fptr p = (fptr)e->field->data; #ifdef _MSC_VER // for VC++ compatibility mp_limb_t tmp[2 * MAX_LIMBS]; #else mp_limb_t tmp[2 * p->limbs]; #endif memcpy(tmp, ep->d, p->limbs * sizeof(mp_limb_t)); memset(&tmp[p->limbs], 0, p->limbs * sizeof(mp_limb_t)); _mpz_realloc(z, p->limbs); mont_reduce(z->_mp_d, tmp, p); // Remove leading zero limbs. for (z->_mp_size = p->limbs; !z->_mp_d[z->_mp_size - 1]; z->_mp_size--); } }
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; }
void mpfr_extract (mpz_ptr y, mpfr_srcptr p, unsigned int i) { int two_i = 1 << i; int two_i_2 = i ? two_i / 2 : 1; mp_size_t size_p = MPFR_ABSSIZE(p); /* as 0 <= |p| < 1, we don't have to care with infinities, NaN, ... */ _mpz_realloc (y, two_i_2); if (size_p < two_i) { MPN_ZERO (PTR(y), two_i_2); if (size_p >= two_i_2) MPN_COPY (PTR(y) + two_i - size_p, MPFR_MANT(p), size_p - two_i_2); } else MPN_COPY (PTR(y), MPFR_MANT(p) + size_p - two_i, two_i_2); MPN_NORMALIZE (PTR(y), two_i_2); SIZ(y) = (MPFR_ISNEG(p)) ? -two_i_2 : two_i_2; }
/* pylong -> mpz conversion */ int mpz_set_pylong(mpz_ptr z, PyObject * ll) { register PyLongObject * l = (PyLongObject *) ll; mp_size_t size; int i; if (l==NULL || !PyLong_Check(l)) { PyErr_BadInternalCall(); return -1; } size = mpn_size_from_pylong(l->ob_digit, abs(l->ob_size)); if (z->_mp_alloc < size) _mpz_realloc (z, size); mpn_set_pylong(z->_mp_d, size, l->ob_digit, abs(l->ob_size)); z->_mp_size = l->ob_size < 0 ? -size : size; return size; }
void mpfr_extract (mpz_ptr y, mpfr_srcptr p, unsigned int i) { unsigned long two_i = 1UL << i; unsigned long two_i_2 = i ? two_i / 2 : 1; mp_size_t size_p = MPFR_LIMB_SIZE (p); /* as 0 <= |p| < 1, we don't have to care with infinities, NaN, ... */ MPFR_ASSERTD (!MPFR_IS_SINGULAR (p)); _mpz_realloc (y, two_i_2); if ((mpfr_uexp_t) size_p < two_i) { MPN_ZERO (PTR(y), two_i_2); if ((mpfr_uexp_t) size_p >= two_i_2) MPN_COPY (PTR(y) + two_i - size_p, MPFR_MANT(p), size_p - two_i_2); } else MPN_COPY (PTR(y), MPFR_MANT(p) + size_p - two_i, two_i_2); MPN_NORMALIZE (PTR(y), two_i_2); SIZ(y) = (MPFR_IS_NEG (p)) ? -two_i_2 : two_i_2; }
void mpz_neg (mpz_ptr w, mpz_srcptr u) { mp_ptr wp, up; mp_size_t usize, size; usize = u->_mp_size; if (u != w) { size = ABS (usize); if (w->_mp_alloc < size) _mpz_realloc (w, size); wp = w->_mp_d; up = u->_mp_d; MPN_COPY (wp, up, size); } w->_mp_size = -usize; }
void mpz_umod_2exp (MP_INT *r, const MP_INT *a, u_long b) { size_t nlimbs; const mp_limb_t *ap, *ae; mp_limb_t *rp, *re; if (a->_mp_size >= 0) { mpz_tdiv_r_2exp (r, a, b); return; } nlimbs = ((b + (8 * sizeof (mp_limb_t) - 1)) / (8 * sizeof (mp_limb_t))); if ((size_t) r->_mp_alloc < nlimbs) _mpz_realloc (r, nlimbs); ap = a->_mp_d; ae = ap + min ((size_t) ABS (a->_mp_size), nlimbs); rp = r->_mp_d; while (ap < ae) if ((*rp++ = -*ap++)) goto nocarry; r->_mp_size = 0; return; nocarry: while (ap < ae) *rp++ = ~*ap++; re = r->_mp_d + nlimbs; while (rp < re) *rp++ = ~(mp_limb_t) 0; re[-1] &= ~(mp_limb_t) 0 >> ((8*sizeof (mp_limb_t) - b) % (8*sizeof (mp_limb_t))); r->_mp_size = nlimbs; _mpz_fixsize (r); }
void mpz_sqrtrem (mpz_ptr root, mpz_ptr rem, mpz_srcptr op) { mp_size_t op_size, root_size, rem_size; mp_ptr root_ptr, op_ptr; mp_ptr free_me = NULL; mp_size_t free_me_size; TMP_DECL; TMP_MARK; op_size = op->_mp_size; if (op_size <= 0) { if (op_size < 0) SQRT_OF_NEGATIVE; SIZ(root) = 0; SIZ(rem) = 0; return; } if (rem->_mp_alloc < op_size) _mpz_realloc (rem, op_size); /* The size of the root is accurate after this simple calculation. */ root_size = (op_size + 1) / 2; root_ptr = root->_mp_d; op_ptr = op->_mp_d; if (root->_mp_alloc < root_size) { if (root_ptr == op_ptr) { free_me = root_ptr; free_me_size = root->_mp_alloc; } else (*__gmp_free_func) (root_ptr, root->_mp_alloc * BYTES_PER_MP_LIMB); root->_mp_alloc = root_size; root_ptr = (mp_ptr) (*__gmp_allocate_func) (root_size * BYTES_PER_MP_LIMB); root->_mp_d = root_ptr; } else { /* Make OP not overlap with ROOT. */ if (root_ptr == op_ptr) { /* ROOT and OP are identical. Allocate temporary space for OP. */ op_ptr = (mp_ptr) TMP_ALLOC (op_size * BYTES_PER_MP_LIMB); /* Copy to the temporary space. Hack: Avoid temporary variable by using ROOT_PTR. */ MPN_COPY (op_ptr, root_ptr, op_size); } } rem_size = mpn_sqrtrem (root_ptr, rem->_mp_d, op_ptr, op_size); root->_mp_size = root_size; /* Write remainder size last, to enable us to define this function to give only the square root remainder, if the user calls if with ROOT == REM. */ rem->_mp_size = rem_size; if (free_me != NULL) (*__gmp_free_func) (free_me, free_me_size * BYTES_PER_MP_LIMB); TMP_FREE; }
/* * * Copyright (C) 1998 David Mazieres ([email protected]) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * This program 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * */ #ifdef HAVE_CONFIG_H #include <config.h> #endif /* HAVE_CONFIG_H */ #ifndef HAVE_MPZ_XOR #include "gmp.h" #undef ABS #define ABS(a) ((a) < 0 ? -(a) : (a)) static inline void setlen1 (MP_INT *r, int max) { mp_limb_t *lp = r->_mp_d; mp_limb_t *nz = lp; mp_limb_t *end = lp + max; for (;;) { mp_limb_t lv; if (lp == end) goto carryout; lv = *lp + 1; *lp++ = lv; if (lv) { nz = lp; break; } } while (lp < end) if (*lp++) nz = lp; r->_mp_size = r->_mp_d - nz; return; carryout: r->_mp_size = - ++max; if (max > r->_mp_alloc) _mpz_realloc(r, max); r->_mp_d[max-1] = 1; } #ifdef __cplusplus extern "C" void mpz_xor (MP_INT *, const MP_INT *, const MP_INT *); #endif /* __cplusplus */ void mpz_xor (MP_INT *r, const MP_INT *a, const MP_INT *b) { int sza = ABS (a->_mp_size); int szb = ABS (b->_mp_size); int i; if (sza < szb) { int szt; const MP_INT *t = a; a = b; b = t; szt = sza; sza = szb; szb = szt; } if (r->_mp_alloc < sza) _mpz_realloc(r, sza); if (a->_mp_size >= 0 && b->_mp_size >= 0) { int szr = 0; for (i = 0; i < szb; i++) if ((r->_mp_d[i] = a->_mp_d[i] ^ b->_mp_d[i])) szr = i + 1; for (; i < sza; i++) if ((r->_mp_d[i] = a->_mp_d[i])) szr = i + 1; r->_mp_size = szr; } else if (a->_mp_size >= 0) { for (i = 0; i < szb;) { mp_limb_t bl = b->_mp_d[i]; r->_mp_d[i] = a->_mp_d[i] ^ (bl - 1); i++; if (bl) break; } for (; i < szb; i++) r->_mp_d[i] = a->_mp_d[i] ^ b->_mp_d[i]; for (; i < sza; i++) r->_mp_d[i] = a->_mp_d[i]; setlen1 (r, sza); } else if (b->_mp_size >= 0) { int borrow = 1; for (i = 0; i < szb; i++) { mp_limb_t al = a->_mp_d[i]; r->_mp_d[i] = (al - borrow) ^ b->_mp_d[i]; if (al) borrow = 0; } for (; i < sza; i++) { mp_limb_t al = a->_mp_d[i]; r->_mp_d[i] = al - borrow; if (al) borrow = 0; } setlen1 (r, sza); } else { int szr = 0; int borrow = 1; for (i = 0; i < szb; ) { mp_limb_t al = a->_mp_d[i]; mp_limb_t bl = b->_mp_d[i]; if ((r->_mp_d[i] = (al - borrow) ^ (bl - 1))) szr = i + 1; if (al) borrow = 0; ++i; if (bl) break; } for (; i < szb; i++) { mp_limb_t al = a->_mp_d[i]; if ((r->_mp_d[i] = (al - borrow) ^ b->_mp_d[i])) szr = i + 1; if (al) borrow = 0; } for (; i < sza; i++) { mp_limb_t al = a->_mp_d[i]; if ((r->_mp_d[i] = al - borrow)) szr = i + 1; if (al) borrow = 0; } r->_mp_size = szr; } }
static mp_size_t one_test (mpz_t a, mpz_t b, int i) { struct hgcd_matrix hgcd; struct hgcd_ref ref; mpz_t ref_r0; mpz_t ref_r1; mpz_t hgcd_r0; mpz_t hgcd_r1; int res[2]; mp_size_t asize; mp_size_t bsize; mp_size_t hgcd_init_scratch; mp_size_t hgcd_scratch; mp_ptr hgcd_init_tp; mp_ptr hgcd_tp; mp_limb_t marker[4]; asize = a->_mp_size; bsize = b->_mp_size; ASSERT (asize >= bsize); hgcd_init_scratch = MPN_HGCD_MATRIX_INIT_ITCH (asize); hgcd_init_tp = refmpn_malloc_limbs (hgcd_init_scratch + 2) + 1; mpn_hgcd_matrix_init (&hgcd, asize, hgcd_init_tp); hgcd_scratch = mpn_hgcd_appr_itch (asize); hgcd_tp = refmpn_malloc_limbs (hgcd_scratch + 2) + 1; mpn_random (marker, 4); hgcd_init_tp[-1] = marker[0]; hgcd_init_tp[hgcd_init_scratch] = marker[1]; hgcd_tp[-1] = marker[2]; hgcd_tp[hgcd_scratch] = marker[3]; #if 0 fprintf (stderr, "one_test: i = %d asize = %d, bsize = %d\n", i, a->_mp_size, b->_mp_size); gmp_fprintf (stderr, "one_test: i = %d\n" " a = %Zx\n" " b = %Zx\n", i, a, b); #endif hgcd_ref_init (&ref); mpz_init_set (ref_r0, a); mpz_init_set (ref_r1, b); res[0] = hgcd_ref (&ref, ref_r0, ref_r1); mpz_init_set (hgcd_r0, a); mpz_init_set (hgcd_r1, b); if (bsize < asize) { _mpz_realloc (hgcd_r1, asize); MPN_ZERO (hgcd_r1->_mp_d + bsize, asize - bsize); } res[1] = mpn_hgcd_appr (hgcd_r0->_mp_d, hgcd_r1->_mp_d, asize, &hgcd, hgcd_tp); if (hgcd_init_tp[-1] != marker[0] || hgcd_init_tp[hgcd_init_scratch] != marker[1] || hgcd_tp[-1] != marker[2] || hgcd_tp[hgcd_scratch] != marker[3]) { fprintf (stderr, "ERROR in test %d\n", i); fprintf (stderr, "scratch space overwritten!\n"); if (hgcd_init_tp[-1] != marker[0]) gmp_fprintf (stderr, "before init_tp: %Mx\n" "expected: %Mx\n", hgcd_init_tp[-1], marker[0]); if (hgcd_init_tp[hgcd_init_scratch] != marker[1]) gmp_fprintf (stderr, "after init_tp: %Mx\n" "expected: %Mx\n", hgcd_init_tp[hgcd_init_scratch], marker[1]); if (hgcd_tp[-1] != marker[2]) gmp_fprintf (stderr, "before tp: %Mx\n" "expected: %Mx\n", hgcd_tp[-1], marker[2]); if (hgcd_tp[hgcd_scratch] != marker[3]) gmp_fprintf (stderr, "after tp: %Mx\n" "expected: %Mx\n", hgcd_tp[hgcd_scratch], marker[3]); abort (); } if (!hgcd_appr_valid_p (a, b, res[0], &ref, ref_r0, ref_r1, res[1], &hgcd)) { fprintf (stderr, "ERROR in test %d\n", i); fprintf (stderr, "Invalid results for hgcd and hgcd_ref\n"); fprintf (stderr, "op1="); debug_mp (a, -16); fprintf (stderr, "op2="); debug_mp (b, -16); fprintf (stderr, "hgcd_ref: %ld\n", (long) res[0]); fprintf (stderr, "mpn_hgcd_appr: %ld\n", (long) res[1]); abort (); } refmpn_free_limbs (hgcd_init_tp - 1); refmpn_free_limbs (hgcd_tp - 1); hgcd_ref_clear (&ref); mpz_clear (ref_r0); mpz_clear (ref_r1); mpz_clear (hgcd_r0); mpz_clear (hgcd_r1); return res[0]; }
static mp_size_t one_test (mpz_t a, mpz_t b, int i) { struct hgcd_matrix hgcd; struct hgcd_ref ref; mpz_t ref_r0; mpz_t ref_r1; mpz_t hgcd_r0; mpz_t hgcd_r1; mp_size_t res[2]; mp_size_t asize; mp_size_t bsize; mp_size_t hgcd_init_scratch; mp_size_t hgcd_scratch; mp_ptr hgcd_init_tp; mp_ptr hgcd_tp; asize = a->_mp_size; bsize = b->_mp_size; ASSERT (asize >= bsize); hgcd_init_scratch = MPN_HGCD_MATRIX_INIT_ITCH (asize); hgcd_init_tp = refmpn_malloc_limbs (hgcd_init_scratch); mpn_hgcd_matrix_init (&hgcd, asize, hgcd_init_tp); hgcd_scratch = mpn_hgcd_itch (asize); hgcd_tp = refmpn_malloc_limbs (hgcd_scratch); #if 0 fprintf (stderr, "one_test: i = %d asize = %d, bsize = %d\n", i, a->_mp_size, b->_mp_size); gmp_fprintf (stderr, "one_test: i = %d\n" " a = %Zx\n" " b = %Zx\n", i, a, b); #endif hgcd_ref_init (&ref); mpz_init_set (ref_r0, a); mpz_init_set (ref_r1, b); res[0] = hgcd_ref (&ref, ref_r0, ref_r1); mpz_init_set (hgcd_r0, a); mpz_init_set (hgcd_r1, b); if (bsize < asize) { _mpz_realloc (hgcd_r1, asize); MPN_ZERO (hgcd_r1->_mp_d + bsize, asize - bsize); } res[1] = mpn_hgcd (hgcd_r0->_mp_d, hgcd_r1->_mp_d, asize, &hgcd, hgcd_tp); if (res[0] != res[1]) { fprintf (stderr, "ERROR in test %d\n", i); fprintf (stderr, "Different return value from hgcd and hgcd_ref\n"); fprintf (stderr, "op1="); debug_mp (a, -16); fprintf (stderr, "op2="); debug_mp (b, -16); fprintf (stderr, "hgcd_ref: %ld\n", (long) res[0]); fprintf (stderr, "mpn_hgcd: %ld\n", (long) res[1]); abort (); } if (res[0] > 0) { if (!hgcd_ref_equal (&hgcd, &ref) || !mpz_mpn_equal (ref_r0, hgcd_r0->_mp_d, res[1]) || !mpz_mpn_equal (ref_r1, hgcd_r1->_mp_d, res[1])) { fprintf (stderr, "ERROR in test %d\n", i); fprintf (stderr, "mpn_hgcd and hgcd_ref returned different values\n"); fprintf (stderr, "op1="); debug_mp (a, -16); fprintf (stderr, "op2="); debug_mp (b, -16); abort (); } } refmpn_free_limbs (hgcd_init_tp); refmpn_free_limbs (hgcd_tp); hgcd_ref_clear (&ref); mpz_clear (ref_r0); mpz_clear (ref_r1); mpz_clear (hgcd_r0); mpz_clear (hgcd_r1); return res[0]; }
void mpz_com (mpz_ptr dst, mpz_srcptr src) { mp_size_t size = src->_mp_size; mp_srcptr src_ptr; mp_ptr dst_ptr; if (size >= 0) { /* As with infinite precision: one's complement, two's complement. But this can be simplified using the identity -x = ~x + 1. So we're going to compute (~~x) + 1 = x + 1! */ if (dst->_mp_alloc < size + 1) _mpz_realloc (dst, size + 1); src_ptr = src->_mp_d; dst_ptr = dst->_mp_d; if (size == 0) { /* Special case, as mpn_add wants the first arg's size >= the second arg's size. */ dst_ptr[0] = 1; dst->_mp_size = -1; return; } { mp_limb_t cy; cy = mpn_add_1 (dst_ptr, src_ptr, size, (mp_limb_t) 1); if (cy) { dst_ptr[size] = cy; size++; } } /* Store a negative size, to indicate ones-extension. */ dst->_mp_size = -size; } else { /* As with infinite precision: two's complement, then one's complement. But that can be simplified using the identity -x = ~(x - 1). So we're going to compute ~~(x - 1) = x - 1! */ size = -size; if (dst->_mp_alloc < size) _mpz_realloc (dst, size); src_ptr = src->_mp_d; dst_ptr = dst->_mp_d; mpn_sub_1 (dst_ptr, src_ptr, size, (mp_limb_t) 1); size -= dst_ptr[size - 1] == 0; /* Store a positive size, to indicate zero-extension. */ dst->_mp_size = size; } }
void mpz_setbit (mpz_ptr d, mp_bitcnt_t bit_index) { mp_size_t dsize = d->_mp_size; mp_ptr dp = d->_mp_d; mp_size_t limb_index; limb_index = bit_index / GMP_NUMB_BITS; if (dsize >= 0) { if (limb_index < dsize) { dp[limb_index] |= (mp_limb_t) 1 << (bit_index % GMP_NUMB_BITS); d->_mp_size = dsize; } else { /* Ugh. The bit should be set outside of the end of the number. We have to increase the size of the number. */ if (UNLIKELY (d->_mp_alloc < limb_index + 1)) dp = _mpz_realloc (d, limb_index + 1); MPN_ZERO (dp + dsize, limb_index - dsize); dp[limb_index] = (mp_limb_t) 1 << (bit_index % GMP_NUMB_BITS); d->_mp_size = limb_index + 1; } } else { mp_size_t zero_bound; /* Simulate two's complement arithmetic, i.e. simulate 1. Set OP = ~(OP - 1) [with infinitely many leading ones]. 2. Set the bit. 3. Set OP = ~OP + 1. */ dsize = -dsize; /* No upper bound on this loop, we're sure there's a non-zero limb sooner ot later. */ for (zero_bound = 0; ; zero_bound++) if (dp[zero_bound] != 0) break; if (limb_index > zero_bound) { if (limb_index < dsize) { mp_limb_t dlimb; dlimb = dp[limb_index]; dlimb &= ~((mp_limb_t) 1 << (bit_index % GMP_NUMB_BITS)); dp[limb_index] = dlimb; if (UNLIKELY (dlimb == 0 && limb_index == dsize-1)) { /* high limb became zero, must normalize */ do { dsize--; } while (dsize > 0 && dp[dsize-1] == 0); d->_mp_size = -dsize; } } } else if (limb_index == zero_bound) { dp[limb_index] = ((dp[limb_index] - 1) & ~((mp_limb_t) 1 << (bit_index % GMP_NUMB_BITS))) + 1; if (dp[limb_index] == 0) { mp_size_t i; for (i = limb_index + 1; i < dsize; i++) { dp[i] += 1; if (dp[i] != 0) goto fin; } /* We got carry all way out beyond the end of D. Increase its size (and allocation if necessary). */ dsize++; if (UNLIKELY (d->_mp_alloc < dsize)) dp = _mpz_realloc (d, dsize); dp[i] = 1; d->_mp_size = -dsize; fin:; } } else { mpn_decr_u (dp + limb_index, (mp_limb_t) 1 << (bit_index % GMP_NUMB_BITS)); dsize -= dp[dsize - 1] == 0; d->_mp_size = -dsize; } } }
void mpz_gcdext (mpz_ptr g, mpz_ptr s, mpz_ptr t, mpz_srcptr a, mpz_srcptr b) { mp_size_t asize, bsize, usize, vsize; mp_srcptr ap, bp; mp_ptr up, vp; mp_size_t gsize, ssize, tmp_ssize; mp_ptr gp, sp, tmp_gp, tmp_sp; mpz_srcptr u, v; mpz_ptr ss, tt; __mpz_struct stmp, gtmp; TMP_DECL; TMP_MARK; /* mpn_gcdext requires that U >= V. Therefore, we often have to swap U and V. This in turn leads to a lot of complications. The computed cofactor will be the wrong one, so we have to fix that up at the end. */ asize = ABS (SIZ (a)); bsize = ABS (SIZ (b)); ap = PTR (a); bp = PTR (b); if (asize > bsize || (asize == bsize && mpn_cmp (ap, bp, asize) > 0)) { usize = asize; vsize = bsize; up = (mp_ptr) TMP_ALLOC ((usize + 1) * BYTES_PER_MP_LIMB); vp = (mp_ptr) TMP_ALLOC ((vsize + 1) * BYTES_PER_MP_LIMB); MPN_COPY (up, ap, usize); MPN_COPY (vp, bp, vsize); u = a; v = b; ss = s; tt = t; } else { usize = bsize; vsize = asize; up = (mp_ptr) TMP_ALLOC ((usize + 1) * BYTES_PER_MP_LIMB); vp = (mp_ptr) TMP_ALLOC ((vsize + 1) * BYTES_PER_MP_LIMB); MPN_COPY (up, bp, usize); MPN_COPY (vp, ap, vsize); u = b; v = a; ss = t; tt = s; } tmp_gp = (mp_ptr) TMP_ALLOC ((usize + 1) * BYTES_PER_MP_LIMB); tmp_sp = (mp_ptr) TMP_ALLOC ((usize + 1) * BYTES_PER_MP_LIMB); if (vsize == 0) { tmp_sp[0] = 1; tmp_ssize = 1; MPN_COPY (tmp_gp, up, usize); gsize = usize; } else gsize = mpn_gcdext (tmp_gp, tmp_sp, &tmp_ssize, up, usize, vp, vsize); ssize = ABS (tmp_ssize); PTR (>mp) = tmp_gp; SIZ (>mp) = gsize; PTR (&stmp) = tmp_sp; SIZ (&stmp) = (tmp_ssize ^ SIZ (u)) >= 0 ? ssize : -ssize; if (tt != NULL) { if (SIZ (v) == 0) SIZ (tt) = 0; else { mpz_t x; MPZ_TMP_INIT (x, ssize + usize + 1); mpz_mul (x, &stmp, u); mpz_sub (x, >mp, x); mpz_tdiv_q (tt, x, v); } } if (ss != NULL) { if (ALLOC (ss) < ssize) _mpz_realloc (ss, ssize); sp = PTR (ss); MPN_COPY (sp, tmp_sp, ssize); SIZ (ss) = SIZ (&stmp); } if (ALLOC (g) < gsize) _mpz_realloc (g, gsize); gp = PTR (g); MPN_COPY (gp, tmp_gp, gsize); SIZ (g) = gsize; TMP_FREE; }
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; } }