Beispiel #1
0
static PyObject *
GMPy_Rational_FloorDiv(PyObject *x, PyObject *y, CTXT_Object *context)
{
    MPZ_Object *result;
    MPQ_Object *tempq;

    CHECK_CONTEXT(context);

    result = GMPy_MPZ_New(context);
    tempq = GMPy_MPQ_New(context);
    if (!result || !tempq) {
        Py_XDECREF((PyObject*)result);
        Py_XDECREF((PyObject*)tempq);
        return NULL;
    }

    if (MPQ_Check(x) && MPQ_Check(y)) {
        if (mpq_sgn(MPQ(y)) == 0) {
            ZERO_ERROR("division or modulo by zero");
            goto error;
        }
        mpq_div(tempq->q, MPQ(x), MPQ(y));
        mpz_fdiv_q(result->z, mpq_numref(tempq->q), mpq_denref(tempq->q));
        Py_DECREF((PyObject*)tempq);
        return (PyObject*)result;
    }

    if (IS_RATIONAL(x) && IS_RATIONAL(y)) {
        MPQ_Object *tempx, *tempy;

        tempx = GMPy_MPQ_From_Number(x, context);
        tempy = GMPy_MPQ_From_Number(y, context);
        if (!tempx || !tempy) {
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            goto error;
        }
        if (mpq_sgn(tempy->q) == 0) {
            ZERO_ERROR("division or modulo by zero");
            Py_DECREF((PyObject*)tempx);
            Py_DECREF((PyObject*)tempy);
            goto error;
        }

        mpq_div(tempq->q, tempx->q, tempy->q);
        mpz_fdiv_q(result->z, mpq_numref(tempq->q), mpq_denref(tempq->q));
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
        Py_DECREF((PyObject*)tempq);
        return (PyObject*)result;
    }

    Py_DECREF((PyObject*)result);
    Py_RETURN_NOTIMPLEMENTED;

  error:
    Py_DECREF((PyObject*)result);
    Py_DECREF((PyObject*)tempq);
    return NULL;
}
Beispiel #2
0
// Algorithm 19.2  [PDF page 24](http://cr.yp.to/lineartime/dcba-20040404.pdf)
//
// See [reduce test](test-reduce.html) for basic usage.
void reduce(mpz_t i, mpz_t pai, const mpz_t p, const mpz_t a) {
	mpz_t r, j, b, p2, a2;

	// **Sep 1**
	//
	//  If p does not divide a: Print (0,a) and stop.
	mpz_init(r);
	mpz_fdiv_r(r, a, p);
	if (mpz_cmp_ui(r, 0) != 0) {
		mpz_clear(r);
		mpz_set_ui(i, 0);
		mpz_set(pai, a);
		return;
	}

	// **Sep 2**
	//
	//  Compute (j,b) ← reduce(p^2 ,a/p)
	mpz_init(j);
	mpz_init(b);
	mpz_init(p2);
	mpz_init(a2);
	mpz_mul(p2, p, p);
	mpz_fdiv_q(a2, a, p);
	reduce(j, b, p2, a2);
	mpz_clear(p2);
	mpz_clear(a2);

	// **Sep 3**
	//
	//  If p divides b: Print (2 j +2,b/p) and stop.
	mpz_fdiv_r(r, b, p);
	if (mpz_cmp_ui(r, 0) == 0) {
		mpz_mul_ui(j, j, 2);
		mpz_add_ui(j, j, 2);
		mpz_set(i, j);

		mpz_fdiv_q(b, b, p);
		mpz_set(pai, b);

		mpz_clear(r);
		mpz_clear(b);
		mpz_clear(j);
		return;
	}
	mpz_clear(r);

	// **Sep 4**
	//
	//  Print (2 j +1,b).
	mpz_mul_ui(j, j, 2);
	mpz_add_ui(j, j, 1);
	mpz_set(i, j);
	mpz_set(pai, b);

	// Free the memory.
	mpz_clear(b);
	mpz_clear(j);
}
Beispiel #3
0
//     gcd = gcd(a,b)  greatest common divisor
//     ppi = ppi(a,b)  powers in a of primes inside b
//     ppo = ppo(a,b)  powers in a of primes outside b
//
//
//
// Algorithm 11.3 [PDF page 14](http://cr.yp.to/lineartime/dcba-20040404.pdf)
//
// See [gcdppippo test](test-gcdppippo.html) for basic usage.
void gcd_ppi_ppo(mpz_t gcd, mpz_t ppi, mpz_t ppo, const mpz_t a, const mpz_t b) {
	mpz_t g;
	mpz_init(g);
	mpz_gcd(ppi, a, b);
	mpz_set(gcd, ppi);
	mpz_fdiv_q(ppo, a, ppi);
	while(1) {
		mpz_gcd(g, ppi, ppo);
		if (mpz_cmp_ui(g, 1) == 0) {
			mpz_clear(g);
			return;
		}
		mpz_mul(ppi, ppi, g);
		mpz_fdiv_q(ppo, ppo, g);
	}
}
Beispiel #4
0
//     gcd  =  gcd(a,b)  greatest common divisor
//     ppg  =  ppg(a,b)  prime powers in a greater than those in b
//     pple = pple(a,b)  prime powers in a less than or equal to those in b
//
//
//
// Algorithm 11.4 [PDF page 14](http://cr.yp.to/lineartime/dcba-20040404.pdf)
//
// See [gcdppgpple test](test-gcdppgpple.html) for basic usage.
void gcd_ppg_pple(mpz_t gcd, mpz_t ppg, mpz_t pple, const mpz_t a, const mpz_t b) {
	mpz_t g;
	mpz_init(g);
	mpz_gcd(pple, a, b);
	mpz_set(gcd, pple);
	mpz_fdiv_q(ppg, a, pple);
	while(1) {
		mpz_gcd(g, ppg, pple);
		if (mpz_cmp_ui(g, 1) == 0) {
			mpz_clear(g);
			return;
		}
		mpz_mul(ppg, ppg, g);
		mpz_fdiv_q(pple, pple, g);
	}
}
Beispiel #5
0
/*
 * Step 3 of bleichenbacher's algorithm : search space reduction
 */
