Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Index: gmpy_mpz.c
- ===================================================================
- --- gmpy_mpz.c (revision 311)
- +++ gmpy_mpz.c (working copy)
- @@ -400,72 +400,99 @@
- return result;
- }
- +static int gmpy_mpz_bit_set_iterable(PyObject *self, PyObject *other) {
- + long bit_index;
- + PyObject *iterator, *item;
- +
- + iterator = PyObject_GetIter(other);
- + if (!iterator) {
- + TYPE_ERROR("bit_set() failed with iterator");
- + return -1;
- + }
- +
- + while ((item = PyIter_Next(iterator))) {
- +
- + bit_index = clong_From_Integer(item);
- + if(bit_index == -1 && PyErr_Occurred()) {
- + TYPE_ERROR("bit_set() requires 'mpz','int' arguments");
- + goto err;
- + }
- +
- + if(bit_index < 0) {
- + VALUE_ERROR("bit_index must be >= 0");
- + goto err;
- + }
- +
- + mpz_setbit(Pympz_AS_MPZ(self), bit_index);
- + Py_DECREF(item);
- + }
- + Py_DECREF(iterator);
- + return 0;
- + err:
- + Py_DECREF(item);
- + Py_DECREF(iterator);
- + return -1;
- +}
- +
- +static int gmpy_mpz_bit_setall(PyObject *self, PyObject *other) {
- + Py_ssize_t i, cur, length, start, stop, step, slicelength;
- +
- + if (!PySlice_Check(other))
- + return gmpy_mpz_bit_set_iterable(self, other);
- +
- + /* slice */
- + length = mpz_sizeinbase(Pympz_AS_MPZ(self), 2);
- + if (PySlice_GetIndicesEx((PySliceObject*)other, length,
- + &start, &stop, &step, &slicelength) < 0) {
- + TYPE_ERROR("bit_set() failed with slice");
- + return -1;
- + }
- +
- + for (cur = start, i = 0; i < slicelength;
- + cur += step, i++) {
- + mpz_setbit(Pympz_AS_MPZ(self), cur);
- + }
- + return 0;
- +}
- +
- static PyObject *
- Pympz_bit_set(PyObject *self, PyObject *other)
- {
- long bit_index;
- - PyObject *result, *iterator, *item;
- - int temp;
- - Py_ssize_t i, length, start, stop, step, slicelength;
- + PyObject *result = NULL;
- + int is_mpz = 0;
- - if((Pyxmpz_Check(self) && (PyIter_Check(other)))) {
- - iterator = PyObject_GetIter(other);
- - if(!iterator) {
- - TYPE_ERROR("bit_set() failed with iterator");
- - return NULL;
- - }
- - while((item = PyIter_Next(iterator))) {
- - bit_index = clong_From_Integer(item);
- - if(bit_index == -1 && PyErr_Occurred()) {
- - TYPE_ERROR("bit_set() requires 'mpz','int' arguments");
- - Py_DECREF(item);
- - Py_DECREF(iterator);
- - return NULL;
- - }
- - if(bit_index < 0) {
- - VALUE_ERROR("bit_index must be >= 0");
- - Py_DECREF(item);
- - Py_DECREF(iterator);
- - return NULL;
- - }
- - mpz_setbit(Pympz_AS_MPZ(self), bit_index);
- - Py_DECREF(item);
- - }
- - Py_DECREF(iterator);
- - Py_RETURN_NONE;
- - } else if((Pyxmpz_Check(self) && (PySlice_Check(other)))) {
- - length = mpz_sizeinbase(Pympz_AS_MPZ(self), 2);
- - temp = PySlice_GetIndicesEx((PySliceObject*)other, length, &start, &stop, &step, &slicelength);
- - if(temp == -1) {
- - TYPE_ERROR("bit_set() failed with slice");
- - return NULL;
- - }
- - for(i=start;i<stop;i+=step) {
- - mpz_setbit(Pympz_AS_MPZ(self), i);
- - }
- - Py_RETURN_NONE;
- - } else {
- - bit_index = clong_From_Integer(other);
- - if(bit_index == -1 && PyErr_Occurred()) {
- - TYPE_ERROR("bit_set() requires 'mpz','int' arguments");
- - return NULL;
- - }
- + if (!Pyxmpz_Check(self)) {
- + is_mpz = 1;
- + CREATE0_ONE_MPZANY(result);
- + mpz_set(Pympz_AS_MPZ(result), Pympz_AS_MPZ(self));
- + self = result;
- + }
- - if(bit_index < 0) {
- - VALUE_ERROR("bit_index must be >= 0");
- - return NULL;
- - }
- + bit_index = clong_From_Integer(other);
- + if (bit_index < 0) {
- + if (bit_index == -1 && PyErr_Occurred()) {
- + /* integer index failed */
- + PyErr_Clear();
- + if (gmpy_mpz_bit_setall(self, other) == -1)
- + goto err;
- + goto ret;
- + }
- + VALUE_ERROR("bit_index must be >= 0");
- + goto err;
- + }
- - if(Pyxmpz_Check(self)) {
- - mpz_setbit(Pympz_AS_MPZ(self), bit_index);
- - Py_RETURN_NONE;
- - } else {
- - CREATE0_ONE_MPZANY(result);
- - mpz_set(Pympz_AS_MPZ(result), Pympz_AS_MPZ(self));
- - mpz_setbit(Pympz_AS_MPZ(result), bit_index);
- - return result;
- - }
- - }
- + mpz_setbit(Pympz_AS_MPZ(self), bit_index);
- + goto ret;
- +
- + err:
- + if (is_mpz)
- + Py_DECREF(result);
- + return NULL;
- + ret:
- + if (is_mpz)
- + return result; /* return new reference */
- + Py_RETURN_NONE;
- }
- static char doc_bit_flipm[]="\
Add Comment
Please, Sign In to add comment