@@ -365,7 +365,7 @@ def test_p_code(self):
365365 (got ,) = struct .unpack (code , got )
366366 self .assertEqual (got , expectedback )
367367
368- def test_705836 (self ):
368+ def check_705836 (self , format , reverse_format ):
369369 # SF bug 705836. "<f" and ">f" had a severe rounding bug, where a carry
370370 # from the low-order discarded bits could propagate into the exponent
371371 # field, causing the result to be wrong by a factor of 2.
@@ -376,27 +376,33 @@ def test_705836(self):
376376 delta /= 2.0
377377 smaller = base - delta
378378 # Packing this rounds away a solid string of trailing 1 bits.
379- packed = struct .pack ("<f" , smaller )
380- unpacked = struct .unpack ("<f" , packed )[0 ]
379+ packed = struct .pack (format , smaller )
380+ unpacked = struct .unpack (format , packed )[0 ]
381381 # This failed at base = 2, 4, and 32, with unpacked = 1, 2, and
382382 # 16, respectively.
383383 self .assertEqual (base , unpacked )
384- bigpacked = struct .pack (">f" , smaller )
384+
385+ bigpacked = struct .pack (reverse_format , smaller )
385386 self .assertEqual (bigpacked , string_reverse (packed ))
386- unpacked = struct .unpack (">f" , bigpacked )[0 ]
387+ unpacked = struct .unpack (reverse_format , bigpacked )[0 ]
387388 self .assertEqual (base , unpacked )
388389
389390 # Largest finite IEEE single.
390391 big = (1 << 24 ) - 1
391392 big = math .ldexp (big , 127 - 23 )
392- packed = struct .pack (">f" , big )
393- unpacked = struct .unpack (">f" , packed )[0 ]
393+ packed = struct .pack (format , big )
394+ unpacked = struct .unpack (format , packed )[0 ]
394395 self .assertEqual (big , unpacked )
395396
396397 # The same, but tack on a 1 bit so it rounds up to infinity.
397398 big = (1 << 25 ) - 1
398399 big = math .ldexp (big , 127 - 24 )
399- self .assertRaises (OverflowError , struct .pack , ">f" , big )
400+ self .assertRaises (OverflowError , struct .pack , format , big )
401+
402+ def test_705836 (self ):
403+ self .check_705836 ("<f" , ">f" )
404+ self .check_705836 (">f" , "<f" )
405+ self .check_705836 ("f" , "<f" if sys .byteorder == "big" else ">f" )
400406
401407 def test_1530559 (self ):
402408 for code , byteorder in iter_integer_formats ():
@@ -1201,6 +1207,20 @@ def test_half_float(self):
12011207 for formatcode , bits , f in format_bits_float__doubleRoundingError_list :
12021208 self .assertEqual (bits , struct .pack (formatcode , f ))
12031209
1210+ def test_float_round_trip (self ):
1211+ for format in ("f" , "<f" , ">f" , "d" , "<d" , ">d" ):
1212+ with self .subTest (format = format ):
1213+ f = struct .unpack (format , struct .pack (format , 1.5 ))[0 ]
1214+ self .assertEqual (f , 1.5 )
1215+ f = struct .unpack (format , struct .pack (format , NAN ))[0 ]
1216+ self .assertTrue (math .isnan (f ), f )
1217+ f = struct .unpack (format , struct .pack (format , INF ))[0 ]
1218+ self .assertTrue (math .isinf (f ), f )
1219+ self .assertEqual (math .copysign (1.0 , f ), 1.0 )
1220+ f = struct .unpack (format , struct .pack (format , - INF ))[0 ]
1221+ self .assertTrue (math .isinf (f ), f )
1222+ self .assertEqual (math .copysign (1.0 , f ), - 1.0 )
1223+
12041224
12051225if __name__ == '__main__' :
12061226 unittest .main ()
0 commit comments