@@ -1894,6 +1894,47 @@ _PyFloat_DebugMallocStats(FILE *out)
18941894int
18951895PyFloat_Pack2 (double x , char * data , int le )
18961896{
1897+ #if HAVE_FLOAT16
1898+ unsigned char * p = (unsigned char * )data ;
1899+ _Float16 y = (_Float16 )x ;
1900+ int i , incr = 1 ;
1901+
1902+ if (isinf (y ) && !isinf (x )) {
1903+ PyErr_SetString (PyExc_OverflowError ,
1904+ "float too large to pack with e format" );
1905+ return -1 ;
1906+ }
1907+
1908+ /* correct y if x was a sNaN, transformed to qNaN by conversion */
1909+ if (isnan (x )) {
1910+ uint64_t v ;
1911+
1912+ memcpy (& v , & x , 8 );
1913+ if ((v & (1ULL << 51 )) == 0 ) {
1914+ uint16_t u16 ;
1915+ memcpy (& u16 , & y , 2 );
1916+ /* if have payload, make sNaN */
1917+ if (u16 & 0x1ff ) {
1918+ u16 &= ~(1 << 9 );
1919+ }
1920+ memcpy (& y , & u16 , 2 );
1921+ }
1922+ }
1923+
1924+ unsigned char s [sizeof (_Float16 )];
1925+ memcpy (s , & y , sizeof (_Float16 ));
1926+
1927+ if ((_PY_FLOAT_LITTLE_ENDIAN && !le ) || (_PY_FLOAT_BIG_ENDIAN && le )) {
1928+ p += 1 ;
1929+ incr = -1 ;
1930+ }
1931+
1932+ for (i = 0 ; i < 2 ; i ++ ) {
1933+ * p = s [i ];
1934+ p += incr ;
1935+ }
1936+ return 0 ;
1937+ #else
18971938 unsigned char * p = (unsigned char * )data ;
18981939 unsigned char sign ;
18991940 int e ;
@@ -1997,6 +2038,7 @@ PyFloat_Pack2(double x, char *data, int le)
19972038 PyErr_SetString (PyExc_OverflowError ,
19982039 "float too large to pack with e format" );
19992040 return -1 ;
2041+ #endif /* HAVE_FLOAT16 */
20002042}
20012043
20022044int
@@ -2089,6 +2131,42 @@ PyFloat_Pack8(double x, char *data, int le)
20892131double
20902132PyFloat_Unpack2 (const char * data , int le )
20912133{
2134+ #if HAVE_FLOAT16
2135+ unsigned char * p = (unsigned char * )data ;
2136+ _Float16 x ;
2137+
2138+ if ((_PY_FLOAT_LITTLE_ENDIAN && !le ) || (_PY_FLOAT_BIG_ENDIAN && le )) {
2139+ char buf [2 ];
2140+ char * d = & buf [1 ];
2141+ int i ;
2142+
2143+ for (i = 0 ; i < 2 ; i ++ ) {
2144+ * d -- = * p ++ ;
2145+ }
2146+ memcpy (& x , buf , 2 );
2147+ }
2148+ else {
2149+ memcpy (& x , p , 2 );
2150+ }
2151+
2152+ /* return sNaN double if x was sNaN float */
2153+ if (isnan (x )) {
2154+ uint16_t v ;
2155+
2156+ memcpy (& v , & x , 2 );
2157+ if ((v & (1 << 9 )) == 0 ) {
2158+ double y = x ; /* will make qNaN double */
2159+ uint64_t u64 ;
2160+
2161+ memcpy (& u64 , & y , 8 );
2162+ u64 &= ~(1ULL << 51 ); /* make sNaN */
2163+ memcpy (& y , & u64 , 8 );
2164+ return y ;
2165+ }
2166+ }
2167+
2168+ return x ;
2169+ #else
20922170 unsigned char * p = (unsigned char * )data ;
20932171 unsigned char sign ;
20942172 int e ;
@@ -2140,6 +2218,7 @@ PyFloat_Unpack2(const char *data, int le)
21402218 x = - x ;
21412219
21422220 return x ;
2221+ #endif /* HAVE_FLOAT16 */
21432222}
21442223
21452224double
0 commit comments