+--------+--------------------------+--------------------+----------------+------------+
| ``d`` | :c:expr:`double` | float | 8 | \(4) |
+--------+--------------------------+--------------------+----------------+------------+
+| ``F`` | :c:expr:`float complex` | complex | 8 | \(10) |
++--------+--------------------------+--------------------+----------------+------------+
+| ``D`` | :c:expr:`double complex` | complex | 16 | \(10) |
++--------+--------------------------+--------------------+----------------+------------+
| ``s`` | :c:expr:`char[]` | bytes | | \(9) |
+--------+--------------------------+--------------------+----------------+------------+
| ``p`` | :c:expr:`char[]` | bytes | | \(8) |
| ``P`` | :c:expr:`void \*` | integer | | \(5) |
+--------+--------------------------+--------------------+----------------+------------+
-Additionally, if IEC 60559 compatible complex arithmetic (Annex G of the
-C11 standard) is supported, the following format characters are available:
-
-+--------+--------------------------+--------------------+----------------+------------+
-| Format | C Type | Python type | Standard size | Notes |
-+========+==========================+====================+================+============+
-| ``F`` | :c:expr:`float complex` | complex | 8 | \(10) |
-+--------+--------------------------+--------------------+----------------+------------+
-| ``D`` | :c:expr:`double complex` | complex | 16 | \(10) |
-+--------+--------------------------+--------------------+----------------+------------+
-
.. versionchanged:: 3.3
Added support for the ``'n'`` and ``'N'`` formats.
For the ``'E'`` and ``'C'`` format characters, the packed representation uses
the IEEE 754 binary32 and binary64 format for components of the complex
number, regardless of the floating-point format used by the platform.
+ Note that complex types (``F`` and ``D``) are available unconditionally,
+ despite complex types being an optional feature in C.
+ As specified in the C11 standard, each complex type is represented by a
+ two-element C array containing, respectively, the real and imaginary parts.
+
A format character may be preceded by an integral repeat count. For example,
the format string ``'4h'`` means exactly the same as ``'hhhh'``.
#include "pycore_long.h" // _PyLong_AsByteArray()
#include "pycore_moduleobject.h" // _PyModule_GetState()
-#ifdef Py_HAVE_C_COMPLEX
-# include "_complex.h" // complex
-#endif
#include <stddef.h> // offsetof()
/*[clinic input]
return PyFloat_FromDouble(x);
}
-#ifdef Py_HAVE_C_COMPLEX
static PyObject *
nu_float_complex(_structmodulestate *state, const char *p, const formatdef *f)
{
- float complex x;
+ float x[2];
memcpy(&x, p, sizeof(x));
- return PyComplex_FromDoubles(creal(x), cimag(x));
+ return PyComplex_FromDoubles(x[0], x[1]);
}
static PyObject *
nu_double_complex(_structmodulestate *state, const char *p, const formatdef *f)
{
- double complex x;
+ double x[2];
memcpy(&x, p, sizeof(x));
- return PyComplex_FromDoubles(creal(x), cimag(x));
+ return PyComplex_FromDoubles(x[0], x[1]);
}
-#endif
static PyObject *
nu_void_p(_structmodulestate *state, const char *p, const formatdef *f)
return 0;
}
-#ifdef Py_HAVE_C_COMPLEX
static int
np_float_complex(_structmodulestate *state, char *p, PyObject *v,
const formatdef *f)
{
Py_complex c = PyComplex_AsCComplex(v);
- float complex x = CMPLXF((float)c.real, (float)c.imag);
+ float x[2] = {(float)c.real, (float)c.imag};
if (c.real == -1 && PyErr_Occurred()) {
PyErr_SetString(state->StructError,
const formatdef *f)
{
Py_complex c = PyComplex_AsCComplex(v);
- double complex x = CMPLX(c.real, c.imag);
+ double x[2] = {c.real, c.imag};
if (c.real == -1 && PyErr_Occurred()) {
PyErr_SetString(state->StructError,
memcpy(p, &x, sizeof(x));
return 0;
}
-#else
-static int
-np_complex_stub(_structmodulestate *state, char *p, PyObject *v,
- const formatdef *f)
-{
- PyErr_Format(state->StructError,
- "'%c' format not supported on this system",
- f->format);
- return -1;
-}
-static PyObject *
-nu_complex_stub(_structmodulestate *state, const char *p, const formatdef *f)
-{
- PyErr_Format(state->StructError,
- "'%c' format not supported on this system",
- f->format);
- return NULL;
-}
-#endif
static int
np_void_p(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{'e', sizeof(short), _Alignof(short), nu_halffloat, np_halffloat},
{'f', sizeof(float), _Alignof(float), nu_float, np_float},
{'d', sizeof(double), _Alignof(double), nu_double, np_double},
-#ifdef Py_HAVE_C_COMPLEX
- {'F', sizeof(float complex), _Alignof(float complex), nu_float_complex, np_float_complex},
- {'D', sizeof(double complex), _Alignof(double complex), nu_double_complex, np_double_complex},
-#else
- {'F', 1, 0, nu_complex_stub, np_complex_stub},
- {'D', 1, 0, nu_complex_stub, np_complex_stub},
-#endif
+ {'F', 2*sizeof(float), _Alignof(float[2]), nu_float_complex, np_float_complex},
+ {'D', 2*sizeof(double), _Alignof(double[2]), nu_double_complex, np_double_complex},
{'P', sizeof(void *), _Alignof(void *), nu_void_p, np_void_p},
{0}
};
return unpack_double(p, 0);
}
-#ifdef Py_HAVE_C_COMPLEX
static PyObject *
bu_float_complex(_structmodulestate *state, const char *p, const formatdef *f)
{
}
return PyComplex_FromDoubles(x, y);
}
-#endif
static PyObject *
bu_bool(_structmodulestate *state, const char *p, const formatdef *f)
return PyFloat_Pack8(x, p, 0);
}
-#ifdef Py_HAVE_C_COMPLEX
static int
bp_float_complex(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
}
return PyFloat_Pack8(x.imag, p + 8, 0);
}
-#endif
static int
bp_bool(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{'e', 2, 0, bu_halffloat, bp_halffloat},
{'f', 4, 0, bu_float, bp_float},
{'d', 8, 0, bu_double, bp_double},
-#ifdef Py_HAVE_C_COMPLEX
{'F', 8, 0, bu_float_complex, bp_float_complex},
{'D', 16, 0, bu_double_complex, bp_double_complex},
-#else
- {'F', 1, 0, nu_complex_stub, np_complex_stub},
- {'D', 1, 0, nu_complex_stub, np_complex_stub},
-#endif
{0}
};
return unpack_double(p, 1);
}
-#ifdef Py_HAVE_C_COMPLEX
static PyObject *
lu_float_complex(_structmodulestate *state, const char *p, const formatdef *f)
{
}
return PyComplex_FromDoubles(x, y);
}
-#endif
static int
lp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
return PyFloat_Pack8(x, p, 1);
}
-#ifdef Py_HAVE_C_COMPLEX
static int
lp_float_complex(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
}
return PyFloat_Pack8(x.imag, p + 8, 1);
}
-#endif
static formatdef lilendian_table[] = {
{'x', 1, 0, NULL},
{'e', 2, 0, lu_halffloat, lp_halffloat},
{'f', 4, 0, lu_float, lp_float},
{'d', 8, 0, lu_double, lp_double},
-#ifdef Py_HAVE_C_COMPLEX
{'F', 8, 0, lu_float_complex, lp_float_complex},
{'D', 16, 0, lu_double_complex, lp_double_complex},
-#else
- {'F', 1, 0, nu_complex_stub, np_complex_stub},
- {'D', 1, 0, nu_complex_stub, np_complex_stub},
-#endif
{0}
};