This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author anon
Recipients anon, hct, mark.dickinson, meador.inge, pitrou, rhettinger, serhiy.storchaka, tim.peters, vstinner
Date 2013-12-09.17:07:54
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1386608875.35.0.511659992211.issue19915@psf.upfronthosting.co.za>
In-reply-to
Content
Here is my very rough attempt at bits_at. It doesn't handle negative numbers and I am not sure it's safe. This was my first time using Python internals.

Objects/longobject.c:



static PyObject *
long_bits_at(PyLongObject *v, PyObject *args)
{
    PyLongObject *z = NULL;
    
    if(Py_SIZE(v) < 0)
    {
        PyLongObject *a1, *a2;
        Py_RETURN_NOTIMPLEMENTED;
        a1 = (PyLongObject *)long_invert(v);
        //Handle the case where a1 == NULL
        a2 = (PyLongObject *)long_bits_at(a1, args);
        //Handle the case where a2 == NULL
        Py_DECREF(a1);
        Py_DECREF(a2);
        //return a2 ^ ((1 << width) - 1)
    }
    else
    {
        PyObject *at_ = NULL;
        PyObject *width_ = NULL;
        ssize_t at, width, i, j, bitsleft, step;
        ssize_t wordshift, size, newsize, loshift, hishift;
        digit mask;
        
        if (!PyArg_UnpackTuple(args, "bits_at", 1, 2, &at_, &width_))
            return NULL;
        
        at = PyLong_AsSsize_t((PyObject *)at_);
        if (at == -1L && PyErr_Occurred())
            return NULL;
        if (at < 0) {
            PyErr_SetString(PyExc_ValueError, "negative index");
            return NULL;
        }
        
        if (width_ == NULL)
            width = 1;
        else {
            width = PyLong_AsSsize_t((PyObject *)width_);
            if (width == -1L && PyErr_Occurred())
                return NULL;
            if (width < 0) {
                PyErr_SetString(PyExc_ValueError, "negative bit count");
                return NULL;
            }
        }
        
        wordshift = at / PyLong_SHIFT;
        size = ABS(Py_SIZE(v));
        newsize = (width-1) / PyLong_SHIFT + 1;
        if (newsize > size-wordshift)
            newsize = size-wordshift;
        if (newsize <= 0)
            return PyLong_FromLong(0L);
        
        loshift = at % PyLong_SHIFT;
        hishift = PyLong_SHIFT - loshift;
        bitsleft = width;
        z = _PyLong_New(newsize);
        if (z == NULL)
            return NULL;
        
        for (i = 0, j = wordshift; i < newsize; i++, j++) {
            step = bitsleft<hishift ? bitsleft : hishift;
            mask = ((digit)1 << step) - 1;
            z->ob_digit[i] = (v->ob_digit[j] >> loshift) & mask;
            bitsleft -= step;
            
            if (j+1 < size) {
                step = bitsleft<loshift ? bitsleft : loshift;
                mask = ((digit)1 << step) - 1;
                z->ob_digit[i] |= ((v->ob_digit[j+1] & mask) << hishift);
                bitsleft -= step;
            }
        }
        z = long_normalize(z);
    }
    
    return (PyObject *)z;
}

PyDoc_STRVAR(long_bits_at_doc,
"int.bits_at(pos, width=1) -> int\n\
\n\
Equivalent to (int >> pos) & ((1 << width) - 1).");
History
Date User Action Args
2013-12-09 17:07:55anonsetrecipients: + anon, tim.peters, rhettinger, mark.dickinson, pitrou, vstinner, meador.inge, serhiy.storchaka, hct
2013-12-09 17:07:55anonsetmessageid: <1386608875.35.0.511659992211.issue19915@psf.upfronthosting.co.za>
2013-12-09 17:07:55anonlinkissue19915 messages
2013-12-09 17:07:54anoncreate