@@ -119,10 +119,12 @@ enum machine_format_code {
119119 IEEE_754_FLOAT_COMPLEX_LE = 22 ,
120120 IEEE_754_FLOAT_COMPLEX_BE = 23 ,
121121 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
123125};
124126#define MACHINE_FORMAT_CODE_MIN 0
125- #define MACHINE_FORMAT_CODE_MAX 25
127+ #define MACHINE_FORMAT_CODE_MAX 27
126128
127129
128130/*
@@ -611,6 +613,32 @@ QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
611613 return 0 ;
612614}
613615
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+
614642static PyObject *
615643f_getitem (arrayobject * ap , Py_ssize_t i )
616644{
@@ -751,6 +779,7 @@ static const struct arraydescr descriptors[] = {
751779 {'L' , sizeof (long ), LL_getitem , LL_setitem , LL_compareitems , "L" , 1 , 0 },
752780 {'q' , sizeof (long long ), q_getitem , q_setitem , q_compareitems , "q" , 1 , 1 },
753781 {'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 },
754783 {'f' , sizeof (float ), f_getitem , f_setitem , NULL , "f" , 0 , 0 },
755784 {'d' , sizeof (double ), d_getitem , d_setitem , NULL , "d" , 0 , 0 },
756785 {'F' , 2 * sizeof (float ), cf_getitem , cf_setitem , NULL , "F" , 0 , 0 },
@@ -2090,6 +2119,8 @@ static const struct mformatdescr {
20902119 {8 , 0 , 1 }, /* 23: IEEE_754_FLOAT_COMPLEX_BE */
20912120 {16 , 0 , 0 }, /* 24: IEEE_754_DOUBLE_COMPLEX_LE */
20922121 {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 */
20932124};
20942125
20952126
@@ -2124,6 +2155,9 @@ typecode_to_mformat_code(char typecode)
21242155 case 'w' :
21252156 return UTF32_LE + is_big_endian ;
21262157
2158+ case 'e' :
2159+ return _PY_FLOAT_BIG_ENDIAN ? IEEE_754_FLOAT16_BE : IEEE_754_FLOAT16_LE ;
2160+
21272161 case 'f' :
21282162 return _PY_FLOAT_BIG_ENDIAN ? IEEE_754_FLOAT_BE : IEEE_754_FLOAT_LE ;
21292163
@@ -2309,6 +2343,27 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype,
23092343 return NULL ;
23102344 }
23112345 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+ }
23122367 case IEEE_754_FLOAT_LE :
23132368 case IEEE_754_FLOAT_BE : {
23142369 Py_ssize_t i ;
@@ -3129,6 +3184,7 @@ The following type codes are defined:\n\
31293184 'L' unsigned integer 4\n\
31303185 'q' signed integer 8 (see note)\n\
31313186 'Q' unsigned integer 8 (see note)\n\
3187+ 'e' 16-bit IEEE floats 2\n\
31323188 'f' floating-point 4\n\
31333189 'd' floating-point 8\n\
31343190 'F' float complex 8\n\
0 commit comments