fixed_bigint/fixeduint/
abs_diff_impl.rs1use super::{const_ct_select, FixedUInt, MachineWord};
18use crate::const_numtraits::{ConstAbsDiff, ConstOverflowingSub, ConstWrappingSub, ConstZero};
19use crate::machineword::ConstMachineWord;
20use crate::personality::{Personality, PersonalityTag};
21
22c0nst::c0nst! {
23 impl<T: [c0nst] ConstMachineWord + MachineWord, const N: usize, P: Personality> c0nst ConstAbsDiff for FixedUInt<T, N, P> {
24 fn abs_diff(self, other: Self) -> Self {
25 match P::TAG {
26 PersonalityTag::Nct => {
27 if self >= other {
28 self - other
29 } else {
30 other - self
31 }
32 }
33 PersonalityTag::Ct => {
34 let (diff, borrow) =
35 <Self as ConstOverflowingSub>::overflowing_sub(&self, &other);
36 let neg_diff =
37 <Self as ConstWrappingSub>::wrapping_sub(&<Self as ConstZero>::zero(), &diff);
38 const_ct_select(diff, neg_diff, borrow as u8)
39 }
40 }
41 }
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn test_abs_diff() {
51 type U16 = FixedUInt<u8, 2>;
52
53 assert_eq!(
54 ConstAbsDiff::abs_diff(U16::from(10u8), U16::from(3u8)),
55 U16::from(7u8)
56 );
57 assert_eq!(
58 ConstAbsDiff::abs_diff(U16::from(3u8), U16::from(10u8)),
59 U16::from(7u8)
60 );
61 assert_eq!(
62 ConstAbsDiff::abs_diff(U16::from(5u8), U16::from(5u8)),
63 U16::from(0u8)
64 );
65 assert_eq!(
66 ConstAbsDiff::abs_diff(U16::from(0u8), U16::from(100u8)),
67 U16::from(100u8)
68 );
69 assert_eq!(
70 ConstAbsDiff::abs_diff(U16::from(255u8), U16::from(0u8)),
71 U16::from(255u8)
72 );
73 }
74
75 c0nst::c0nst! {
76 pub c0nst fn const_abs_diff<T: [c0nst] ConstMachineWord + MachineWord, const N: usize, P: Personality>(
77 a: FixedUInt<T, N, P>,
78 b: FixedUInt<T, N, P>,
79 ) -> FixedUInt<T, N, P> {
80 ConstAbsDiff::abs_diff(a, b)
81 }
82 }
83
84 #[test]
85 fn test_const_abs_diff() {
86 type U16 = FixedUInt<u8, 2>;
87
88 assert_eq!(
89 const_abs_diff(U16::from(10u8), U16::from(3u8)),
90 U16::from(7u8)
91 );
92
93 #[cfg(feature = "nightly")]
94 {
95 const A: U16 = FixedUInt::from_array([10, 0]);
96 const B: U16 = FixedUInt::from_array([3, 0]);
97 const DIFF: U16 = const_abs_diff(A, B);
98 assert_eq!(DIFF, FixedUInt::from_array([7, 0]));
99 }
100 }
101}