static PyObject *
Pygmpy_f_divmod(PyObject *self, PyObject *args)
{
    PyObject *x, *y, *result;
    PympzObject *q, *r, *tempx, *tempy;

    if(PyTuple_GET_SIZE(args) != 2) {
        TYPE_ERROR("f_divmod() requires 'mpz','mpz' arguments");
        return NULL;
    }

    x = PyTuple_GET_ITEM(args, 0);
    y = PyTuple_GET_ITEM(args, 1);
    CREATE_TWO_MPZ_TUPLE(q, r, result);

    if (CHECK_MPZANY(x) && CHECK_MPZANY(y)) {
        if (mpz_sgn(Pympz_AS_MPZ(y)) == 0) {
            ZERO_ERROR("f_divmod() division by 0");
            Py_DECREF((PyObject*)q);
            Py_DECREF((PyObject*)r);
            Py_DECREF(result);
            return NULL;
        }
        mpz_fdiv_qr(q->z, r->z, Pympz_AS_MPZ(x), Pympz_AS_MPZ(y));
    }
    else {
        tempx = Pympz_From_Integer(x);
        tempy = Pympz_From_Integer(y);
        if (!tempx || !tempy) {
            TYPE_ERROR("f_divmod() requires 'mpz','mpz' arguments");
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)q);
            Py_DECREF((PyObject*)r);
            Py_DECREF(result);
            return NULL;
        }
        if (mpz_sgn(Pympz_AS_MPZ(tempy)) == 0) {
            ZERO_ERROR("f_divmod() division by 0");
            Py_DECREF((PyObject*)tempx);
            Py_DECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)q);
            Py_DECREF((PyObject*)r);
            Py_DECREF(result);
            return NULL;
        }
        mpz_fdiv_qr(q->z, r->z, tempx->z, tempy->z);
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
    }
    PyTuple_SET_ITEM(result, 0, (PyObject*)q);
    PyTuple_SET_ITEM(result, 1, (PyObject*)r);
    return result;
}
示例#2
0
ring_elem RingZZ::remainderAndQuotient(const ring_elem f, const ring_elem g,
                                  ring_elem &quot) const
{
  mpz_ptr q = new_elem();
  mpz_ptr r = new_elem();
  int gsign = mpz_sgn(g.get_mpz());
  mpz_t gg, ghalf;
  mpz_init(gg);
  mpz_init(ghalf);
  mpz_abs(gg,g.get_mpz());
  mpz_fdiv_qr(q, r, f.get_mpz(), gg);
  mpz_tdiv_q_2exp(ghalf, gg, 1);
  if (mpz_cmp(r,ghalf) > 0)  // r > ghalf
    {
      mpz_sub(r,r,gg);
      mpz_add_ui(q,q,1);
    }
  if (gsign < 0)
    mpz_neg(q,q);

  mpz_clear(gg);
  mpz_clear(ghalf);
  quot = ring_elem(q);
  return ring_elem(r);
}
示例#3
0
void C_BigInt::floorDivideInPlace (const C_BigInt inDivisor, C_BigInt & outRemainder) {
  mpz_t quotient ;
  mpz_init (quotient) ;
  mpz_fdiv_qr (quotient, outRemainder.mGMPint, mGMPint, inDivisor.mGMPint) ;
  mpz_swap (quotient, mGMPint) ;
  mpz_clear (quotient) ;
}
示例#4
0
static Variant HHVM_FUNCTION(gmp_div_qr,
                             const Variant& dataA,
                             const Variant& dataB,
                             int64_t round = GMP_ROUND_ZERO) {
  mpz_t gmpDataA, gmpDataB, gmpReturnQ, gmpReturnR;

  if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIV_QR, gmpDataA, dataA)) {
    return false;
  }
  if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIV_QR, gmpDataB, dataB)) {
    mpz_clear(gmpDataA);
    return false;
  }

  if (mpz_sgn(gmpDataB) == 0) {
    mpz_clear(gmpDataA);
    mpz_clear(gmpDataB);

    raise_warning(cs_GMP_INVALID_VALUE_MUST_NOT_BE_ZERO,
                  cs_GMP_FUNC_NAME_GMP_DIV_QR);
    return false;
  }

  mpz_init(gmpReturnQ);
  mpz_init(gmpReturnR);

  switch (round)
  {
  case GMP_ROUND_ZERO:
    mpz_tdiv_qr(gmpReturnQ, gmpReturnR, gmpDataA, gmpDataB);
    break;

  case GMP_ROUND_PLUSINF:
    mpz_cdiv_qr(gmpReturnQ, gmpReturnR, gmpDataA, gmpDataB);
    break;

  case GMP_ROUND_MINUSINF:
    mpz_fdiv_qr(gmpReturnQ, gmpReturnR, gmpDataA, gmpDataB);
    break;

  default:
    mpz_clear(gmpDataA);
    mpz_clear(gmpDataB);
    mpz_clear(gmpReturnQ);
    mpz_clear(gmpReturnR);
    return null_variant;
  }

  ArrayInit returnArray(2, ArrayInit::Map{});
  returnArray.set(0, NEWOBJ(GMPResource)(gmpReturnQ));
  returnArray.set(1, NEWOBJ(GMPResource)(gmpReturnR));

  mpz_clear(gmpDataA);
  mpz_clear(gmpDataB);
  mpz_clear(gmpReturnQ);
  mpz_clear(gmpReturnR);

  return returnArray.toVariant();
}
示例#5
0
文件: big.o.c 项目: hoobaa/mecl
cl_object
_ecl_big_floor(cl_object a, cl_object b, cl_object *pr)
{
        cl_object q = _ecl_big_register0();
        cl_object r = _ecl_big_register1();
        mpz_fdiv_qr(q->big.big_num, r->big.big_num, a->big.big_num, b->big.big_num);
        *pr = _ecl_big_register_normalize(r);
        return _ecl_big_register_normalize(q);
}
示例#6
0
void
modinv(mpz_t r, mpz_t x, mpz_t m)
{
    int iter = 1;
    mpz_t x1, x3, m1, m3, t1, t3, q;

    mpz_init_set_ui(x1, 1L);
    mpz_init_set(x3, x);
    mpz_init(m1);
    mpz_init_set(m3, m);
    mpz_init(t1);
    mpz_init(t3);
    mpz_init(q);

    // Loop while m3 != 0
    int kk = 0;

    while (mpz_sgn(m3) != 0) {
        // Divide and "Subtract"
        mpz_fdiv_qr(q, t3, x3, m3);
        mpz_mul(t1, q, m1);
        mpz_add(t1, t1, x1);
        // Swap
        mpz_swap(x1, m1);
        mpz_swap(m1, t1);
        mpz_swap(x3, m3);
        mpz_swap(m3, t3);
        iter = -iter;
        ++kk;
    }

    // Make sure x3 = gcd(x,m) == 1
    if (mpz_cmp_ui(x3, 1L) != 0) {
        // Error: No inverse exists
        mpz_set_ui(r, 0L);
        goto end;
    }

    // Ensure a positive result
    if (iter < 0)
        mpz_sub(r, m, x1);
    else
        mpz_set(r, x1);

end:
    mpz_clear(x1);
    mpz_clear(x3);
    mpz_clear(m1);
    mpz_clear(m3);
    mpz_clear(t1);
    mpz_clear(t3);
    mpz_clear(q);
}
示例#7
0
static int
sdiv_qr (mpz_t q, mpz_t r, mp_size_t s, const mpz_t a, const mpz_t b)
{
  mpz_fdiv_qr (q, r, a, b);
  if (mpz_size (r) <= s)
    {
      mpz_add (r, r, b);
      mpz_sub_ui (q, q, 1);
    }

  return (mpz_sgn (q) > 0);
}
示例#8
0
void encode(int* array, header h, int level)
{
	int allzeroes = 1;
	if (level == LEVELS || h.size == 1)
	{	
		return encode_last(array, h);
	}
	int counter = 0;
	int index = 0;
	int new_array[headers[level+1].size];
	char* total = malloc(sizeof(char)*h.size);
	if(total == NULL)
	{
		printf("ERROR!\n");
		exit(1);
	}
	char* start = total;
	while(counter < h.size)
	{
		if(h.size - counter < h.chunksize)
		{
			for(int i = 0; i < h.chunksize - h.size + counter; i++)
				total++;
			int tot = h.size - counter;
			for (int i = 0; i < tot; i++)
			{
				total[i] = array[counter] + '0';
				counter++;
			}
		}
		else
		{
			for (int i = 0; i < h.chunksize; i++)
			{
				total[i] = array[counter] + '0';
				counter++;
			}
		}
		mpz_set_str(number, total, h.K);
		mpz_fdiv_qr(k,m,number,divisor);
		if(mpz_sgn(k))
			allzeroes = 0;
		new_array[index] = mpz_get_ui(k);
		unsigned int remains = mpz_get_ui(m);
		fwrite(&remains, sizeof(unsigned int), 1, output);
		index++;
	
	}
	free(start);
	if (allzeroes)
		return;
	return encode(new_array, headers[level+1], level + 1);
}
示例#9
0
文件: rw.c 项目: agl/rwb0fuz1024
// -----------------------------------------------------------------------------
// Calculate a compressed Rabin signature (see Compressing Rabin Signatures,
// Daniel Bleichenbacher)
//
// zsig: (output) the resulting signature
// s: the Rabin signature
// n: the composite group order
// -----------------------------------------------------------------------------
static void
signature_compress(mpz_t zsig, mpz_t s, mpz_t n) {
  mpz_t vs[4];
  mpz_init_set_ui(vs[0], 0);
  mpz_init_set_ui(vs[1], 1);
  mpz_init(vs[2]);
  mpz_init(vs[3]);

  mpz_t root;
  mpz_init(root);
  mpz_sqrt(root, n);

  mpz_t cf;
  mpz_init(cf);

  unsigned i = 1;

  do {
    i = (i + 1) & 3;

    if (i & 1) {
      mpz_fdiv_qr(cf, s, s, n);
    } else {
      mpz_fdiv_qr(cf, n, n, s);
    }
    mpz_mul(vs[i], vs[(i-1)&3], cf);
    mpz_add(vs[i], vs[i], vs[(i-2)&3]);
  } while (mpz_cmp(vs[i], root) < 0);

  mpz_init(zsig);
  mpz_set(zsig, vs[(i-1) & 3]);

  mpz_clear(root);
  mpz_clear(cf);
  mpz_clear(vs[0]);
  mpz_clear(vs[1]);
  mpz_clear(vs[2]);
  mpz_clear(vs[3]);
}
示例#10
0
static PyObject *
GMPy_MPZ_Method_Round(PyObject *self, PyObject *args)
{
    Py_ssize_t round_digits;
    MPZ_Object *result;
    mpz_t temp, rem;

    if (PyTuple_GET_SIZE(args) == 0) {
        Py_INCREF(self);
        return self;
    }

    round_digits = ssize_t_From_Integer(PyTuple_GET_ITEM(args, 0));
    if (round_digits == -1 && PyErr_Occurred()) {
        TYPE_ERROR("__round__() requires 'int' argument");
        return NULL;
    }

    if (round_digits >= 0) {
        Py_INCREF(self);
        return self;
    }

    round_digits = -round_digits;

    if ((result = GMPy_MPZ_New(NULL))) {
        if (round_digits >= mpz_sizeinbase(MPZ(self), 10)) {
            mpz_set_ui(result->z, 0);
        }
        else {
            mpz_inoc(temp);
            mpz_inoc(rem);
            mpz_ui_pow_ui(temp, 10, round_digits);
            mpz_fdiv_qr(result->z, rem, MPZ(self), temp);
            mpz_mul_2exp(rem, rem, 1);
            if (mpz_cmp(rem, temp) > 0) {
                mpz_add_ui(result->z, result->z, 1);
            }
            else if (mpz_cmp(rem, temp) == 0) {
                if (mpz_odd_p(result->z)) {
                    mpz_add_ui(result->z, result->z, 1);
                }
            }
            mpz_mul(result->z, result->z, temp);
            mpz_cloc(rem);
            mpz_cloc(temp);
        }
    }

    return (PyObject*)result;
}
示例#11
0
	/* uint64_t *factors_exp;      /* this can be used to keep track for the full factorization of
	 * an element x²-n. For the use of this version, refer to the
	 * qs_exponent_vector.c version
	 */

	mpz_t factors_vect; /* this nb_primes_in_base bit vector is a substitute of the
	 * factors_exp array, all we actually need for the elimination
	 * in the Linear algebra step is the exponents modulo 2.
	 * This saves huge space within the sieving step
	 */
} smooth_number_t;

