1use std::ops::{Add, AddAssign};

13 integer bits + 11 fractional bits

4const MASK: u32 = (1 << 24) - 1;

13.11 fixed point decimal number

7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub struct FixedPointDecimal(u32);
10impl FixedPointDecimal {
11    pub fn from_position(position_word: u16) -> Self {
12        // Positions have 13 integer bits and 3 fractional bits; shift left 8 to get to 11
13        // fractional bits
14        Self(u32::from(position_word) << 8)
15    }
16
17    pub fn from_delta(delta_word: u16) -> Self {
18        // Deltas have a sign bit, 4 integer bits, and 11 fractional bits
19        // Handle the sign bit by sign extending to 32 bits
20        Self(delta_word as i16 as u32)
21    }
22
23    pub fn integer_part(self) -> u32 {
24        // Shift right 11 to drop all the fractional bits
25        (self.0 & MASK) >> 11
26    }
27}
28
29impl Add for FixedPointDecimal {
30    type Output = Self;
31
32    // Clippy doesn't like the bitwise AND in here for some reason
33    #[allow(clippy::suspicious_arithmetic_impl)]
34    fn add(self, rhs: Self) -> Self::Output {
35        Self(self.0.wrapping_add(rhs.0) & MASK)
36    }
37}
38
39impl AddAssign for FixedPointDecimal {
40    fn add_assign(&mut self, rhs: Self) {
41        *self = *self + rhs;
42    }
43}