2008-12-09 9 views

Répondre

24

La définition de la grammaire de python (à partir de laquelle l'analyseur est généré en utilisant pgen), rechercher les 'puissance': Gramar/Gramar

Le ast python, rechercher les 'ast_for_power': Python/ast.c

La boucle de eval python, chercher 'BINARY_POWER': Python/ceval.c

qui appelle PyNumber_Power (mis en œuvre Objects/abstract.c):

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

Essentiellement, appelez le logement pow. Pour les longs objets (le seul type entier par défaut dans la version 3.0), cela est mis en œuvre dans la fonction long_pow Objects/longobject.c, pour les objets int (dans les branches 2.x), il est mis en œuvre dans la fonction int_pow Object/intobject.c

Si vous creusez dans long_pow, vous pouvez voir que, après vetting les arguments et faire un peu de mettre en place, au cœur de l'exponentiation peut être voir ici:

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

qui utilise des algorithmes décrits dans Chapter 14.6 du Handbook of Applied Cryptography qui décrit des algorithmes d'exponentiation efficaces pour une précision arbitraire arithmétique.

1

Il existe deux implémentations différentes, l'une pour les objets int (long dans 3.0) et l'autre pour les objets flottants. Le flottant pow est la fonction float_pow (PyObject * v, PyObject * w, PyObject * z) définie dans le fichier Objects/floatobject.c du code source Python. Cette fonction appelle pow() de C de math.h de stdlib

L'int Pow a sa propre implémentation, est la fonction int_pow (PyIntObject * v, w * PyIntObject, PyIntObject * z) défini dans les objets/intobject.c (longobject .c pour 3.0) du code source Python.

1

Je pense que les casse-raisins posent des questions sur les astérisques lors de la définition des fonctions.

Vous pouvez trouver réponse à cette page doc Python: http://docs.python.org/tutorial/controlflow.html#more-on-defining-functions

Lorsqu'un paramètre formel final de la forme ** nom est présent, il reçoit un dictionnaire contenant tous les arguments clés à l'exception de ceux correspondant à un paramètre formel.

J'ai semé la description de ce truc ailleurs dans python doc mais je ne m'en souviens pas.

+0

En référence à la fonction appel/définition, ** fait partie de la syntaxe d'appel/définition et non d'un opérateur (http://docs.python.org/3.0/reference/expressions.html#id7, http: // docs.python.org/3.0/reference/compound_stmts.html#function-definitions) –

Questions connexes