11#![ feature( stmt_expr_attributes) ]
22#![ feature( float_gamma) ]
33#![ feature( core_intrinsics) ]
4+ #![ feature( f128) ]
5+ #![ feature( f16) ]
46#![ allow( arithmetic_overflow) ]
57
68use std:: fmt:: Debug ;
@@ -41,103 +43,23 @@ trait FloatToInt<Int>: Copy {
4143 unsafe fn cast_unchecked ( self ) -> Int ;
4244}
4345
44- impl FloatToInt < i8 > for f32 {
45- fn cast ( self ) -> i8 {
46- self as _
47- }
48- unsafe fn cast_unchecked ( self ) -> i8 {
49- self . to_int_unchecked ( )
50- }
51- }
52- impl FloatToInt < i32 > for f32 {
53- fn cast ( self ) -> i32 {
54- self as _
55- }
56- unsafe fn cast_unchecked ( self ) -> i32 {
57- self . to_int_unchecked ( )
58- }
59- }
60- impl FloatToInt < u32 > for f32 {
61- fn cast ( self ) -> u32 {
62- self as _
63- }
64- unsafe fn cast_unchecked ( self ) -> u32 {
65- self . to_int_unchecked ( )
66- }
67- }
68- impl FloatToInt < i64 > for f32 {
69- fn cast ( self ) -> i64 {
70- self as _
71- }
72- unsafe fn cast_unchecked ( self ) -> i64 {
73- self . to_int_unchecked ( )
74- }
75- }
76- impl FloatToInt < u64 > for f32 {
77- fn cast ( self ) -> u64 {
78- self as _
79- }
80- unsafe fn cast_unchecked ( self ) -> u64 {
81- self . to_int_unchecked ( )
82- }
46+ macro_rules! float_to_int {
47+ ( $fty: ty => $( $ity: ty) ,+ $( , ) ?) => {
48+ $(
49+ impl FloatToInt <$ity> for $fty {
50+ fn cast( self ) -> $ity {
51+ self as _
52+ }
53+ unsafe fn cast_unchecked( self ) -> $ity {
54+ self . to_int_unchecked( )
55+ }
56+ }
57+ ) *
58+ } ;
8359}
8460
85- impl FloatToInt < i8 > for f64 {
86- fn cast ( self ) -> i8 {
87- self as _
88- }
89- unsafe fn cast_unchecked ( self ) -> i8 {
90- self . to_int_unchecked ( )
91- }
92- }
93- impl FloatToInt < i32 > for f64 {
94- fn cast ( self ) -> i32 {
95- self as _
96- }
97- unsafe fn cast_unchecked ( self ) -> i32 {
98- self . to_int_unchecked ( )
99- }
100- }
101- impl FloatToInt < u32 > for f64 {
102- fn cast ( self ) -> u32 {
103- self as _
104- }
105- unsafe fn cast_unchecked ( self ) -> u32 {
106- self . to_int_unchecked ( )
107- }
108- }
109- impl FloatToInt < i64 > for f64 {
110- fn cast ( self ) -> i64 {
111- self as _
112- }
113- unsafe fn cast_unchecked ( self ) -> i64 {
114- self . to_int_unchecked ( )
115- }
116- }
117- impl FloatToInt < u64 > for f64 {
118- fn cast ( self ) -> u64 {
119- self as _
120- }
121- unsafe fn cast_unchecked ( self ) -> u64 {
122- self . to_int_unchecked ( )
123- }
124- }
125- impl FloatToInt < i128 > for f64 {
126- fn cast ( self ) -> i128 {
127- self as _
128- }
129- unsafe fn cast_unchecked ( self ) -> i128 {
130- self . to_int_unchecked ( )
131- }
132- }
133- impl FloatToInt < u128 > for f64 {
134- fn cast ( self ) -> u128 {
135- self as _
136- }
137- unsafe fn cast_unchecked ( self ) -> u128 {
138- self . to_int_unchecked ( )
139- }
140- }
61+ float_to_int ! ( f32 => i8 , u8 , i16 , u16 , i32 , u32 , i64 , u64 , i128 , u128 ) ;
62+ float_to_int ! ( f64 => i8 , u8 , i16 , u16 , i32 , u32 , i64 , u64 , i128 , u128 ) ;
14163
14264/// Test this cast both via `as` and via `approx_unchecked` (i.e., it must not saturate).
14365#[ track_caller]
@@ -153,18 +75,29 @@ where
15375
15476fn basic ( ) {
15577 // basic arithmetic
78+ assert_eq ( 6.0_f16 * 6.0_f16 , 36.0_f16 ) ;
15679 assert_eq ( 6.0_f32 * 6.0_f32 , 36.0_f32 ) ;
15780 assert_eq ( 6.0_f64 * 6.0_f64 , 36.0_f64 ) ;
81+ assert_eq ( 6.0_f128 * 6.0_f128 , 36.0_f128 ) ;
82+ assert_eq ( -{ 5.0_f16 } , -5.0_f16 ) ;
15883 assert_eq ( -{ 5.0_f32 } , -5.0_f32 ) ;
15984 assert_eq ( -{ 5.0_f64 } , -5.0_f64 ) ;
85+ assert_eq ( -{ 5.0_f128 } , -5.0_f128 ) ;
86+
16087 // infinities, NaN
88+ // FIXME(f16_f128): add when constants and `is_infinite` are available
16189 assert ! ( ( 5.0_f32 / 0.0 ) . is_infinite( ) ) ;
16290 assert_ne ! ( { 5.0_f32 / 0.0 } , { -5.0_f32 / 0.0 } ) ;
16391 assert ! ( ( 5.0_f64 / 0.0 ) . is_infinite( ) ) ;
16492 assert_ne ! ( { 5.0_f64 / 0.0 } , { 5.0_f64 / -0.0 } ) ;
16593 assert_ne ! ( f32 :: NAN , f32 :: NAN ) ;
16694 assert_ne ! ( f64 :: NAN , f64 :: NAN ) ;
95+
16796 // negative zero
97+ let posz = 0.0f16 ;
98+ let negz = -0.0f16 ;
99+ assert_eq ( posz, negz) ;
100+ assert_ne ! ( posz. to_bits( ) , negz. to_bits( ) ) ;
168101 let posz = 0.0f32 ;
169102 let negz = -0.0f32 ;
170103 assert_eq ( posz, negz) ;
@@ -173,15 +106,30 @@ fn basic() {
173106 let negz = -0.0f64 ;
174107 assert_eq ( posz, negz) ;
175108 assert_ne ! ( posz. to_bits( ) , negz. to_bits( ) ) ;
109+ let posz = 0.0f128 ;
110+ let negz = -0.0f128 ;
111+ assert_eq ( posz, negz) ;
112+ assert_ne ! ( posz. to_bits( ) , negz. to_bits( ) ) ;
113+
176114 // byte-level transmute
177- let x: u64 = unsafe { std:: mem:: transmute ( 42.0_f64 ) } ;
178- let y: f64 = unsafe { std:: mem:: transmute ( x) } ;
179- assert_eq ( y, 42.0_f64 ) ;
115+ let x: u16 = unsafe { std:: mem:: transmute ( 42.0_f16 ) } ;
116+ let y: f16 = unsafe { std:: mem:: transmute ( x) } ;
117+ assert_eq ( y, 42.0_f16 ) ;
180118 let x: u32 = unsafe { std:: mem:: transmute ( 42.0_f32 ) } ;
181119 let y: f32 = unsafe { std:: mem:: transmute ( x) } ;
182120 assert_eq ( y, 42.0_f32 ) ;
121+ let x: u64 = unsafe { std:: mem:: transmute ( 42.0_f64 ) } ;
122+ let y: f64 = unsafe { std:: mem:: transmute ( x) } ;
123+ assert_eq ( y, 42.0_f64 ) ;
124+ let x: u128 = unsafe { std:: mem:: transmute ( 42.0_f128 ) } ;
125+ let y: f128 = unsafe { std:: mem:: transmute ( x) } ;
126+ assert_eq ( y, 42.0_f128 ) ;
183127
184128 // `%` sign behavior, some of this used to be buggy
129+ assert ! ( ( black_box( 1.0f16 ) % 1.0 ) . is_sign_positive( ) ) ;
130+ assert ! ( ( black_box( 1.0f16 ) % -1.0 ) . is_sign_positive( ) ) ;
131+ assert ! ( ( black_box( -1.0f16 ) % 1.0 ) . is_sign_negative( ) ) ;
132+ assert ! ( ( black_box( -1.0f16 ) % -1.0 ) . is_sign_negative( ) ) ;
185133 assert ! ( ( black_box( 1.0f32 ) % 1.0 ) . is_sign_positive( ) ) ;
186134 assert ! ( ( black_box( 1.0f32 ) % -1.0 ) . is_sign_positive( ) ) ;
187135 assert ! ( ( black_box( -1.0f32 ) % 1.0 ) . is_sign_negative( ) ) ;
@@ -190,7 +138,12 @@ fn basic() {
190138 assert ! ( ( black_box( 1.0f64 ) % -1.0 ) . is_sign_positive( ) ) ;
191139 assert ! ( ( black_box( -1.0f64 ) % 1.0 ) . is_sign_negative( ) ) ;
192140 assert ! ( ( black_box( -1.0f64 ) % -1.0 ) . is_sign_negative( ) ) ;
141+ assert ! ( ( black_box( 1.0f128 ) % 1.0 ) . is_sign_positive( ) ) ;
142+ assert ! ( ( black_box( 1.0f128 ) % -1.0 ) . is_sign_positive( ) ) ;
143+ assert ! ( ( black_box( -1.0f128 ) % 1.0 ) . is_sign_negative( ) ) ;
144+ assert ! ( ( black_box( -1.0f128 ) % -1.0 ) . is_sign_negative( ) ) ;
193145
146+ // FIXME(f16_f128): add when `abs` is available
194147 assert_eq ! ( ( -1.0f32 ) . abs( ) , 1.0f32 ) ;
195148 assert_eq ! ( 34.2f64 . abs( ) , 34.2f64 ) ;
196149}
0 commit comments