@@ -30,6 +30,10 @@ trait TestableFloat: Sized {
3030 const EPS_ADD : Self ;
3131 const EPS_MUL : Self ;
3232 const EPS_DIV : Self ;
33+ const RAW_1 : Self :: Int ;
34+ const RAW_12_DOT_5 : Self :: Int ;
35+ const RAW_1337 : Self :: Int ;
36+ const RAW_MINUS_14_DOT_25 : Self :: Int ;
3337}
3438
3539impl TestableFloat for f16 {
@@ -50,6 +54,10 @@ impl TestableFloat for f16 {
5054 const EPS_ADD : Self = if cfg ! ( miri) { 1e1 } else { 0.0 } ;
5155 const EPS_MUL : Self = if cfg ! ( miri) { 1e3 } else { 0.0 } ;
5256 const EPS_DIV : Self = if cfg ! ( miri) { 1e0 } else { 0.0 } ;
57+ const RAW_1 : Self :: Int = 0x3c00 ;
58+ const RAW_12_DOT_5 : Self :: Int = 0x4a40 ;
59+ const RAW_1337 : Self :: Int = 0x6539 ;
60+ const RAW_MINUS_14_DOT_25 : Self :: Int = 0xcb20 ;
5361}
5462
5563impl TestableFloat for f32 {
@@ -72,6 +80,10 @@ impl TestableFloat for f32 {
7280 const EPS_ADD : Self = if cfg ! ( miri) { 1e-3 } else { 0.0 } ;
7381 const EPS_MUL : Self = if cfg ! ( miri) { 1e-1 } else { 0.0 } ;
7482 const EPS_DIV : Self = if cfg ! ( miri) { 1e-4 } else { 0.0 } ;
83+ const RAW_1 : Self :: Int = 0x3f800000 ;
84+ const RAW_12_DOT_5 : Self :: Int = 0x41480000 ;
85+ const RAW_1337 : Self :: Int = 0x44a72000 ;
86+ const RAW_MINUS_14_DOT_25 : Self :: Int = 0xc1640000 ;
7587}
7688
7789impl TestableFloat for f64 {
@@ -90,6 +102,10 @@ impl TestableFloat for f64 {
90102 const EPS_ADD : Self = if cfg ! ( miri) { 1e-6 } else { 0.0 } ;
91103 const EPS_MUL : Self = if cfg ! ( miri) { 1e-6 } else { 0.0 } ;
92104 const EPS_DIV : Self = if cfg ! ( miri) { 1e-6 } else { 0.0 } ;
105+ const RAW_1 : Self :: Int = 0x3ff0000000000000 ;
106+ const RAW_12_DOT_5 : Self :: Int = 0x4029000000000000 ;
107+ const RAW_1337 : Self :: Int = 0x4094e40000000000 ;
108+ const RAW_MINUS_14_DOT_25 : Self :: Int = 0xc02c800000000000 ;
93109}
94110
95111impl TestableFloat for f128 {
@@ -108,6 +124,10 @@ impl TestableFloat for f128 {
108124 const EPS_ADD : Self = if cfg ! ( miri) { 1e-6 } else { 0.0 } ;
109125 const EPS_MUL : Self = if cfg ! ( miri) { 1e-6 } else { 0.0 } ;
110126 const EPS_DIV : Self = if cfg ! ( miri) { 1e-6 } else { 0.0 } ;
127+ const RAW_1 : Self :: Int = 0x3fff0000000000000000000000000000 ;
128+ const RAW_12_DOT_5 : Self :: Int = 0x40029000000000000000000000000000 ;
129+ const RAW_1337 : Self :: Int = 0x40094e40000000000000000000000000 ;
130+ const RAW_MINUS_14_DOT_25 : Self :: Int = 0xc002c800000000000000000000000000 ;
111131}
112132
113133/// Determine the tolerance for values of the argument type.
@@ -1479,3 +1499,31 @@ float_test! {
14791499 assert_approx_eq!( a. algebraic_rem( b) , a % b, Float :: EPS_DIV ) ;
14801500 }
14811501}
1502+
1503+ float_test ! {
1504+ name: to_bits_conv,
1505+ attrs: {
1506+ const : #[ cfg( false ) ] ,
1507+ f16: #[ cfg( target_has_reliable_f16) ] ,
1508+ f128: #[ cfg( target_has_reliable_f128) ] ,
1509+ } ,
1510+ test<Float > {
1511+ assert_eq!( ( 1 as Float ) . to_bits( ) , Float :: RAW_1 ) ;
1512+ assert_eq!( ( 12.5 as Float ) . to_bits( ) , Float :: RAW_12_DOT_5 ) ;
1513+ assert_eq!( ( 1337 as Float ) . to_bits( ) , Float :: RAW_1337 ) ;
1514+ assert_eq!( ( -14.25 as Float ) . to_bits( ) , Float :: RAW_MINUS_14_DOT_25 ) ;
1515+ assert_biteq!( Float :: from_bits( Float :: RAW_1 ) , 1.0 ) ;
1516+ assert_biteq!( Float :: from_bits( Float :: RAW_12_DOT_5 ) , 12.5 ) ;
1517+ assert_biteq!( Float :: from_bits( Float :: RAW_1337 ) , 1337.0 ) ;
1518+ assert_biteq!( Float :: from_bits( Float :: RAW_MINUS_14_DOT_25 ) , -14.25 ) ;
1519+
1520+ // Check that NaNs roundtrip their bits regardless of signaling-ness
1521+ let masked_nan1 = Float :: NAN . to_bits( ) ^ Float :: NAN_MASK1 ;
1522+ let masked_nan2 = Float :: NAN . to_bits( ) ^ Float :: NAN_MASK2 ;
1523+ assert!( Float :: from_bits( masked_nan1) . is_nan( ) ) ;
1524+ assert!( Float :: from_bits( masked_nan2) . is_nan( ) ) ;
1525+
1526+ assert_eq!( Float :: from_bits( masked_nan1) . to_bits( ) , masked_nan1) ;
1527+ assert_eq!( Float :: from_bits( masked_nan2) . to_bits( ) , masked_nan2) ;
1528+ }
1529+ }
0 commit comments