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}