1use std::ops::Sub;
2use std::ops::SubAssign;
3
4use crate::bits::Bits;
5use crate::signed_bits::SignedBits;
6
7impl<const N: usize> Sub<Bits<N>> for Bits<N> {
8 type Output = Self;
9 #[allow(clippy::suspicious_arithmetic_impl)]
10 fn sub(self, rhs: Self) -> Self::Output {
11 Self(u128::wrapping_sub(self.0, rhs.0) & Self::mask().0)
12 }
13}
14
15impl<const N: usize> Sub<Bits<N>> for u128 {
16 type Output = Bits<N>;
17 fn sub(self, rhs: Bits<N>) -> Self::Output {
18 Bits::<N>::from(self) - rhs
19 }
20}
21
22impl<const N: usize> Sub<u128> for Bits<N> {
23 type Output = Self;
24 fn sub(self, rhs: u128) -> Self::Output {
25 self - Bits::<N>::from(rhs)
26 }
27}
28
29impl<const N: usize> SubAssign<u128> for Bits<N> {
30 fn sub_assign(&mut self, rhs: u128) {
31 *self = *self - rhs;
32 }
33}
34
35impl<const N: usize> SubAssign<Bits<N>> for Bits<N> {
36 fn sub_assign(&mut self, rhs: Bits<N>) {
37 *self = *self - rhs;
38 }
39}
40
41impl<const N: usize> Sub<SignedBits<N>> for SignedBits<N> {
42 type Output = Self;
43 fn sub(self, rhs: Self) -> Self::Output {
44 (self.as_unsigned() - rhs.as_unsigned()).as_signed()
45 }
46}
47
48impl<const N: usize> Sub<i128> for SignedBits<N> {
49 type Output = Self;
50 fn sub(self, rhs: i128) -> Self::Output {
51 self - SignedBits::<N>::from(rhs)
52 }
53}
54
55impl<const N: usize> SubAssign<i128> for SignedBits<N> {
56 fn sub_assign(&mut self, rhs: i128) {
57 *self = *self - rhs;
58 }
59}
60
61impl<const N: usize> SubAssign<SignedBits<N>> for SignedBits<N> {
62 fn sub_assign(&mut self, rhs: SignedBits<N>) {
63 *self = *self - rhs;
64 }
65}
66
67#[cfg(test)]
68mod test {
69 use super::*;
70 use std::num::Wrapping;
71
72 #[test]
73 fn test_sub_bits() {
74 let bits: Bits<8> = 0b1101_1010.into();
75 let result = bits - bits;
76 assert_eq!(result.0, 0_u128);
77 let x: std::num::Wrapping<u8> = Wrapping(0b1101_1010);
78 let bits: Bits<8> = 0b1101_1010.into();
79 let result = bits - bits - bits;
80 assert_eq!(Wrapping(result.0 as u8), x - x - x);
81 let mut bits: Bits<128> = 0.into();
82 bits.set_bit(127, true);
83 let result = bits - bits;
84 assert_eq!(result.0, 0_u128);
85 let bits: Bits<54> = 0b1101_1010.into();
86 let result = bits - 1;
87 let bits_m_1: Bits<54> = 0b1101_1001.into();
88 assert_eq!(result, bits_m_1);
89 let result = 1 - bits;
90 assert_eq!(result.0, 2 + (Bits::<54>::mask().0 - bits.0));
93 }
94
95 #[test]
96 fn test_subassign_bits() {
97 let mut bits: Bits<8> = 0b1101_1010.into();
98 let bits_m_1: Bits<8> = 0b1101_1001.into();
99 bits -= bits_m_1;
100 assert_eq!(bits.0, 1_u128);
101 let mut bits: Bits<8> = 0b1101_1010.into();
102 bits -= 1;
103 assert_eq!(bits.0, 0b1101_1001_u128);
104 }
105
106 #[test]
107 fn test_subtraction_i8() {
108 for i in i8::MIN..i8::MAX {
109 for j in i8::MIN..i8::MAX {
110 let signed_i: SignedBits<8> = (i as i128).into();
111 let signed_j: SignedBits<8> = (j as i128).into();
112 let signed_k = signed_i - signed_j;
113 let built_in_k = i8::wrapping_sub(i, j) as i128;
114 assert_eq!(signed_k.0, built_in_k);
115 }
116 }
117 }
118
119 #[test]
120 fn test_subtraction_i128() {
121 for i in [i128::MIN, -1, 0, 1, i128::MAX] {
122 for j in [i128::MIN, -1, 0, 1, i128::MAX] {
123 let signed_i: SignedBits<128> = i.into();
124 let signed_j: SignedBits<128> = j.into();
125 let signed_k = signed_i - signed_j;
126 let built_in_k = i.wrapping_sub(j);
127 assert_eq!(signed_k.0, built_in_k);
128 }
129 }
130 }
131
132 #[test]
133 fn test_subassign() {
134 let mut x = SignedBits::<8>::from(1);
135 x -= SignedBits::<8>::from(-2);
136 assert_eq!(x.0, 3);
137 }
138}