| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 74a1606 commit 906aff2
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -42,13 +42,15 @@ defined: | |||
| 42 | 42 | +-----------+--------------------+-------------------+-----------------------+-------+ | |
| 43 | 43 | | ``'Q'`` | unsigned long long | int | 8 | | | |
| 44 | 44 | +-----------+--------------------+-------------------+-----------------------+-------+ | |
| 45 | + | ``'e'`` | _Float16 | float | 2 | \(3) | | ||
| 46 | + +-----------+--------------------+-------------------+-----------------------+-------+ | ||
| 45 | 47 | | ``'f'`` | float | float | 4 | | | |
| 46 | 48 | +-----------+--------------------+-------------------+-----------------------+-------+ | |
| 47 | 49 | | ``'d'`` | double | float | 8 | | | |
| 48 | 50 | +-----------+--------------------+-------------------+-----------------------+-------+ | |
| 49 | - | ``'F'`` | float complex | complex | 8 | \(3) | | ||
| 51 | + | ``'F'`` | float complex | complex | 8 | \(4) | | ||
| 50 | 52 | +-----------+--------------------+-------------------+-----------------------+-------+ | |
| 51 | - | ``'D'`` | double complex | complex | 16 | \(3) | | ||
| 53 | + | ``'D'`` | double complex | complex | 16 | \(4) | | ||
| 52 | 54 | +-----------+--------------------+-------------------+-----------------------+-------+ | |
| 53 | 55 | ||
| 54 | 56 | ||
@@ -69,6 +71,15 @@ Notes: | |||
| 69 | 71 | .. versionadded:: 3.13 | |
| 70 | 72 | ||
| 71 | 73 | (3) | |
| 74 | + The IEEE 754 binary16 "half precision" type was introduced in the 2008 | ||
| 75 | + revision of the `IEEE 754 standard <ieee 754 standard_>`_. | ||
| 76 | + This type is not widely supported by C compilers. It's available | ||
| 77 | + as :c:expr:`_Float16` type, if the compiler supports the Annex H | ||
| 78 | + of the C23 standard. | ||
| 79 | + | ||
| 80 | + .. versionadded:: next | ||
| 81 | + | ||
| 82 | + (4) | ||
| 72 | 83 | Complex types (``F`` and ``D``) are available unconditionally, | |
| 73 | 84 | regardless on support for complex types (the Annex G of the C11 standard) | |
| 74 | 85 | by the C compiler. | |
@@ -304,3 +315,5 @@ Examples:: | |||
| 304 | 315 | ||
| 305 | 316 | `NumPy <https://numpy.org/>`_ | |
| 306 | 317 | The NumPy package defines another array type. | |
| 318 | + | ||
| 319 | + .. _ieee 754 standard: https://en.wikipedia.org/wiki/IEEE_754-2008_revision | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -642,6 +642,10 @@ array | |||
| 642 | 642 | formatting characters ``'F'`` and ``'D'`` respectively. | |
| 643 | 643 | (Contributed by Sergey B Kirpichev in :gh:`146151`.) | |
| 644 | 644 | ||
| 645 | + * Support half-floats (16-bit IEEE 754 binary interchange format): formatting | ||
| 646 | + character ``'e'``. | ||
| 647 | + (Contributed by Sergey B Kirpichev in :gh:`146238`.) | ||
| 648 | + | ||
| 645 | 649 | ||
| 646 | 650 | base64 | |
| 647 | 651 | ------ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -31,7 +31,7 @@ class ArraySubclassWithKwargs(array.array): | |||
| 31 | 31 | def __init__(self, typecode, newarg=None): | |
| 32 | 32 | array.array.__init__(self) | |
| 33 | 33 | ||
| 34 | - typecodes = 'uwbBhHiIlLfdqQFD' | ||
| 34 | + typecodes = 'uwbBhHiIlLfdqQFDe' | ||
| 35 | 35 | ||
| 36 | 36 | class MiscTest(unittest.TestCase): | |
| 37 | 37 | ||
@@ -117,8 +117,10 @@ def __index__(self): | |||
| 117 | 117 | IEEE_754_FLOAT_COMPLEX_BE = 23 | |
| 118 | 118 | IEEE_754_DOUBLE_COMPLEX_LE = 24 | |
| 119 | 119 | IEEE_754_DOUBLE_COMPLEX_BE = 25 | |
| 120 | + IEEE_754_FLOAT16_LE = 26 | ||
| 121 | + IEEE_754_FLOAT16_BE = 27 | ||
| 120 | 122 | ||
| 121 | - MACHINE_FORMAT_CODE_MAX = 25 | ||
| 123 | + MACHINE_FORMAT_CODE_MAX = 27 | ||
| 122 | 124 | ||
| 123 | 125 | ||
| 124 | 126 | class ArrayReconstructorTest(unittest.TestCase): | |
@@ -1588,6 +1590,13 @@ def test_byteswap(self): | |||
| 1588 | 1590 | self.assertEqual(a, b) | |
| 1589 | 1591 | ||
| 1590 | 1592 | ||
| 1593 | + class HalfFloatTest(FPTest, unittest.TestCase): | ||
| 1594 | + example = [-42.0, 0, 42, 1e2, -1e4] | ||
| 1595 | + smallerexample = [-42.0, 0, 42, 1e2, -2e4] | ||
| 1596 | + biggerexample = [-42.0, 0, 42, 1e2, 1e4] | ||
| 1597 | + typecode = 'e' | ||
| 1598 | + minitemsize = 2 | ||
| 1599 | + | ||
| 1591 | 1600 | class FloatTest(FPTest, unittest.TestCase): | |
| 1592 | 1601 | typecode = 'f' | |
| 1593 | 1602 | minitemsize = 4 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Support half-floats (type code ``'e'`` of the :mod:`struct` module) in the | ||
| 2 | + :mod:`array` module. Patch by Sergey B Kirpichev. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -119,10 +119,12 @@ enum machine_format_code { | |||
| 119 | 119 | IEEE_754_FLOAT_COMPLEX_LE = 22, | |
| 120 | 120 | IEEE_754_FLOAT_COMPLEX_BE = 23, | |
| 121 | 121 | IEEE_754_DOUBLE_COMPLEX_LE = 24, | |
| 122 | - IEEE_754_DOUBLE_COMPLEX_BE = 25 | ||
| 122 | + IEEE_754_DOUBLE_COMPLEX_BE = 25, | ||
| 123 | + IEEE_754_FLOAT16_LE = 26, | ||
| 124 | + IEEE_754_FLOAT16_BE = 27 | ||
| 123 | 125 | }; | |
| 124 | 126 | #define MACHINE_FORMAT_CODE_MIN 0 | |
| 125 | - #define MACHINE_FORMAT_CODE_MAX 25 | ||
| 127 | + #define MACHINE_FORMAT_CODE_MAX 27 | ||
| 126 | 128 | ||
| 127 | 129 | ||
| 128 | 130 | /* | |
@@ -611,6 +613,32 @@ QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) | |||
| 611 | 613 | return 0; | |
| 612 | 614 | } | |
| 613 | 615 | ||
| 616 | + static PyObject * | ||
| 617 | + e_getitem(arrayobject *ap, Py_ssize_t i) | ||
| 618 | + { | ||
| 619 | + double x = PyFloat_Unpack2(ap->ob_item + sizeof(short)*i, | ||
| 620 | + PY_LITTLE_ENDIAN); | ||
| 621 | + | ||
| 622 | + return PyFloat_FromDouble(x); | ||
| 623 | + } | ||
| 624 | + | ||
| 625 | + static int | ||
| 626 | + e_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) | ||
| 627 | + { | ||
| 628 | + float x; | ||
| 629 | + if (!PyArg_Parse(v, "f;array item must be float", &x)) { | ||
| 630 | + return -1; | ||
| 631 | + } | ||
| 632 | + | ||
| 633 | + CHECK_ARRAY_BOUNDS(ap, i); | ||
| 634 | + | ||
| 635 | + if (i >= 0) { | ||
| 636 | + return PyFloat_Pack2(x, ap->ob_item + sizeof(short)*i, | ||
| 637 | + PY_LITTLE_ENDIAN); | ||
| 638 | + } | ||
| 639 | + return 0; | ||
| 640 | + } | ||
| 641 | + | ||
| 614 | 642 | static PyObject * | |
| 615 | 643 | f_getitem(arrayobject *ap, Py_ssize_t i) | |
| 616 | 644 | { | |
@@ -751,6 +779,7 @@ static const struct arraydescr descriptors[] = { | |||
| 751 | 779 | {'L', sizeof(long), LL_getitem, LL_setitem, LL_compareitems, "L", 1, 0}, | |
| 752 | 780 | {'q', sizeof(long long), q_getitem, q_setitem, q_compareitems, "q", 1, 1}, | |
| 753 | 781 | {'Q', sizeof(long long), QQ_getitem, QQ_setitem, QQ_compareitems, "Q", 1, 0}, | |
| 782 | + {'e', sizeof(short), e_getitem, e_setitem, NULL, "e", 0, 0}, | ||
| 754 | 783 | {'f', sizeof(float), f_getitem, f_setitem, NULL, "f", 0, 0}, | |
| 755 | 784 | {'d', sizeof(double), d_getitem, d_setitem, NULL, "d", 0, 0}, | |
| 756 | 785 | {'F', 2*sizeof(float), cf_getitem, cf_setitem, NULL, "F", 0, 0}, | |
@@ -2090,6 +2119,8 @@ static const struct mformatdescr { | |||
| 2090 | 2119 | {8, 0, 1}, /* 23: IEEE_754_FLOAT_COMPLEX_BE */ | |
| 2091 | 2120 | {16, 0, 0}, /* 24: IEEE_754_DOUBLE_COMPLEX_LE */ | |
| 2092 | 2121 | {16, 0, 1}, /* 25: IEEE_754_DOUBLE_COMPLEX_BE */ | |
| 2122 | + {2, 0, 0}, /* 26: IEEE_754_FLOAT16_LE */ | ||
| 2123 | + {2, 0, 1} /* 27: IEEE_754_FLOAT16_BE */ | ||
| 2093 | 2124 | }; | |
| 2094 | 2125 | ||
| 2095 | 2126 | ||
@@ -2124,6 +2155,9 @@ typecode_to_mformat_code(char typecode) | |||
| 2124 | 2155 | case 'w': | |
| 2125 | 2156 | return UTF32_LE + is_big_endian; | |
| 2126 | 2157 | ||
| 2158 | + case 'e': | ||
| 2159 | + return _PY_FLOAT_BIG_ENDIAN ? IEEE_754_FLOAT16_BE : IEEE_754_FLOAT16_LE; | ||
| 2160 | + | ||
| 2127 | 2161 | case 'f': | |
| 2128 | 2162 | return _PY_FLOAT_BIG_ENDIAN ? IEEE_754_FLOAT_BE : IEEE_754_FLOAT_LE; | |
| 2129 | 2163 | ||
@@ -2309,6 +2343,27 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, | |||
| 2309 | 2343 | return NULL; | |
| 2310 | 2344 | } | |
| 2311 | 2345 | switch (mformat_code) { | |
| 2346 | + case IEEE_754_FLOAT16_LE: | ||
| 2347 | + case IEEE_754_FLOAT16_BE: { | ||
| 2348 | + Py_ssize_t i; | ||
| 2349 | + int le = (mformat_code == IEEE_754_FLOAT_LE) ? 1 : 0; | ||
| 2350 | + Py_ssize_t itemcount = Py_SIZE(items) / 2; | ||
| 2351 | + const char *memstr = PyBytes_AS_STRING(items); | ||
| 2352 | + | ||
| 2353 | + converted_items = PyList_New(itemcount); | ||
| 2354 | + if (converted_items == NULL) | ||
| 2355 | + return NULL; | ||
| 2356 | + for (i = 0; i < itemcount; i++) { | ||
| 2357 | + PyObject *pyfloat = PyFloat_FromDouble( | ||
| 2358 | + PyFloat_Unpack2(&memstr[i * 2], le)); | ||
| 2359 | + if (pyfloat == NULL) { | ||
| 2360 | + Py_DECREF(converted_items); | ||
| 2361 | + return NULL; | ||
| 2362 | + } | ||
| 2363 | + PyList_SET_ITEM(converted_items, i, pyfloat); | ||
| 2364 | + } | ||
| 2365 | + break; | ||
| 2366 | + } | ||
| 2312 | 2367 | case IEEE_754_FLOAT_LE: | |
| 2313 | 2368 | case IEEE_754_FLOAT_BE: { | |
| 2314 | 2369 | Py_ssize_t i; | |
@@ -3129,6 +3184,7 @@ The following type codes are defined:\n\ | |||
| 3129 | 3184 | 'L' unsigned integer 4\n\ | |
| 3130 | 3185 | 'q' signed integer 8 (see note)\n\ | |
| 3131 | 3186 | 'Q' unsigned integer 8 (see note)\n\ | |
| 3187 | + 'e' 16-bit IEEE floats 2\n\ | ||
| 3132 | 3188 | 'f' floating-point 4\n\ | |
| 3133 | 3189 | 'd' floating-point 8\n\ | |
| 3134 | 3190 | 'F' float complex 8\n\ | |
| Back | FazBrowse Home | New Git URL |
0 commit comments