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?
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With