@@ -56,24 +56,12 @@ impl Unpacked {
56
56
///
57
57
/// Should **never ever** be implemented for other types or be used outside the dec2flt module.
58
58
/// Inherits from `Float` because there is some overlap, but all the reused methods are trivial.
59
- /// The "methods" (pseudo-constants) with default implementation should not be overriden.
60
59
pub trait RawFloat : Float + Copy + Debug + LowerExp
61
60
+ Mul < Output =Self > + Div < Output =Self > + Neg < Output =Self >
62
61
{
63
- // suffix of "2" because Float::infinity is deprecated
64
- #[ allow( deprecated) ]
65
- fn infinity2 ( ) -> Self {
66
- Float :: infinity ( )
67
- }
68
-
69
- // suffix of "2" because Float::nan is deprecated
70
- #[ allow( deprecated) ]
71
- fn nan2 ( ) -> Self {
72
- Float :: nan ( )
73
- }
74
-
75
- // suffix of "2" because Float::zero is deprecated
76
- fn zero2 ( ) -> Self ;
62
+ const INFINITY : Self ;
63
+ const NAN : Self ;
64
+ const ZERO : Self ;
77
65
78
66
// suffix of "2" because Float::integer_decode is deprecated
79
67
#[ allow( deprecated) ]
@@ -94,94 +82,83 @@ pub trait RawFloat : Float + Copy + Debug + LowerExp
94
82
/// represented, the other code in this module makes sure to never let that happen.
95
83
fn from_int ( x : u64 ) -> Self ;
96
84
97
- /// Get the value 10<sup>e</sup> from a pre-computed table. Panics for e >=
98
- /// ceil_log5_of_max_sig() .
85
+ /// Get the value 10<sup>e</sup> from a pre-computed table.
86
+ /// Panics for `e >= CEIL_LOG5_OF_MAX_SIG` .
99
87
fn short_fast_pow10 ( e : usize ) -> Self ;
100
88
101
- // FIXME Everything that follows should be associated constants, but taking the value of an
102
- // associated constant from a type parameter does not work (yet?)
103
- // A possible workaround is having a `FloatInfo` struct for all the constants, but so far
104
- // the methods aren't painful enough to rewrite.
105
-
106
89
/// What the name says. It's easier to hard code than juggling intrinsics and
107
90
/// hoping LLVM constant folds it.
108
- fn ceil_log5_of_max_sig ( ) -> i16 ;
91
+ const CEIL_LOG5_OF_MAX_SIG : i16 ;
109
92
110
93
// A conservative bound on the decimal digits of inputs that can't produce overflow or zero or
111
94
/// subnormals. Probably the decimal exponent of the maximum normal value, hence the name.
112
- fn max_normal_digits ( ) -> usize ;
95
+ const MAX_NORMAL_DIGITS : usize ;
113
96
114
97
/// When the most significant decimal digit has a place value greater than this, the number
115
98
/// is certainly rounded to infinity.
116
- fn inf_cutoff ( ) -> i64 ;
99
+ const INF_CUTOFF : i64 ;
117
100
118
101
/// When the most significant decimal digit has a place value less than this, the number
119
102
/// is certainly rounded to zero.
120
- fn zero_cutoff ( ) -> i64 ;
103
+ const ZERO_CUTOFF : i64 ;
121
104
122
105
/// The number of bits in the exponent.
123
- fn exp_bits ( ) -> u8 ;
106
+ const EXP_BITS : u8 ;
124
107
125
108
/// The number of bits in the singificand, *including* the hidden bit.
126
- fn sig_bits ( ) -> u8 ;
109
+ const SIG_BITS : u8 ;
127
110
128
111
/// The number of bits in the singificand, *excluding* the hidden bit.
129
- fn explicit_sig_bits ( ) -> u8 {
130
- Self :: sig_bits ( ) - 1
131
- }
112
+ const EXPLICIT_SIG_BITS : u8 ;
132
113
133
114
/// The maximum legal exponent in fractional representation.
134
- fn max_exp ( ) -> i16 {
135
- ( 1 << ( Self :: exp_bits ( ) - 1 ) ) - 1
136
- }
115
+ const MAX_EXP : i16 ;
137
116
138
117
/// The minimum legal exponent in fractional representation, excluding subnormals.
139
- fn min_exp ( ) -> i16 {
140
- -Self :: max_exp ( ) + 1
141
- }
118
+ const MIN_EXP : i16 ;
142
119
143
120
/// `MAX_EXP` for integral representation, i.e., with the shift applied.
144
- fn max_exp_int ( ) -> i16 {
145
- Self :: max_exp ( ) - ( Self :: sig_bits ( ) as i16 - 1 )
146
- }
121
+ const MAX_EXP_INT : i16 ;
147
122
148
123
/// `MAX_EXP` encoded (i.e., with offset bias)
149
- fn max_encoded_exp ( ) -> i16 {
150
- ( 1 << Self :: exp_bits ( ) ) - 1
151
- }
124
+ const MAX_ENCODED_EXP : i16 ;
152
125
153
126
/// `MIN_EXP` for integral representation, i.e., with the shift applied.
154
- fn min_exp_int ( ) -> i16 {
155
- Self :: min_exp ( ) - ( Self :: sig_bits ( ) as i16 - 1 )
156
- }
127
+ const MIN_EXP_INT : i16 ;
157
128
158
129
/// The maximum normalized singificand in integral representation.
159
- fn max_sig ( ) -> u64 {
160
- ( 1 << Self :: sig_bits ( ) ) - 1
161
- }
130
+ const MAX_SIG : u64 ;
162
131
163
132
/// The minimal normalized significand in integral representation.
164
- fn min_sig ( ) -> u64 {
165
- 1 << ( Self :: sig_bits ( ) - 1 )
166
- }
133
+ const MIN_SIG : u64 ;
167
134
}
168
135
169
- impl RawFloat for f32 {
170
- fn zero2 ( ) -> Self {
171
- 0.0
172
- }
173
-
174
- fn sig_bits ( ) -> u8 {
175
- 24
176
- }
177
-
178
- fn exp_bits ( ) -> u8 {
179
- 8
136
+ // Mostly a workaround for #34344.
137
+ macro_rules! other_constants {
138
+ ( $type: ident) => {
139
+ const EXPLICIT_SIG_BITS : u8 = Self :: SIG_BITS - 1 ;
140
+ const MAX_EXP : i16 = ( 1 << ( Self :: EXP_BITS - 1 ) ) - 1 ;
141
+ const MIN_EXP : i16 = -Self :: MAX_EXP + 1 ;
142
+ const MAX_EXP_INT : i16 = Self :: MAX_EXP - ( Self :: SIG_BITS as i16 - 1 ) ;
143
+ const MAX_ENCODED_EXP : i16 = ( 1 << Self :: EXP_BITS ) - 1 ;
144
+ const MIN_EXP_INT : i16 = Self :: MIN_EXP - ( Self :: SIG_BITS as i16 - 1 ) ;
145
+ const MAX_SIG : u64 = ( 1 << Self :: SIG_BITS ) - 1 ;
146
+ const MIN_SIG : u64 = 1 << ( Self :: SIG_BITS - 1 ) ;
147
+
148
+ const INFINITY : Self = $crate:: $type:: INFINITY ;
149
+ const NAN : Self = $crate:: $type:: NAN ;
150
+ const ZERO : Self = 0.0 ;
180
151
}
152
+ }
181
153
182
- fn ceil_log5_of_max_sig ( ) -> i16 {
183
- 11
184
- }
154
+ impl RawFloat for f32 {
155
+ const SIG_BITS : u8 = 24 ;
156
+ const EXP_BITS : u8 = 8 ;
157
+ const CEIL_LOG5_OF_MAX_SIG : i16 = 11 ;
158
+ const MAX_NORMAL_DIGITS : usize = 35 ;
159
+ const INF_CUTOFF : i64 = 40 ;
160
+ const ZERO_CUTOFF : i64 = -48 ;
161
+ other_constants ! ( f32 ) ;
185
162
186
163
fn transmute ( self ) -> u64 {
187
164
let bits: u32 = unsafe { transmute ( self ) } ;
@@ -207,37 +184,17 @@ impl RawFloat for f32 {
207
184
fn short_fast_pow10 ( e : usize ) -> Self {
208
185
table:: F32_SHORT_POWERS [ e]
209
186
}
210
-
211
- fn max_normal_digits ( ) -> usize {
212
- 35
213
- }
214
-
215
- fn inf_cutoff ( ) -> i64 {
216
- 40
217
- }
218
-
219
- fn zero_cutoff ( ) -> i64 {
220
- -48
221
- }
222
187
}
223
188
224
189
225
190
impl RawFloat for f64 {
226
- fn zero2 ( ) -> Self {
227
- 0.0
228
- }
229
-
230
- fn sig_bits ( ) -> u8 {
231
- 53
232
- }
233
-
234
- fn exp_bits ( ) -> u8 {
235
- 11
236
- }
237
-
238
- fn ceil_log5_of_max_sig ( ) -> i16 {
239
- 23
240
- }
191
+ const SIG_BITS : u8 = 53 ;
192
+ const EXP_BITS : u8 = 11 ;
193
+ const CEIL_LOG5_OF_MAX_SIG : i16 = 23 ;
194
+ const MAX_NORMAL_DIGITS : usize = 305 ;
195
+ const INF_CUTOFF : i64 = 310 ;
196
+ const ZERO_CUTOFF : i64 = -326 ;
197
+ other_constants ! ( f64 ) ;
241
198
242
199
fn transmute ( self ) -> u64 {
243
200
let bits: u64 = unsafe { transmute ( self ) } ;
@@ -262,38 +219,27 @@ impl RawFloat for f64 {
262
219
fn short_fast_pow10 ( e : usize ) -> Self {
263
220
table:: F64_SHORT_POWERS [ e]
264
221
}
265
-
266
- fn max_normal_digits ( ) -> usize {
267
- 305
268
- }
269
-
270
- fn inf_cutoff ( ) -> i64 {
271
- 310
272
- }
273
-
274
- fn zero_cutoff ( ) -> i64 {
275
- -326
276
- }
277
-
278
222
}
279
223
280
- /// Convert an Fp to the closest f64. Only handles number that fit into a normalized f64.
224
+ /// Convert an Fp to the closest machine float type.
225
+ /// Does not handle subnormal results.
281
226
pub fn fp_to_float < T : RawFloat > ( x : Fp ) -> T {
282
227
let x = x. normalize ( ) ;
283
228
// x.f is 64 bit, so x.e has a mantissa shift of 63
284
229
let e = x. e + 63 ;
285
- if e > T :: max_exp ( ) {
230
+ if e > T :: MAX_EXP {
286
231
panic ! ( "fp_to_float: exponent {} too large" , e)
287
- } else if e > T :: min_exp ( ) {
232
+ } else if e > T :: MIN_EXP {
288
233
encode_normal ( round_normal :: < T > ( x) )
289
234
} else {
290
235
panic ! ( "fp_to_float: exponent {} too small" , e)
291
236
}
292
237
}
293
238
294
- /// Round the 64-bit significand to 53 bit with half-to-even. Does not handle exponent overflow.
239
+ /// Round the 64-bit significand to T::SIG_BITS bits with half-to-even.
240
+ /// Does not handle exponent overflow.
295
241
pub fn round_normal < T : RawFloat > ( x : Fp ) -> Unpacked {
296
- let excess = 64 - T :: sig_bits ( ) as i16 ;
242
+ let excess = 64 - T :: SIG_BITS as i16 ;
297
243
let half: u64 = 1 << ( excess - 1 ) ;
298
244
let ( q, rem) = ( x. f >> excess, x. f & ( ( 1 << excess) - 1 ) ) ;
299
245
assert_eq ! ( q << excess | rem, x. f) ;
@@ -303,8 +249,8 @@ pub fn round_normal<T: RawFloat>(x: Fp) -> Unpacked {
303
249
Unpacked :: new ( q, k)
304
250
} else if rem == half && ( q % 2 ) == 0 {
305
251
Unpacked :: new ( q, k)
306
- } else if q == T :: max_sig ( ) {
307
- Unpacked :: new ( T :: min_sig ( ) , k + 1 )
252
+ } else if q == T :: MAX_SIG {
253
+ Unpacked :: new ( T :: MIN_SIG , k + 1 )
308
254
} else {
309
255
Unpacked :: new ( q + 1 , k)
310
256
}
@@ -313,22 +259,22 @@ pub fn round_normal<T: RawFloat>(x: Fp) -> Unpacked {
313
259
/// Inverse of `RawFloat::unpack()` for normalized numbers.
314
260
/// Panics if the significand or exponent are not valid for normalized numbers.
315
261
pub fn encode_normal < T : RawFloat > ( x : Unpacked ) -> T {
316
- debug_assert ! ( T :: min_sig ( ) <= x. sig && x. sig <= T :: max_sig ( ) ,
262
+ debug_assert ! ( T :: MIN_SIG <= x. sig && x. sig <= T :: MAX_SIG ,
317
263
"encode_normal: significand not normalized" ) ;
318
264
// Remove the hidden bit
319
- let sig_enc = x. sig & !( 1 << T :: explicit_sig_bits ( ) ) ;
265
+ let sig_enc = x. sig & !( 1 << T :: EXPLICIT_SIG_BITS ) ;
320
266
// Adjust the exponent for exponent bias and mantissa shift
321
- let k_enc = x. k + T :: max_exp ( ) + T :: explicit_sig_bits ( ) as i16 ;
322
- debug_assert ! ( k_enc != 0 && k_enc < T :: max_encoded_exp ( ) ,
267
+ let k_enc = x. k + T :: MAX_EXP + T :: EXPLICIT_SIG_BITS as i16 ;
268
+ debug_assert ! ( k_enc != 0 && k_enc < T :: MAX_ENCODED_EXP ,
323
269
"encode_normal: exponent out of range" ) ;
324
270
// Leave sign bit at 0 ("+"), our numbers are all positive
325
- let bits = ( k_enc as u64 ) << T :: explicit_sig_bits ( ) | sig_enc;
271
+ let bits = ( k_enc as u64 ) << T :: EXPLICIT_SIG_BITS | sig_enc;
326
272
T :: from_bits ( bits)
327
273
}
328
274
329
- /// Construct the subnormal. A mantissa of 0 is allowed and constructs zero.
275
+ /// Construct a subnormal. A mantissa of 0 is allowed and constructs zero.
330
276
pub fn encode_subnormal < T : RawFloat > ( significand : u64 ) -> T {
331
- assert ! ( significand < T :: min_sig ( ) , "encode_subnormal: not actually subnormal" ) ;
277
+ assert ! ( significand < T :: MIN_SIG , "encode_subnormal: not actually subnormal" ) ;
332
278
// Encoded exponent is 0, the sign bit is 0, so we just have to reinterpret the bits.
333
279
T :: from_bits ( significand)
334
280
}
@@ -364,8 +310,8 @@ pub fn prev_float<T: RawFloat>(x: T) -> T {
364
310
Zero => panic ! ( "prev_float: argument is zero" ) ,
365
311
Normal => {
366
312
let Unpacked { sig, k } = x. unpack ( ) ;
367
- if sig == T :: min_sig ( ) {
368
- encode_normal ( Unpacked :: new ( T :: max_sig ( ) , k - 1 ) )
313
+ if sig == T :: MIN_SIG {
314
+ encode_normal ( Unpacked :: new ( T :: MAX_SIG , k - 1 ) )
369
315
} else {
370
316
encode_normal ( Unpacked :: new ( sig - 1 , k) )
371
317
}
@@ -380,7 +326,7 @@ pub fn prev_float<T: RawFloat>(x: T) -> T {
380
326
pub fn next_float < T : RawFloat > ( x : T ) -> T {
381
327
match x. classify ( ) {
382
328
Nan => panic ! ( "next_float: argument is NaN" ) ,
383
- Infinite => T :: infinity2 ( ) ,
329
+ Infinite => T :: INFINITY ,
384
330
// This seems too good to be true, but it works.
385
331
// 0.0 is encoded as the all-zero word. Subnormals are 0x000m...m where m is the mantissa.
386
332
// In particular, the smallest subnormal is 0x0...01 and the largest is 0x000F...F.
0 commit comments