mpz_t N; /* number to factorize */
matrix_t matrix;

uint64_t nb_smooth_numbers_found = 0;
uint64_t nb_qr_primes; /* number of primes p where N is a quadratic residue mod p */
uint64_t *primes; /* array holding the primes of the smoothness base */

smooth_number_t *smooth_numbers;
int NB_VECTORS_OFFSET = 5; /* number of additional rows in the matrix, to make sure that a linear relation exists */

//-----------------------------------------------------------
// base <- exp((1/2) sqrt(ln(n) ln(ln(n))))
//-----------------------------------------------------------
void get_smoothness_base(mpz_t base, mpz_t n) {
	mpfr_t fN, lnN, lnlnN;
	mpfr_init(fN), mpfr_init(lnN), mpfr_init(lnlnN);

	mpfr_set_z(fN, n, MPFR_RNDU);
	mpfr_log(lnN, fN, MPFR_RNDU);
	mpfr_log(lnlnN, lnN, MPFR_RNDU);

	mpfr_mul(fN, lnN, lnlnN, MPFR_RNDU);
	mpfr_sqrt(fN, fN, MPFR_RNDU);
	mpfr_div_ui(fN, fN, 2, MPFR_RNDU);
	mpfr_exp(fN, fN, MPFR_RNDU);

	mpfr_get_z(base, fN, MPFR_RNDU);

	mpfr_clears(fN, lnN, lnlnN, NULL);
}

