Como é ** implementado em Python?

votos
11

Eu estou querendo saber onde eu encontrar a fonte para mostrar como o operador ** é implementado em Python. Alguém pode me apontar na direção certa?

Publicado 09/12/2008 em 23:07
fonte usuário
Em outras línguas...                            


4 respostas

votos
24

A definição python gramática (a partir do qual o analisador é gerada utilizando pgen ), procure 'poder': Gramar / Gramar

O ast python, procure 'ast_for_power': Python / ast.c

O loop python eval, procure 'BINARY_POWER': Python / ceval.c

Que chama PyNumber_Power (implementado em objetos / abstract.c ):

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

Essencialmente, invocar o pow slot. Para objetos longos (o único tipo inteiro padrão no 3.0) Isto é implementado na função long_pow Objetos / longobject.c , por objetos int (nos ramos 2.x) que é implementado na função int_pow Objeto / intobject.c

Se você cavar long_pow, você pode ver que depois de vetar os argumentos e fazer um pouco de configurar, no coração da exponenciação pode ser ver aqui:

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

Que utiliza algoritmos discutidos no Capítulo 14.6 do Handbook of Applied Cryptography que descreve algoritmos de exponenciação eficientes para aritmética de precisão arbitrária.

Respondeu 10/12/2008 em 00:33
fonte usuário

votos
1

Acho caseysrandomthoughts estão perguntando sobre asteriscos em funções definição.

Você poderia encontrar resposta para esta página doc Python: http://docs.python.org/tutorial/controlflow.html#more-on-defining-functions

Quando um parâmetro formal final do formulário ** nome está presente, ele recebe um dicionário contendo todos os argumentos de palavra-chave, exceto para aqueles que corresponde a um parâmetro formal.

Eu tenho descrição porca deste material em outro lugar no doc python, mas não posso de lembrar.

Respondeu 10/12/2008 em 00:47
fonte usuário

votos
1

Existem duas implementações diferentes para um int (longa em 3.0) objectos e uma outra para objectos flutuantes.

O pow flutuador é o float_pow (PyObject * v, PyObject * w, PyObject * z) função definida em arquivo Objectos / floatobject.c do código fonte do Python. Esta função chama pow () de math.h C do stdlib

O pow int tem a sua própria aplicação, é a função int_pow (PyIntObject * v, PyIntObject * w, PyIntObject * z) definida na Objectos / intobject.c (longobject.c para 3,0) do código fonte do Python.

Respondeu 10/12/2008 em 00:32
fonte usuário

votos
1

É o poder de operador

python.org doc - operador de energia

Edit: Ah, Dang, o código, certo. Espero que o link ainda ajuda. Leia Sloppy da minha parte

Respondeu 09/12/2008 em 23:10
fonte usuário

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