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