27
27
//! Many functions in this module only handle normal numbers. The dec2flt routines conservatively
28
28
//! take the universally-correct slow path (Algorithm M) for very small and very large numbers.
29
29
//! That algorithm needs only next_float() which does handle subnormals and zeros.
30
- use u32;
31
30
use cmp:: Ordering :: { Less , Equal , Greater } ;
31
+ use convert:: TryInto ;
32
32
use ops:: { Mul , Div , Neg } ;
33
33
use fmt:: { Debug , LowerExp } ;
34
- use mem:: transmute;
35
34
use num:: diy_float:: Fp ;
36
35
use num:: FpCategory :: { Infinite , Zero , Subnormal , Normal , Nan } ;
37
36
use num:: Float ;
@@ -66,12 +65,6 @@ pub trait RawFloat : Float + Copy + Debug + LowerExp
66
65
/// Returns the mantissa, exponent and sign as integers.
67
66
fn integer_decode ( self ) -> ( u64 , i16 , i8 ) ;
68
67
69
- /// Get the raw binary representation of the float.
70
- fn transmute ( self ) -> u64 ;
71
-
72
- /// Transmute the raw binary representation into a float.
73
- fn from_bits ( bits : u64 ) -> Self ;
74
-
75
68
/// Decode the float.
76
69
fn unpack ( self ) -> Unpacked ;
77
70
@@ -159,7 +152,7 @@ impl RawFloat for f32 {
159
152
160
153
/// Returns the mantissa, exponent and sign as integers.
161
154
fn integer_decode ( self ) -> ( u64 , i16 , i8 ) {
162
- let bits: u32 = unsafe { transmute ( self ) } ;
155
+ let bits = self . to_bits ( ) ;
163
156
let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 } ;
164
157
let mut exponent: i16 = ( ( bits >> 23 ) & 0xff ) as i16 ;
165
158
let mantissa = if exponent == 0 {
@@ -172,16 +165,6 @@ impl RawFloat for f32 {
172
165
( mantissa as u64 , exponent, sign)
173
166
}
174
167
175
- fn transmute ( self ) -> u64 {
176
- let bits: u32 = unsafe { transmute ( self ) } ;
177
- bits as u64
178
- }
179
-
180
- fn from_bits ( bits : u64 ) -> f32 {
181
- assert ! ( bits < u32 :: MAX as u64 , "f32::from_bits: too many bits" ) ;
182
- unsafe { transmute ( bits as u32 ) }
183
- }
184
-
185
168
fn unpack ( self ) -> Unpacked {
186
169
let ( sig, exp, _sig) = self . integer_decode ( ) ;
187
170
Unpacked :: new ( sig, exp)
@@ -210,7 +193,7 @@ impl RawFloat for f64 {
210
193
211
194
/// Returns the mantissa, exponent and sign as integers.
212
195
fn integer_decode ( self ) -> ( u64 , i16 , i8 ) {
213
- let bits: u64 = unsafe { transmute ( self ) } ;
196
+ let bits = self . to_bits ( ) ;
214
197
let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 } ;
215
198
let mut exponent: i16 = ( ( bits >> 52 ) & 0x7ff ) as i16 ;
216
199
let mantissa = if exponent == 0 {
@@ -223,15 +206,6 @@ impl RawFloat for f64 {
223
206
( mantissa, exponent, sign)
224
207
}
225
208
226
- fn transmute ( self ) -> u64 {
227
- let bits: u64 = unsafe { transmute ( self ) } ;
228
- bits
229
- }
230
-
231
- fn from_bits ( bits : u64 ) -> f64 {
232
- unsafe { transmute ( bits) }
233
- }
234
-
235
209
fn unpack ( self ) -> Unpacked {
236
210
let ( sig, exp, _sig) = self . integer_decode ( ) ;
237
211
Unpacked :: new ( sig, exp)
@@ -296,14 +270,14 @@ pub fn encode_normal<T: RawFloat>(x: Unpacked) -> T {
296
270
"encode_normal: exponent out of range" ) ;
297
271
// Leave sign bit at 0 ("+"), our numbers are all positive
298
272
let bits = ( k_enc as u64 ) << T :: EXPLICIT_SIG_BITS | sig_enc;
299
- T :: from_bits ( bits)
273
+ T :: from_bits ( bits. try_into ( ) . unwrap_or_else ( |_| unreachable ! ( ) ) )
300
274
}
301
275
302
276
/// Construct a subnormal. A mantissa of 0 is allowed and constructs zero.
303
277
pub fn encode_subnormal < T : RawFloat > ( significand : u64 ) -> T {
304
278
assert ! ( significand < T :: MIN_SIG , "encode_subnormal: not actually subnormal" ) ;
305
279
// Encoded exponent is 0, the sign bit is 0, so we just have to reinterpret the bits.
306
- T :: from_bits ( significand)
280
+ T :: from_bits ( significand. try_into ( ) . unwrap_or_else ( |_| unreachable ! ( ) ) )
307
281
}
308
282
309
283
/// Approximate a bignum with an Fp. Rounds within 0.5 ULP with half-to-even.
@@ -363,8 +337,7 @@ pub fn next_float<T: RawFloat>(x: T) -> T {
363
337
// too is exactly what we want!
364
338
// Finally, f64::MAX + 1 = 7eff...f + 1 = 7ff0...0 = f64::INFINITY.
365
339
Zero | Subnormal | Normal => {
366
- let bits: u64 = x. transmute ( ) ;
367
- T :: from_bits ( bits + 1 )
340
+ T :: from_bits ( x. to_bits ( ) + T :: Bits :: from ( 1u8 ) )
368
341
}
369
342
}
370
343
}
0 commit comments