Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
	}
}
Ejemplo n.º 6
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;
		}
	}
Ejemplo n.º 7
0
Archivo: inv.c Proyecto: mahdiz/mpclib
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);
    }
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
Archivo: set.c Proyecto: mahdiz/mpclib
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;
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
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--);
	}
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
0
/* 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;
}
Ejemplo n.º 20
0
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;
}
Ejemplo n.º 21
0
Archivo: neg.c Proyecto: mahdiz/mpclib
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;
}
Ejemplo n.º 22
0
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);
}
Ejemplo n.º 23
0
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;
}
Ejemplo n.º 24
0
/*
 *
 * 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;
  }
}
Ejemplo n.º 25
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;

  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];
}
Ejemplo n.º 26
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];
}
Ejemplo n.º 27
0
Archivo: com.c Proyecto: mahdiz/mpclib
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;
    }
}
Ejemplo n.º 28
0
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;
	}
    }
}
Ejemplo n.º 29
0
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 (&gtmp) = tmp_gp;
  SIZ (&gtmp) = 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, &gtmp, 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;
}
Ejemplo 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;

  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;
    }
}