2008-12-09 34 views

Respuesta

24

La definición pitón gramática (de la que se genera el analizador utilizando pgen), busque 'poder': Gramar/Gramar

El ast pitón, buscar 'ast_for_power': Python/ast.c

La pitón bucle eval, buscar '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 predeterminado en 3.0) esto se implementa en la función long_pow Objects/longobject.c, de objetos int (en las ramas 2.x) se implementa en la función int_pow Object/intobject.c

Si se mira en long_pow, se puede ver que después de vetar los argumentos y haciendo un poco de configurar, el corazón de la exponenciación puede ser 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) 
     } 
    } 
} 

Qué utiliza algoritmos discutidos en Chapter 14.6 del Handbook of Applied Cryptography que describe los algoritmos de exponenciación eficientes para la precisión arbitraria aritmética.

1

Existen 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, es la función int_pow (PyIntObject * v, PyIntObject * w, PyIntObject * z) definida en Objects/intobject.c (longobject .c para 3.0) del código fuente de Python.

1

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

se puede encontrar respuesta a esta página doc Python: http://docs.python.org/tutorial/controlflow.html#more-on-defining-functions

Cuando un parámetro formal definitiva de la forma ** nombre está presente, se recibe un diccionario que contiene todos los argumentos con excepción de las correspondientes a un parámetro formal.

He sembrado la descripción de estas cosas en otro lugar en el documento de Python, pero no puedo recordar.

+0

Cuando se hace referencia a la llamada/definición de función, ** es parte de la sintaxis de llamada/definición y no de un operador (http://docs.python.org/3.0/reference/expressions.html#id7, http: // docs.python.org/3.0/reference/compound_stmts.html#function-definitions) –

Cuestiones relacionadas