// returns the index of the first element to start sieving from
// (first multiple of root that is directly greater than start)
// res = p*t + root >= start */
void get_sieving_start_index(mpz_t res, mpz_t start, mpz_t p,
		unsigned long root) {
	mpz_t q, r;
	mpz_init(q);
	mpz_init(r);

	mpz_sub_ui(start, start, root);
	mpz_fdiv_qr(q, r, start, p);

	if (mpz_cmp_ui(r, 0) != 0)
		mpz_add_ui(q, q, 1);

	mpz_mul(q, q, p); /* next element p*q+root that is directly >= start */
	mpz_add_ui(q, q, root);
	mpz_set(res, q);
	mpz_clear(q);
	mpz_clear(r);
}
示例#12
0
文件: pidigits.c 项目: 0day-ci/gcc
static int extract_digit()
{
  if (mpz_cmp(numer, accum) > 0)
    return -1;

  /* Compute (numer * 3 + accum) / denom */
  mpz_mul_2exp(tmp1, numer, 1);
  mpz_add(tmp1, tmp1, numer);
  mpz_add(tmp1, tmp1, accum);
  mpz_fdiv_qr(tmp1, tmp2, tmp1, denom);

  /* Now, if (numer * 4 + accum) % denom... */
  mpz_add(tmp2, tmp2, numer);

  /* ... is normalized, then the two divisions have the same result.  */
  if (mpz_cmp(tmp2, denom) >= 0)
    return -1;

  return mpz_get_ui(tmp1);
}
//~ Initialises remainning data of 'op'
void init_glvRData(SGLVData *op){
	
	mpz_t  u, v, x1, x2, y1, y2, q, r, x, y, tmp;
	mpz_inits (u, v, x1, x2, y1, y2, q, r, x, y, tmp, NULL);
	
	mpz_set (u, op->efp);
	mpz_set (v, op->phi);
	
	mpz_set_ui (x1, 1);
	mpz_set_ui (y2, 1);
	
	while(mpz_cmp(u, op->refp) > 0){
		mpz_fdiv_qr (q, r, v, u);
		
		mpz_mul (tmp, q, x1);
		mpz_sub (x, x2, tmp);
		mpz_mul (tmp, q, y1);
		mpz_sub (y, y2, tmp);
		
		mpz_set (v, u);
		mpz_set (u, r);
		
		mpz_set (x2, x1);
		mpz_set (x1, x);
		mpz_set (y2, y1);
		mpz_set (y1, y);
	}
	
	mpz_add (op->aa, u, y);		// aa = u + y
	mpz_neg (op->bb, y);	 	// bb = -y
	
	mpz_mul (x1, op->bb, op->bb);		// x1 = (bb)^2
	mpz_mul (x2, u, op->bb);			// x2 = u * bb
	mpz_mul (op->Na, u, u);				// Na = u^2
	mpz_add (op->Na, op->Na, x1);		// Na = u^2 + (bb)^2 
	mpz_sub (op->Na, op->Na, x2);		// Na = u^2 + (bb)^2 - (u * bb)
	
	mpz_clears (u, v, x1, x2, y1, y2, q, r, x, y, tmp, NULL);
}
示例#14
0
文件: fdiv_qr.c 项目: goens/flint2
void
fmpz_fdiv_qr(fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h)
{
    fmpz c1 = *g;
    fmpz c2 = *h;

    if (fmpz_is_zero(h))
    {
        printf("Exception: division by zero in fmpz_fdiv_q\n");
        abort();
    }

    if (!COEFF_IS_MPZ(c1))      /* g is small */
    {
        if (!COEFF_IS_MPZ(c2))  /* h is also small */
        {
            fmpz q = c1 / c2;   /* compute C quotient */
            fmpz r = c1 - c2 * q;   /* compute remainder */

            if ((c2 > 0L && r < 0L) || (c2 < 0L && r > 0L))
            {
                q--;            /* q cannot overflow as remainder implies |c2| != 1 */
                r += c2;
            }

            fmpz_set_si(f, q);
            fmpz_set_si(s, r);
        }
        else                    /* h is large and g is small */
        {
            if (c1 == 0L)
            {
                fmpz_set_ui(f, 0L); /* g is zero */
                fmpz_set_si(s, c1);
            }
            else if ((c1 < 0L && fmpz_sgn(h) < 0) || (c1 > 0L && fmpz_sgn(h) > 0))  /* signs are the same */
            {
                fmpz_zero(f);   /* quotient is positive, round down to zero */
                fmpz_set_si(s, c1);
            }
            else
            {
                fmpz_add(s, g, h);
                fmpz_set_si(f, -1L);    /* quotient is negative, round down to minus one */
            }
        }
    }
    else                        /* g is large */
    {
        __mpz_struct *mpz_ptr, *mpz_ptr2;

        _fmpz_promote(f); /* must not hang on to ptr whilst promoting s */
        mpz_ptr2 = _fmpz_promote(s);
		mpz_ptr  = COEFF_TO_PTR(*f);

		if (!COEFF_IS_MPZ(c2))  /* h is small */
        {
            if (c2 > 0)         /* h > 0 */
            {
                mpz_fdiv_qr_ui(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), c2);
            }
            else
            {
                mpz_cdiv_qr_ui(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), -c2);
                mpz_neg(mpz_ptr, mpz_ptr);
            }
        }
        else                    /* both are large */
        {
            mpz_fdiv_qr(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2));
        }
        _fmpz_demote_val(f);    /* division by h may result in small value */
        _fmpz_demote_val(s);    /* division by h may result in small value */
    }
}
示例#15
0
void
hex_random_op4 (enum hex_random_op op, unsigned long maxbits,
		char **ap, char **bp, char **cp, char **dp)
{
  mpz_t a, b, c, d;
  unsigned long abits, bbits;
  unsigned signs;

  mpz_init (a);
  mpz_init (b);
  mpz_init (c);
  mpz_init (d);

  if (op == OP_POWM)
    {
      unsigned long cbits;
      abits = gmp_urandomb_ui (state, 32) % maxbits;
      bbits = 1 + gmp_urandomb_ui (state, 32) % maxbits;
      cbits = 2 + gmp_urandomb_ui (state, 32) % maxbits;

      mpz_rrandomb (a, state, abits);
      mpz_rrandomb (b, state, bbits);
      mpz_rrandomb (c, state, cbits);

      signs = gmp_urandomb_ui (state, 3);
      if (signs & 1)
	mpz_neg (a, a);
      if (signs & 2)
	{
	  mpz_t g;

	  /* If we negate the exponent, must make sure that gcd(a, c) = 1 */
	  if (mpz_sgn (a) == 0)
	    mpz_set_ui (a, 1);
	  else
	    {
	      mpz_init (g);

	      for (;;)
		{
		  mpz_gcd (g, a, c);
		  if (mpz_cmp_ui (g, 1) == 0)
		    break;
		  mpz_divexact (a, a, g);
		}
	      mpz_clear (g);
	    }
	  mpz_neg (b, b);
	}
      if (signs & 4)
	mpz_neg (c, c);

      mpz_powm (d, a, b, c);
    }
  else
    {
      unsigned long qbits;
      bbits = 1 + gmp_urandomb_ui (state, 32) % maxbits;
      qbits = gmp_urandomb_ui (state, 32) % maxbits;
      abits = bbits + qbits;
      if (abits > 30)
	abits -= 30;
      else
	abits = 0;

      mpz_rrandomb (a, state, abits);
      mpz_rrandomb (b, state, bbits);

      signs = gmp_urandomb_ui (state, 2);
      if (signs & 1)
	mpz_neg (a, a);
      if (signs & 2)
	mpz_neg (b, b);

      switch (op)
	{
	default:
	  abort ();
	case OP_CDIV:
	  mpz_cdiv_qr (c, d, a, b);
	  break;
	case OP_FDIV:
	  mpz_fdiv_qr (c, d, a, b);
	  break;
	case OP_TDIV:
	  mpz_tdiv_qr (c, d, a, b);
	  break;
	}
    }
  gmp_asprintf (ap, "%Zx", a);
  gmp_asprintf (bp, "%Zx", b);
  gmp_asprintf (cp, "%Zx", c);
  gmp_asprintf (dp, "%Zx", d);

  mpz_clear (a);
  mpz_clear (b);
  mpz_clear (c);
  mpz_clear (d);
}
示例#16
0
文件: intinf.c 项目: Munksgaard/mosml
value largeint_fdivmod(value quotdest, value remdest, value li1, value li2)
{ 
  mpz_fdiv_qr(Large_val(quotdest), Large_val(remdest), 
	     Large_val(li1), Large_val(li2)); 
  return Val_unit;
}
示例#17
0
文件: prime.c 项目: zoresvit/sandbox
void genNextLevelPrime(mpz_t prime, mpz_t r, mpz_t s, size_t length, gmp_randstate_t rand_state)
{
    size_t k;

    mpz_t sinv;     /* s^(-1) - inverse of s (mod r) */
    mpz_t pow;      /* 2^(n-1) */
    mpz_t dprod;    /* 2rs */
    mpz_t Q;        /* [pow / dprod] - integer part */
    mpz_t R;        /* remainder of pow/dprod */
    mpz_t cond;     /* temporary variable for 2*s*s^(-1) - 1 to check condition */
    mpz_t Po;
    /* Po = 2*s*s^(-1) - 1 + Q*2rs, if 2*s*s^(-1) - 1 > R */
    /* Po = 2*s*s^(-1) - 1 + (Q+1)*2rs, if 2*s*s^(-1) - 1 < R*/

    mpz_init(prime);
    mpz_init(sinv);
    mpz_init(pow);
    mpz_init(dprod);
    mpz_init(Q);
    mpz_init(R);
    mpz_init(cond);
    mpz_init(Po);

    inverse(sinv, s, r);

    mpz_ui_pow_ui(pow, 2, length-1);

    /* find product 2rs */
    mpz_mul_ui(dprod, r, 2);
    mpz_mul(dprod, dprod, s);

    /* compute Q and R */
    mpz_fdiv_qr(Q, R, pow, dprod);

    /* compute 2*s*s^(-1) - 1 for condition check */
    mpz_mul_ui(cond, s, 2);
    mpz_mul(cond, cond, sinv);
    mpz_sub_ui(cond, cond, 1);

    if(mpz_cmp(cond, R) > 0)
    {
        mpz_mul(Po, Q, dprod);
        mpz_add(Po, Po, cond);
    }
    else /* cond < R */
    {
        mpz_add_ui(Q, Q, 1);
        mpz_mul(Po, Q, dprod);
        mpz_add(Po, Po, cond);
    }

    /* TODO: fix the magic number and use 2k < 2^t limit  */
    for(k = 0; k < 0.35*(length-1); ++k)
    {
        mpz_mul_ui(prime, dprod, k);
        mpz_add(prime, prime, Po);

        /* exit loop if the number is definately prime (return value is 2) */
        if(mpz_probab_prime_p(prime, 40))
            break;
    }

    mpz_clear(sinv);
    mpz_clear(pow);
    mpz_clear(dprod);
    mpz_clear(Q);
    mpz_clear(R);
    mpz_clear(cond);
    mpz_clear(Po);
}
示例#18
0
/*-------------------------------------------------------------------------*/
static int
pol_expand(curr_poly_t *c, mpz_t gmp_N)
{
    /* compute coefficients */
    mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help4);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_d);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_a[5]);
    mpz_sub(c->gmp_help3, gmp_N, c->gmp_help4);
    mpz_fdiv_qr(c->gmp_help3, c->gmp_help1, c->gmp_help3, c->gmp_p);
    if (mpz_sgn(c->gmp_help1))
        return 0;

    if (mpz_cmp_ui(c->gmp_p, 1) == 0)
        mpz_set_ui(c->gmp_help2, 1);
    else {
        if (!mpz_invert(c->gmp_help2, c->gmp_d, c->gmp_p))
            return 0;
    }
    mpz_mul(c->gmp_help4, c->gmp_help2, c->gmp_help2);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help4);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help3);
    mpz_fdiv_r(c->gmp_a[4], c->gmp_help4, c->gmp_p);
    mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help4);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_a[4]);
    mpz_sub(c->gmp_help3, c->gmp_help3, c->gmp_help4);
    mpz_fdiv_qr(c->gmp_help3, c->gmp_help1, c->gmp_help3, c->gmp_p);
    if (mpz_sgn(c->gmp_help1))
        return 0;

    mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_d);
    mpz_fdiv_q(c->gmp_a[3], c->gmp_help3, c->gmp_help4);
    mpz_fdiv_q(c->gmp_a[3], c->gmp_a[3], c->gmp_p);
    mpz_mul(c->gmp_a[3], c->gmp_a[3], c->gmp_p);
    mpz_mul(c->gmp_help4, c->gmp_help2, c->gmp_help2);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help2);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help3);
    mpz_fdiv_r(c->gmp_help1, c->gmp_help4, c->gmp_p);
    mpz_add(c->gmp_a[3], c->gmp_a[3], c->gmp_help1);
    mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_d);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_a[3]);
    mpz_sub(c->gmp_help3, c->gmp_help3, c->gmp_help4);
    mpz_fdiv_qr(c->gmp_help3, c->gmp_help1, c->gmp_help3, c->gmp_p);
    if (mpz_sgn(c->gmp_help1))
        return 0;

    mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d);
    mpz_fdiv_q(c->gmp_a[2], c->gmp_help3, c->gmp_help4);
    mpz_fdiv_q(c->gmp_a[2], c->gmp_a[2], c->gmp_p);
    mpz_mul(c->gmp_a[2], c->gmp_a[2], c->gmp_p);
    mpz_mul(c->gmp_help4, c->gmp_help2, c->gmp_help2);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help3);
    mpz_fdiv_r(c->gmp_help1, c->gmp_help4, c->gmp_p);
    mpz_add(c->gmp_a[2], c->gmp_a[2], c->gmp_help1);
    mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_a[2]);
    mpz_sub(c->gmp_help3, c->gmp_help3, c->gmp_help4);
    mpz_fdiv_qr(c->gmp_help3, c->gmp_help1, c->gmp_help3, c->gmp_p);
    if (mpz_sgn(c->gmp_help1))
        return 0;

    mpz_fdiv_q(c->gmp_a[1], c->gmp_help3, c->gmp_d);
    mpz_fdiv_q(c->gmp_a[1], c->gmp_a[1], c->gmp_p);
    mpz_mul(c->gmp_a[1], c->gmp_a[1], c->gmp_p);
    mpz_mul(c->gmp_help4, c->gmp_help3, c->gmp_help2);
    mpz_fdiv_r(c->gmp_help1, c->gmp_help4, c->gmp_p);
    mpz_add(c->gmp_a[1], c->gmp_a[1], c->gmp_help1);
    mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_a[1]);
    mpz_sub(c->gmp_help3, c->gmp_help3, c->gmp_help4);
    mpz_fdiv_qr(c->gmp_help3, c->gmp_help1, c->gmp_help3, c->gmp_p);
    if (mpz_sgn(c->gmp_help1))
        return 0;

    mpz_set(c->gmp_a[0], c->gmp_help3);

    mpz_fdiv_qr(c->gmp_help1, c->gmp_a[3], c->gmp_a[3], c->gmp_d);
    mpz_add(c->gmp_help2, c->gmp_a[3], c->gmp_a[3]);
    if (mpz_cmp(c->gmp_d, c->gmp_help2) < 0) {
        mpz_sub(c->gmp_a[3], c->gmp_a[3], c->gmp_d);
        mpz_add_ui(c->gmp_help1, c->gmp_help1, 1);
    }
    mpz_mul(c->gmp_help1, c->gmp_help1, c->gmp_p);
    mpz_add(c->gmp_a[4], c->gmp_a[4], c->gmp_help1);

    mpz_fdiv_qr(c->gmp_help1, c->gmp_a[2], c->gmp_a[2], c->gmp_d);
    mpz_add(c->gmp_help2, c->gmp_a[2], c->gmp_a[2]);
    if (mpz_cmp(c->gmp_d, c->gmp_help2) < 0) {
        mpz_sub(c->gmp_a[2], c->gmp_a[2], c->gmp_d);
        mpz_add_ui(c->gmp_help1, c->gmp_help1, 1);
    }
    mpz_mul(c->gmp_help1, c->gmp_help1, c->gmp_p);
    mpz_add(c->gmp_a[3], c->gmp_a[3], c->gmp_help1);

    mpz_set(c->gmp_lina[1], c->gmp_p);
    mpz_neg(c->gmp_lina[0], c->gmp_d);
    mpz_invert(c->gmp_m, c->gmp_p, gmp_N);
    mpz_mul(c->gmp_m, c->gmp_m, c->gmp_d);
    mpz_mod(c->gmp_m, c->gmp_m, gmp_N);

    if (verbose > 2) {
        int i;

        printf("pol-expand\npol0: ");
        for (i = 5; i >= 0; i--) {
            mpz_out_str(stdout, 10, c->gmp_a[i]);
            printf(" ");
        }
        printf("\npol1: ");
        mpz_out_str(stdout, 10, c->gmp_lina[1]);
        printf(" ");
        mpz_out_str(stdout, 10, c->gmp_lina[0]);
        printf("\n\n");
    }

    return 1;
}
示例#19
0
int
main(void)
{
    int i, result;
    FLINT_TEST_INIT(state);

    flint_printf("fdiv_qr....");
    fflush(stdout);

    

    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, b, c, r;
        mpz_t d, e, f, g, h, s;
        slong j;


        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);
        fmpz_init(r);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);
        mpz_init(h);
        mpz_init(s);

        fmpz_randbits(a, state, 1000);
        do { 
           fmpz_randbits(b, state, 500);
        } while(fmpz_is_zero(b));

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        for (j = 1; j < 100; j++)
           fmpz_fdiv_qr(c, r, a, b);
        mpz_fdiv_qr(f, s, d, e);

        fmpz_get_mpz(g, c);
        fmpz_get_mpz(h, r);

        result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0);
        if (!result)
        {
            flint_printf("FAIL:\n");
            gmp_printf
                ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d,
                 e, f, g, h, s);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);
        fmpz_clear(r);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
        mpz_clear(h);
        mpz_clear(s);
    }

    /* Check aliasing of c and a */
    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, b, c, r;
        mpz_t d, e, f, g, h, s;

        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);
        fmpz_init(r);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);
        mpz_init(h);
        mpz_init(s);

        fmpz_randtest(a, state, 200);
        fmpz_randtest_not_zero(b, state, 200);

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        fmpz_fdiv_qr(a, r, a, b);
        mpz_fdiv_qr(f, s, d, e);

        fmpz_get_mpz(g, a);
        fmpz_get_mpz(h, r);

        result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0);
        if (!result)
        {
            flint_printf("FAIL:\n");
            gmp_printf
                ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d,
                 e, f, g, h, s);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);
        fmpz_clear(r);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
        mpz_clear(h);
        mpz_clear(s);
    }

    /* Check aliasing of c and b */
    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, b, c, r;
        mpz_t d, e, f, g, h, s;

        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);
        fmpz_init(r);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);
        mpz_init(h);
        mpz_init(s);

        fmpz_randtest(a, state, 200);
        fmpz_randtest_not_zero(b, state, 200);

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        fmpz_fdiv_qr(b, r, a, b);
        mpz_fdiv_qr(f, s, d, e);

        fmpz_get_mpz(g, b);
        fmpz_get_mpz(h, r);

        result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0);
        if (!result)
        {
            flint_printf("FAIL:\n");
            gmp_printf
                ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d,
                 e, f, g, h, s);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);
        fmpz_clear(r);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
        mpz_clear(h);
        mpz_clear(s);
    }

    /* Check aliasing of r and a */
    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, b, c, r;
        mpz_t d, e, f, g, h, s;

        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);
        fmpz_init(r);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);
        mpz_init(h);
        mpz_init(s);

        fmpz_randtest(a, state, 200);
        fmpz_randtest_not_zero(b, state, 200);

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        fmpz_fdiv_qr(c, a, a, b);
        mpz_fdiv_qr(f, s, d, e);

        fmpz_get_mpz(g, c);
        fmpz_get_mpz(h, a);

        result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0);
        if (!result)
        {
            flint_printf("FAIL:\n");
            gmp_printf
                ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d,
                 e, f, g, h, s);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);
        fmpz_clear(r);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
        mpz_clear(h);
        mpz_clear(s);
    }

    /* Check aliasing of r and b */
    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, b, c, r;
        mpz_t d, e, f, g, h, s;

        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);
        fmpz_init(r);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);
        mpz_init(h);
        mpz_init(s);

        fmpz_randtest(a, state, 200);
        fmpz_randtest_not_zero(b, state, 200);

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        fmpz_fdiv_qr(c, b, a, b);
        mpz_fdiv_qr(f, s, d, e);

        fmpz_get_mpz(g, c);
        fmpz_get_mpz(h, b);

        result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0);
        if (!result)
        {
            flint_printf("FAIL:\n");
            gmp_printf
                ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d,
                 e, f, g, h, s);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);
        fmpz_clear(r);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
        mpz_clear(h);
        mpz_clear(s);
    }

    FLINT_TEST_CLEANUP(state);
    
    flint_printf("PASS\n");
    return 0;
}
示例#20
0
RCP<const Basic> pow(const RCP<const Basic> &a, const RCP<const Basic> &b)
{
    if (eq(b, zero)) return one;
    if (eq(b, one)) return a;
    if (eq(a, zero)) return zero;
    if (eq(a, one)) return one;
    if (eq(a, minus_one)) {
        if (is_a<Integer>(*b)) {
            return is_a<Integer>(*div(b, integer(2))) ? one : minus_one;
        } else if (is_a<Rational>(*b) &&
                    (rcp_static_cast<const Rational>(b)->i.get_num() == 1) &&
                    (rcp_static_cast<const Rational>(b)->i.get_den() == 2)) {
            return I;
        }
    }

    if (is_a_Number(*a) && is_a_Number(*b)) {
        if (is_a<Integer>(*b)) {
            if (is_a<Rational>(*a)) {
                RCP<const Rational> exp_new = rcp_static_cast<const Rational>(a);
                return exp_new->powrat(*rcp_static_cast<const Integer>(b));
            } else if (is_a<Integer>(*a)) {
                RCP<const Integer> exp_new = rcp_static_cast<const Integer>(a);
                return exp_new->powint(*rcp_static_cast<const Integer>(b));
            } else if (is_a<Complex>(*a)) {
                RCP<const Complex> exp_new = rcp_static_cast<const Complex>(a);
                RCP<const Integer> pow_new = rcp_static_cast<const Integer>(b);
                RCP<const Number> res = exp_new->pow(*pow_new);
                return res;
            } else {
                throw std::runtime_error("Not implemented");
            }
        } else if (is_a<Rational>(*b)) {
            mpz_class q, r, num, den;
            num = rcp_static_cast<const Rational>(b)->i.get_num();
            den = rcp_static_cast<const Rational>(b)->i.get_den();

            if (num > den || num < 0) {
                mpz_fdiv_qr(q.get_mpz_t(), r.get_mpz_t(), num.get_mpz_t(),
                    den.get_mpz_t());
            } else {
                return rcp(new Pow(a, b));
            }
            // Here we make the exponent postive and a fraction between
            // 0 and 1. We multiply numerator and denominator appropriately
            // to achieve this
            if (is_a<Rational>(*a)) {
                RCP<const Rational> exp_new = rcp_static_cast<const Rational>(a);
                RCP<const Basic> frac =
                    div(exp_new->powrat(Integer(q)), integer(exp_new->i.get_den()));
                RCP<const Basic> surds =
                    mul(rcp(new Pow(integer(exp_new->i.get_num()), div(integer(r), integer(den)))),
                        rcp(new Pow(integer(exp_new->i.get_den()), sub(one, div(integer(r), integer(den))))));
                return mul(frac, surds);
            } else if (is_a<Integer>(*a)) {
                RCP<const Integer> exp_new = rcp_static_cast<const Integer>(a);
                RCP<const Number> frac = exp_new->powint(Integer(q));
                map_basic_basic surd;
                if ((exp_new->is_negative()) && (2 * r == den)) {
                    frac = mulnum(frac, I);
                    exp_new = exp_new->mulint(*minus_one);
                    // if exp_new is one, no need to add it to dict
                    if (exp_new->is_one())
                        return frac;
                    surd[exp_new] = div(integer(r), integer(den));
                } else {
                    surd[exp_new] = div(integer(r), integer(den));
                }
                return rcp(new Mul(frac, std::move(surd)));
            } else if (is_a<Complex>(*a)) {
                return rcp(new Pow(a, b));
            } else {
                throw std::runtime_error("Not implemented");
            }
        } else if (is_a<Complex>(*b)) {
            return rcp(new Pow(a, b));
        } else {
            throw std::runtime_error("Not implemented");
        }
    }
    if (is_a<Mul>(*a) && is_a<Integer>(*b)) {
        // Convert (x*y)^b = x^b*y^b, where 'b' is an integer. This holds for
        // any complex 'x', 'y' and integer 'b'.
        return rcp_static_cast<const Mul>(a)->power_all_terms(b);
    }
    if (is_a<Pow>(*a) && is_a<Integer>(*b)) {
        // Convert (x^y)^b = x^(b*y), where 'b' is an integer. This holds for
        // any complex 'x', 'y' and integer 'b'.
        RCP<const Pow> A = rcp_static_cast<const Pow>(a);
        return pow(A->base_, mul(A->exp_, b));
    }
    return rcp(new Pow(a, b));
}
示例#21
0
static PyObject *
GMPy_Integer_DivMod(PyObject *x, PyObject *y, CTXT_Object *context)
{
    PyObject *result;
    MPZ_Object *tempx, *tempy, *rem, *quo;
    mpz_t tempz;
    long temp;
    int error;

    result = PyTuple_New(2);
    rem = GMPy_MPZ_New(context);
    quo = GMPy_MPZ_New(context);
    if (!result || !rem || !quo) {
        Py_XDECREF((PyObject*)rem);
        Py_XDECREF((PyObject*)quo);
        Py_XDECREF(result);
        return NULL;
    }

    if (CHECK_MPZANY(x)) {
        if (PyIntOrLong_Check(y)) {
            temp = GMPy_Integer_AsLongAndError(y, &error);
            if (error) {
                mpz_inoc(tempz);
                mpz_set_PyIntOrLong(tempz, y);
                mpz_fdiv_qr(quo->z, rem->z, MPZ(x), tempz);
                mpz_cloc(tempz);
            }
            else if (temp > 0) {
                mpz_fdiv_qr_ui(quo->z, rem->z, MPZ(x), temp);
            }
            else if (temp == 0) {
                ZERO_ERROR("division or modulo by zero");
                Py_DECREF((PyObject*)rem);
                Py_DECREF((PyObject*)quo);
                Py_DECREF(result);
                return NULL;
            }
            else {
                mpz_cdiv_qr_ui(quo->z, rem->z, MPZ(x), -temp);
                mpz_neg(quo->z, quo->z);
            }
            PyTuple_SET_ITEM(result, 0, (PyObject*)quo);
            PyTuple_SET_ITEM(result, 1, (PyObject*)rem);
            return result;
        }
        
        if (CHECK_MPZANY(y)) {
            if (mpz_sgn(MPZ(y)) == 0) {
                ZERO_ERROR("division or modulo by zero");
                Py_DECREF((PyObject*)rem);
                Py_DECREF((PyObject*)quo);
                Py_DECREF(result);
                return NULL;
            }
            mpz_fdiv_qr(quo->z, rem->z, MPZ(x), MPZ(y));
            PyTuple_SET_ITEM(result, 0, (PyObject*)quo);
            PyTuple_SET_ITEM(result, 1, (PyObject*)rem);
            return result;
        }
    }

    if (CHECK_MPZANY(y) && PyIntOrLong_Check(x)) {
        if (mpz_sgn(MPZ(y)) == 0) {
            ZERO_ERROR("division or modulo by zero");
            Py_DECREF((PyObject*)rem);
            Py_DECREF((PyObject*)quo);
            Py_DECREF(result);
            return NULL;
        }
        mpz_inoc(tempz);
        mpz_set_PyIntOrLong(tempz, x);
        mpz_fdiv_qr(quo->z, rem->z, tempz, MPZ(y));
        mpz_cloc(tempz);
        PyTuple_SET_ITEM(result, 0, (PyObject*)quo);
        PyTuple_SET_ITEM(result, 1, (PyObject*)rem);
        return (PyObject*)result;
    }

    if (IS_INTEGER(x) && IS_INTEGER(y)) {
        tempx = GMPy_MPZ_From_Integer(x, context);
        tempy = GMPy_MPZ_From_Integer(y, context);
        if (!tempx || !tempy) {
            SYSTEM_ERROR("could not convert Integer to mpz");
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)rem);
            Py_DECREF((PyObject*)quo);
            Py_DECREF(result);
            return NULL;
        }
        if (mpz_sgn(tempy->z) == 0) {
            ZERO_ERROR("division or modulo by zero");
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)rem);
            Py_DECREF((PyObject*)quo);
            Py_DECREF(result);
            return NULL;
        }
        mpz_fdiv_qr(quo->z, rem->z, tempx->z, tempy->z);
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
        PyTuple_SET_ITEM(result, 0, (PyObject*)quo);
        PyTuple_SET_ITEM(result, 1, (PyObject*)rem);
        return result;
    }

    Py_DECREF((PyObject*)result);
    Py_RETURN_NOTIMPLEMENTED;
}
示例#22
0
文件: rem1.c 项目: sriramnrn/gcc
static int
mpfr_rem1 (mpfr_ptr rem, long *quo, mp_rnd_t rnd_q,
           mpfr_srcptr x, mpfr_srcptr y, mp_rnd_t rnd)
{
  mp_exp_t ex, ey;
  int compare, inex, q_is_odd, sign, signx = MPFR_SIGN (x);
  mpz_t mx, my, r;

  MPFR_ASSERTD (rnd_q == GMP_RNDN || rnd_q == GMP_RNDZ);

  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x) || MPFR_IS_SINGULAR (y)))
    {
      if (MPFR_IS_NAN (x) || MPFR_IS_NAN (y) || MPFR_IS_INF (x)
          || MPFR_IS_ZERO (y))
        {
          /* for remquo, quo is undefined */
          MPFR_SET_NAN (rem);
          MPFR_RET_NAN;
        }
      else                      /* either y is Inf and x is 0 or non-special,
                                   or x is 0 and y is non-special,
                                   in both cases the quotient is zero. */
        {
          if (quo)
            *quo = 0;
          return mpfr_set (rem, x, rnd);
        }
    }

  /* now neither x nor y is NaN, Inf or zero */

  mpz_init (mx);
  mpz_init (my);
  mpz_init (r);

  ex = mpfr_get_z_exp (mx, x);  /* x = mx*2^ex */
  ey = mpfr_get_z_exp (my, y);  /* y = my*2^ey */

  /* to get rid of sign problems, we compute it separately:
     quo(-x,-y) = quo(x,y), rem(-x,-y) = -rem(x,y)
     quo(-x,y) = -quo(x,y), rem(-x,y)  = -rem(x,y)
     thus quo = sign(x/y)*quo(|x|,|y|), rem = sign(x)*rem(|x|,|y|) */
  sign = (signx == MPFR_SIGN (y)) ? 1 : -1;
  mpz_abs (mx, mx);
  mpz_abs (my, my);
  q_is_odd = 0;

  /* divide my by 2^k if possible to make operations mod my easier */
  {
    unsigned long k = mpz_scan1 (my, 0);
    ey += k;
    mpz_div_2exp (my, my, k);
  }

  if (ex <= ey)
    {
      /* q = x/y = mx/(my*2^(ey-ex)) */
      mpz_mul_2exp (my, my, ey - ex);   /* divide mx by my*2^(ey-ex) */
      if (rnd_q == GMP_RNDZ)
        /* 0 <= |r| <= |my|, r has the same sign as mx */
        mpz_tdiv_qr (mx, r, mx, my);
      else
        /* 0 <= |r| <= |my|, r has the same sign as my */
        mpz_fdiv_qr (mx, r, mx, my);

      if (rnd_q == GMP_RNDN)
        q_is_odd = mpz_tstbit (mx, 0);
      if (quo)                  /* mx is the quotient */
        {
          mpz_tdiv_r_2exp (mx, mx, WANTED_BITS);
          *quo = mpz_get_si (mx);
        }
    }
  else                          /* ex > ey */
    {
      if (quo)
        /* for remquo, to get the low WANTED_BITS more bits of the quotient,
           we first compute R =  X mod Y*2^WANTED_BITS, where X and Y are
           defined below. Then the low WANTED_BITS of the quotient are
           floor(R/Y). */
        mpz_mul_2exp (my, my, WANTED_BITS);     /* 2^WANTED_BITS*Y */
      else
        /* Let X = mx*2^(ex-ey) and Y = my. Then both X and Y are integers.
           Assume X = R mod Y, then x = X*2^ey = R*2^ey mod (Y*2^ey=y).
           To be able to perform the rounding, we need the least significant
           bit of the quotient, i.e., one more bit in the remainder,
           which is obtained by dividing by 2Y. */
        mpz_mul_2exp (my, my, 1);       /* 2Y */

      mpz_set_ui (r, 2);
      mpz_powm_ui (r, r, ex - ey, my);  /* 2^(ex-ey) mod my */
      mpz_mul (r, r, mx);
      mpz_mod (r, r, my);

      if (quo)                  /* now 0 <= r < 2^WANTED_BITS*Y */
        {
          mpz_div_2exp (my, my, WANTED_BITS);   /* back to Y */
          mpz_tdiv_qr (mx, r, r, my);
          /* oldr = mx*my + newr */
          *quo = mpz_get_si (mx);
          q_is_odd = *quo & 1;
        }
      else                      /* now 0 <= r < 2Y */
        {
          mpz_div_2exp (my, my, 1);     /* back to Y */
          if (rnd_q == GMP_RNDN)
            {
              /* least significant bit of q */
              q_is_odd = mpz_cmpabs (r, my) >= 0;
              if (q_is_odd)
                mpz_sub (r, r, my);
            }
        }
      /* now 0 <= |r| < |my|, and if needed,
         q_is_odd is the least significant bit of q */
    }

  if (mpz_cmp_ui (r, 0) == 0)
    inex = mpfr_set_ui (rem, 0, GMP_RNDN);
  else
    {
      if (rnd_q == GMP_RNDN)
        {
          /* FIXME: the comparison 2*r < my could be done more efficiently
             at the mpn level */
          mpz_mul_2exp (r, r, 1);
          compare = mpz_cmpabs (r, my);
          mpz_div_2exp (r, r, 1);
          compare = ((compare > 0) ||
                     ((rnd_q == GMP_RNDN) && (compare == 0) && q_is_odd));
          /* if compare != 0, we need to subtract my to r, and add 1 to quo */
          if (compare)
            {
              mpz_sub (r, r, my);
              if (quo && (rnd_q == GMP_RNDN))
                *quo += 1;
            }
        }
      inex = mpfr_set_z (rem, r, rnd);
      /* if ex > ey, rem should be multiplied by 2^ey, else by 2^ex */
      MPFR_EXP (rem) += (ex > ey) ? ey : ex;
    }

  if (quo)
    *quo *= sign;

  /* take into account sign of x */
  if (signx < 0)
    {
      mpfr_neg (rem, rem, GMP_RNDN);
      inex = -inex;
    }

  mpz_clear (mx);
  mpz_clear (my);
  mpz_clear (r);

  return inex;
}
示例#23
0
文件: mul.cpp 项目: v0dro/symengine
// Mul (t**exp) to the dict "d"
void Mul::dict_add_term_new(const Ptr<RCP<const Number>> &coef, map_basic_basic &d,
    const RCP<const Basic> &exp, const RCP<const Basic> &t)
{
    auto it = d.find(t);
    if (it == d.end()) {
        // Don't check for `exp = 0` here
        // `pow` for Complex is not expanded by default
        if (is_a<Integer>(*t) || is_a<Rational>(*t)) {
            if (is_a<Integer>(*exp)) {
                imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t),
                    rcp_static_cast<const Number>(exp)));
            } else if (is_a<Rational>(*exp)) {
                // Here we make the exponent postive and a fraction between
                // 0 and 1.
                mpz_class q, r, num, den;
                num = rcp_static_cast<const Rational>(exp)->i.get_num();
                den = rcp_static_cast<const Rational>(exp)->i.get_den();
                mpz_fdiv_qr(q.get_mpz_t(), r.get_mpz_t(), num.get_mpz_t(),
                    den.get_mpz_t());

                insert(d, t, Rational::from_mpq(mpq_class(r, den)));
                imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t),
                    rcp_static_cast<const Number>(integer(q))));
            } else {
                insert(d, t, exp);
            }
        } else if (is_a<Integer>(*exp) && is_a<Complex>(*t)) {
            if (rcp_static_cast<const Integer>(exp)->is_one()) {
                imulnum(outArg(*coef), rcp_static_cast<const Number>(t));
            } else if (rcp_static_cast<const Integer>(exp)->is_minus_one()) {
                idivnum(outArg(*coef), rcp_static_cast<const Number>(t));
            } else {
                insert(d, t, exp);
            }
        } else {
            insert(d, t, exp);
        }
    } else {
        // Very common case, needs to be fast:
        if (is_a_Number(*exp) && is_a_Number(*it->second)) {
            RCP<const Number> tmp = rcp_static_cast<const Number>(it->second);
            iaddnum(outArg(tmp),
                rcp_static_cast<const Number>(exp));
            it->second = tmp;
        }
        else
            it->second = add(it->second, exp);

        if (is_a<Integer>(*it->second)) {
            // `pow` for Complex is not expanded by default
            if (is_a<Integer>(*t) || is_a<Rational>(*t)) {
                if (!rcp_static_cast<const Integer>(it->second)->is_zero()) {
                    imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t),
                        rcp_static_cast<const Number>(it->second)));
                }
                d.erase(it);
            } else if (rcp_static_cast<const Integer>(it->second)->is_zero()) {
                d.erase(it);
            } else if (is_a<Complex>(*t)) {
                if (rcp_static_cast<const Integer>(it->second)->is_one()) {
                    imulnum(outArg(*coef), rcp_static_cast<const Number>(t));
                    d.erase(it);
                } else if (rcp_static_cast<const Integer>(it->second)->is_minus_one()) {
                    idivnum(outArg(*coef), rcp_static_cast<const Number>(t));
                    d.erase(it);
                }
            }
        } else if (is_a<Rational>(*it->second)) {
            if (is_a_Number(*t)) {
                mpz_class q, r, num, den;
                num = rcp_static_cast<const Rational>(it->second)->i.get_num();
                den = rcp_static_cast<const Rational>(it->second)->i.get_den();
                // Here we make the exponent postive and a fraction between
                // 0 and 1.
                if (num > den || num < 0) {
                    mpz_fdiv_qr(q.get_mpz_t(), r.get_mpz_t(), num.get_mpz_t(),
                                den.get_mpz_t());

                    it->second = Rational::from_mpq(mpq_class(r, den));
                    imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t),
                                                  rcp_static_cast<const Number>(integer(q))));
                }
            }
        }
    }
}
void Serveur_xD(int dim, mpz_t ** tab_cli,
                mpz_t Answer[(int)pow(2, (dim - 1))], mpz_t * tab_serv)
{
    int lenth_u_v = pow(MAX_GRID_SIZE, (dim - 1));
    mpz_t * tab_u_v_1 = malloc(sizeof(mpz_t) * lenth_u_v);
    mpz_t * tab_u_v_2 = malloc(sizeof(mpz_t) * lenth_u_v);
    for (int i = 0; i < lenth_u_v; i++)
    {
        mpz_init(tab_u_v_1[i]);
        mpz_init(tab_u_v_2[i]);
    }

    mpz_t tab_tmp_1[MAX_GRID_SIZE];
    mpz_t tab_tmp_2[MAX_GRID_SIZE];
    for (int i = 0; i < MAX_GRID_SIZE; i++)
    {
        mpz_init(tab_tmp_1[i]);
        mpz_init(tab_tmp_2[i]);
    }

    int n_tab_cli = dim - 1;

    /* Part 1: First operation note to tab_u_v */
    for (int i = 0; i < lenth_u_v; i++)
    {

        for (int j = 0; j < MAX_GRID_SIZE; j++)
        {
            mpz_set(tab_tmp_1[j], tab_serv[i * MAX_GRID_SIZE + j]);

        } // one line copy done from server

        /* compute every table with tab_cli and change to u and v*/
        Serveur(tab_u_v_1[i], tab_tmp_1, tab_cli[n_tab_cli]);
        mpz_fdiv_qr (tab_u_v_1[i], tab_u_v_2[i], tab_u_v_1[i], KPub[0]);
    } /* Part 1 END */

    /* Part 2: separation and compute circularly */
    int count_position = 0;
    int count_uv = 0;
    for (int d = 1; d <= (dim - 2); d++)
    {
        n_tab_cli--;
        for (int i = 0; i < (lenth_u_v / (pow(2, (d - 1)))); i++)
        {
            if(count_position != (MAX_GRID_SIZE - 1))
            {
                mpz_set(tab_tmp_1[count_position], tab_u_v_1[i]);
                mpz_set(tab_tmp_2[count_position], tab_u_v_2[i]);
                count_position++;
            }
            else
            {
                mpz_set(tab_tmp_1[count_position], tab_u_v_1[i]);
                mpz_set(tab_tmp_2[count_position], tab_u_v_2[i]);
                Serveur(tab_u_v_1[count_uv], tab_tmp_1, tab_cli[n_tab_cli]);
                Serveur(tab_u_v_2[count_uv], tab_tmp_2, tab_cli[n_tab_cli]);
                count_uv++;
                count_position = 0;
            }
        } /* Compute done */

        for (int i = 0; i < (lenth_u_v / (d * MAX_GRID_SIZE)); i++) //
        {
            mpz_fdiv_qr (tab_u_v_1[i],
                         tab_u_v_1[i + (lenth_u_v / (d * MAX_GRID_SIZE))],
                         tab_u_v_1[i], KPub[0]);
            mpz_fdiv_qr (tab_u_v_2[i],
                         tab_u_v_2[i + (lenth_u_v / (d * MAX_GRID_SIZE))],
                         tab_u_v_2[i], KPub[0]);
        }
    } /* Part 2 END */

    /* Part 3: Compute the value return to client */
    count_position = 0;
    count_uv = 0;
    for (int i = 0; i < (MAX_GRID_SIZE * (pow(2, (dim - 2)))); i++)
    {
        if(count_position != (MAX_GRID_SIZE - 1))
        {
            mpz_set(tab_tmp_1[count_position], tab_u_v_1[i]);
            mpz_set(tab_tmp_2[count_position], tab_u_v_2[i]);
            count_position++;
        }
        else
        {
            mpz_set(tab_tmp_1[count_position], tab_u_v_1[i]);
            mpz_set(tab_tmp_2[count_position], tab_u_v_2[i]);
            count_position = 0;
            Serveur(Answer[count_uv], tab_tmp_1, tab_cli[0]);
            Serveur(Answer[count_uv + (int)pow(2, (dim - 2))],
                    tab_tmp_2, tab_cli[0]);

            if(count_uv < (pow(2, (dim - 2))) - 2)
            {
                count_uv+=2;
            }
            else
            {
                count_uv = 1;
            }
        }
    } /* Part 3 END */

    for (int i = 0; i < MAX_GRID_SIZE; i++)
    {
        mpz_clear(tab_tmp_1[i]);
        mpz_clear(tab_tmp_2[i]);
    }

    for (int i = 0; i < lenth_u_v; i++)
    {
        mpz_clear(tab_u_v_1[i]);
        mpz_clear(tab_u_v_2[i]);
    }
    free(tab_u_v_1);
    free(tab_u_v_2);

}
示例#25
0
static PyObject *
GMPy_Integer_DivMod(PyObject *x, PyObject *y, CTXT_Object *context)
{
    PyObject *result = NULL;
    MPZ_Object *tempx = NULL, *tempy = NULL, *rem = NULL, *quo = NULL;

    if (!(result = PyTuple_New(2)) ||
        !(rem = GMPy_MPZ_New(context)) ||
        !(quo = GMPy_MPZ_New(context))) {

        /* LCOV_EXCL_START */
        goto error;
        /* LCOV_EXCL_STOP */
    }

    if (CHECK_MPZANY(x)) {
        if (PyIntOrLong_Check(y)) {
            int error;
            long temp = GMPy_Integer_AsLongAndError(y, &error);

            if (error) {
                mpz_t tempz;
                mpz_inoc(tempz);
                mpz_set_PyIntOrLong(tempz, y);
                mpz_fdiv_qr(quo->z, rem->z, MPZ(x), tempz);
                mpz_cloc(tempz);
            }
            else if (temp > 0) {
                mpz_fdiv_qr_ui(quo->z, rem->z, MPZ(x), temp);
            }
            else if (temp == 0) {
                ZERO_ERROR("division or modulo by zero");
                goto error;
            }
            else {
                mpz_cdiv_qr_ui(quo->z, rem->z, MPZ(x), -temp);
                mpz_neg(quo->z, quo->z);
            }
            PyTuple_SET_ITEM(result, 0, (PyObject*)quo);
            PyTuple_SET_ITEM(result, 1, (PyObject*)rem);
            return result;
        }

        if (CHECK_MPZANY(y)) {
            if (mpz_sgn(MPZ(y)) == 0) {
                ZERO_ERROR("division or modulo by zero");
                goto error;
            }
            mpz_fdiv_qr(quo->z, rem->z, MPZ(x), MPZ(y));
            PyTuple_SET_ITEM(result, 0, (PyObject*)quo);
            PyTuple_SET_ITEM(result, 1, (PyObject*)rem);
            return result;
        }
    }

    if (CHECK_MPZANY(y) && PyIntOrLong_Check(x)) {
        if (mpz_sgn(MPZ(y)) == 0) {
            ZERO_ERROR("division or modulo by zero");
            goto error;
        }
        else {
            mpz_t tempz;
            mpz_inoc(tempz);
            mpz_set_PyIntOrLong(tempz, x);
            mpz_fdiv_qr(quo->z, rem->z, tempz, MPZ(y));
            mpz_cloc(tempz);
            PyTuple_SET_ITEM(result, 0, (PyObject*)quo);
            PyTuple_SET_ITEM(result, 1, (PyObject*)rem);
            return (PyObject*)result;
        }
    }

    if (IS_INTEGER(x) && IS_INTEGER(y)) {

        if (!(tempx = GMPy_MPZ_From_Integer(x, context)) ||
            !(tempy = GMPy_MPZ_From_Integer(y, context))) {

            /* LCOV_EXCL_START */
            goto error;
            /* LCOV_EXCL_STOP */
        }
        if (mpz_sgn(tempy->z) == 0) {
            ZERO_ERROR("division or modulo by zero");
            goto error;
        }
        mpz_fdiv_qr(quo->z, rem->z, tempx->z, tempy->z);
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
        PyTuple_SET_ITEM(result, 0, (PyObject*)quo);
        PyTuple_SET_ITEM(result, 1, (PyObject*)rem);
        return result;
    }

    /* LCOV_EXCL_START */
    SYSTEM_ERROR("Internal error in GMPy_Integer_DivMod().");
    /* LCOV_EXCL_STOP */
  error:
    Py_XDECREF((PyObject*)tempx);
    Py_XDECREF((PyObject*)tempy);
    Py_XDECREF((PyObject*)rem);
    Py_XDECREF((PyObject*)quo);
    Py_XDECREF(result);
    return NULL;
}
示例#26
0
static PyObject *
Pympq_round(PyObject *self, PyObject *args)
{
    Py_ssize_t round_digits = 0;
    PympqObject *resultq;
    PympzObject *resultz;
    mpz_t temp, rem;

    /* If args is NULL or the size of args is 0, we just return an mpz. */

    if (!args || PyTuple_GET_SIZE(args) == 0) {
        if (!(resultz = (PympzObject*)Pympz_new()))
            return NULL;

        mpz_inoc(rem);
        mpz_fdiv_qr(resultz->z, rem, mpq_numref(Pympq_AS_MPQ(self)),
                    mpq_denref(Pympq_AS_MPQ(self)));
        mpz_mul_2exp(rem, rem, 1);
        if (mpz_cmp(rem, mpq_denref(Pympq_AS_MPQ(self))) > 0) {
            mpz_add_ui(resultz->z, resultz->z, 1);
        }
        else if (mpz_cmp(rem, mpq_denref(Pympq_AS_MPQ(self))) == 0) {
            if (mpz_odd_p(resultz->z)) {
                mpz_add_ui(resultz->z, resultz->z, 1);
            }
        }
        mpz_cloc(rem);
        return (PyObject*)resultz;
    }

    if (PyTuple_GET_SIZE(args) > 1) {
        TYPE_ERROR("Too many arguments for __round__().");
        return NULL;
    }

    if (PyTuple_GET_SIZE(args) == 1) {
        round_digits = ssize_t_From_Integer(PyTuple_GET_ITEM(args, 0));
        if (round_digits == -1 && PyErr_Occurred()) {
            TYPE_ERROR("__round__() requires 'int' argument");
            return NULL;
        }
    }

    if (!(resultq = (PympqObject*)Pympq_new()))
        return NULL;

    mpz_inoc(temp);
    mpz_ui_pow_ui(temp, 10, round_digits > 0 ? round_digits : -round_digits);

    mpq_set(resultq->q, Pympq_AS_MPQ(self));
    if (round_digits > 0) {
        mpz_mul(mpq_numref(resultq->q), mpq_numref(resultq->q), temp);
        mpq_canonicalize(resultq->q);
        if (!(resultz = (PympzObject*)Pympq_round((PyObject*)resultq, NULL))) {
            mpz_cloc(temp);
            return NULL;
        }
        mpz_set(mpq_numref(resultq->q), resultz->z);
        Py_DECREF((PyObject*)resultz);
        mpz_set(mpq_denref(resultq->q), temp);
        mpz_cloc(temp);
        mpq_canonicalize(resultq->q);
    }
    else {
        mpz_mul(mpq_denref(resultq->q), mpq_denref(resultq->q), temp);
        mpq_canonicalize(resultq->q);
        if (!(resultz = (PympzObject*)Pympq_round((PyObject*)resultq, NULL))) {
            mpz_cloc(temp);
            return NULL;
        }
        mpq_set_ui(resultq->q, 0, 1);
        mpz_mul(mpq_numref(resultq->q), resultz->z, temp);
        Py_DECREF((PyObject*)resultz);
        mpz_cloc(temp);
        mpq_canonicalize(resultq->q);
    }
    return (PyObject*)resultq;
}