fixed_bigint/fixeduint/
midpoint_impl.rs1use super::{FixedUInt, MachineWord};
18use crate::machineword::ConstMachineWord;
19use const_num_traits::Midpoint;
20use const_num_traits::Personality;
21
22c0nst::c0nst! {
23 c0nst impl<T: [c0nst] ConstMachineWord + MachineWord, const N: usize, P: Personality> Midpoint for FixedUInt<T, N, P> {
24 type Output = Self;
25 fn midpoint(self, rhs: Self) -> Self {
26 (self & rhs) + ((self ^ rhs) >> 1usize)
28 }
29 }
30
31 c0nst impl<T: [c0nst] ConstMachineWord + MachineWord, const N: usize, P: Personality> Midpoint for &FixedUInt<T, N, P> {
32 type Output = FixedUInt<T, N, P>;
33 fn midpoint(self, rhs: Self) -> FixedUInt<T, N, P> {
34 <FixedUInt<T, N, P> as Midpoint>::midpoint(*self, *rhs)
35 }
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42
43 #[test]
44 fn test_midpoint() {
45 type U16 = FixedUInt<u8, 2>;
46
47 assert_eq!(
49 Midpoint::midpoint(U16::from(0u8), U16::from(10u8)),
50 U16::from(5u8)
51 );
52
53 assert_eq!(
55 Midpoint::midpoint(U16::from(10u8), U16::from(0u8)),
56 U16::from(5u8)
57 );
58
59 assert_eq!(
61 Midpoint::midpoint(U16::from(0u8), U16::from(9u8)),
62 U16::from(4u8)
63 );
64
65 assert_eq!(
67 Midpoint::midpoint(U16::from(42u8), U16::from(42u8)),
68 U16::from(42u8)
69 );
70
71 let max = U16::from(0xFFFFu16);
73 assert_eq!(Midpoint::midpoint(max, max), max);
74
75 assert_eq!(
77 Midpoint::midpoint(U16::from(0u8), max),
78 U16::from(0x7FFFu16)
79 );
80 }
81
82 c0nst::c0nst! {
83 pub c0nst fn const_midpoint<T: [c0nst] ConstMachineWord + MachineWord, const N: usize, P: Personality>(
84 a: FixedUInt<T, N, P>,
85 b: FixedUInt<T, N, P>,
86 ) -> FixedUInt<T, N, P> {
87 Midpoint::midpoint(a, b)
88 }
89 }
90
91 #[test]
92 fn test_const_midpoint() {
93 type U16 = FixedUInt<u8, 2>;
94
95 assert_eq!(
96 const_midpoint(U16::from(0u8), U16::from(10u8)),
97 U16::from(5u8)
98 );
99
100 #[cfg(feature = "nightly")]
101 {
102 const A: U16 = FixedUInt::from_array([0, 0]);
103 const B: U16 = FixedUInt::from_array([10, 0]);
104 const MID: U16 = const_midpoint(A, B);
105 assert_eq!(MID, FixedUInt::from_array([5, 0]));
106
107 const MAX: U16 = FixedUInt::from_array([0xFF, 0xFF]);
109 const MID_MAX: U16 = const_midpoint(MAX, MAX);
110 assert_eq!(MID_MAX, MAX);
111 }
112 }
113
114 #[test]
117 fn test_midpoint_polymorphic() {
118 fn test_mid<T>(a: T, b: T, expected: T)
119 where
120 T: Midpoint<Output = T> + Eq + core::fmt::Debug + Copy,
121 {
122 assert_eq!(Midpoint::midpoint(a, b), expected);
123 assert_eq!(Midpoint::midpoint(b, a), expected); }
125
126 type U8x2 = FixedUInt<u8, 2>;
128 type U8x4 = FixedUInt<u8, 4>;
129 type U16x2 = FixedUInt<u16, 2>;
130
131 test_mid(U8x2::from(0u8), U8x2::from(100u8), U8x2::from(50u8));
133 test_mid(U8x4::from(0u8), U8x4::from(100u8), U8x4::from(50u8));
134 test_mid(U16x2::from(0u8), U16x2::from(100u8), U16x2::from(50u8));
135
136 test_mid(0u8, 100u8, 50u8);
138 test_mid(0u16, 100u16, 50u16);
139 test_mid(0u32, 100u32, 50u32);
140
141 test_mid(U8x2::from(0u8), U8x2::from(99u8), U8x2::from(49u8));
143 test_mid(0u8, 99u8, 49u8);
144
145 let max_u16 = U8x2::from(0xFFFFu16);
147 test_mid(max_u16, max_u16, max_u16);
148 test_mid(u16::MAX, u16::MAX, u16::MAX);
149 }
150}