1use super::*;
2
3impl<
4 const N: u32,
5 const ES: u32,
6 const SIZE: usize,
7> Quire<N, ES, SIZE> {
8 pub(crate) fn add<Int: crate::Int>(&mut self, posit: Posit<N, ES, Int>) {
9 if posit == Posit::ZERO {
10 ()
11 } else if posit == Posit::NAR || self.is_nar() {
12 *self = Quire::NAR
13 } else {
14 let decoded = unsafe { posit.decode_regular() };
16 unsafe { self.accumulate_decoded(decoded) }
18 }
19 }
20
21 pub(crate) fn sub<Int: crate::Int>(&mut self, posit: Posit<N, ES, Int>) {
22 self.add(-posit)
23 }
24}
25
26impl<
27 const N: u32,
28 const ES: u32,
29 Int: crate::Int,
30 const SIZE: usize,
31> core::ops::AddAssign<Posit<N, ES, Int>> for Quire<N, ES, SIZE> {
32 fn add_assign(&mut self, rhs: Posit<N, ES, Int>) {
43 self.add(rhs)
44 }
45}
46
47impl<
48 const N: u32,
49 const ES: u32,
50 Int: crate::Int,
51 const SIZE: usize,
52> core::ops::AddAssign<&Posit<N, ES, Int>> for Quire<N, ES, SIZE> {
53 fn add_assign(&mut self, rhs: &Posit<N, ES, Int>) {
64 self.add(*rhs)
65 }
66}
67
68impl<
69 const N: u32,
70 const ES: u32,
71 Int: crate::Int,
72 const SIZE: usize,
73> core::ops::SubAssign<Posit<N, ES, Int>> for Quire<N, ES, SIZE> {
74 fn sub_assign(&mut self, rhs: Posit<N, ES, Int>) {
85 self.sub(rhs)
86 }
87}
88
89impl<
90 const N: u32,
91 const ES: u32,
92 Int: crate::Int,
93 const SIZE: usize,
94> core::ops::SubAssign<&Posit<N, ES, Int>> for Quire<N, ES, SIZE> {
95 fn sub_assign(&mut self, rhs: &Posit<N, ES, Int>) {
106 self.sub(*rhs)
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113 use malachite::rational::Rational;
114 use proptest::prelude::*;
115
116 mod posit_posit {
118 use super::*;
121
122 macro_rules! test_exhaustive {
123 ($name:ident, $posit:ty, $quire:ty) => {
124 #[test]
125 fn $name() {
126 for a in <$posit>::cases_exhaustive_all() {
127 for b in <$posit>::cases_exhaustive_all() {
128 let posit = a + b;
129 let mut quire = <$quire>::from(a);
130 quire += b;
131 assert!(super::rational::try_is_correct_rounded(Rational::try_from(quire), posit))
132 }
133 }
134 }
135 };
136 }
137
138 macro_rules! test_proptest {
139 ($name:ident, $posit:ty, $quire:ty) => {
140 proptest!{
141 #![proptest_config(ProptestConfig::with_cases(crate::PROPTEST_CASES))]
142 #[test]
143 fn $name(
144 a in <$posit>::cases_proptest_all(),
145 b in <$posit>::cases_proptest_all(),
146 ) {
147 let posit = a + b;
148 let mut quire = <$quire>::from(a);
149 quire += b;
150 assert!(super::rational::try_is_correct_rounded(Rational::try_from(quire), posit))
151 }
152 }
153 };
154 }
155
156 test_exhaustive!{posit_10_0_exhaustive, Posit<10, 0, i16>, Quire<10, 0, 128>}
157 test_exhaustive!{posit_10_1_exhaustive, Posit<10, 1, i16>, Quire<10, 1, 128>}
158 test_exhaustive!{posit_10_2_exhaustive, Posit<10, 2, i16>, Quire<10, 2, 128>}
159 test_exhaustive!{posit_10_3_exhaustive, Posit<10, 3, i16>, Quire<10, 3, 128>}
160 test_exhaustive!{posit_8_0_exhaustive, Posit<8, 0, i8>, Quire<8, 0, 128>}
161
162 test_exhaustive!{p8_exhaustive, crate::p8, crate::q8}
163 test_proptest!{p16_proptest, crate::p16, crate::q16}
164 test_proptest!{p32_proptest, crate::p32, crate::q32}
165 test_proptest!{p64_proptest, crate::p64, crate::q64}
166
167 test_exhaustive!{posit_3_0_exhaustive, Posit<3, 0, i8>, Quire<3, 0, 128>}
168 test_exhaustive!{posit_4_0_exhaustive, Posit<4, 0, i8>, Quire<4, 0, 128>}
169 test_exhaustive!{posit_4_1_exhaustive, Posit<4, 1, i8>, Quire<4, 1, 128>}
170 }
171
172 mod quire_posit {
174 use super::*;
175
176 macro_rules! test_proptest {
177 ($name:ident, $posit:ty, $quire:ty) => {
178 proptest!{
179 #![proptest_config(ProptestConfig::with_cases(crate::PROPTEST_CASES))]
180 #[test]
181 fn $name(
182 q in <$quire>::cases_proptest_all(),
183 p in <$posit>::cases_proptest_all(),
184 ) {
185 let mut quire = q.clone();
186 quire += p;
187 match (Rational::try_from(q), Rational::try_from(p)) {
188 (Ok(q), Ok(p)) => assert_eq!(Rational::try_from(quire), Ok(q + p)),
189 _ => assert!(quire.is_nar()),
190 }
191 }
192 }
193 };
194 }
195
196 test_proptest!{posit_10_0_proptest, Posit<10, 0, i16>, Quire<10, 0, 128>}
197 test_proptest!{posit_10_1_proptest, Posit<10, 1, i16>, Quire<10, 1, 128>}
198 test_proptest!{posit_10_2_proptest, Posit<10, 2, i16>, Quire<10, 2, 128>}
199 test_proptest!{posit_10_3_proptest, Posit<10, 3, i16>, Quire<10, 3, 128>}
200 test_proptest!{posit_8_0_proptest, Posit<8, 0, i8>, Quire<8, 0, 128>}
201
202 test_proptest!{p8_proptest, crate::p8, crate::q8}
203 test_proptest!{p16_proptest, crate::p16, crate::q16}
204 test_proptest!{p32_proptest, crate::p32, crate::q32}
205 test_proptest!{p64_proptest, crate::p64, crate::q64}
206
207 test_proptest!{posit_3_0_proptest, Posit<3, 0, i8>, Quire<3, 0, 128>}
208 test_proptest!{posit_4_0_proptest, Posit<4, 0, i8>, Quire<4, 0, 128>}
209 test_proptest!{posit_4_1_proptest, Posit<4, 1, i8>, Quire<4, 1, 128>}
210 }
211}