int b98_update_boundaries(struct bleichenbacher_98_t *b98)
{
	mpz_t min_r, max_r;

	mpz_init(min_r);
	mpz_mul(min_r, b98->a, b98->s );
	mpz_sub(min_r, min_r, b98->max_range);
	mpz_cdiv_q (min_r, min_r, b98->n);
	if (!mpz_sgn(min_r))
		mpz_add_ui(min_r, min_r, 1);

	mpz_init(max_r);
	mpz_mul(max_r, b98->b, b98->s );
	mpz_sub(max_r, max_r, b98->min_range);
	mpz_fdiv_q (max_r, max_r, b98->n);

	if (mpz_cmp(min_r, max_r) > 0)
	{
		mpz_set(min_r, b98->r);
		mpz_set(max_r, b98->r);
	}


	b98_update_a(b98->a, min_r, b98->s,  b98->min_range,  b98->max_range, b98->n );
	b98_update_b(b98->b, max_r, b98->s,  b98->min_range,  b98->max_range, b98->n );

	mpz_clear(min_r);
	mpz_clear(max_r);
	return 0x00;
}
Beispiel #6
0
int main(void)
{
   mpz_t f_n, f_r, tmp;
   mpz_init(f_n);
   mpz_init(f_r);
   mpz_init(tmp);
   unsigned count = 0;
   
   unsigned n;
   for(n=23;n<101;n++) {
      unsigned r;
      for(r=1;r<=n;r++) {
         factorial(tmp, n);
         mpz_set(f_n, tmp);
         
         factorial(tmp, r);
         mpz_set(f_r, tmp);
         
         factorial(tmp, n - r);
         mpz_mul(f_r, f_r, tmp);
         
         mpz_fdiv_q(f_n, f_n, f_r);
         
         if(mpz_cmp_ui(f_n, 1000000) > 0)
            count++;
      }
   }
   
   printf("%u\n",count);
   return 0;
}
Beispiel #7
0
void LLLoperations::REDI(int k, int ell,
                         MutableMatrix *A,
                         MutableMatrix *Achange, // can be NULL
                         MutableMatrix *lambda)
{
  // set q = ...
  // negate q.
  ring_elem Dl, mkl, q;
  if (!lambda->get_entry(ell,k,mkl)) return;
  lambda->get_entry(ell,ell,Dl);
  mpz_ptr a = mkl.get_mpz();
  mpz_ptr b = Dl.get_mpz();  // b = D#ell
  mpz_t c, d;
  mpz_init(c);
  mpz_init(d);
  mpz_mul_2exp(c,a,1); // c = 2*lambda#(k,ell)
  mpz_abs(d,c);        // d = abs(2*lambda#(k,ell)
  mpz_add(c,c,b);      // c = 2*lambda#(k,ell) + D#ell
  mpz_mul_2exp(d,b,1); // d = 2*D#ell
  mpz_fdiv_q(c,c,d);   // c = (almost) final q
  mpz_neg(c,c);
  q = c;

  //A->addColumnMultiple(ell,q,k);
  //lambda->addColumnMultiple(ell,q,k);

  A->column_op(k,q,ell);
  if (Achange) Achange->column_op(k,q,ell);
  lambda->column_op(k,q,ell);

  mpz_clear(c);
  mpz_clear(d);
}
Beispiel #8
0
static PyObject *
GMPy_MPZ_FloorDiv_Slot(PyObject *x, PyObject *y)
{
    if (CHECK_MPZANY(x) && CHECK_MPZANY(y)) {
        MPZ_Object *result;

        if (mpz_sgn(MPZ(y)) == 0) {
            ZERO_ERROR("division or modulo by zero");
            return NULL;
        }
        if ((result = GMPy_MPZ_New(NULL))) {
            mpz_fdiv_q(result->z, MPZ(x), MPZ(y));
        }
        return (PyObject*)result;
    }

    if (IS_INTEGER(x) && IS_INTEGER(y))
        return GMPy_Integer_FloorDiv(x, y, NULL);

    if (IS_RATIONAL(x) && IS_RATIONAL(y))
        return GMPy_Rational_FloorDiv(x, y, NULL);

    if (IS_REAL(x) && IS_REAL(y))
        return GMPy_Real_FloorDiv(x, y, NULL);

    if (IS_COMPLEX(x) && IS_COMPLEX(y))
        return GMPy_Complex_FloorDiv(x, y, NULL);

    Py_RETURN_NOTIMPLEMENTED;
}
static PyObject *
Pygmpy_f_div(PyObject *self, PyObject *args)
{
    PyObject *x, *y;
    PympzObject *q, *tempx, *tempy;

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

    x = PyTuple_GET_ITEM(args, 0);
    y = PyTuple_GET_ITEM(args, 1);
    if (!(q = Pympz_new()))
        return NULL;

    if (CHECK_MPZANY(x) && CHECK_MPZANY(y)) {
        if (mpz_sgn(Pympz_AS_MPZ(y)) == 0) {
            ZERO_ERROR("f_div() division by 0");
            Py_DECREF((PyObject*)q);
            return NULL;
        }
        mpz_fdiv_q(q->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_div() requires 'mpz','mpz' arguments");
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)q);
            return NULL;
        }
        if (mpz_sgn(Pympz_AS_MPZ(tempy)) == 0) {
            ZERO_ERROR("f_div() division by 0");
            Py_DECREF((PyObject*)tempx);
            Py_DECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)q);
            return NULL;
        }
        mpz_fdiv_q(q->z, tempx->z, tempy->z);
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
    }
    return (PyObject*)q;
}
Beispiel #10
0
static PyObject *
GMPy_MPZ_IFloorDiv_Slot(PyObject *self, PyObject *other)
{
    MPZ_Object *rz;

    if (!(rz =  GMPy_MPZ_New(NULL)))
        return NULL;

    if (CHECK_MPZANY(other)) {
        if (mpz_sgn(MPZ(other)) == 0) {
            ZERO_ERROR("mpz division by zero");
            return NULL;
        }
        mpz_fdiv_q(rz->z, MPZ(self), MPZ(other));
        return (PyObject*)rz;
    }

    if (PyIntOrLong_Check(other)) {
        int error;
        long temp = GMPy_Integer_AsLongAndError(other, &error);

        if (!error) {
            if (temp == 0) {
                ZERO_ERROR("mpz division by zero");
                return NULL;
            }
            else if(temp > 0) {
                mpz_fdiv_q_ui(rz->z, MPZ(self), temp);
            }
            else {
                mpz_cdiv_q_ui(rz->z, MPZ(self), -temp);
                mpz_neg(rz->z, rz->z);
            }
        }
        else {
            mpz_t tempz;
            mpz_inoc(tempz);
            mpz_set_PyIntOrLong(tempz, other);
            mpz_fdiv_q(rz->z, MPZ(self), tempz);
            mpz_cloc(tempz);
        }
        return (PyObject*)rz;
    }

    Py_RETURN_NOTIMPLEMENTED;
}
Beispiel #11
0
void fdiv_q(const Ptr<RCP<const Integer>> &q, const Integer &n, const Integer &d)
{
    mpz_t q_;
    mpz_init(q_);
    mpz_fdiv_q (q_, n.as_mpz().get_mpz_t(), d.as_mpz().get_mpz_t());
    *q = integer(mpz_class(q_));
    mpz_clear(q_);
}
Beispiel #12
0
int inverse(mpz_t rop, const mpz_t a, const mpz_t n) {
  /* Calculate the multiplicative inverse of a mod n

     Used to generate the private key
   */

  mpz_t t;
  mpz_init_set_ui(t, 0);
  mpz_t newt;
  mpz_init_set_ui(newt, 1);
  mpz_t r;
  mpz_init_set(r, n);
  mpz_t newr;
  mpz_init_set(newr, a);

  mpz_t quotient;
  mpz_init(quotient);

  mpz_t temp;
  mpz_init(temp);
  mpz_t swapped;
  mpz_init(swapped);

  while (mpz_cmp_ui(newr, 0) != 0) {
    mpz_fdiv_q(quotient, r, newr);

    mpz_set(swapped, newt);
    mpz_mul(temp, quotient, newt);
    mpz_sub(newt, t, temp);
    mpz_set(t, swapped);

    mpz_set(swapped, newr);
    mpz_mul(temp, quotient, newr);
    mpz_sub(newr, r, temp);
    mpz_set(r, swapped);
  }

  if (mpz_cmp_ui(r, 1) > 0) {
    return 1;
  }

  if (mpz_cmp_ui(t, 0) < 0) {
    mpz_add(temp, t, n);
    mpz_set(t, temp);
  }

  mpz_set(rop, t);

  mpz_clear(r);
  mpz_clear(newt);
  mpz_clear(newr);
  mpz_clear(quotient);
  mpz_clear(temp);
  mpz_clear(swapped);
  mpz_clear(t);

  return 0;
}
Beispiel #13
0
static PyObject *
GMPy_Rational_DivMod(PyObject *x, PyObject *y, CTXT_Object *context)
{
    MPQ_Object *tempx, *tempy, *rem;
    MPZ_Object *quo;
    PyObject *result;

    CHECK_CONTEXT(context);

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

    if (IS_RATIONAL(x) && IS_RATIONAL(y)) {
        tempx = GMPy_MPQ_From_Number(x, context);
        tempy = GMPy_MPQ_From_Number(y, context);
        if (!tempx || !tempy) {
            SYSTEM_ERROR("could not convert Rational to mpq");
            goto error;
        }
        if (mpq_sgn(tempy->q) == 0) {
            ZERO_ERROR("division or modulo by zero");
            goto error;
        }

        mpq_div(rem->q, tempx->q, tempy->q);
        mpz_fdiv_q(quo->z, mpq_numref(rem->q), mpq_denref(rem->q));
        /* Need to calculate x - quo * y. */
        mpq_set_z(rem->q, quo->z);
        mpq_mul(rem->q, rem->q, tempy->q);
        mpq_sub(rem->q, tempx->q, rem->q);
        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;

  error:
    Py_XDECREF((PyObject*)tempx);
    Py_XDECREF((PyObject*)tempy);
    Py_DECREF((PyObject*)rem);
    Py_DECREF((PyObject*)quo);
    Py_DECREF(result);
    return NULL;
}
Beispiel #14
0
// This algorithm factors a as a product of powers of elements of P if possible; otherwise it
// proclaims failure.
//
// Algorithm 20.1  [PDF page 25](http://cr.yp.to/lineartime/dcba-20040404.pdf)
//
// See [findfactor test](test-findfactor.html) for basic usage.
int find_factor(mpz_array *out, const mpz_t a0, const mpz_t a, mpz_t *p, size_t from, size_t to) {
	mpz_t m, c, y, b, c2;
	size_t n = to - from;
	unsigned int r = 1;

	// If #P = 1: Find p ∈ P. Compute (n, c) ← reduce(p,a) by Algorithm 19.2. If
	// c != 1, proclaim failure and stop. Otherwise print (p,n) and stop
	if (n == 0) {
		mpz_init(m);
		mpz_init(c);
		reduce(m, c, p[from], a);
		if (mpz_cmp_ui(c, 1) != 0) {
			r = 0;
		} else {
			if (mpz_cmp(a0, p[from]) != 0) {
				mpz_init(y);
				mpz_fdiv_q(y, a0, p[from]);
				array_add(out, a0);
				array_add(out, p[from]);
				array_add(out, y);
				mpz_clear(y);
				r = 0;
			}
		}
		mpz_clear(m);
		mpz_clear(c);
		return r;
	}
	// Select Q ⊆ P with #Q = b#P/2c.

	// Compute y ← prod Q
	mpz_init(y);
	prod(y, p, from, to - n/2 - 1);

	// Compute (b, c) ← (ppi,ppo)(a, y)
	mpz_init(b);
	mpz_init(c2);
	ppi_ppo(b, c2, a, y);

	// Apply Algorithm 20.1 to (b,Q) recursively. If Algorithm 20.1 fails, proclaim
	// failure and stop.
	if (!find_factor(out, a0, b, p, from, to - n/2 - 1)) {
		r = 0;
	// Apply Algorithm 20.1 to (c,P−Q) recursively. If Algorithm 20.1 fails, proclaim
	// failure and stop.
	} else if (!find_factor(out, a0, c2, p, to - n/2, to)) {
		r = 0;
	}

	// Free the memory.
	mpz_clear(y);
	mpz_clear(b);
	mpz_clear(c2);
	return r;
}
Beispiel #15
0
void
fmpz_fdiv_q(fmpz_t f, 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 (r && (c2 ^ r) < 0L)
                --q;

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

        if (!COEFF_IS_MPZ(c2))  /* h is small */
        {
            if (c2 > 0)         /* h > 0 */
            {
                mpz_fdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2);
            }
            else
            {
                mpz_cdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), -c2);
                mpz_neg(mpz_ptr, mpz_ptr);
            }
        }
        else                    /* both are large */
        {
            mpz_fdiv_q(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2));
        }
        _fmpz_demote_val(f);    /* division by h may result in small value */
    }
}
Beispiel #16
0
static PyObject *
Pyxmpz_inplace_floordiv(PyObject *a, PyObject *b)
{
    mpz_t tempz;
    mpir_si temp_si;
    int overflow;

    if (PyIntOrLong_Check(b)) {
        temp_si = PyLong_AsSIAndOverflow(b, &overflow);
        if (overflow) {
            mpz_inoc(tempz);
            mpz_set_PyIntOrLong(tempz, b);
            mpz_fdiv_q(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), tempz);
            mpz_cloc(tempz);
        }
        else if(temp_si == 0) {
            ZERO_ERROR("xmpz division by zero");
            return NULL;
        }
        else if(temp_si > 0) {
            mpz_fdiv_q_ui(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), temp_si);
        }
        else {
            mpz_cdiv_q_ui(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), -temp_si);
            mpz_neg(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a));
        }
        Py_INCREF(a);
        return a;
    }

    if (CHECK_MPZANY(b)) {
        if (mpz_sgn(Pyxmpz_AS_MPZ(b)) == 0) {
            ZERO_ERROR("xmpz division by zero");
            return NULL;
        }
        mpz_fdiv_q(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(b));
        Py_INCREF(a);
        return a;
    }

    Py_RETURN_NOTIMPLEMENTED;
}
Beispiel #17
0
static PyObject *
GMPy_Rational_DivMod(PyObject *x, PyObject *y, CTXT_Object *context)
{
    MPQ_Object *tempx = NULL, *tempy = NULL, *rem = NULL;
    MPZ_Object *quo = NULL;
    PyObject *result = NULL;

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

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

    if (IS_RATIONAL(x) && IS_RATIONAL(y)) {

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

            /* LCOV_EXCL_START */
            goto error;
            /* LCOV_EXCL_STOP */
        }
        if (mpq_sgn(tempy->q) == 0) {
            ZERO_ERROR("division or modulo by zero");
            goto error;
        }

        mpq_div(rem->q, tempx->q, tempy->q);
        mpz_fdiv_q(quo->z, mpq_numref(rem->q), mpq_denref(rem->q));
        /* Need to calculate x - quo * y. */
        mpq_set_z(rem->q, quo->z);
        mpq_mul(rem->q, rem->q, tempy->q);
        mpq_sub(rem->q, tempx->q, rem->q);
        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_Rational_DivMod().");
  error:
    Py_XDECREF((PyObject*)tempx);
    Py_XDECREF((PyObject*)tempy);
    Py_XDECREF((PyObject*)rem);
    Py_XDECREF((PyObject*)quo);
    Py_XDECREF(result);
    return NULL;
    /* LCOV_EXCL_STOP */
}
Beispiel #18
0
static Variant HHVM_FUNCTION(gmp_div_q,
                             const Variant& dataA,
                             const Variant& dataB,
                             int64_t round = GMP_ROUND_ZERO) {
  mpz_t gmpDataA, gmpDataB, gmpReturn;

  if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIV_Q, gmpDataA, dataA)) {
    return false;
  }
  if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIV_Q, 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_Q);
    return false;
  }

  mpz_init(gmpReturn);
  switch (round)
  {
    case GMP_ROUND_ZERO:
      mpz_tdiv_q(gmpReturn, gmpDataA, gmpDataB);
      break;

    case GMP_ROUND_PLUSINF:
      mpz_cdiv_q(gmpReturn, gmpDataA, gmpDataB);
      break;

    case GMP_ROUND_MINUSINF:
      mpz_fdiv_q(gmpReturn, gmpDataA, gmpDataB);
      break;

    default:
      mpz_clear(gmpDataA);
      mpz_clear(gmpDataB);
      mpz_clear(gmpReturn);
      return null_variant;
  }

  Variant ret = NEWOBJ(GMPResource)(gmpReturn);

  mpz_clear(gmpDataA);
  mpz_clear(gmpDataB);
  mpz_clear(gmpReturn);

  return ret;
}
Beispiel #19
0
static PyObject *
GMPy_XMPZ_IFloorDiv_Slot(PyObject *self, PyObject *other)
{
    if (PyIntOrLong_Check(other)) {
        int error;
        native_si temp = GMPy_Integer_AsNative_siAndError(other, &error);

        if (!error) {
            if (temp == 0) {
                ZERO_ERROR("xmpz division by zero");
                return NULL;
            }
            else if(temp > 0) {
                mpz_fdiv_q_ui(MPZ(self), MPZ(self), temp);
            }
            else {
                mpz_cdiv_q_ui(MPZ(self), MPZ(self), -temp);
                mpz_neg(MPZ(self), MPZ(self));
            }
        }
        else {
            mpz_set_PyIntOrLong(global.tempz, other);
            mpz_fdiv_q(MPZ(self), MPZ(self), global.tempz);
        }
        Py_INCREF(self);
        return self;
    }

    if (CHECK_MPZANY(other)) {
        if (mpz_sgn(MPZ(other)) == 0) {
            ZERO_ERROR("xmpz division by zero");
            return NULL;
        }
        mpz_fdiv_q(MPZ(self), MPZ(self), MPZ(other));
        Py_INCREF(self);
        return self;
    }

    Py_RETURN_NOTIMPLEMENTED;
}
Beispiel #20
0
static PyObject *
Pympq_floor(PyObject *self, PyObject *other)
{
    PympzObject *result;

    if ((result = (PympzObject*)Pympz_new())) {
        mpz_fdiv_q(result->z,
                   mpq_numref(Pympq_AS_MPQ(self)),
                   mpq_denref(Pympq_AS_MPQ(self)));
    }

    return (PyObject*)result;
}
Beispiel #21
0
// Check Fermat probable primality test (2-PRP): 2 ** (n-1) = 1 (mod n)
// true: n is probable prime
// false: n is composite; set fractional length in the nLength output
static
bool PrimeTest(mpz_t *n, unsigned int *pnLength)
{
	//fast tests
	/*{
		for(uint i=MAX_SIEVE_AMOUNT; i<MAX_SIEVE_AMOUNT+100; ++i)
		{
			if (mpz_divisible_ui_p(*n,Primes::v[i]))
			{
				return false;
			}
		}
	}*/


	mpz_t a, e, r;
	mpz_init_set_ui(a, 2); // base; Fermat witness
	mpz_init(e);
	mpz_sub_ui(e, *n, 1);
	mpz_init(r);
	
	mpz_powm(r, a, e, *n); // r = (2**(n-1))%n
	mpz_clear(a);
	mpz_clear(e);
	if (!mpz_cmp_ui(r, 1)) //if r is 1, this is a witness!
	{
		mpz_clear(r);
		return true;
	}
	
	// Failed Fermat test, calculate fractional length
	// nFractionalLength = ( (n-r) << nFractionalBits ) / n
	mpz_sub(r, *n, r);
	mpz_mul_2exp(r, r, nFractionalBits);
	mpz_fdiv_q(r, r, *n);
	unsigned int nFractionalLength = mpz_get_ui(r);
	mpz_clear(r);
	
	if (nFractionalLength >= (1 << nFractionalBits))
	{
		cout << "PrimeTest() : fractional assert" << endl;
		return false;
	}
	*pnLength = (*pnLength & TARGET_LENGTH_MASK) | nFractionalLength;
	return false;
}
Beispiel #22
0
static PyObject *
GMPy_Rational_Mod(PyObject *x, PyObject *y, CTXT_Object *context)
{
    mpz_t tempz;
    MPQ_Object *tempx, *tempy, *result;

    CHECK_CONTEXT(context);

    if (!(result = GMPy_MPQ_New(context)))
        return NULL;

    if (IS_RATIONAL(x) && IS_RATIONAL(y)) {
        tempx = GMPy_MPQ_From_Number(x, context);
        tempy = GMPy_MPQ_From_Number(y, context);
        if (!tempx || !tempy) {
            SYSTEM_ERROR("could not convert Rational to mpq");
            goto error;
        }
        if (mpq_sgn(tempy->q) == 0) {
            ZERO_ERROR("division or modulo by zero");
            goto error;
        }

        mpz_inoc(tempz);
        mpq_div(result->q, tempx->q, tempy->q);
        mpz_fdiv_q(tempz, mpq_numref(result->q), mpq_denref(result->q));
        /* Need to calculate x - tempz * y. */
        mpq_set_z(result->q, tempz);
        mpq_mul(result->q, result->q, tempy->q);
        mpq_sub(result->q, tempx->q, result->q);
        mpz_cloc(tempz);
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
        return (PyObject*)result;
    }

    Py_DECREF((PyObject*)result);
    Py_RETURN_NOTIMPLEMENTED;

  error:
    Py_XDECREF((PyObject*)tempx);
    Py_XDECREF((PyObject*)tempy);
    Py_DECREF((PyObject*)result);
    return NULL;
}
enum lp_result PL_polyhedron_opt(Polyhedron *P, Value *obj, Value denom,
				enum lp_dir dir, Value *opt)
{
    int i;
    int first = 1;
    Value val, d;
    enum lp_result res = lp_empty;

