2
2
3
3
use crate :: fmt:: { Debug , LowerExp } ;
4
4
use crate :: num:: FpCategory ;
5
- use crate :: ops:: { Add , Div , Mul , Neg } ;
5
+ use crate :: ops:: { self , Add , Div , Mul , Neg } ;
6
6
7
7
use core:: f64;
8
8
9
+ pub trait CastInto < T : Copy > : Copy {
10
+ fn cast ( self ) -> T ;
11
+ }
12
+
13
+ pub trait Integer :
14
+ Sized
15
+ + Clone
16
+ + Copy
17
+ + Debug
18
+ + ops:: Shr < u32 , Output = Self >
19
+ + ops:: Shl < u32 , Output = Self >
20
+ + ops:: BitAnd < Output = Self >
21
+ + ops:: BitOr < Output = Self >
22
+ + PartialEq
23
+ + CastInto < i16 >
24
+ {
25
+ const ZERO : Self ;
26
+ const ONE : Self ;
27
+ }
28
+
29
+ macro_rules! int {
30
+ ( $( $ty: ty) ,+) => {
31
+ $(
32
+ impl CastInto <i16 > for $ty {
33
+ fn cast( self ) -> i16 {
34
+ self as i16
35
+ }
36
+ }
37
+
38
+
39
+ impl Integer for $ty {
40
+ const ZERO : Self = 0 ;
41
+ const ONE : Self = 1 ;
42
+ }
43
+ ) +
44
+ }
45
+ }
46
+
47
+ int ! ( u16 , u32 , u64 ) ;
48
+
9
49
/// A helper trait to avoid duplicating basically all the conversion code for IEEE floats.
10
50
///
11
51
/// See the parent module's doc comment for why this is necessary.
@@ -26,6 +66,9 @@ pub trait RawFloat:
26
66
+ Copy
27
67
+ Debug
28
68
{
69
+ /// The unsigned integer with the same size as the float
70
+ type Int : Integer + Into < u64 > ;
71
+
29
72
/* general constants */
30
73
31
74
const INFINITY : Self ;
@@ -39,6 +82,9 @@ pub trait RawFloat:
39
82
/// Mantissa digits including the hidden bit (provided by core)
40
83
const MANTISSA_BITS : u32 ;
41
84
85
+ const EXPONENT_MASK : Self :: Int ;
86
+ const MANTISSA_MASK : Self :: Int ;
87
+
42
88
/// The number of bits in the significand, *excluding* the hidden bit.
43
89
const MANTISSA_EXPLICIT_BITS : u32 = Self :: MANTISSA_BITS - 1 ;
44
90
@@ -91,13 +137,14 @@ pub trait RawFloat:
91
137
/// This is the max exponent in binary converted to the max exponent in decimal. Allows fast
92
138
/// pathing anything larger than `10^LARGEST_POWER_OF_TEN`, which will round to infinity.
93
139
// const LARGEST_POWER_OF_TEN: i32;
94
- const LARGEST_POWER_OF_TEN : i32 = ( Self :: EXPONENT_BIAS as f64 / f64:: consts:: LOG2_10 ) as i32 ;
140
+ const LARGEST_POWER_OF_TEN : i32 =
141
+ ( ( Self :: EXPONENT_BIAS as f64 + 1.0 ) / f64:: consts:: LOG2_10 ) as i32 ;
95
142
96
143
/// Smallest decimal exponent for a non-zero value. This allows for fast pathing anything
97
- /// smaller than `10^SMALLEST_POWER_OF_TEN`.
98
- const SMALLEST_POWER_OF_TEN : i32 ;
99
- // const SMALLEST_POWER_OF_TEN: i32 =
100
- // -(((Self::EXPONENT_BIAS + Self::MANTISSA_BITS) as f64) / f64::consts::LOG2_10) as i32 - 2 ;
144
+ // / smaller than `10^SMALLEST_POWER_OF_TEN`.
145
+ // const SMALLEST_POWER_OF_TEN: i32;
146
+ const SMALLEST_POWER_OF_TEN : i32 =
147
+ -( ( ( Self :: EXPONENT_BIAS + Self :: MANTISSA_BITS + 64 ) as f64 ) / f64:: consts:: LOG2_10 ) as i32 ;
101
148
102
149
/// Maximum exponent that can be represented for a disguised-fast path case.
103
150
/// This is `MAX_EXPONENT_FAST_PATH + ⌊(MANTISSA_EXPLICIT_BITS+1)/log2(10)⌋`
@@ -122,72 +169,83 @@ pub trait RawFloat:
122
169
/// Returns the category that this number falls into.
123
170
fn classify ( self ) -> FpCategory ;
124
171
172
+ /// Transmute to the integer representation
173
+ fn to_bits ( self ) -> Self :: Int ;
174
+
125
175
/// Returns the mantissa, exponent and sign as integers.
126
- fn integer_decode ( self ) -> ( u64 , i16 , i8 ) ;
176
+ fn integer_decode ( self ) -> ( u64 , i16 , i8 ) {
177
+ let bits = self . to_bits ( ) ;
178
+ let sign: i8 = if bits >> ( Self :: BITS - 1 ) == Self :: Int :: ZERO { 1 } else { -1 } ;
179
+ let mut exponent: i16 =
180
+ ( ( bits & Self :: EXPONENT_MASK ) >> Self :: MANTISSA_EXPLICIT_BITS ) . cast ( ) ;
181
+ let mantissa = if exponent == 0 {
182
+ ( bits & Self :: MANTISSA_MASK ) << 1
183
+ } else {
184
+ ( bits & Self :: MANTISSA_MASK ) | ( Self :: Int :: ONE << Self :: MANTISSA_EXPLICIT_BITS )
185
+ } ;
186
+ // Exponent bias + mantissa shift
187
+ exponent -= ( Self :: EXPONENT_BIAS + Self :: MANTISSA_EXPLICIT_BITS ) as i16 ;
188
+ ( mantissa. into ( ) , exponent, sign)
189
+ }
127
190
}
128
191
129
- // #[cfg(not(bootstrap))]
130
- // impl RawFloat for f16 {
131
- // const INFINITY: Self = Self::INFINITY;
132
- // const NEG_INFINITY: Self = Self::NEG_INFINITY;
133
- // const NAN: Self = Self::NAN;
134
- // const NEG_NAN: Self = -Self::NAN;
135
-
136
- // const BITS: u32 = 16;
137
- // const MANTISSA_DIGITS: u32 = Self::MANTISSA_DIGITS;
138
-
139
- // const MIN_EXPONENT_FAST_PATH: i64 = -4; // assuming FLT_EVAL_METHOD = 0
140
- // const MAX_EXPONENT_FAST_PATH: i64 = 4;
141
-
142
- // const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -17;
143
- // const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 10;
144
- // const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = 17;
145
- // const SMALLEST_POWER_OF_TEN: i32 = -65;
146
- // const LARGEST_POWER_OF_TEN: i32 = Self::MAX_10_EXP;
147
-
148
- // #[inline]
149
- // fn from_u64(v: u64) -> Self {
150
- // debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH);
151
- // v as _
152
- // }
153
-
154
- // #[inline]
155
- // fn from_u64_bits(v: u64) -> Self {
156
- // Self::from_bits((v & 0xFFFF) as u16)
157
- // }
158
-
159
- // fn pow10_fast_path(exponent: usize) -> Self {
160
- // #[allow(clippy::use_self)]
161
- // const TABLE: [f32; 16] =
162
- // [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 0., 0., 0., 0., 0.];
163
- // TABLE[exponent & 15]
164
- // }
165
-
166
- // /// Returns the mantissa, exponent and sign as integers.
167
- // fn integer_decode(self) -> (u64, i16, i8) {
168
- // let bits = self.to_bits();
169
- // let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 };
170
- // let mut exponent: i16 = ((bits >> 23) & 0xff) as i16;
171
- // let mantissa =
172
- // if exponent == 0 { (bits & 0x7fffff) << 1 } else { (bits & 0x7fffff) | 0x800000 };
173
- // // Exponent bias + mantissa shift
174
- // exponent -= 127 + 23;
175
- // (mantissa as u64, exponent, sign)
176
- // }
177
-
178
- // fn classify(self) -> FpCategory {
179
- // self.classify()
180
- // }
181
- // }
192
+ #[ cfg( not( bootstrap) ) ]
193
+ impl RawFloat for f16 {
194
+ type Int = u16 ;
195
+
196
+ const INFINITY : Self = Self :: INFINITY ;
197
+ const NEG_INFINITY : Self = Self :: NEG_INFINITY ;
198
+ const NAN : Self = Self :: NAN ;
199
+ const NEG_NAN : Self = -Self :: NAN ;
200
+
201
+ const BITS : u32 = 16 ;
202
+ const MANTISSA_BITS : u32 = Self :: MANTISSA_DIGITS ;
203
+ const EXPONENT_MASK : Self :: Int = Self :: EXP_MASK ;
204
+ const MANTISSA_MASK : Self :: Int = Self :: MAN_MASK ;
205
+
206
+ const MIN_EXPONENT_ROUND_TO_EVEN : i32 = -17 ;
207
+ const MAX_EXPONENT_ROUND_TO_EVEN : i32 = 10 ;
208
+ // const SMALLEST_POWER_OF_TEN: i32 = -27;
209
+ // const LARGEST_POWER_OF_TEN: i32 = Self::MAX_10_EXP;
210
+
211
+ #[ inline]
212
+ fn from_u64 ( v : u64 ) -> Self {
213
+ debug_assert ! ( v <= Self :: MAX_MANTISSA_FAST_PATH ) ;
214
+ v as _
215
+ }
216
+
217
+ #[ inline]
218
+ fn from_u64_bits ( v : u64 ) -> Self {
219
+ Self :: from_bits ( ( v & 0xFF ) as u16 )
220
+ }
221
+
222
+ fn pow10_fast_path ( exponent : usize ) -> Self {
223
+ #[ allow( clippy:: use_self) ]
224
+ const TABLE : [ f16 ; 8 ] = [ 1e0 , 1e1 , 1e2 , 1e3 , 1e4 , 0.0 , 0.0 , 0. ] ;
225
+ TABLE [ exponent & 15 ]
226
+ }
227
+
228
+ fn to_bits ( self ) -> Self :: Int {
229
+ self . to_bits ( )
230
+ }
231
+
232
+ fn classify ( self ) -> FpCategory {
233
+ todo ! ( )
234
+ }
235
+ }
182
236
183
237
impl RawFloat for f32 {
238
+ type Int = u32 ;
239
+
184
240
const INFINITY : Self = f32:: INFINITY ;
185
241
const NEG_INFINITY : Self = f32:: NEG_INFINITY ;
186
242
const NAN : Self = f32:: NAN ;
187
243
const NEG_NAN : Self = -f32:: NAN ;
188
244
189
245
const BITS : u32 = 32 ;
190
246
const MANTISSA_BITS : u32 = Self :: MANTISSA_DIGITS ;
247
+ const EXPONENT_MASK : Self :: Int = Self :: EXP_MASK ;
248
+ const MANTISSA_MASK : Self :: Int = Self :: MAN_MASK ;
191
249
192
250
// const MANTISSA_EXPLICIT_BITS: u32 = 23;
193
251
const MIN_EXPONENT_ROUND_TO_EVEN : i32 = -17 ;
@@ -198,7 +256,7 @@ impl RawFloat for f32 {
198
256
// const MINIMUM_EXPONENT: i32 = -127;
199
257
// const INFINITE_POWER: i32 = 0xFF;
200
258
// const SIGN_INDEX: u32 = 31;
201
- const SMALLEST_POWER_OF_TEN : i32 = -65 ;
259
+ // const SMALLEST_POWER_OF_TEN: i32 = -65;
202
260
// const LARGEST_POWER_OF_TEN: i32 = 38;
203
261
204
262
#[ inline]
@@ -219,16 +277,8 @@ impl RawFloat for f32 {
219
277
TABLE [ exponent & 15 ]
220
278
}
221
279
222
- /// Returns the mantissa, exponent and sign as integers.
223
- fn integer_decode ( self ) -> ( u64 , i16 , i8 ) {
224
- let bits = self . to_bits ( ) ;
225
- let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 } ;
226
- let mut exponent: i16 = ( ( bits >> 23 ) & 0xff ) as i16 ;
227
- let mantissa =
228
- if exponent == 0 { ( bits & 0x7fffff ) << 1 } else { ( bits & 0x7fffff ) | 0x800000 } ;
229
- // Exponent bias + mantissa shift
230
- exponent -= 127 + 23 ;
231
- ( mantissa as u64 , exponent, sign)
280
+ fn to_bits ( self ) -> Self :: Int {
281
+ self . to_bits ( )
232
282
}
233
283
234
284
fn classify ( self ) -> FpCategory {
@@ -237,13 +287,17 @@ impl RawFloat for f32 {
237
287
}
238
288
239
289
impl RawFloat for f64 {
290
+ type Int = u64 ;
291
+
240
292
const INFINITY : Self = Self :: INFINITY ;
241
293
const NEG_INFINITY : Self = Self :: NEG_INFINITY ;
242
294
const NAN : Self = Self :: NAN ;
243
295
const NEG_NAN : Self = -Self :: NAN ;
244
296
245
297
const BITS : u32 = 64 ;
246
298
const MANTISSA_BITS : u32 = Self :: MANTISSA_DIGITS ;
299
+ const EXPONENT_MASK : Self :: Int = Self :: EXP_MASK ;
300
+ const MANTISSA_MASK : Self :: Int = Self :: MAN_MASK ;
247
301
248
302
// const MANTISSA_EXPLICIT_BITS: u32 = 52;
249
303
const MIN_EXPONENT_ROUND_TO_EVEN : i32 = -4 ;
@@ -254,7 +308,7 @@ impl RawFloat for f64 {
254
308
// const MINIMUM_EXPONENT: i32 = -1023;
255
309
// const INFINITE_POWER: i32 = 0x7FF;
256
310
// const SIGN_INDEX: u32 = 63;
257
- const SMALLEST_POWER_OF_TEN : i32 = -342 ;
311
+ // const SMALLEST_POWER_OF_TEN: i32 = -342;
258
312
// const LARGEST_POWER_OF_TEN: i32 = 308;
259
313
260
314
#[ inline]
@@ -276,19 +330,8 @@ impl RawFloat for f64 {
276
330
TABLE [ exponent & 31 ]
277
331
}
278
332
279
- /// Returns the mantissa, exponent and sign as integers.
280
- fn integer_decode ( self ) -> ( u64 , i16 , i8 ) {
281
- let bits = self . to_bits ( ) ;
282
- let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 } ;
283
- let mut exponent: i16 = ( ( bits >> 52 ) & 0x7ff ) as i16 ;
284
- let mantissa = if exponent == 0 {
285
- ( bits & 0xfffffffffffff ) << 1
286
- } else {
287
- ( bits & 0xfffffffffffff ) | 0x10000000000000
288
- } ;
289
- // Exponent bias + mantissa shift
290
- exponent -= 1023 + 52 ;
291
- ( mantissa, exponent, sign)
333
+ fn to_bits ( self ) -> Self :: Int {
334
+ self . to_bits ( )
292
335
}
293
336
294
337
fn classify ( self ) -> FpCategory {
0 commit comments