La définition de la structure de données du type nombre à virgule flottante dans la machine virtuelle cpython est la suivante :
typedef struct { PyObject_HEAD double ob_fval; } PyFloatObject;
La définition de la structure de données ci-dessus est la suivante :
Les données ci-dessus structure Le champ le plus important d'entre eux est ob_fval, c'est là que les nombres à virgule flottante sont réellement stockés.
ob_refcnt est le nombre de références de l'objet.
ob_type est le type d'objet.
Semblable aux tuples et aux objets de liste dont nous avons parlé plus tôt, lorsque le type float est implémenté en interne dans cpython, une couche intermédiaire sera également créée pour l'objet float. Accélérez l'allocation de mémoire des nombres à virgule flottante. Le code spécifique pertinent est le suivant :
#define PyFloat_MAXFREELIST 100 static int numfree = 0; static PyFloatObject *free_list = NULL;
Faire long à l'intérieur de cpython mettra en cache l'espace mémoire de 100 objets flottants, s'il dépasse 100, la mémoire sera libérée directement. Ce qu'il faut noter ici, c'est que seuls tous les objets float peuvent être mis en cache à l'aide d'un pointeur. Comment cela est-il réalisé ?
Ceci est implémenté à l'aide du champ struct _typeobject *ob_type; dans l'objet PyFloatObject. Utilisez ce champ pour pointer vers l'espace mémoire du prochain objet float. Étant donné que les données de free_list ne sont pas utilisées, vous pouvez utiliser cette fonctionnalité pour en enregistrer. espace mémoire. Voici le processus spécifique de création d'un objet float :
PyObject * PyFloat_FromDouble(double fval) { // 首先查看 free_list 当中是否有空闲的 float 对象 PyFloatObject *op = free_list; if (op != NULL) { // 如果有 那么就将让 free_list 指向 free_list 当中的下一个 float 对象 并且将对应的个数减 1 free_list = (PyFloatObject *) Py_TYPE(op); numfree--; } else { // 否则的话就需要申请内存空间 op = (PyFloatObject*) PyObject_MALLOC(sizeof(PyFloatObject)); if (!op) return PyErr_NoMemory(); } /* Inline PyObject_New */ (void)PyObject_INIT(op, &PyFloat_Type); // PyObject_INIT 这个宏的主要作用是将对象的引用计数设置成 1 op->ob_fval = fval; return (PyObject *) op; }
Ce qui suit est l'implémentation spécifique de l'ajout de nombres à virgule flottante dans cpython. L'ensemble du processus est relativement simple, il suffit d'obtenir la nouvelle valeur, d'en créer une nouvelle. PyFloatObject et ajoutez ce retour d'objet.
static PyObject * float_add(PyObject *v, PyObject *w) { double a,b; CONVERT_TO_DOUBLE(v, a); // CONVERT_TO_DOUBLE 这个宏的主要作用就是将对象的 ob_fval 这个字段的值保存到 a 当中 CONVERT_TO_DOUBLE(w, b); // 这个就是将 w 当中的 ob_fval 字段的值保存到 b 当中 a = a + b; return PyFloat_FromDouble(a); // 创建一个新的 float 对象 并且将这个对象返回 }
Il en va de même pour la soustraction.
static PyObject * float_sub(PyObject *v, PyObject *w) { double a,b; CONVERT_TO_DOUBLE(v, a); CONVERT_TO_DOUBLE(w, b); a = a - b; return PyFloat_FromDouble(a); }
static PyObject * float_mul(PyObject *v, PyObject *w) { double a,b; CONVERT_TO_DOUBLE(v, a); CONVERT_TO_DOUBLE(w, b); PyFPE_START_PROTECT("multiply", return 0) a = a * b; PyFPE_END_PROTECT(a) return PyFloat_FromDouble(a); }
static PyObject * float_div(PyObject *v, PyObject *w) { double a,b; CONVERT_TO_DOUBLE(v, a); CONVERT_TO_DOUBLE(w, b); if (b == 0.0) { PyErr_SetString(PyExc_ZeroDivisionError, "float division by zero"); return NULL; } a = a / b; return PyFloat_FromDouble(a); }
Une ligne d'instructions de sortie est ajoutée ici, c'est pour notre commodité lors des tests ultérieurs.
static PyObject * float_neg(PyFloatObject *v) { printf("%.2lf 正在进行取反运算\n", v->ob_fval); return PyFloat_FromDouble(-v->ob_fval); }
static PyObject * float_abs(PyFloatObject *v) { printf("%.2lf 正在进行取 abs 运算\n", v->ob_fval); return PyFloat_FromDouble(fabs(v->ob_fval)); }
static int float_bool(PyFloatObject *v) { printf("%.2lf 正在进行取 bool 运算\n", v->ob_fval); return v->ob_fval != 0.0; }
L'image ci-dessous est notre modification du programme cpython !
Ce qui suit est le résultat lorsque nous exploitons à nouveau les nombres à virgule flottante après la modification. Ce que vous pouvez voir, c'est que les instructions que nous avons ajoutées au code ci-dessus sont affichées.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!