Ejemplo n.º 1
0
int main(void)
{
   int i, result;
   flint_rand_t state;
   
   printf("xgcd....");
   fflush(stdout);
   
   flint_randinit(state);

   for (i = 0; i < 100000; i++) 
   {
      mp_limb_t a, b, c, g, bits1, bits2, bits3, ph, pl, qh, ql;
      mp_limb_t s, t;
      
      bits1 = n_randint(state, FLINT_BITS-1) + 1;
      bits2 = n_randint(state, bits1) + 1;
      bits3 = n_randint(state, FLINT_BITS - bits1) + 1;

      do
      {
         a = n_randbits(state, bits1);
         b = n_randbits(state, bits2);
      } while ((n_gcd(a, b) != 1UL) || (b > a));

      c = n_randbits(state, bits3);

      g = n_xgcd(&s, &t, a*c, b*c);

      umul_ppmm(ph, pl, a*c, s);
      umul_ppmm(qh, ql, b*c, t);
      sub_ddmmss(ph, pl, ph, pl, qh, ql);
      
      result = ((g == c) && (ph == 0UL) && (pl == c));
      if (!result)
      {
         printf("FAIL:\n");
         printf("a = %lu, b = %lu, c = %lu, g = %lu, s = %lu, t = %lu\n", a, b, c, g, s, t); 
         abort();
      }
   }

   flint_randclear(state);

   printf("PASS\n");
   return 0;
}
Ejemplo n.º 2
0
int main(void)
{
   int i, result;
   flint_rand_t state;
   flint_randinit(state);

   printf("sdiv_qrnnd....");
   fflush(stdout);

   for (i = 0; i < 1000000; i++)
   {
      mp_limb_signed_t d, nh, nl, q, r, ph, pl;

      do 
      {
         d = n_randtest_not_zero(state);
         nh = n_randtest(state);
      } while (FLINT_ABS(nh) >= FLINT_ABS(d)/2);
      nl = n_randtest(state);

      sdiv_qrnnd(q, r, nh, nl, d);
      smul_ppmm(ph, pl, d, q);
      if (r < 0L) sub_ddmmss(ph, pl, ph, pl, 0UL, -r);
      else add_ssaaaa(ph, pl, ph, pl, 0UL, r);

      result = ((ph == nh) && (pl == nl));

      if (!result)
      {
         printf("FAIL:\n");
         printf("nh = %lu, nl = %lu, d = %lu\n", nh, nl, d); 
         printf("ph = %lu, pl = %lu\n", ph, pl);
         abort();
      }
   }

   flint_randclear(state);

   printf("PASS\n");
   return 0;
}
Ejemplo n.º 3
0
Archivo: add.c Proyecto: jwbober/arb
static __inline__ long
_fmpr_add_small(fmpr_t z, mp_limb_t x, int xsign, const fmpz_t xexp, mp_limb_t y, int ysign, const fmpz_t yexp, long shift, long prec, long rnd)
{
    mp_limb_t hi, lo, t, u;
    int sign = ysign;

    t = x;
    u = y;

    lo = u << shift;
    hi = (shift == 0) ? 0 : (u >> (FLINT_BITS - shift));

    if (xsign == ysign)
    {
        add_ssaaaa(hi, lo, hi, lo, 0, t);
    }
    else
    {
        if (hi == 0)
        {
            if (lo >= t)
            {
                lo = lo - t;
            }
            else
            {
                lo = t - lo;
                sign = !sign;
            }
        }
        else
        {
            sub_ddmmss(hi, lo, hi, lo, 0, t);
        }
    }

    if (hi == 0)
        return fmpr_set_round_ui_2exp_fmpz(z, lo, xexp, sign, prec, rnd);
    else
        return fmpr_set_round_uiui_2exp_fmpz(z, hi, lo, xexp, sign, prec, rnd);
}
Ejemplo n.º 4
0
void
check_data (void)
{
#define M  MP_LIMB_T_MAX

  static const struct {
    mp_limb_t  want_dh,want_dl, mh,ml, sh,sl;
  } data[] = {
    { 0,0,  0,0,  0,0 },
    { 0,0,  0,1,  0,1 },
    { 0,0,  1,2,  1,2 },

    { 0,1,  0,2,  0,1 },
    { 0,M,  1,0,  0,1 },
    { M,M,  0,0,  0,1 },

    { M,M,  0,M-1,  0,M },
    { 0,0,  0,M-1,  0,M-1 },
    { 0,1,  0,M-1,  0,M-2 },
  };
  int  i;
  mp_limb_t  got_dh, got_dl;

  for (i = 0; i < numberof (data); i++)
    {
      sub_ddmmss (got_dh,got_dl, data[i].mh,data[i].ml, data[i].sh,data[i].sl);
      if (got_dh != data[i].want_dh || got_dl != data[i].want_dl)
        {
          printf ("check_data wrong at data[%d]\n", i);
          mp_limb_trace ("  mh", data[i].mh);
          mp_limb_trace ("  ml", data[i].ml);
          mp_limb_trace ("  sh", data[i].sh);
          mp_limb_trace ("  sl", data[i].sl);
          mp_limb_trace ("  want dh", data[i].want_dh);
          mp_limb_trace ("  want dl", data[i].want_dl);
          mp_limb_trace ("  got dh ", got_dh);
          mp_limb_trace ("  got dl ", got_dl);
          abort ();
        }
    }
}
Ejemplo n.º 5
0
int main(void)
{
   int i, result;
   flint_rand_t state;
   
   printf("submod....");
   fflush(stdout);

   flint_randinit(state);

   for (i = 0; i < 1000000; i++)
   {
      mp_limb_t a, b, d, r1, r2, s1;
      
      d = n_randtest(state);
      a = n_randint(state, d);
      b = n_randint(state, d);
      
      r1 = n_submod(a, b, d);

      add_ssaaaa(s1, r2, 0UL, a, 0UL, d);
      sub_ddmmss(s1, r2, s1, r2, 0UL, b);
      if ((s1) || (r2 >= d)) r2 -= d;
      
      result = (r1 == r2);
      if (!result)
      {
         printf("FAIL:\n");
         printf("a = %lu, b = %lu, d = %lu\n", a, b, d); 
         printf("r1 = %lu, r2 = %lu\n", r1, r2);
         abort();
      }
   }

   flint_randclear(state);

   printf("PASS\n");
   return 0;
}
Ejemplo n.º 6
0
Archivo: subti3.c Proyecto: 0day-ci/gcc
int main(void)
{
  TIunion aa, bb, cc;
  TItype m = 0x1111111111111110ULL;
  TItype n = 0x1111111111111111ULL;
  TItype d;

  aa.s.high = m;
  aa.s.low = m;
  bb.s.high = n;
  bb.s.low = n;


  sub_ddmmss (&cc.s.high, &cc.s.low, aa.s.high, aa.s.low, bb.s.high, bb.s.low);
  d = aa.t - bb.t;
  if (d != cc.t)
   abort();
  cc.t = aa.t -d;
  if (cc.t != bb.t)
   abort();
 return 0;
}
Ejemplo n.º 7
0
void
check_random (void)
{
  mp_limb_t  want_dh,want_dl, got_dh,got_dl, mh,ml, sh,sl;
  int  i;
  gmp_randstate_t rands;
  
  gmp_randinit_default(rands);

  for (i = 0; i < 20; i++)
    {
      mh = urandom (rands);
      ml = urandom (rands);
      sh = urandom (rands);
      sl = urandom (rands);

      refmpn_sub_ddmmss (&want_dh,&want_dl, mh,ml, sh,sl);

      sub_ddmmss (got_dh,got_dl, mh,ml, sh,sl);

      if (got_dh != want_dh || got_dl != want_dl)
        {
          printf ("check_data wrong at data[%d]\n", i);
          mp_limb_trace ("  mh", mh);
          mp_limb_trace ("  ml", ml);
          mp_limb_trace ("  sh", sh);
          mp_limb_trace ("  sl", sl);
          mp_limb_trace ("  want dh", want_dh);
          mp_limb_trace ("  want dl", want_dl);
          mp_limb_trace ("  got dh ", got_dh);
          mp_limb_trace ("  got dl ", got_dl);
          abort ();
        }
    }
    gmp_randclear(rands);
}
void my_udiv_qr_3by2 ( mp_limb_t* p_q, mp_limb_t* p_r1, mp_limb_t* p_r0, mp_limb_t* p_n2, mp_limb_t* p_n1, mp_limb_t* p_n0, mp_limb_t* p_d1, mp_limb_t* p_d0, mp_limb_t* p_dinv, mp_limb_t* p__q0, mp_limb_t* p__t1, mp_limb_t* p__t0, mp_limb_t* p__mask) {

/*
mp_limb_t q = *p_q;
mp_limb_t r0 = *p_r0;
mp_limb_t r1 = *p_r1;
mp_limb_t n0 = *p_n0;
mp_limb_t n1 = *p_n1;
mp_limb_t n2 = *p_n2;
mp_limb_t dinv = *p_dinv;
mp_limb_t d0 = *p_d0;
mp_limb_t d1 = *p_d1;
    mp_limb_t _q0, _t1, _t0, _mask;                                     
_q0 = *p__q0;
_t0 = *p__t0;
_t1 = *p__t1;
_mask = *p__mask;
*/
#define q (*p_q)
#define r0 (*p_r0)
#define r1 (*p_r1)
#define n0 (*p_n0)
#define n1 (*p_n1)
#define n2 (*p_n2)
#define dinv (*p_dinv)
#define d0 (*p_d0)
#define d1 (*p_d1)
#define _q0 (*p__q0)
#define _t0 (*p__t0)
#define _t1 (*p__t1)
#define _mask (*p__mask)

printf("n0 %08lx\n", n0);
printf("n1 %08lx\n", n1);
printf("n2 %08lx\n", n2);
printf("dinv %08lx\n", dinv);
printf("d0 %08lx\n", d0);
printf("d1 %08lx\n", d1);

    umul_ppmm ((q), _q0, (n2), (dinv));                                 
printf("q %08lx\n", q);
printf("_q0 %08lx\n", _q0);
    add_ssaaaa ((q), _q0, (q), _q0, (n2), (n1));                        
printf("q %08lx\n", q);
                                                                        
    /* Compute the two most significant limbs of n - q'd */             
    (r1) = (n1) - (d1) * (q);                                           
printf("r1 %08lx\n", r1);
    (r0) = (n0);                                                        
printf("r0 %08lx\n", r0);
    sub_ddmmss ((r1), (r0), (r1), (r0), (d1), (d0));                    
    umul_ppmm (_t1, _t0, (d0), (q));                                    
printf("_t0 %08lx\n", _t0);
printf("_t1 %08lx\n", _t1);
    sub_ddmmss ((r1), (r0), (r1), (r0), _t1, _t0);                      
    (q)++;                                                              
                                                                        
    /* Conditionally adjust q and the remainders */                     
    _mask = - (mp_limb_t) ((r1) >= _q0);                                
printf("_mask %08lx\n", _mask);
    (q) += _mask;                                                       
printf("q %08lx\n", q);
    add_ssaaaa ((r1), (r0), (r1), (r0), _mask & (d1), _mask & (d0));    
    if (UNLIKELY ((r1) >= (d1)))                                        
      {                                                                 
        if ((r1) > (d1) || (r0) >= (d0))                                
          {                                                             
            (q)++;                                                      
printf("q %08lx\n", q);
            sub_ddmmss ((r1), (r0), (r1), (r0), (d1), (d0));            
          }                                                             
      }                                                                 

#undef q
#undef r0
#undef r1
#undef n0
#undef n1
#undef n2
#undef dinv
#undef d0
#undef d1
#undef _q0
#undef _t1
#undef _t0
#undef _mask
}
Ejemplo n.º 9
0
mp_limb_t _ll_factor_SQUFOF(mp_limb_t n_hi, mp_limb_t n_lo, ulong max_iters)
{
    mp_limb_t n[2];
	 mp_limb_t sqrt[2];
	 mp_limb_t rem[2];
	 mp_size_t num, sqroot, p, q;

    mp_limb_t l, l2, iq, pnext;
    mp_limb_t qarr[50];
    mp_limb_t qupto, qlast, t, r = 0;
    ulong i, j;

	 n[0] = n_lo;
	 n[1] = n_hi;

    if (n_hi) num = mpn_sqrtrem(sqrt, rem, n, 2);
    else num = ((sqrt[0] = n_sqrtrem(rem, n_lo)) != 0UL);
	
    sqroot = sqrt[0];
    p = sqroot;
    q = rem[0];

    if ((q == 0) || (num == 0))
    {
        return sqroot;
    }
   
    l = 1 + 2*n_sqrt(2*p);
    l2 = l/2;
    qupto = 0;
    qlast = 1;

    for (i = 0; i < max_iters; i++)
    {
        iq = (sqroot + p)/q;
        pnext = iq*q - p;
        if (q <= l) 
        {
            if ((q & 1UL) == 0UL) 
            {
                qarr[qupto] = q/2;
                qupto++;
                if (qupto >= 50UL) return 0UL;
            } else if (q <= l2)
            {
                qarr[qupto] = q;
                qupto++;
                if (qupto >= 50UL) return 0UL;
            }
        }

        t = qlast + iq*(p - pnext);
        qlast = q;
        q = t;
        p = pnext;
        if ((i & 1) == 1) continue;
        if (!n_is_square(q)) continue;
        r = n_sqrt(q);
        if (qupto == 0UL) break;
        for (j = 0; j < qupto; j++)	
            if (r == qarr[j]) goto cont;
        break;
      cont: ;
        if (r == 1UL) return 0UL;
   }
   
    if (i == max_iters) return 0UL;  /* taken too long, give up */

    qlast = r;
    p = p + r*((sqroot - p)/r);

	umul_ppmm(rem[1], rem[0], p, p);
    sub_ddmmss(sqrt[1], sqrt[0], n[1], n[0], rem[1], rem[0]);
	if (sqrt[1])
	{
        int norm;
        count_leading_zeros(norm, qlast);
        udiv_qrnnd(q, rem[0], (sqrt[1] << norm) + r_shift(sqrt[0], FLINT_BITS - norm), sqrt[0] << norm, qlast << norm); 
        rem[0] >>= norm;
    }
    else
    {
Ejemplo n.º 10
0
mp_limb_t
mpn_divrem (mp_ptr qp, mp_size_t qextra_limbs,
	    mp_ptr np, mp_size_t nsize,
	    mp_srcptr dp, mp_size_t dsize)
{
  mp_limb_t most_significant_q_limb = 0;

  switch (dsize)
    {
    case 0:
      /* We are asked to divide by zero, so go ahead and do it!  (To make
	 the compiler not remove this statement, return the value.)  */
      return 1 / dsize;

    case 1:
      {
	mp_size_t i;
	mp_limb_t n1;
	mp_limb_t d;

	d = dp[0];
	n1 = np[nsize - 1];

	if (n1 >= d)
	  {
	    n1 -= d;
	    most_significant_q_limb = 1;
	  }

	qp += qextra_limbs;
	for (i = nsize - 2; i >= 0; i--)
	  udiv_qrnnd (qp[i], n1, n1, np[i], d);
	qp -= qextra_limbs;

	for (i = qextra_limbs - 1; i >= 0; i--)
	  udiv_qrnnd (qp[i], n1, n1, 0, d);

	np[0] = n1;
      }
      break;

    case 2:
      {
	mp_size_t i;
	mp_limb_t n1, n0, n2;
	mp_limb_t d1, d0;

	np += nsize - 2;
	d1 = dp[1];
	d0 = dp[0];
	n1 = np[1];
	n0 = np[0];

	if (n1 >= d1 && (n1 > d1 || n0 >= d0))
	  {
	    sub_ddmmss (n1, n0, n1, n0, d1, d0);
	    most_significant_q_limb = 1;
	  }

	for (i = qextra_limbs + nsize - 2 - 1; i >= 0; i--)
	  {
	    mp_limb_t q;
	    mp_limb_t r;

	    if (i >= qextra_limbs)
	      np--;
	    else
	      np[0] = 0;

	    if (n1 == d1)
	      {
		/* Q should be either 111..111 or 111..110.  Need special
		   treatment of this rare case as normal division would
		   give overflow.  */
		q = ~(mp_limb_t) 0;

		r = n0 + d1;
		if (r < d1)	/* Carry in the addition? */
		  {
		    add_ssaaaa (n1, n0, r - d0, np[0], 0, d0);
		    qp[i] = q;
		    continue;
		  }
		n1 = d0 - (d0 != 0);
		n0 = -d0;
	      }
	    else
	      {
		udiv_qrnnd (q, r, n1, n0, d1);
		umul_ppmm (n1, n0, d0, q);
	      }

	    n2 = np[0];
	  q_test:
	    if (n1 > r || (n1 == r && n0 > n2))
	      {
		/* The estimated Q was too large.  */
		q--;

		sub_ddmmss (n1, n0, n1, n0, 0, d0);
		r += d1;
		if (r >= d1)	/* If not carry, test Q again.  */
		  goto q_test;
	      }

	    qp[i] = q;
	    sub_ddmmss (n1, n0, r, n2, n1, n0);
	  }
	np[1] = n1;
	np[0] = n0;
      }
      break;

    default:
      {
	mp_size_t i;
	mp_limb_t dX, d1, n0;

	np += nsize - dsize;
	dX = dp[dsize - 1];
	d1 = dp[dsize - 2];
	n0 = np[dsize - 1];

	if (n0 >= dX)
	  {
	    if (n0 > dX || mpn_cmp (np, dp, dsize - 1) >= 0)
	      {
		mpn_sub_n (np, np, dp, dsize);
		n0 = np[dsize - 1];
		most_significant_q_limb = 1;
	      }
	  }

	for (i = qextra_limbs + nsize - dsize - 1; i >= 0; i--)
	  {
	    mp_limb_t q;
	    mp_limb_t n1, n2;
	    mp_limb_t cy_limb;

	    if (i >= qextra_limbs)
	      {
		np--;
		n2 = np[dsize];
	      }
	    else
	      {
		n2 = np[dsize - 1];
		MPN_COPY_DECR (np + 1, np, dsize);
		np[0] = 0;
	      }

	    if (n0 == dX)
	      /* This might over-estimate q, but it's probably not worth
		 the extra code here to find out.  */
	      q = ~(mp_limb_t) 0;
	    else
	      {
		mp_limb_t r;

		udiv_qrnnd (q, r, n0, np[dsize - 1], dX);
		umul_ppmm (n1, n0, d1, q);

		while (n1 > r || (n1 == r && n0 > np[dsize - 2]))
		  {
		    q--;
		    r += dX;
		    if (r < dX)	/* I.e. "carry in previous addition?"  */
		      break;
		    n1 -= n0 < d1;
		    n0 -= d1;
		  }
	      }

	    /* Possible optimization: We already have (q * n0) and (1 * n1)
	       after the calculation of q.  Taking advantage of that, we
	       could make this loop make two iterations less.  */

	    cy_limb = mpn_submul_1 (np, dp, dsize, q);

	    if (n2 != cy_limb)
	      {
		mpn_add_n (np, np, dp, dsize);
		q--;
	      }

	    qp[i] = q;
	    n0 = np[dsize - 1];
	  }
      }
    }

  return most_significant_q_limb;
}
Ejemplo n.º 11
0
mp_limb_t
mpn_div_qr_1n_pi2 (mp_ptr qp,
		   mp_srcptr up, mp_size_t un,
		   struct precomp_div_1_pi2 *pd)
{
  mp_limb_t most_significant_q_limb;
  mp_size_t i;
  mp_limb_t r, u2, u1, u0;
  mp_limb_t d0, di1, di0;
  mp_limb_t q3a, q2a, q2b, q1b, q2c, q1c, q1d, q0d;
  mp_limb_t cnd;

  ASSERT (un >= 2);
  ASSERT ((pd->d & GMP_NUMB_HIGHBIT) != 0);
  ASSERT (! MPN_OVERLAP_P (qp, un-2, up, un) || qp+2 >= up);
  ASSERT_MPN (up, un);

#define q3 q3a
#define q2 q2b
#define q1 q1b

  up += un - 3;
  r = up[2];
  d0 = pd->d;

  most_significant_q_limb = (r >= d0);
  r -= d0 & -most_significant_q_limb;

  qp += un - 3;
  qp[2] = most_significant_q_limb;

  di1 = pd->dip[1];
  di0 = pd->dip[0];

  for (i = un - 3; i >= 0; i -= 2)
    {
      u2 = r;
      u1 = up[1];
      u0 = up[0];

      /* Dividend in {r,u1,u0} */

      umul_ppmm (q1d,q0d, u1, di0);
      umul_ppmm (q2b,q1b, u1, di1);
      q2b++;				/* cannot spill */
      add_sssaaaa (r,q2b,q1b, q2b,q1b, u1,u0);

      umul_ppmm (q2c,q1c, u2,  di0);
      add_sssaaaa (r,q2b,q1b, q2b,q1b, q2c,q1c);
      umul_ppmm (q3a,q2a, u2, di1);

      add_sssaaaa (r,q2b,q1b, q2b,q1b, q2a,q1d);

      q3 += r;

      r = u0 - q2 * d0;

      cnd = (r >= q1);
      r += d0 & -cnd;
      sub_ddmmss (q3,q2,  q3,q2,  0,cnd);

      if (UNLIKELY (r >= d0))
	{
	  r -= d0;
	  add_ssaaaa (q3,q2,  q3,q2,  0,1);
	}

      qp[0] = q2;
      qp[1] = q3;

      up -= 2;
      qp -= 2;
    }

  if ((un & 1) == 0)
    {
      u2 = r;
      u1 = up[1];

      udiv_qrnnd_preinv (q3, r, u2, u1, d0, di1);
      qp[1] = q3;
    }

  return r;

#undef q3
#undef q2
#undef q1
}