1
- use core:: { fmt, mem, ops} ;
1
+ use core:: ops:: { self , Neg } ;
2
+ use core:: { fmt, mem} ;
2
3
3
4
use super :: int_traits:: { Int , MinInt } ;
4
5
@@ -23,10 +24,9 @@ pub trait Float:
23
24
type Int : Int < OtherSign = Self :: SignedInt , Unsigned = Self :: Int > ;
24
25
25
26
/// A int of the same width as the float
26
- type SignedInt : Int + MinInt < OtherSign = Self :: Int , Unsigned = Self :: Int > ;
27
-
28
- /// An int capable of containing the exponent bits plus a sign bit. This is signed.
29
- type ExpInt : Int ;
27
+ type SignedInt : Int
28
+ + MinInt < OtherSign = Self :: Int , Unsigned = Self :: Int >
29
+ + Neg < Output = Self :: SignedInt > ;
30
30
31
31
const ZERO : Self ;
32
32
const NEG_ZERO : Self ;
@@ -98,7 +98,7 @@ pub trait Float:
98
98
}
99
99
100
100
/// Returns the exponent, not adjusting for bias.
101
- fn exp ( self ) -> Self :: ExpInt ;
101
+ fn exp ( self ) -> i32 ;
102
102
103
103
/// Returns the significand with no implicit bit (or the "fractional" part)
104
104
fn frac ( self ) -> Self :: Int {
@@ -138,23 +138,20 @@ pub trait Float:
138
138
}
139
139
140
140
/// Access the associated `Int` type from a float (helper to avoid ambiguous associated types).
141
- #[ allow( dead_code) ]
142
141
pub type IntTy < F > = <F as Float >:: Int ;
143
142
144
143
macro_rules! float_impl {
145
144
(
146
145
$ty: ident,
147
146
$ity: ident,
148
147
$sity: ident,
149
- $expty: ident,
150
148
$bits: expr,
151
149
$significand_bits: expr,
152
150
$from_bits: path
153
151
) => {
154
152
impl Float for $ty {
155
153
type Int = $ity;
156
154
type SignedInt = $sity;
157
- type ExpInt = $expty;
158
155
159
156
const ZERO : Self = 0.0 ;
160
157
const NEG_ZERO : Self = -0.0 ;
@@ -191,8 +188,8 @@ macro_rules! float_impl {
191
188
fn is_sign_negative( self ) -> bool {
192
189
self . is_sign_negative( )
193
190
}
194
- fn exp( self ) -> Self :: ExpInt {
195
- ( ( self . to_bits( ) & Self :: EXP_MASK ) >> Self :: SIG_BITS ) as Self :: ExpInt
191
+ fn exp( self ) -> i32 {
192
+ ( ( self . to_bits( ) & Self :: EXP_MASK ) >> Self :: SIG_BITS ) as i32
196
193
}
197
194
fn from_bits( a: Self :: Int ) -> Self {
198
195
Self :: from_bits( a)
@@ -226,11 +223,11 @@ macro_rules! float_impl {
226
223
}
227
224
228
225
#[ cfg( f16_enabled) ]
229
- float_impl ! ( f16, u16 , i16 , i8 , 16 , 10 , f16:: from_bits) ;
230
- float_impl ! ( f32 , u32 , i32 , i16 , 32 , 23 , f32_from_bits) ;
231
- float_impl ! ( f64 , u64 , i64 , i16 , 64 , 52 , f64_from_bits) ;
226
+ float_impl ! ( f16, u16 , i16 , 16 , 10 , f16:: from_bits) ;
227
+ float_impl ! ( f32 , u32 , i32 , 32 , 23 , f32_from_bits) ;
228
+ float_impl ! ( f64 , u64 , i64 , 64 , 52 , f64_from_bits) ;
232
229
#[ cfg( f128_enabled) ]
233
- float_impl ! ( f128, u128 , i128 , i16 , 128 , 112 , f128:: from_bits) ;
230
+ float_impl ! ( f128, u128 , i128 , 128 , 112 , f128:: from_bits) ;
234
231
235
232
/* FIXME(msrv): vendor some things that are not const stable at our MSRV */
236
233
@@ -245,3 +242,63 @@ pub const fn f64_from_bits(bits: u64) -> f64 {
245
242
// SAFETY: POD cast with no preconditions
246
243
unsafe { mem:: transmute :: < u64 , f64 > ( bits) }
247
244
}
245
+
246
+ /// Trait for floats twice the bit width of another integer.
247
+ #[ allow( unused) ]
248
+ pub trait DFloat : Float {
249
+ /// Float that is half the bit width of the floatthis trait is implemented for.
250
+ type H : HFloat < D = Self > ;
251
+
252
+ /// Narrow the float type.
253
+ fn narrow ( self ) -> Self :: H ;
254
+ }
255
+
256
+ /// Trait for floats half the bit width of another float.
257
+ #[ allow( unused) ]
258
+ pub trait HFloat : Float {
259
+ /// Float that is double the bit width of the float this trait is implemented for.
260
+ type D : DFloat < H = Self > ;
261
+
262
+ /// Widen the float type.
263
+ fn widen ( self ) -> Self :: D ;
264
+ }
265
+
266
+ macro_rules! impl_d_float {
267
+ ( $( $X: ident $D: ident) ,* ) => {
268
+ $(
269
+ impl DFloat for $D {
270
+ type H = $X;
271
+
272
+ fn narrow( self ) -> Self :: H {
273
+ self as $X
274
+ }
275
+ }
276
+ ) *
277
+ } ;
278
+ }
279
+
280
+ macro_rules! impl_h_float {
281
+ ( $( $H: ident $X: ident) ,* ) => {
282
+ $(
283
+ impl HFloat for $H {
284
+ type D = $X;
285
+
286
+ fn widen( self ) -> Self :: D {
287
+ self as $X
288
+ }
289
+ }
290
+ ) *
291
+ } ;
292
+ }
293
+
294
+ impl_d_float ! ( f32 f64 ) ;
295
+ #[ cfg( f16_enabled) ]
296
+ impl_d_float ! ( f16 f32 ) ;
297
+ #[ cfg( f128_enabled) ]
298
+ impl_d_float ! ( f64 f128) ;
299
+
300
+ impl_h_float ! ( f32 f64 ) ;
301
+ #[ cfg( f16_enabled) ]
302
+ impl_h_float ! ( f16 f32 ) ;
303
+ #[ cfg( f128_enabled) ]
304
+ impl_h_float ! ( f64 f128) ;
0 commit comments