diff -r 62438d1b11c7 Objects/longobject.c --- a/Objects/longobject.c Fri May 02 23:26:03 2014 +0200 +++ b/Objects/longobject.c Sat May 03 14:40:57 2014 +0200 @@ -34,6 +34,9 @@ static PyLongObject small_ints[NSMALLNEG Py_ssize_t quick_int_allocs, quick_neg_int_allocs; #endif +/* Forward declaration */ +static PyObject* long_pow2(Py_ssize_t pow2); + static PyObject * get_small_int(sdigit ival) { @@ -3855,6 +3858,16 @@ long_pow(PyObject *v, PyObject *w, PyObj } } + if (c == NULL && Py_SIZE(a) == 1 && a->ob_digit[0] == 2) { + Py_ssize_t shiftby = PyLong_AsSsize_t((PyObject *)b); + if (!(shiftby == -1L && PyErr_Occurred())) { + Py_DECREF(a); + Py_DECREF(b); + return long_pow2(shiftby); + } else + PyErr_Clear(); + } + if (c) { /* if modulus == 0: raise ValueError() */ @@ -4099,6 +4112,31 @@ long_rshift(PyLongObject *a, PyLongObjec } +/* Compute 2 ** k for k >= 0 */ +static PyObject * +long_pow2(Py_ssize_t k) +{ + PyLongObject *z; + Py_ssize_t n, r; + + assert(k >= 0); + if (k <= 30) { + int pow2 = 1 << (int)k; + return PyLong_FromLong(pow2); + } + + n = k / PyLong_SHIFT; + r = k % PyLong_SHIFT; + + z = _PyLong_New(1 + n); + if (z == NULL) + return NULL; + if (n) + memset(z->ob_digit, 0, n * sizeof(z->ob_digit[0])); + z->ob_digit[n] = (digit)1 << r; + return (PyObject *)z; +} + static PyObject * long_lshift(PyObject *v, PyObject *w) {