@@ -122,10 +122,12 @@ enum machine_format_code {
122122 IEEE_754_FLOAT_COMPLEX_LE = 22 ,
123123 IEEE_754_FLOAT_COMPLEX_BE = 23 ,
124124 IEEE_754_DOUBLE_COMPLEX_LE = 24 ,
125- IEEE_754_DOUBLE_COMPLEX_BE = 25
125+ IEEE_754_DOUBLE_COMPLEX_BE = 25 ,
126+ IEEE_754_FLOAT16_LE = 26 ,
127+ IEEE_754_FLOAT16_BE = 27
126128};
127129#define MACHINE_FORMAT_CODE_MIN 0
128- #define MACHINE_FORMAT_CODE_MAX 25
130+ #define MACHINE_FORMAT_CODE_MAX 27
129131
130132
131133/*
@@ -614,6 +616,32 @@ QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
614616 return 0 ;
615617}
616618
619+ static PyObject *
620+ e_getitem (arrayobject * ap , Py_ssize_t i )
621+ {
622+ double x = PyFloat_Unpack2 (ap -> ob_item + sizeof (short )* i ,
623+ PY_LITTLE_ENDIAN );
624+
625+ return PyFloat_FromDouble (x );
626+ }
627+
628+ static int
629+ e_setitem (arrayobject * ap , Py_ssize_t i , PyObject * v )
630+ {
631+ float x ;
632+ if (!PyArg_Parse (v , "f;array item must be float" , & x )) {
633+ return -1 ;
634+ }
635+
636+ CHECK_ARRAY_BOUNDS (ap , i );
637+
638+ if (i >= 0 ) {
639+ return PyFloat_Pack2 (x , ap -> ob_item + sizeof (short )* i ,
640+ PY_LITTLE_ENDIAN );
641+ }
642+ return 0 ;
643+ }
644+
617645static PyObject *
618646f_getitem (arrayobject * ap , Py_ssize_t i )
619647{
@@ -754,6 +782,7 @@ static const struct arraydescr descriptors[] = {
754782 {'L' , sizeof (long ), LL_getitem , LL_setitem , LL_compareitems , "L" , 1 , 0 },
755783 {'q' , sizeof (long long ), q_getitem , q_setitem , q_compareitems , "q" , 1 , 1 },
756784 {'Q' , sizeof (long long ), QQ_getitem , QQ_setitem , QQ_compareitems , "Q" , 1 , 0 },
785+ {'e' , sizeof (short ), e_getitem , e_setitem , NULL , "e" , 0 , 0 },
757786 {'f' , sizeof (float ), f_getitem , f_setitem , NULL , "f" , 0 , 0 },
758787 {'d' , sizeof (double ), d_getitem , d_setitem , NULL , "d" , 0 , 0 },
759788 {'F' , 2 * sizeof (float ), cf_getitem , cf_setitem , NULL , "F" , 0 , 0 },
@@ -2093,6 +2122,8 @@ static const struct mformatdescr {
20932122 {8 , 0 , 1 }, /* 23: IEEE_754_FLOAT_COMPLEX_BE */
20942123 {16 , 0 , 0 }, /* 24: IEEE_754_DOUBLE_COMPLEX_LE */
20952124 {16 , 0 , 1 }, /* 25: IEEE_754_DOUBLE_COMPLEX_BE */
2125+ {2 , 0 , 0 }, /* 26: IEEE_754_FLOAT16_LE */
2126+ {2 , 0 , 1 } /* 27: IEEE_754_FLOAT16_BE */
20962127};
20972128
20982129
@@ -2127,6 +2158,9 @@ typecode_to_mformat_code(char typecode)
21272158 case 'w' :
21282159 return UTF32_LE + is_big_endian ;
21292160
2161+ case 'e' :
2162+ return _PY_FLOAT_BIG_ENDIAN ? IEEE_754_FLOAT16_BE : IEEE_754_FLOAT16_LE ;
2163+
21302164 case 'f' :
21312165 if (sizeof (float ) == 4 ) {
21322166 const float y = 16711938.0 ;
@@ -2326,6 +2360,27 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype,
23262360 return NULL ;
23272361 }
23282362 switch (mformat_code ) {
2363+ case IEEE_754_FLOAT16_LE :
2364+ case IEEE_754_FLOAT16_BE : {
2365+ Py_ssize_t i ;
2366+ int le = (mformat_code == IEEE_754_FLOAT_LE ) ? 1 : 0 ;
2367+ Py_ssize_t itemcount = Py_SIZE (items ) / 2 ;
2368+ const char * memstr = PyBytes_AS_STRING (items );
2369+
2370+ converted_items = PyList_New (itemcount );
2371+ if (converted_items == NULL )
2372+ return NULL ;
2373+ for (i = 0 ; i < itemcount ; i ++ ) {
2374+ PyObject * pyfloat = PyFloat_FromDouble (
2375+ PyFloat_Unpack2 (& memstr [i * 2 ], le ));
2376+ if (pyfloat == NULL ) {
2377+ Py_DECREF (converted_items );
2378+ return NULL ;
2379+ }
2380+ PyList_SET_ITEM (converted_items , i , pyfloat );
2381+ }
2382+ break ;
2383+ }
23292384 case IEEE_754_FLOAT_LE :
23302385 case IEEE_754_FLOAT_BE : {
23312386 Py_ssize_t i ;
@@ -3146,6 +3201,7 @@ The following type codes are defined:\n\
31463201 'L' unsigned integer 4\n\
31473202 'q' signed integer 8 (see note)\n\
31483203 'Q' unsigned integer 8 (see note)\n\
3204+ 'e' 16-bit IEEE floats 2\n\
31493205 'f' floating-point 4\n\
31503206 'd' floating-point 8\n\
31513207 'F' float complex 8\n\
0 commit comments