Takrifan struktur data jenis nombor titik terapung dalam mesin maya cpython adalah seperti berikut:
typedef struct { PyObject_HEAD double ob_fval; } PyFloatObject;
Di Atas Gambar rajah definisi struktur data adalah seperti berikut:
Medan paling penting dalam struktur data di atas ialah ob_fval, yang sebenarnya menyimpan nombor titik terapung tempat.
ob_refcnt ialah kiraan rujukan objek.
ob_type ialah jenis objek.
Sama seperti tuple dan senaraikan objek yang kita bincangkan sebelum ini, di dalam cpython Apabila melaksanakan float taip, lapisan tengah juga akan ditambahkan pada objek apungan untuk mempercepatkan peruntukan memori nombor titik terapung Kod khusus yang berkaitan adalah seperti berikut:
#define PyFloat_MAXFREELIST 100 static int numfree = 0; static PyFloatObject *free_list = NULL;
Melakukan gandaan di dalam cpython akan cache 100 apungan. ruang ingatan objek melebihi 100, memori akan dikeluarkan secara langsung Apa yang perlu diperhatikan di sini ialah semua objek terapung boleh dicache dengan hanya satu penunjuk.
Ini dilaksanakan menggunakan medan struct _typeobject *ob_type dalam objek PyFloatObject Gunakan medan ini untuk menunjuk ke ruang memori objek apungan seterusnya Ciri Menjimatkan sedikit ruang memori. Berikut ialah proses khusus untuk mencipta objek terapung:
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; }
Berikut ialah pelaksanaan khusus penambahan nombor titik terapung dalam cpython Keseluruhan proses ini agak mudah , hanya dapatkan nilai baharu dan buat objek PyFloatObject baharu dan kembalikan objek ini.
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 对象 并且将这个对象返回 }
Begitu juga dengan penolakan.
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); }
Barisan pernyataan output ditambahkan di sini nanti.
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; }
Gambar di bawah ialah pengubahsuaian program cpython kami!
Berikut ialah output apabila kami mengendalikan nombor titik terapung semula selepas pengubahsuaian Apa yang anda boleh lihat ialah pernyataan yang kami tambah dalam kod di atas adalah output.
Atas ialah kandungan terperinci Apakah prinsip pelaksanaan nombor titik terapung dalam mesin maya Python?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!