@@ -38,6 +38,7 @@ pub trait Float:
38
38
const MAX : Self ;
39
39
const MIN : Self ;
40
40
const PI : Self ;
41
+ const NEG_PI : Self ;
41
42
const FRAC_PI_2 : Self ;
42
43
43
44
/// The bitwidth of the float type
@@ -71,7 +72,9 @@ pub trait Float:
71
72
fn to_bits ( self ) -> Self :: Int ;
72
73
73
74
/// Returns `self` transmuted to `Self::SignedInt`
74
- fn to_bits_signed ( self ) -> Self :: SignedInt ;
75
+ fn to_bits_signed ( self ) -> Self :: SignedInt {
76
+ self . to_bits ( ) . signed ( )
77
+ }
75
78
76
79
/// Checks if two floats have the same bit representation. *Except* for NaNs! NaN can be
77
80
/// represented in multiple different ways. This method returns `true` if two NaNs are
@@ -158,7 +161,15 @@ pub trait Float:
158
161
pub type IntTy < F > = <F as Float >:: Int ;
159
162
160
163
macro_rules! float_impl {
161
- ( $ty: ident, $ity: ident, $sity: ident, $expty: ident, $bits: expr, $significand_bits: expr) => {
164
+ (
165
+ $ty: ident,
166
+ $ity: ident,
167
+ $sity: ident,
168
+ $expty: ident,
169
+ $bits: expr,
170
+ $significand_bits: expr,
171
+ $from_bits: path
172
+ ) => {
162
173
impl Float for $ty {
163
174
type Int = $ity;
164
175
type SignedInt = $sity;
@@ -173,13 +184,10 @@ macro_rules! float_impl {
173
184
const NAN : Self = Self :: NAN ;
174
185
const MAX : Self = -Self :: MIN ;
175
186
// Sign bit set, saturated mantissa, saturated exponent with last bit zeroed
176
- // FIXME(msrv): just use `from_bits` when available
177
- // SAFETY: POD cast with no preconditions
178
- const MIN : Self = unsafe {
179
- mem:: transmute:: <Self :: Int , Self >( Self :: Int :: MAX & !( 1 << Self :: SIG_BITS ) )
180
- } ;
187
+ const MIN : Self = $from_bits( Self :: Int :: MAX & !( 1 << Self :: SIG_BITS ) ) ;
181
188
182
189
const PI : Self = core:: $ty:: consts:: PI ;
190
+ const NEG_PI : Self = -Self :: PI ;
183
191
const FRAC_PI_2 : Self = core:: $ty:: consts:: FRAC_PI_2 ;
184
192
185
193
const BITS : u32 = $bits;
@@ -193,9 +201,6 @@ macro_rules! float_impl {
193
201
fn to_bits( self ) -> Self :: Int {
194
202
self . to_bits( )
195
203
}
196
- fn to_bits_signed( self ) -> Self :: SignedInt {
197
- self . to_bits( ) as Self :: SignedInt
198
- }
199
204
fn is_nan( self ) -> bool {
200
205
self . is_nan( )
201
206
}
@@ -220,8 +225,22 @@ macro_rules! float_impl {
220
225
}
221
226
222
227
#[ cfg( f16_enabled) ]
223
- float_impl ! ( f16, u16 , i16 , i8 , 16 , 10 ) ;
224
- float_impl ! ( f32 , u32 , i32 , i16 , 32 , 23 ) ;
225
- float_impl ! ( f64 , u64 , i64 , i16 , 64 , 52 ) ;
228
+ float_impl ! ( f16, u16 , i16 , i8 , 16 , 10 , f16 :: from_bits ) ;
229
+ float_impl ! ( f32 , u32 , i32 , i16 , 32 , 23 , f32_from_bits ) ;
230
+ float_impl ! ( f64 , u64 , i64 , i16 , 64 , 52 , f64_from_bits ) ;
226
231
#[ cfg( f128_enabled) ]
227
- float_impl ! ( f128, u128 , i128 , i16 , 128 , 112 ) ;
232
+ float_impl ! ( f128, u128 , i128 , i16 , 128 , 112 , f128:: from_bits) ;
233
+
234
+ /* FIXME(msrv): vendor some things that are not const stable at our MSRV */
235
+
236
+ /// `f32::from_bits`
237
+ pub const fn f32_from_bits ( bits : u32 ) -> f32 {
238
+ // SAFETY: POD cast with no preconditions
239
+ unsafe { mem:: transmute :: < u32 , f32 > ( bits) }
240
+ }
241
+
242
+ /// `f64::from_bits`
243
+ pub const fn f64_from_bits ( bits : u64 ) -> f64 {
244
+ // SAFETY: POD cast with no preconditions
245
+ unsafe { mem:: transmute :: < u64 , f64 > ( bits) }
246
+ }
0 commit comments