¿Cómo se ** implementa en Python?

votos
11

Me pregunto dónde encontraré la fuente para mostrar cómo se implementa el operador ** en Python. ¿Alguien me puede apuntar en la dirección correcta?

Publicado el 09/12/2008 a las 23:07
fuente por usuario
En otros idiomas...                            


4 respuestas

votos
24

La definición de gramática de Python (a partir de la cual se genera el analizador usando pgen ), busca 'poder': Gramar / Gramar

El python ast, busca 'ast_for_power': Python / ast.c

El bucle python eval, busque 'BINARY_POWER': Python / ceval.c

Que llama a PyNumber_Power (implementado en Objects / abstract.c ):

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

Básicamente, invoque la ranura pow . Para objetos largos (el único tipo entero por defecto en 3.0) esto se implementa en la función long_pow Objects / longobject.c , para int objects (en las ramas 2.x) se implementa en la función int_pow Object / intobject.c

Si profundizas en long_pow, puedes ver que después de examinar los argumentos y hacer un poco de configuración, el corazón de la exponenciación se puede ver aquí:

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)
        }
    }
}

El cual usa algoritmos discutidos en el Capítulo 14.6 del Manual de Criptografía Aplicada que describe algoritmos eficientes de exponenciación para la aritmética de precisión arbitraria.

Respondida el 10/12/2008 a las 00:33
fuente por usuario

votos
1

Creo que los pensamientos aleatorios de los casos preguntan sobre los asteriscos en la definición de las funciones.

Puede encontrar la respuesta en esta página de documentación de Python: http://docs.python.org/tutorial/controlflow.html#more-on-defining-functions

Cuando un parámetro formal final del nombre del formulario ** está presente, recibe un diccionario que contiene todos los argumentos de palabra clave, excepto los que corresponden a un parámetro formal.

He sembrado una descripción de estas cosas en otro lugar en Python Doc pero no puedo recordar.

Respondida el 10/12/2008 a las 00:47
fuente por usuario

votos
1

Hay dos implementaciones diferentes, una para objetos int (long in 3.0) y otra para objetos float.

El flotante pow es la función float_pow (PyObject * v, PyObject * w, PyObject * z) definida en el archivo Objects / floatobject.c del código fuente de Python. Esto funciona llamadas pow () de C stdlib's math.h

El int pow tiene su propia implementación, la función int_pow (PyIntObject * v, PyIntObject * w, PyIntObject * z) se define en Objects / intobject.c (longobject.c para 3.0) del código fuente de Python.

Respondida el 10/12/2008 a las 00:32
fuente por usuario

votos
1

Es el poder para el operador

python.org doc - Operador de energía

Editar: Oh, dang, el código, correcto. Espero que el enlace todavía ayude. Sloppy leyó de mi parte

Respondida el 09/12/2008 a las 23:10
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more