11use float:: Float ;
2- use int:: { CastInto , Int , WideInt } ;
2+ use int:: { CastInto , Int , HInt , DInt } ;
33
44fn mul < F : Float > ( a : F , b : F ) -> F
55where
66 u32 : CastInto < F :: Int > ,
77 F :: Int : CastInto < u32 > ,
88 i32 : CastInto < F :: Int > ,
99 F :: Int : CastInto < i32 > ,
10- F :: Int : WideInt ,
10+ F :: Int : HInt ,
1111{
1212 let one = F :: Int :: ONE ;
1313 let zero = F :: Int :: ZERO ;
@@ -112,8 +112,7 @@ where
112112 // have (exponentBits + 2) integral digits, all but two of which must be
113113 // zero. Normalizing this result is just a conditional left-shift by one
114114 // and bumping the exponent accordingly.
115- let ( mut product_high, mut product_low) =
116- <F :: Int as WideInt >:: wide_mul ( a_significand, b_significand << exponent_bits) ;
115+ let ( mut product_low, mut product_high) = a_significand. widen_mul ( b_significand << exponent_bits) . lo_hi ( ) ;
117116
118117 let a_exponent_i32: i32 = a_exponent. cast ( ) ;
119118 let b_exponent_i32: i32 = b_exponent. cast ( ) ;
@@ -126,7 +125,8 @@ where
126125 if ( product_high & implicit_bit) != zero {
127126 product_exponent = product_exponent. wrapping_add ( 1 ) ;
128127 } else {
129- <F :: Int as WideInt >:: wide_shift_left ( & mut product_high, & mut product_low, 1 ) ;
128+ product_high = ( product_high << 1 ) | ( product_low >> ( bits - 1 ) ) ;
129+ product_low <<= 1 ;
130130 }
131131
132132 // If we have overflowed the type, return +/- infinity.
@@ -142,17 +142,23 @@ where
142142 // handle this case separately, but we make it a special case to
143143 // simplify the shift logic.
144144 let shift = one. wrapping_sub ( product_exponent. cast ( ) ) . cast ( ) ;
145- if shift >= bits as i32 {
145+ if shift >= bits {
146146 return F :: from_repr ( product_sign) ;
147147 }
148148
149149 // Otherwise, shift the significand of the result so that the round
150150 // bit is the high bit of productLo.
151- <F :: Int as WideInt >:: wide_shift_right_with_sticky (
152- & mut product_high,
153- & mut product_low,
154- shift,
155- )
151+ if shift < bits {
152+ let sticky = product_low << ( bits - shift) ;
153+ product_low = product_high << ( bits - shift) | product_low >> shift | sticky;
154+ product_high >>= shift;
155+ } else if shift < ( 2 * bits) {
156+ let sticky = product_high << ( 2 * bits - shift) | product_low;
157+ product_low = product_high >> ( shift - bits) | sticky;
158+ product_high = zero;
159+ } else {
160+ product_high = zero;
161+ }
156162 } else {
157163 // Result is normal before rounding; insert the exponent.
158164 product_high &= significand_mask;
0 commit comments