예제 #1
0
static PyObject *
GMPy_MPZ_c_div_2exp(PyObject *self, PyObject *args)
{
    mp_bitcnt_t nbits;
    MPZ_Object *result, *tempx;

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

    nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1));
    if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
        return NULL;
    }

    tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL);
    result = GMPy_MPZ_New(NULL);
    if (!tempx || !result) {
        Py_XDECREF((PyObject*)result);
        Py_XDECREF((PyObject*)tempx);
        return NULL;
    }

    mpz_cdiv_q_2exp(result->z, tempx->z, nbits);
    Py_DECREF((PyObject*)tempx);
    return (PyObject*)result;
}
예제 #2
0
static PyObject *
GMPy_MPZ_Lshift_Slot(PyObject *self, PyObject *other)
{
    mp_bitcnt_t count;
    MPZ_Object *result, *tempx;

    count = mp_bitcnt_t_From_Integer(other);
    if ((count == (mp_bitcnt_t)(-1)) && PyErr_Occurred())
        return NULL;

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

    if (CHECK_MPZANY(self)) {
        mpz_mul_2exp(result->z, MPZ(self), count);
        return (PyObject*)result;
    }
    else {
        if (!(tempx = GMPy_MPZ_From_Integer(self, NULL))) {
            Py_XDECREF((PyObject*)result);
            Py_XDECREF((PyObject*)tempx);
            return NULL;
        }

        mpz_mul_2exp(result->z, tempx->z, count);
        Py_DECREF((PyObject*)tempx);
        return (PyObject*)result;
    }
}
예제 #3
0
static PyObject *
GMPy_MPZ_bit_test_function(PyObject *self, PyObject *args)
{
    mp_bitcnt_t bit_index;
    int temp;
    MPZ_Object *tempx = NULL;

    if (PyTuple_GET_SIZE(args) != 2) {
        goto err;
    }

    if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) {
        goto err;
    }

    bit_index = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1));
    if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
        goto err_index;
    }

    temp = mpz_tstbit(tempx->z, bit_index);
    Py_DECREF((PyObject*)tempx);

    if (temp)
        Py_RETURN_TRUE;
    else
        Py_RETURN_FALSE;

  err:
    TYPE_ERROR("bit_test() requires 'mpz','int' arguments");
  err_index:
    Py_DECREF((PyObject*)tempx);
    return NULL;
}
예제 #4
0
파일: gmpy2_random.c 프로젝트: godbomb/gmpy
static PyObject *
GMPy_MPZ_urandomb_Function(PyObject *self, PyObject *args)
{
    MPZ_Object *result;
    mp_bitcnt_t len;

    if (PyTuple_GET_SIZE(args) != 2) {
        TYPE_ERROR("mpz_urandomb() requires 2 arguments");
        return NULL;
    }

    if (!RandomState_Check(PyTuple_GET_ITEM(args, 0))) {
        TYPE_ERROR("mpz_urandomb() requires 'random_state' and 'bit_count' arguments");
        return NULL;
    }

    len = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1));
    if (len == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
        TYPE_ERROR("mpz_urandomb() requires 'random_state' and 'bit_count' arguments");
        return NULL;
    }

    if ((result = GMPy_MPZ_New(NULL))) {
        mpz_urandomb(result->z, RANDOM_STATE(PyTuple_GET_ITEM(args, 0)), len);
    }

    return (PyObject*)result;
}
예제 #5
0
static PyObject *
GMPy_MPZ_bit_flip_function(PyObject *self, PyObject *args)
{
    mp_bitcnt_t bit_index;
    MPZ_Object *result = NULL, *tempx = NULL;

    if (PyTuple_GET_SIZE(args) != 2)
        goto err;

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

    if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)))
        goto err;

    bit_index = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1));
    if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred())
        goto err_index;

    mpz_set(result->z, tempx->z);
    mpz_combit(result->z, bit_index);

  err:
    TYPE_ERROR("bit_flip() requires 'mpz','int' arguments");
  err_index:
    Py_XDECREF((PyObject*)result);
    Py_XDECREF((PyObject*)tempx);
    return NULL;
}
예제 #6
0
static PyObject *
GMPy_XMPZ_IPow_Slot(PyObject *self, PyObject *other, PyObject *mod)
{
    mp_bitcnt_t exp;

    exp = mp_bitcnt_t_From_Integer(other);
    if (exp == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
        PyErr_Clear();
        Py_RETURN_NOTIMPLEMENTED;
    }

    mpz_pow_ui(MPZ(self), MPZ(self), exp);
    Py_INCREF((PyObject*)self);
    return (PyObject*)self;
}
예제 #7
0
static PyObject *
GMPy_MPZ_bit_test_method(PyObject *self, PyObject *other)
{
    mp_bitcnt_t bit_index;

    bit_index = mp_bitcnt_t_From_Integer(other);
    if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
        return NULL;
    }

    if (mpz_tstbit(MPZ(self), bit_index))
        Py_RETURN_TRUE;
    else
        Py_RETURN_FALSE;
}
예제 #8
0
static PyObject *
GMPy_XMPZ_ILshift_Slot(PyObject *self, PyObject *other)
{
    mp_bitcnt_t shift;

    if (IS_INTEGER(other)) {
        shift = mp_bitcnt_t_From_Integer(other);
        if (shift == (mp_bitcnt_t)(-1) && PyErr_Occurred())
            return NULL;

        mpz_mul_2exp(MPZ(self), MPZ(self), shift);
        Py_INCREF(self);
        return self;
    }

    Py_RETURN_NOTIMPLEMENTED;
}
예제 #9
0
static PyObject *
GMPy_MPZ_bit_flip_method(PyObject *self, PyObject *other)
{
    mp_bitcnt_t bit_index;
    MPZ_Object *result = NULL;

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

    bit_index = mp_bitcnt_t_From_Integer(other);
    if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred())
        return NULL;

    mpz_set(result->z, MPZ(self));
    mpz_combit(result->z, bit_index);
    return (PyObject*)result;
}
예제 #10
0
static PyObject *
GMPy_MPZ_IPow_Slot(PyObject *self, PyObject *other, PyObject *mod)
{
    MPZ_Object *r;
    mp_bitcnt_t exp;

    exp = mp_bitcnt_t_From_Integer(other);
    if (exp == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
        PyErr_Clear();
        Py_RETURN_NOTIMPLEMENTED;
    }

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

    mpz_pow_ui(r->z, MPZ(self), exp);
    return (PyObject*)r;
}
예제 #11
0
static PyObject *
GMPy_MPZ_ILshift_Slot(PyObject *self, PyObject *other)
{
    MPZ_Object *rz;
    mp_bitcnt_t shift;

    if (IS_INTEGER(other)) {
        shift = mp_bitcnt_t_From_Integer(other);
        if (shift == (mp_bitcnt_t)(-1) && PyErr_Occurred())
            return NULL;

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

        mpz_mul_2exp(rz->z, MPZ(self), shift);
        return (PyObject *)rz;
    }
    Py_RETURN_NOTIMPLEMENTED;
}
예제 #12
0
static PyObject *
GMPy_MPZ_bit_mask(PyObject *self, PyObject *other)
{
    mp_bitcnt_t n = 0;
    MPZ_Object* result;

    n = mp_bitcnt_t_From_Integer(other);
    if (n == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
        return NULL;
    }

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

    mpz_set_ui(result->z, 1);
    mpz_mul_2exp(result->z, result->z, n);
    mpz_sub_ui(result->z, result->z, 1);

    return (PyObject*)result;
}
예제 #13
0
static PyObject *
GMPy_MPZ_bit_scan0_method(PyObject *self, PyObject *args)
{
    mp_bitcnt_t index, starting_bit = 0;

    if (PyTuple_GET_SIZE(args) == 1) {
        starting_bit = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 0));
        if (starting_bit == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
            return NULL;
        }
    }

    index = mpz_scan0(MPZ(self), starting_bit);

    if (index == (mp_bitcnt_t)(-1)) {
        Py_RETURN_NONE;
    }
    else {
        return PyIntOrLong_FromMpBitCnt(index);
    }
}
예제 #14
0
static PyObject *
GMPy_MPZ_t_divmod_2exp(PyObject *self, PyObject *args)
{
    mp_bitcnt_t nbits;
    MPZ_Object *q, *r, *tempx;
    PyObject *result;

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

    nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1));
    if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
        return NULL;
    }

    tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL);
    q = GMPy_MPZ_New(NULL);
    r = GMPy_MPZ_New(NULL);
    result = PyTuple_New(2);
    if (!tempx || !q || !r || !result) {
        Py_XDECREF(result);
        Py_XDECREF((PyObject*)tempx);
        Py_XDECREF((PyObject*)q);
        Py_XDECREF((PyObject*)r);
        return NULL;
    }

    mpz_tdiv_q_2exp(q->z, tempx->z, nbits);
    mpz_tdiv_r_2exp(r->z, tempx->z, nbits);

    Py_DECREF((PyObject*)tempx);
    PyTuple_SET_ITEM(result, 0, (PyObject*)q);
    PyTuple_SET_ITEM(result, 1, (PyObject*)r);
    return result;
}
예제 #15
0
static PyObject *
GMPy_MPZ_bit_scan1_function(PyObject *self, PyObject *args)
{
    mp_bitcnt_t index, starting_bit = 0;
    MPZ_Object *tempx = NULL;

    if (PyTuple_GET_SIZE(args) == 0 || PyTuple_GET_SIZE(args) > 2) {
        goto err;
    }

    if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) {
        goto err;
    }

    if (PyTuple_GET_SIZE(args) == 2) {
        starting_bit = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1));
        if (starting_bit == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
            goto err_index;
        }
    }

    index = mpz_scan1(tempx->z, starting_bit);

    Py_DECREF((PyObject*)tempx);
    if (index == (mp_bitcnt_t)(-1)) {
        Py_RETURN_NONE;
    }
    else {
        return PyIntOrLong_FromMpBitCnt(index);
    }

  err:
    TYPE_ERROR("bit_scan0() requires 'mpz',['int'] arguments");
  err_index:
    Py_DECREF((PyObject*)tempx);
    return NULL;
}
예제 #16
0
static PyObject *
GMPy_MPZ_pack(PyObject *self, PyObject *args)
{
    mp_bitcnt_t nbits, total_bits, tempx_bits;
    Py_ssize_t index, lst_count, i, temp_bits, limb_count;
    PyObject *lst;
    mpz_t temp;
    MPZ_Object *result, *tempx = 0;
    CTXT_Object *context = NULL;

    if (PyTuple_GET_SIZE(args) != 2) {
        TYPE_ERROR("pack() requires 'list','int' arguments");
        return NULL;
    }

    nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1));
    if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
        return NULL;
    }

    if (!PyList_Check(PyTuple_GET_ITEM(args, 0))) {
        TYPE_ERROR("pack() requires 'list','int' arguments");
        return NULL;
    }

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

    lst = PyTuple_GET_ITEM(args, 0);
    lst_count = PyList_GET_SIZE(lst);
    total_bits = nbits * lst_count;

    if ((total_bits / lst_count) != nbits) {
        VALUE_ERROR("result too large to store in an 'mpz'");
        return NULL;
    }

    mpz_set_ui(result->z, 0);
    mpz_setbit(result->z, total_bits + (mp_bits_per_limb * 2));

    mpz_init(temp);
    mpz_set_ui(temp, 0);
    limb_count = 0;
    tempx_bits = 0;

    for (index = 0; index < lst_count; index++) {
        if (!(tempx = GMPy_MPZ_From_Integer(PyList_GetItem(lst, index), context))
            || (mpz_sgn(tempx->z) < 0)
            || (mpz_sizeinbase(tempx->z,2) > (size_t)nbits)) {
            TYPE_ERROR("pack() requires list elements be positive integers < 2^n bits");
            mpz_clear(temp);
            Py_XDECREF((PyObject*)tempx);
            Py_DECREF((PyObject*)result);
            return NULL;
        }
        mpz_mul_2exp(tempx->z, tempx->z, tempx_bits);
        mpz_add(temp, temp, tempx->z);
        tempx_bits += nbits;
        i = 0;
        temp_bits = mpz_sizeinbase(temp, 2) * mpz_sgn(temp);
        while (tempx_bits >= (mp_bitcnt_t)mp_bits_per_limb) {
            if (temp_bits > 0) {
                result->z->_mp_d[limb_count] = mpz_getlimbn(temp, i);
            }
            i += 1;
            tempx_bits -= mp_bits_per_limb;
            limb_count += 1;
            temp_bits -= mp_bits_per_limb;
        }
        if (temp_bits > 0) {
            mpz_tdiv_q_2exp(temp, temp, mp_bits_per_limb * i);
        }
        else {
            mpz_set_ui(temp, 0);
        }
        Py_DECREF((PyObject*)tempx);
    }
    result->z->_mp_d[limb_count] = mpz_getlimbn(temp, 0);
    mpz_clrbit(result->z, total_bits + (mp_bits_per_limb * 2));
    mpz_clear(temp);
    return (PyObject*)result;
}
예제 #17
0
static PyObject *
GMPy_MPZ_unpack(PyObject *self, PyObject *args)
{
    mp_bitcnt_t nbits, total_bits, guard_bit, extra_bits, temp_bits;
    Py_ssize_t index = 0, lst_count, i, lst_ptr = 0;
    PyObject *result;
    mpz_t temp;
    mp_limb_t extra = 0;
    MPZ_Object *item, *tempx = NULL;
    CTXT_Object *context = NULL;

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

    nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1));
    if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
        return NULL;
    }

    if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), context))) {
        TYPE_ERROR("unpack() requires 'int','int' arguments");
        return NULL;
    }

    if (mpz_sgn(tempx->z) < 0) {
        VALUE_ERROR("unpack() requires x >= 0");
        return NULL;
    }

    if (mpz_sgn(tempx->z) == 0) {
        total_bits = 0;
    }
    else {
        total_bits = mpz_sizeinbase(tempx->z, 2);
    }

    lst_count = total_bits / nbits;
    if ((total_bits % nbits) || !lst_count) {
        lst_count += 1;
    }

    if (!(result = PyList_New(lst_count))) {
        Py_DECREF((PyObject*)tempx);
        return NULL;
    }

    if (mpz_sgn(tempx->z) == 0) {
        if (!(item = GMPy_MPZ_New(context))) {
            Py_DECREF((PyObject*)tempx);
            Py_DECREF(result);
            return NULL;
        }
        mpz_set_ui(item->z, 0);
        PyList_SET_ITEM(result, 0, (PyObject*)item);
        Py_DECREF((PyObject*)tempx);
        return result;
    }

    mpz_init(temp);
    guard_bit = nbits + (2 * mp_bits_per_limb);
    extra_bits = 0;
    index = 0;

    while (lst_ptr < lst_count) {
        i = 0;
        temp_bits = 0;
        mpz_set_ui(temp, 0);
        mpz_setbit(temp, guard_bit);
        while (temp_bits + extra_bits < nbits) {
            temp->_mp_d[i++] = mpz_getlimbn(tempx->z, index++);
            temp_bits += mp_bits_per_limb;
        }
        mpz_clrbit(temp, guard_bit);
        mpz_mul_2exp(temp, temp, extra_bits);
        if (mpz_sgn(temp) == 0 && extra != 0) {
            mpz_set_ui(temp, 1);
            temp->_mp_d[0] = extra;
        }
        else {
           mpn_add_1(temp->_mp_d, temp->_mp_d, mpz_size(temp), extra);
        }
        temp_bits += extra_bits;

        while ((lst_ptr < lst_count) && (temp_bits >= nbits)) {
            if(!(item = GMPy_MPZ_New(context))) {
                mpz_clear(temp);
                Py_DECREF((PyObject*)tempx);
                Py_DECREF(result);
                return NULL;
            }
            mpz_tdiv_r_2exp(item->z, temp, nbits);
            PyList_SET_ITEM(result, lst_ptr++, (PyObject*)item);
            mpz_tdiv_q_2exp(temp, temp, nbits);
            temp_bits -= nbits;
        }
        extra = mpz_getlimbn(temp, 0);
        extra_bits = temp_bits;
    }
    Py_DECREF((PyObject*)tempx);
    mpz_clear(temp);
    return result;
}