2727//! Many functions in this module only handle normal numbers. The dec2flt routines conservatively
2828//! take the universally-correct slow path (Algorithm M) for very small and very large numbers.
2929//! That algorithm needs only next_float() which does handle subnormals and zeros.
30- use u32;
3130use cmp:: Ordering :: { Less , Equal , Greater } ;
31+ use convert:: TryInto ;
3232use ops:: { Mul , Div , Neg } ;
3333use fmt:: { Debug , LowerExp } ;
34- use mem:: transmute;
3534use num:: diy_float:: Fp ;
3635use num:: FpCategory :: { Infinite , Zero , Subnormal , Normal , Nan } ;
3736use num:: Float ;
@@ -66,12 +65,6 @@ pub trait RawFloat : Float + Copy + Debug + LowerExp
6665 /// Returns the mantissa, exponent and sign as integers.
6766 fn integer_decode ( self ) -> ( u64 , i16 , i8 ) ;
6867
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-
7568 /// Decode the float.
7669 fn unpack ( self ) -> Unpacked ;
7770
@@ -159,7 +152,7 @@ impl RawFloat for f32 {
159152
160153 /// Returns the mantissa, exponent and sign as integers.
161154 fn integer_decode ( self ) -> ( u64 , i16 , i8 ) {
162- let bits: u32 = unsafe { transmute ( self ) } ;
155+ let bits = self . to_bits ( ) ;
163156 let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 } ;
164157 let mut exponent: i16 = ( ( bits >> 23 ) & 0xff ) as i16 ;
165158 let mantissa = if exponent == 0 {
@@ -172,16 +165,6 @@ impl RawFloat for f32 {
172165 ( mantissa as u64 , exponent, sign)
173166 }
174167
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-
185168 fn unpack ( self ) -> Unpacked {
186169 let ( sig, exp, _sig) = self . integer_decode ( ) ;
187170 Unpacked :: new ( sig, exp)
@@ -210,7 +193,7 @@ impl RawFloat for f64 {
210193
211194 /// Returns the mantissa, exponent and sign as integers.
212195 fn integer_decode ( self ) -> ( u64 , i16 , i8 ) {
213- let bits: u64 = unsafe { transmute ( self ) } ;
196+ let bits = self . to_bits ( ) ;
214197 let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 } ;
215198 let mut exponent: i16 = ( ( bits >> 52 ) & 0x7ff ) as i16 ;
216199 let mantissa = if exponent == 0 {
@@ -223,15 +206,6 @@ impl RawFloat for f64 {
223206 ( mantissa, exponent, sign)
224207 }
225208
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-
235209 fn unpack ( self ) -> Unpacked {
236210 let ( sig, exp, _sig) = self . integer_decode ( ) ;
237211 Unpacked :: new ( sig, exp)
@@ -296,14 +270,14 @@ pub fn encode_normal<T: RawFloat>(x: Unpacked) -> T {
296270 "encode_normal: exponent out of range" ) ;
297271 // Leave sign bit at 0 ("+"), our numbers are all positive
298272 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 ! ( ) ) )
300274}
301275
302276/// Construct a subnormal. A mantissa of 0 is allowed and constructs zero.
303277pub fn encode_subnormal < T : RawFloat > ( significand : u64 ) -> T {
304278 assert ! ( significand < T :: MIN_SIG , "encode_subnormal: not actually subnormal" ) ;
305279 // 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 ! ( ) ) )
307281}
308282
309283/// 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 {
363337 // too is exactly what we want!
364338 // Finally, f64::MAX + 1 = 7eff...f + 1 = 7ff0...0 = f64::INFINITY.
365339 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 ) )
368341 }
369342 }
370343}
0 commit comments