Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is ** implemented in Python?

Tags:

python

I'm wondering where I find the source to show how the operator ** is implemented in Python. Can someone point me in the right direction?

like image 334
Nope Avatar asked Dec 09 '08 22:12

Nope


People also ask

What does * represent in Python?

The asterisk (star) operator is used in Python with more than one meaning attached to it. For numeric data types, * is used as multiplication operator >>> a=10;b=20 >>> a*b 200 >>> a=1.5; b=2.5; >>> a*b 3.75 >>> a=2+3j; b=3+2j >>> a*b 13j.

How is Python code implemented?

The default implementation of the Python programming language is Cpython. As the name suggests Cpython is written in C language. Cpython compiles the python source code into intermediate bytecode, which is executed by the Cpython virtual machine.

Which is the fastest implementation of Python?

The fastest implementation of python is pypy. As mentioned above, pypy uses justin-time compilation. The JIT compilation makes pypy faster than the other implementations. JIT compilation lets the source code to be compiled into native machine code which makes it very fast.


1 Answers

The python grammar definition (from which the parser is generated using pgen), look for 'power': Gramar/Gramar

The python ast, look for 'ast_for_power': Python/ast.c

The python eval loop, look for 'BINARY_POWER': Python/ceval.c

Which calls PyNumber_Power (implemented in Objects/abstract.c):

PyObject *
PyNumber_Power(PyObject *v, PyObject *w, PyObject *z)
{
    return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()");
}

Essentially, invoke the pow slot. For long objects (the only default integer type in 3.0) this is implemented in the long_pow function Objects/longobject.c, for int objects (in the 2.x branches) it is implemented in the int_pow function Object/intobject.c

If you dig into long_pow, you can see that after vetting the arguments and doing a bit of set up, the heart of the exponentiation can be see here:

if (Py_SIZE(b) <= FIVEARY_CUTOFF) {
    /* Left-to-right binary exponentiation (HAC Algorithm 14.79) */
    /* http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf    */
    for (i = Py_SIZE(b) - 1; i >= 0; --i) {
        digit bi = b->ob_digit[i];

        for (j = 1 << (PyLong_SHIFT-1); j != 0; j >>= 1) {
            MULT(z, z, z)
            if (bi & j)
                MULT(z, a, z)
        }
    }
}
else {
    /* Left-to-right 5-ary exponentiation (HAC Algorithm 14.82) */
    Py_INCREF(z);   /* still holds 1L */
    table[0] = z;
    for (i = 1; i < 32; ++i)
        MULT(table[i-1], a, table[i])

    for (i = Py_SIZE(b) - 1; i >= 0; --i) {
        const digit bi = b->ob_digit[i];

        for (j = PyLong_SHIFT - 5; j >= 0; j -= 5) {
            const int index = (bi >> j) & 0x1f;
            for (k = 0; k < 5; ++k)
                MULT(z, z, z)
            if (index)
                MULT(z, table[index], z)
        }
    }
}

Which uses algorithms discussed in Chapter 14.6 of the Handbook of Applied Cryptography which describes efficient exponentiation algorithms for arbitrary precision arithmetic.

like image 82
Aaron Maenpaa Avatar answered Oct 29 '22 06:10

Aaron Maenpaa