softposit/p32e2/math/
ceil.rs

1use super::P32E2;
2use crate::u32_with_sign;
3
4impl P32E2 {
5    pub const fn ceil(self) -> Self {
6        let mut mask = 0x2000_0000_u32;
7        let mut scale = 0_u32;
8
9        let mut ui_a = self.to_bits();
10        let sign = (ui_a & 0x8000_0000) != 0;
11
12        // sign is True if pA > NaR.
13        if sign {
14            ui_a = ui_a.wrapping_neg();
15        } // A is now |A|.
16        let u_a = if ui_a <= 0x_4000_0000 {
17            // 0 <= |pA| < 1 floor to zero.(if not negative and whole number)
18            if sign && (ui_a != 0x0) {
19                0x0
20            } else {
21                0x_4000_0000
22            }
23        } else if ui_a <= 0x_4800_0000 {
24            // 0 <= |pA| < 1 floor to 1.(if not negative and whole number)
25            if sign && (ui_a != 0x_4800_0000) {
26                0x_4000_0000
27            } else {
28                0x_4800_0000
29            }
30        } else if ui_a <= 0x_4C00_0000 {
31            // 0 <= |pA| < 2 floor to zero.(if not negative and whole number)
32            if sign && (ui_a != 0x_4C00_0000) {
33                0x_4800_0000
34            } else {
35                0x_4C00_0000
36            }
37        } else if ui_a >= 0x7E80_0000 {
38            // If |A| is 0x7E80_0000 (posit is pure integer value), leave it unchanged.
39            return self; // This also takes care of the NaR case, 0x8000_0000.
40        } else {
41            // 34% of the cases, we have to decode the posit.
42
43            while (mask & ui_a) != 0 {
44                scale += 4;
45                mask >>= 1;
46            }
47            mask >>= 1;
48
49            //Exponential (2 bits)
50            if (mask & ui_a) != 0 {
51                scale += 2;
52            }
53            mask >>= 1;
54            if (mask & ui_a) != 0 {
55                scale += 1;
56            }
57            mask >>= scale;
58
59            //the rest of the bits
60            mask >>= 1;
61            let mut tmp = ui_a & mask;
62            let bit_n_plus_one = tmp;
63            ui_a ^= tmp; // Erase the bit, if it was set.
64            tmp = ui_a & (mask - 1); // this is actually bits_more
65
66            ui_a ^= tmp;
67
68            if !sign && (bit_n_plus_one | tmp) != 0 {
69                ui_a += mask << 1;
70            }
71            ui_a
72        };
73        Self::from_bits(u32_with_sign(u_a, sign))
74    }
75}