    POL_ENSURE_VERTICES(P);
    if (emptyQ(P))
	return res;

    value_init(val);
    value_init(d);
    for (i = 0; i < P->NbRays; ++ i) {
	Inner_Product(P->Ray[i]+1, obj, P->Dimension+1, &val);
	if (value_zero_p(P->Ray[i][0]) && value_notzero_p(val)) {
	    res = lp_unbounded;
	    break;
	}
	if (value_zero_p(P->Ray[i][1+P->Dimension])) {
	    if ((dir == lp_min && value_neg_p(val)) ||
		(dir == lp_max && value_pos_p(val))) {
		res = lp_unbounded;
		break;
	    }
	} else {
	    res = lp_ok;
	    value_multiply(d, denom, P->Ray[i][1+P->Dimension]);
	    if (dir == lp_min)
		mpz_cdiv_q(val, val, d);
	    else
		mpz_fdiv_q(val, val, d);
	    if (first || (dir == lp_min ? value_lt(val, *opt) :
				          value_gt(val, *opt)))
		value_assign(*opt, val);
	    first = 0;
	}
    }
    value_clear(d);
    value_clear(val);

    return res;
}
Beispiel #24
0
static void copy_solution(struct isl_vec *vec, int maximize, isl_int *opt,
	isl_int *opt_denom, PipQuast *sol)
{
	int i;
	PipList *list;
	isl_int tmp;

	if (opt) {
		if (opt_denom) {
			isl_seq_cpy_from_pip(opt,
				 &sol->list->vector->the_vector[0], 1);
			isl_seq_cpy_from_pip(opt_denom,
				 &sol->list->vector->the_deno[0], 1);
		} else if (maximize)
			mpz_fdiv_q(*opt, sol->list->vector->the_vector[0],
					 sol->list->vector->the_deno[0]);
		else
			mpz_cdiv_q(*opt, sol->list->vector->the_vector[0],
					 sol->list->vector->the_deno[0]);
	}

	if (!vec)
		return;

	isl_int_init(tmp);
	isl_int_set_si(vec->el[0], 1);
	for (i = 0, list = sol->list->next; list; ++i, list = list->next) {
		isl_seq_cpy_from_pip(&vec->el[1 + i],
			&list->vector->the_deno[0], 1);
		isl_int_lcm(vec->el[0], vec->el[0], vec->el[1 + i]);
	}
	for (i = 0, list = sol->list->next; list; ++i, list = list->next) {
		isl_seq_cpy_from_pip(&tmp, &list->vector->the_deno[0], 1);
		isl_int_divexact(tmp, vec->el[0], tmp);
		isl_seq_cpy_from_pip(&vec->el[1 + i],
			&list->vector->the_vector[0], 1);
		isl_int_mul(vec->el[1 + i], vec->el[1 + i], tmp);
	}
	isl_int_clear(tmp);
}
Beispiel #25
0
void llln_redi (int k, int l, int C, int F)
{
   int i;
   mpz_t q;
   mpz_t auxi1;

   mpz_init (q);
   mpz_init (auxi1);

   mpz_mul_ui (auxi1, llln_lambda[k][l], 2);
   mpz_abs (auxi1, auxi1);

   if (mpz_cmp (auxi1, llln_d[l]) > 0) {
      mpz_mul_ui (auxi1, llln_lambda[k][l], 2);
      mpz_add (auxi1, auxi1, llln_d[l]);
      mpz_mul_ui (q, llln_d[l], 2);
      mpz_fdiv_q (q, auxi1, q);

      for (i=1; i<F+1; i++) {
         mpz_mul (auxi1, q, llln_H[l][i]);
         mpz_sub (llln_H[k][i], llln_H[k][i], auxi1);
      }
    for (i=1; i<C+1; i++) {
         mpz_mul (auxi1, q, llln_b[l][i]);
         mpz_sub (llln_b[k][i], llln_b[k][i], auxi1);
      }
      mpz_mul (auxi1, q, llln_d[l]);

      mpz_sub (llln_lambda[k][l], llln_lambda[k][l], auxi1);

      for (i=1; i<=l-1; i++){
         mpz_mul (auxi1, q, llln_lambda[l][i]);
         mpz_sub (llln_lambda[k][i], llln_lambda[k][i], auxi1);
      }
 }

   mpz_clear (q);
   mpz_clear (auxi1);
}
Beispiel #26
0
void binomialCoefficient(mpz_ptr result, mpz_t top, mpz_t bottom) {
  mpz_t i;

  mpz_init(i);

  mpz_sub(i, top, bottom);

  mpz_add_ui(i, i, 1);

  mpz_t numerator;

  mpz_init_set_ui(numerator, 1);

  while (mpz_cmp(i, top) < 1) {
    mpz_mul(numerator, numerator, i);

    mpz_add_ui(i, i, 1);
  }

  mpz_set_ui(i, 2);

  mpz_t denominator;

  mpz_init_set_ui(denominator, 1);

  while (mpz_cmp(i, bottom) < 1) {
    mpz_mul(denominator, denominator, i);

    mpz_add_ui(i, i, 1);
  }

  mpz_fdiv_q(result, numerator, denominator);

  mpz_clear(i);

  mpz_clear(numerator);

  mpz_clear(denominator);
}
Beispiel #27
0
// base64 will be a pointer to the converted string
long hex_to_base64(char *hex, char **base64) {
  mpz_t decimal;
  mpz_init_set_str (decimal, hex, 16);
  mpz_t base;
  mpz_init_set_ui(base, 64);
  mpz_t place_value;
  mpz_init(place_value);
  long power = 0;
  mpz_pow_ui(place_value, base, power);
  while(mpz_cmp(decimal, place_value) > 0) {
    power++;
    mpz_pow_ui(place_value, base, power);
  }

  long length = power;
  *base64 = (char *) malloc(length);

  if(power > 0) {
    power--;
  }

  while(power >= 0) {
    mpz_pow_ui(place_value, base, power);
    mpz_t quotient;
    mpz_init(quotient);
    mpz_fdiv_q(quotient, decimal, place_value);
    unsigned long quotient_ui = mpz_get_ui(quotient);
    char place_char = base64_table[quotient_ui];
    (*base64)[(length - 1) - power] = place_char;
    mpz_t decrement;
    mpz_init(decrement);
    mpz_mul_ui(decrement, place_value, quotient_ui);
    mpz_sub(decimal, decimal, decrement);
    power--;
  }

  return length;
}
int shankSquares(mpz_t *n)
{
	mpz_t myN, constA, constB, tmp, tmp2;
	mpz_t Pi, Qi, Plast, Qlast, Qnext, bi;
	long counter = 1;
	int status = FAIL;
	
	printf("[INFO ] Trying shank squares\n");


	mpz_init_set(myN, *n);

	mpz_init(tmp);	mpz_init(tmp2);
	mpz_init(bi);	mpz_init(Qnext);
	mpz_init(Pi);

	mpz_mul_ui(tmp, myN, SHANKQUAREK); // constA = k*N
	mpz_init_set(constA, tmp);

	mpz_sqrt(tmp, constA);	// constB = floor(sqrt(constA))
	mpz_init_set(constB, tmp);

	mpz_init_set(Plast, constB);


	mpz_pow_ui(tmp, Plast, 2);	// Qi = (constA) - (Pi**2)
	mpz_sub(tmp, constA, tmp);
	mpz_init_set(Qi, tmp);

	
	mpz_init_set_ui(Qlast, 1);


	while (counter < SHANKQUAREMAX)
	{

		mpz_add(tmp, constB, Plast);	//bi = floor( (constB) + (Plast) / Qi )
		mpz_fdiv_q(bi, tmp, Qi);

		mpz_mul(tmp, bi, Qi);			//Pi = (bi * Qi) - (Plast)
		mpz_sub(Pi, tmp, Plast);

		mpz_sub(tmp, Plast, Pi);		//Qnext = Qlast + (bi * (Plast - Pi))
		mpz_mul(tmp, tmp, bi);
		mpz_add(Qnext, Qlast, tmp);

		if (mpz_perfect_square_p(Qi) != 0 && counter % 2 == 0)
		{
			break;
		}
		else
		{
			mpz_set(Plast, Pi);
			mpz_set(Qlast, Qi);
			mpz_set(Qi, Qnext);	
		}

		counter += 1;
	}


	mpz_sub(tmp, constB, Plast);	//bi = floor( ( constB - Plast ) / sqrt(Qi) )
	mpz_sqrt(tmp2, Qi);
	mpz_fdiv_q(bi, tmp, tmp2);

	mpz_sqrt(tmp, Qi);				//Plast = (bi * sqrt(Qi)) + Plast
	mpz_mul(tmp, tmp, bi);
	mpz_add(Plast, tmp, Plast);

	mpz_sqrt(Qlast, Qi);

	mpz_pow_ui(tmp2, Plast, 2);		//Qnext = ((constA) - Plast**2) / Qlast
	mpz_sub(tmp, constA, tmp2);
	mpz_div(Qnext, tmp, Qlast);

	mpz_set(Qi, Qnext);

	counter = 0;

	while (counter < SHANKQUAREMAX)
	{
		mpz_add(tmp, constB, Plast);	//bi = floor( ( constB + Plast ) / Qi )
		mpz_fdiv_q(bi, tmp, Qi);

		mpz_mul(tmp, bi, Qi);			//Pi = (bi*Qi) - Plast
		mpz_sub(Pi, tmp, Plast);

		mpz_sub(tmp, Plast, Pi);		//Qnext = Qlast + (bi * (Plast - Pi))
		mpz_mul(tmp, tmp, bi);
		mpz_add(Qnext, Qlast, tmp);

		if (mpz_cmp(Pi, Plast) == 0)
		{
			break;
		}

		mpz_set(Plast, Pi);
		mpz_set(Qlast, Qi);
		mpz_set(Qi, Qnext);

		counter += 1;
	}

	mpz_gcd(tmp, myN, Pi);

	if (mpz_cmp_ui(tmp, 1) != 0 && mpz_cmp(tmp, myN) != 0)
	{
		printWin(&tmp, "Shanks squares");
		status = WIN;
	}

	mpz_clear(myN);		mpz_clear(constA);
	mpz_clear(constB);	mpz_clear(tmp);		mpz_clear(tmp2);
	mpz_clear(Pi);		mpz_clear(Qi);		mpz_clear(Plast);
	mpz_clear(Qlast);	mpz_clear(Qnext);	mpz_clear(bi);

	return status;

}
Beispiel #29
0
extern void _jl_mpz_div(mpz_t* rop, mpz_t* op1, mpz_t* op2) {
  mpz_fdiv_q(*rop, *op1, *op2);
}
Beispiel #30
0
/* Evaluate the expression E and put the result in R.  */
void
mpz_eval_expr (mpz_ptr r, expr_t e)
{
  mpz_t lhs, rhs;

  switch (e->op)
    {
    case LIT:
      mpz_set (r, e->operands.val);
      return;
    case PLUS:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_add (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case MINUS:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_sub (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case MULT:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_mul (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case DIV:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_fdiv_q (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case MOD:
      mpz_init (rhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_abs (rhs, rhs);
      mpz_eval_mod_expr (r, e->operands.ops.lhs, rhs);
      mpz_clear (rhs);
      return;
    case REM:
      /* Check if lhs operand is POW expression and optimize for that case.  */
      if (e->operands.ops.lhs->op == POW)
	{
	  mpz_t powlhs, powrhs;
	  mpz_init (powlhs);
	  mpz_init (powrhs);
	  mpz_init (rhs);
	  mpz_eval_expr (powlhs, e->operands.ops.lhs->operands.ops.lhs);
	  mpz_eval_expr (powrhs, e->operands.ops.lhs->operands.ops.rhs);
	  mpz_eval_expr (rhs, e->operands.ops.rhs);
	  mpz_powm (r, powlhs, powrhs, rhs);
	  if (mpz_cmp_si (rhs, 0L) < 0)
	    mpz_neg (r, r);
	  mpz_clear (powlhs);
	  mpz_clear (powrhs);
	  mpz_clear (rhs);
	  return;
	}

      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_fdiv_r (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#if __GNU_MP_VERSION >= 2
    case INVMOD:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_invert (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case POW:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      if (mpz_cmpabs_ui (lhs, 1) <= 0)
	{
	  /* For 0^rhs and 1^rhs, we just need to verify that
	     rhs is well-defined.  For (-1)^rhs we need to
	     determine (rhs mod 2).  For simplicity, compute
	     (rhs mod 2) for all three cases.  */
	  expr_t two, et;
	  two = malloc (sizeof (struct expr));
	  two -> op = LIT;
	  mpz_init_set_ui (two->operands.val, 2L);
	  makeexp (&et, MOD, e->operands.ops.rhs, two);
	  e->operands.ops.rhs = et;
	}

      mpz_eval_expr (rhs, e->operands.ops.rhs);
      if (mpz_cmp_si (rhs, 0L) == 0)
	/* x^0 is 1 */
	mpz_set_ui (r, 1L);
      else if (mpz_cmp_si (lhs, 0L) == 0)
	/* 0^y (where y != 0) is 0 */
	mpz_set_ui (r, 0L);
      else if (mpz_cmp_ui (lhs, 1L) == 0)
	/* 1^y is 1 */
	mpz_set_ui (r, 1L);
      else if (mpz_cmp_si (lhs, -1L) == 0)
	/* (-1)^y just depends on whether y is even or odd */
	mpz_set_si (r, (mpz_get_ui (rhs) & 1) ? -1L : 1L);
      else if (mpz_cmp_si (rhs, 0L) < 0)
	/* x^(-n) is 0 */
	mpz_set_ui (r, 0L);
      else
	{
	  unsigned long int cnt;
	  unsigned long int y;
	  /* error if exponent does not fit into an unsigned long int.  */
	  if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
	    goto pow_err;

	  y = mpz_get_ui (rhs);
	  /* x^y == (x/(2^c))^y * 2^(c*y) */
#if __GNU_MP_VERSION >= 2
	  cnt = mpz_scan1 (lhs, 0);
#else
	  cnt = 0;
#endif
	  if (cnt != 0)
	    {
	      if (y * cnt / cnt != y)
		goto pow_err;
	      mpz_tdiv_q_2exp (lhs, lhs, cnt);
	      mpz_pow_ui (r, lhs, y);
	      mpz_mul_2exp (r, r, y * cnt);
	    }
	  else
	    mpz_pow_ui (r, lhs, y);
	}
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    pow_err:
      error = "result of `pow' operator too large";
      mpz_clear (lhs); mpz_clear (rhs);
      longjmp (errjmpbuf, 1);
    case GCD:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_gcd (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
    case LCM:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_lcm (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case AND:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_and (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case IOR:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_ior (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
    case XOR:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_xor (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case NEG:
      mpz_eval_expr (r, e->operands.ops.lhs);
      mpz_neg (r, r);
      return;
    case NOT:
      mpz_eval_expr (r, e->operands.ops.lhs);
      mpz_com (r, r);
      return;
    case SQRT:
      mpz_init (lhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      if (mpz_sgn (lhs) < 0)
	{
	  error = "cannot take square root of negative numbers";
	  mpz_clear (lhs);
	  longjmp (errjmpbuf, 1);
	}
      mpz_sqrt (r, lhs);
      return;
#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
    case ROOT:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      if (mpz_sgn (rhs) <= 0)
	{
	  error = "cannot take non-positive root orders";
	  mpz_clear (lhs); mpz_clear (rhs);
	  longjmp (errjmpbuf, 1);
	}
      if (mpz_sgn (lhs) < 0 && (mpz_get_ui (rhs) & 1) == 0)
	{
	  error = "cannot take even root orders of negative numbers";
	  mpz_clear (lhs); mpz_clear (rhs);
	  longjmp (errjmpbuf, 1);
	}

      {
	unsigned long int nth = mpz_get_ui (rhs);
	if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
	  {
	    /* If we are asked to take an awfully large root order, cheat and
	       ask for the largest order we can pass to mpz_root.  This saves
	       some error prone special cases.  */
	    nth = ~(unsigned long int) 0;
	  }
	mpz_root (r, lhs, nth);
      }
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case FAC:
      mpz_eval_expr (r, e->operands.ops.lhs);
      if (mpz_size (r) > 1)
	{
	  error = "result of `!' operator too large";
	  longjmp (errjmpbuf, 1);
	}
      mpz_fac_ui (r, mpz_get_ui (r));
      return;
#if __GNU_MP_VERSION >= 2
    case POPCNT:
      mpz_eval_expr (r, e->operands.ops.lhs);
      { long int cnt;
	cnt = mpz_popcount (r);
	mpz_set_si (r, cnt);
      }
      return;
    case HAMDIST:
      { long int cnt;
	mpz_init (lhs); mpz_init (rhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	mpz_eval_expr (rhs, e->operands.ops.rhs);
	cnt = mpz_hamdist (lhs, rhs);
	mpz_clear (lhs); mpz_clear (rhs);
	mpz_set_si (r, cnt);
      }
      return;
#endif
    case LOG2:
      mpz_eval_expr (r, e->operands.ops.lhs);
      { unsigned long int cnt;
	if (mpz_sgn (r) <= 0)
	  {
	    error = "logarithm of non-positive number";
	    longjmp (errjmpbuf, 1);
	  }
	cnt = mpz_sizeinbase (r, 2);
	mpz_set_ui (r, cnt - 1);
      }
      return;
    case LOG:
      { unsigned long int cnt;
	mpz_init (lhs); mpz_init (rhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	mpz_eval_expr (rhs, e->operands.ops.rhs);
	if (mpz_sgn (lhs) <= 0)
	  {
	    error = "logarithm of non-positive number";
	    mpz_clear (lhs); mpz_clear (rhs);
	    longjmp (errjmpbuf, 1);
	  }
	if (mpz_cmp_ui (rhs, 256) >= 0)
	  {
	    error = "logarithm base too large";
	    mpz_clear (lhs); mpz_clear (rhs);
	    longjmp (errjmpbuf, 1);
	  }
	cnt = mpz_sizeinbase (lhs, mpz_get_ui (rhs));
	mpz_set_ui (r, cnt - 1);
	mpz_clear (lhs); mpz_clear (rhs);
      }
      return;
    case FERMAT:
      {
	unsigned long int t;
	mpz_init (lhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	t = (unsigned long int) 1 << mpz_get_ui (lhs);
	if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0 || t == 0)
	  {
	    error = "too large Mersenne number index";
	    mpz_clear (lhs);
	    longjmp (errjmpbuf, 1);
	  }
	mpz_set_ui (r, 1);
	mpz_mul_2exp (r, r, t);
	mpz_add_ui (r, r, 1);
	mpz_clear (lhs);
      }
      return;
    case MERSENNE:
      mpz_init (lhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0)
	{
	  error = "too large Mersenne number index";
	  mpz_clear (lhs);
	  longjmp (errjmpbuf, 1);
	}
      mpz_set_ui (r, 1);
      mpz_mul_2exp (r, r, mpz_get_ui (lhs));
      mpz_sub_ui (r, r, 1);
      mpz_clear (lhs);
      return;
    case FIBONACCI:
      { mpz_t t;
	unsigned long int n, i;
	mpz_init (lhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
	  {
	    error = "Fibonacci index out of range";
	    mpz_clear (lhs);
	    longjmp (errjmpbuf, 1);
	  }
	n = mpz_get_ui (lhs);
	mpz_clear (lhs);

#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
	mpz_fib_ui (r, n);
#else
	mpz_init_set_ui (t, 1);
	mpz_set_ui (r, 1);

	if (n <= 2)
	  mpz_set_ui (r, 1);
	else
	  {
	    for (i = 3; i <= n; i++)
	      {
		mpz_add (t, t, r);
		mpz_swap (t, r);
	      }
	  }
	mpz_clear (t);
#endif
      }
      return;
    case RANDOM:
      {
	unsigned long int n;
	mpz_init (lhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
	  {
	    error = "random number size out of range";
	    mpz_clear (lhs);
	    longjmp (errjmpbuf, 1);
	  }
	n = mpz_get_ui (lhs);
	mpz_clear (lhs);
	mpz_urandomb (r, rstate, n);
      }
      return;
    case NEXTPRIME:
      {
	mpz_eval_expr (r, e->operands.ops.lhs);
	mpz_nextprime (r, r);
      }
      return;
    case BINOM:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      {
	unsigned long int k;
	if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
	  {
	    error = "k too large in (n over k) expression";
	    mpz_clear (lhs); mpz_clear (rhs);
	    longjmp (errjmpbuf, 1);
	  }
	k = mpz_get_ui (rhs);
	mpz_bin_ui (r, lhs, k);
      }
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case TIMING:
      {
	int t0;
	t0 = cputime ();
	mpz_eval_expr (r, e->operands.ops.lhs);
	printf ("time: %d\n", cputime () - t0);
      }
      return;
    default:
      abort ();
    }
}