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 } ;
32- use ops:: { Mul , Div , Neg } ;
31+ use convert:: { TryFrom , TryInto } ;
32+ use ops:: { Add , 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 ;
@@ -56,22 +55,27 @@ impl Unpacked {
5655///
5756/// Should **never ever** be implemented for other types or be used outside the dec2flt module.
5857/// Inherits from `Float` because there is some overlap, but all the reused methods are trivial.
59- pub trait RawFloat : Float + Copy + Debug + LowerExp
60- + Mul < Output =Self > + Div < Output =Self > + Neg < Output =Self >
58+ pub trait RawFloat
59+ : Float
60+ + Copy
61+ + Debug
62+ + LowerExp
63+ + Mul < Output =Self >
64+ + Div < Output =Self >
65+ + Neg < Output =Self >
66+ where
67+ Self : Float < Bits = <Self as RawFloat >:: RawBits >
6168{
6269 const INFINITY : Self ;
6370 const NAN : Self ;
6471 const ZERO : Self ;
6572
73+ /// Same as `Float::Bits` with extra traits.
74+ type RawBits : Add < Output = Self :: RawBits > + From < u8 > + TryFrom < u64 > ;
75+
6676 /// Returns the mantissa, exponent and sign as integers.
6777 fn integer_decode ( self ) -> ( u64 , i16 , i8 ) ;
6878
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-
7579 /// Decode the float.
7680 fn unpack ( self ) -> Unpacked ;
7781
@@ -149,6 +153,8 @@ macro_rules! other_constants {
149153}
150154
151155impl RawFloat for f32 {
156+ type RawBits = u32 ;
157+
152158 const SIG_BITS : u8 = 24 ;
153159 const EXP_BITS : u8 = 8 ;
154160 const CEIL_LOG5_OF_MAX_SIG : i16 = 11 ;
@@ -159,7 +165,7 @@ impl RawFloat for f32 {
159165
160166 /// Returns the mantissa, exponent and sign as integers.
161167 fn integer_decode ( self ) -> ( u64 , i16 , i8 ) {
162- let bits: u32 = unsafe { transmute ( self ) } ;
168+ let bits = self . to_bits ( ) ;
163169 let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 } ;
164170 let mut exponent: i16 = ( ( bits >> 23 ) & 0xff ) as i16 ;
165171 let mantissa = if exponent == 0 {
@@ -172,16 +178,6 @@ impl RawFloat for f32 {
172178 ( mantissa as u64 , exponent, sign)
173179 }
174180
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-
185181 fn unpack ( self ) -> Unpacked {
186182 let ( sig, exp, _sig) = self . integer_decode ( ) ;
187183 Unpacked :: new ( sig, exp)
@@ -200,6 +196,8 @@ impl RawFloat for f32 {
200196
201197
202198impl RawFloat for f64 {
199+ type RawBits = u64 ;
200+
203201 const SIG_BITS : u8 = 53 ;
204202 const EXP_BITS : u8 = 11 ;
205203 const CEIL_LOG5_OF_MAX_SIG : i16 = 23 ;
@@ -210,7 +208,7 @@ impl RawFloat for f64 {
210208
211209 /// Returns the mantissa, exponent and sign as integers.
212210 fn integer_decode ( self ) -> ( u64 , i16 , i8 ) {
213- let bits: u64 = unsafe { transmute ( self ) } ;
211+ let bits = self . to_bits ( ) ;
214212 let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 } ;
215213 let mut exponent: i16 = ( ( bits >> 52 ) & 0x7ff ) as i16 ;
216214 let mantissa = if exponent == 0 {
@@ -223,15 +221,6 @@ impl RawFloat for f64 {
223221 ( mantissa, exponent, sign)
224222 }
225223
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-
235224 fn unpack ( self ) -> Unpacked {
236225 let ( sig, exp, _sig) = self . integer_decode ( ) ;
237226 Unpacked :: new ( sig, exp)
@@ -296,14 +285,14 @@ pub fn encode_normal<T: RawFloat>(x: Unpacked) -> T {
296285 "encode_normal: exponent out of range" ) ;
297286 // Leave sign bit at 0 ("+"), our numbers are all positive
298287 let bits = ( k_enc as u64 ) << T :: EXPLICIT_SIG_BITS | sig_enc;
299- T :: from_bits ( bits)
288+ T :: from_bits ( bits. try_into ( ) . unwrap_or_else ( |_| unreachable ! ( ) ) )
300289}
301290
302291/// Construct a subnormal. A mantissa of 0 is allowed and constructs zero.
303292pub fn encode_subnormal < T : RawFloat > ( significand : u64 ) -> T {
304293 assert ! ( significand < T :: MIN_SIG , "encode_subnormal: not actually subnormal" ) ;
305294 // Encoded exponent is 0, the sign bit is 0, so we just have to reinterpret the bits.
306- T :: from_bits ( significand)
295+ T :: from_bits ( significand. try_into ( ) . unwrap_or_else ( |_| unreachable ! ( ) ) )
307296}
308297
309298/// Approximate a bignum with an Fp. Rounds within 0.5 ULP with half-to-even.
@@ -363,8 +352,7 @@ pub fn next_float<T: RawFloat>(x: T) -> T {
363352 // too is exactly what we want!
364353 // Finally, f64::MAX + 1 = 7eff...f + 1 = 7ff0...0 = f64::INFINITY.
365354 Zero | Subnormal | Normal => {
366- let bits: u64 = x. transmute ( ) ;
367- T :: from_bits ( bits + 1 )
355+ T :: from_bits ( x. to_bits ( ) + T :: Bits :: from ( 1u8 ) )
368356 }
369357 }
370358}
0 commit comments