1 // Adapted from https://github.com/Alexhuszagh/rust-lexical.
2 
3 //! Bit-shift helpers.
4 
5 use super::float::ExtendedFloat;
6 use core::mem;
7 
8 // Shift extended-precision float right `shift` bytes.
9 #[inline]
shr(fp: &mut ExtendedFloat, shift: i32)10 pub(crate) fn shr(fp: &mut ExtendedFloat, shift: i32) {
11     let bits: u64 = mem::size_of::<u64>() as u64 * 8;
12     debug_assert!((shift as u64) < bits, "shr() overflow in shift right.");
13 
14     fp.mant >>= shift;
15     fp.exp += shift;
16 }
17 
18 // Shift extended-precision float right `shift` bytes.
19 //
20 // Accepts when the shift is the same as the type size, and
21 // sets the value to 0.
22 #[inline]
overflowing_shr(fp: &mut ExtendedFloat, shift: i32)23 pub(crate) fn overflowing_shr(fp: &mut ExtendedFloat, shift: i32) {
24     let bits: u64 = mem::size_of::<u64>() as u64 * 8;
25     debug_assert!(
26         (shift as u64) <= bits,
27         "overflowing_shr() overflow in shift right."
28     );
29 
30     fp.mant = if shift as u64 == bits {
31         0
32     } else {
33         fp.mant >> shift
34     };
35     fp.exp += shift;
36 }
37 
38 // Shift extended-precision float left `shift` bytes.
39 #[inline]
shl(fp: &mut ExtendedFloat, shift: i32)40 pub(crate) fn shl(fp: &mut ExtendedFloat, shift: i32) {
41     let bits: u64 = mem::size_of::<u64>() as u64 * 8;
42     debug_assert!((shift as u64) < bits, "shl() overflow in shift left.");
43 
44     fp.mant <<= shift;
45     fp.exp -= shift;
46 }
47