qfall_math/rational/q/arithmetic/
sub.rs1use super::super::Q;
12use crate::{
13 integer::Z,
14 macros::arithmetics::{
15 arithmetic_assign_between_types, arithmetic_assign_trait_borrowed_to_owned,
16 arithmetic_between_types, arithmetic_trait_borrowed_to_owned,
17 arithmetic_trait_mixed_borrowed_owned,
18 },
19};
20use flint_sys::fmpq::{fmpq_sub, fmpq_sub_fmpz, fmpq_sub_si, fmpq_sub_ui};
21use std::ops::{Sub, SubAssign};
22
23impl SubAssign<&Q> for Q {
24 fn sub_assign(&mut self, other: &Self) {
49 unsafe { fmpq_sub(&mut self.value, &self.value, &other.value) };
50 }
51}
52impl SubAssign<&Z> for Q {
53 fn sub_assign(&mut self, other: &Z) {
55 unsafe { fmpq_sub_fmpz(&mut self.value, &self.value, &other.value) };
56 }
57}
58impl SubAssign<i64> for Q {
59 fn sub_assign(&mut self, other: i64) {
61 unsafe { fmpq_sub_si(&mut self.value, &self.value, other) };
62 }
63}
64impl SubAssign<u64> for Q {
65 fn sub_assign(&mut self, other: u64) {
67 unsafe { fmpq_sub_ui(&mut self.value, &self.value, other) };
68 }
69}
70impl SubAssign<f64> for Q {
71 fn sub_assign(&mut self, other: f64) {
73 let other = Q::from(other);
74
75 unsafe { fmpq_sub(&mut self.value, &self.value, &other.value) };
76 }
77}
78
79arithmetic_assign_trait_borrowed_to_owned!(SubAssign, sub_assign, Q, Q);
80arithmetic_assign_trait_borrowed_to_owned!(SubAssign, sub_assign, Q, Z);
81arithmetic_assign_between_types!(SubAssign, sub_assign, Q, i64, i32 i16 i8);
82arithmetic_assign_between_types!(SubAssign, sub_assign, Q, u64, u32 u16 u8);
83arithmetic_assign_between_types!(SubAssign, sub_assign, Q, f64, f32);
84
85impl Sub for &Q {
86 type Output = Q;
87 fn sub(self, other: Self) -> Self::Output {
109 let mut out = Q::default();
110 unsafe {
111 fmpq_sub(&mut out.value, &self.value, &other.value);
112 }
113 out
114 }
115}
116
117arithmetic_trait_borrowed_to_owned!(Sub, sub, Q, Q, Q);
118arithmetic_trait_mixed_borrowed_owned!(Sub, sub, Q, Q, Q);
119arithmetic_between_types!(Sub, sub, Q, Q, i64 i32 i16 i8 u64 u32 u16 u8 f32 f64);
120
121impl Sub<&Z> for &Q {
122 type Output = Q;
123
124 fn sub(self, other: &Z) -> Self::Output {
147 let mut out = Q::default();
148 unsafe {
149 fmpq_sub_fmpz(&mut out.value, &self.value, &other.value);
150 }
151 out
152 }
153}
154
155arithmetic_trait_borrowed_to_owned!(Sub, sub, Q, Z, Q);
156arithmetic_trait_mixed_borrowed_owned!(Sub, sub, Q, Z, Q);
157
158#[cfg(test)]
159mod test_sub_assign {
160 use crate::{integer::Z, rational::Q};
161
162 #[test]
164 fn correct_small() {
165 let mut a = Q::MINUS_ONE;
166 let b = Q::ONE;
167 let c = Q::MINUS_ONE;
168 let d = Q::from((-1, 2));
169
170 a -= &b;
171 assert_eq!(-2, a);
172 a -= &c;
173 assert_eq!(-1, a);
174 a -= &c;
175 assert_eq!(0, a);
176 a -= &c;
177 assert_eq!(1, a);
178 a -= &c;
179 assert_eq!(2, a);
180 a -= 2 * b;
181 assert_eq!(0, a);
182 a -= d;
183 assert_eq!(Q::from((1, 2)), a);
184 }
185
186 #[test]
188 fn correct_large() {
189 let mut a = Q::from(i64::MAX);
190 let b = -1 * Q::from(i64::MIN);
191 let c = -1 * Q::from(u64::MAX);
192
193 a -= b;
194 assert_eq!(-1, a);
195 a -= c;
196 assert_eq!(u64::MAX - 1, a);
197 }
198
199 #[test]
201 fn availability() {
202 let mut a = Q::from((1, 2));
203 let b = Q::from((4, 5));
204 let c = Z::ONE;
205
206 a -= &b;
207 a -= b;
208 a -= &c;
209 a -= c;
210 a -= 0.5_f64;
211 a -= 0.5_f32;
212 a -= 1_u8;
213 a -= 1_u16;
214 a -= 1_u32;
215 a -= 1_u64;
216 a -= 1_i8;
217 a -= 1_i16;
218 a -= 1_i32;
219 a -= 1_i64;
220 }
221}
222
223#[cfg(test)]
224mod test_sub {
225 use super::Q;
226
227 #[test]
229 fn sub() {
230 let a: Q = Q::from(42);
231 let b: Q = Q::from((42, 2));
232 let c: Q = a - b;
233 assert_eq!(c, Q::from(21));
234 }
235
236 #[test]
238 fn sub_borrow() {
239 let a: Q = Q::from(42);
240 let b: Q = Q::from((42, 2));
241 let c: Q = &a - &b;
242 assert_eq!(c, Q::from(21));
243 }
244
245 #[test]
247 fn sub_first_borrowed() {
248 let a: Q = Q::from((42, 5));
249 let b: Q = Q::from((42, 10));
250 let c: Q = &a - b;
251 assert_eq!(c, Q::from((21, 5)));
252 }
253
254 #[test]
256 fn sub_second_borrowed() {
257 let a: Q = Q::from(42);
258 let b: Q = Q::from((42, 2));
259 let c: Q = a - &b;
260 assert_eq!(c, Q::from(21));
261 }
262
263 #[test]
265 fn sub_large() {
266 let a: Q = Q::from(i64::MAX);
267 let b: Q = Q::from(u64::MAX - 1);
268 let c: Q = Q::from((1, i64::MAX));
269 let d: Q = Q::from((1, u64::MAX));
270 let e: Q = &b - &a;
271 let f: Q = &c - &d;
272 assert_eq!(e, a);
273 assert_eq!(f, Q::from((-1, u64::MAX)) + Q::from((1, i64::MAX)));
274 }
275}
276
277#[cfg(test)]
278mod test_sub_between_z_and_q {
279 use super::Z;
280 use crate::rational::Q;
281
282 #[test]
284 fn sub() {
285 let a: Q = Q::from((5, 7));
286 let b: Z = Z::from(4);
287 let c: Q = a - b;
288 assert_eq!(c, Q::from((-23, 7)));
289 }
290
291 #[test]
293 fn sub_borrow() {
294 let a: Q = Q::from((5, 7));
295 let b: Z = Z::from(4);
296 let c: Q = &a - &b;
297 assert_eq!(c, Q::from((-23, 7)));
298 }
299
300 #[test]
302 fn sub_first_borrowed() {
303 let a: Q = Q::from((5, 7));
304 let b: Z = Z::from(4);
305 let c: Q = &a - b;
306 assert_eq!(c, Q::from((-23, 7)));
307 }
308
309 #[test]
311 fn sub_second_borrowed() {
312 let a: Q = Q::from((5, 7));
313 let b: Z = Z::from(4);
314 let c: Q = a - &b;
315 assert_eq!(c, Q::from((-23, 7)));
316 }
317
318 #[test]
320 fn sub_large_numbers() {
321 let a: Q = Q::from((u64::MAX, 2));
322 let b: Q = Q::from((1, u64::MAX));
323 let c: Z = Z::from(u64::MAX);
324 let d: Q = a - &c;
325 let e: Q = b - c;
326 assert_eq!(d, Q::from((u64::MAX, 2)) - Q::from(u64::MAX));
327 assert_eq!(e, Q::from((1, u64::MAX)) - Q::from(u64::MAX));
328 }
329}
330
331#[cfg(test)]
332mod test_sub_between_types {
333 use crate::rational::Q;
334
335 #[test]
337 #[allow(clippy::op_ref)]
338 fn sub() {
339 let a: Q = Q::from(42);
340 let b: u64 = 1;
341 let c: u32 = 1;
342 let d: u16 = 1;
343 let e: u8 = 1;
344 let f: i64 = 1;
345 let g: i32 = 1;
346 let h: i16 = 1;
347 let i: i8 = 1;
348 let j: f32 = 1.3;
349 let k: f64 = 1.3;
350
351 let _: Q = &a - &b;
352 let _: Q = &a - &c;
353 let _: Q = &a - &d;
354 let _: Q = &a - &e;
355 let _: Q = &a - &f;
356 let _: Q = &a - &g;
357 let _: Q = &a - &h;
358 let _: Q = &a - &i;
359 let _: Q = &a - &j;
360 let _: Q = &a - &k;
361
362 let _: Q = &b - &a;
363 let _: Q = &c - &a;
364 let _: Q = &d - &a;
365 let _: Q = &e - &a;
366 let _: Q = &f - &a;
367 let _: Q = &g - &a;
368 let _: Q = &h - &a;
369 let _: Q = &i - &a;
370 let _: Q = &j - &a;
371 let _: Q = &k - &a;
372
373 let _: Q = &a - b;
374 let _: Q = &a - c;
375 let _: Q = &a - d;
376 let _: Q = &a - e;
377 let _: Q = &a - f;
378 let _: Q = &a - g;
379 let _: Q = &a - h;
380 let _: Q = &a - i;
381 let _: Q = &a - j;
382 let _: Q = &a - k;
383
384 let _: Q = &b - Q::from(42);
385 let _: Q = &c - Q::from(42);
386 let _: Q = &d - Q::from(42);
387 let _: Q = &e - Q::from(42);
388 let _: Q = &f - Q::from(42);
389 let _: Q = &g - Q::from(42);
390 let _: Q = &h - Q::from(42);
391 let _: Q = &i - Q::from(42);
392 let _: Q = &j - Q::from(42);
393 let _: Q = &k - Q::from(42);
394
395 let _: Q = Q::from(42) - &b;
396 let _: Q = Q::from(42) - &c;
397 let _: Q = Q::from(42) - &d;
398 let _: Q = Q::from(42) - &e;
399 let _: Q = Q::from(42) - &f;
400 let _: Q = Q::from(42) - &g;
401 let _: Q = Q::from(42) - &h;
402 let _: Q = Q::from(42) - &i;
403 let _: Q = Q::from(42) - &j;
404 let _: Q = Q::from(42) - &k;
405
406 let _: Q = b - &a;
407 let _: Q = c - &a;
408 let _: Q = d - &a;
409 let _: Q = e - &a;
410 let _: Q = f - &a;
411 let _: Q = g - &a;
412 let _: Q = h - &a;
413 let _: Q = i - &a;
414 let _: Q = j - &a;
415 let _: Q = k - &a;
416
417 let _: Q = Q::from(42) - b;
418 let _: Q = Q::from(42) - c;
419 let _: Q = Q::from(42) - d;
420 let _: Q = Q::from(42) - e;
421 let _: Q = Q::from(42) - f;
422 let _: Q = Q::from(42) - g;
423 let _: Q = Q::from(42) - h;
424 let _: Q = Q::from(42) - i;
425 let _: Q = Q::from(42) - j;
426 let _: Q = Q::from(42) - k;
427
428 let _: Q = b - Q::from(42);
429 let _: Q = c - Q::from(42);
430 let _: Q = d - Q::from(42);
431 let _: Q = e - Q::from(42);
432 let _: Q = f - Q::from(42);
433 let _: Q = g - Q::from(42);
434 let _: Q = h - Q::from(42);
435 let _: Q = i - Q::from(42);
436 let _: Q = j - Q::from(42);
437 let _: Q = k - Q::from(42);
438 }
439}