qfall_math/integer/z/arithmetic/
div.rs1use super::super::Z;
12use crate::macros::arithmetics::{
13 arithmetic_between_types, arithmetic_trait_borrowed_to_owned,
14 arithmetic_trait_mixed_borrowed_owned,
15};
16use crate::rational::Q;
17use flint_sys::fmpz::{fmpz_cdiv_q, fmpz_fdiv_q, fmpz_tdiv_qr};
18use std::ops::Div;
19
20impl Z {
21 pub fn div_floor(&self, other: impl Into<Z>) -> Self {
45 let other: Z = other.into();
46 assert!(!other.is_zero(), "Tried to divide {self} by zero.");
47 let mut out = Z::default();
48 unsafe {
49 fmpz_fdiv_q(&mut out.value, &self.value, &other.value);
50 }
51 out
52 }
53
54 pub fn div_ceil(&self, other: impl Into<Z>) -> Self {
78 let other: Z = other.into();
79 assert!(!other.is_zero(), "Tried to divide {self} by zero.");
80 let mut out = Z::default();
81 unsafe {
82 fmpz_cdiv_q(&mut out.value, &self.value, &other.value);
83 }
84 out
85 }
86
87 pub fn div_exact(&self, other: impl Into<Z>) -> Option<Self> {
113 let other: Z = other.into();
114 assert!(!other.is_zero(), "Tried to divide {self} by zero.");
115
116 let mut quotient = Z::default();
117 let mut reminder = Z::default();
118 unsafe {
119 fmpz_tdiv_qr(
120 &mut quotient.value,
121 &mut reminder.value,
122 &self.value,
123 &other.value,
124 );
125 }
126
127 if reminder != Z::ZERO {
128 None
129 } else {
130 Some(quotient)
131 }
132 }
133}
134
135impl Div for &Z {
136 type Output = Q;
137 fn div(self, other: Self) -> Self::Output {
163 Q::from((self, other))
164 }
165}
166
167arithmetic_trait_borrowed_to_owned!(Div, div, Z, Z, Q);
168arithmetic_trait_mixed_borrowed_owned!(Div, div, Z, Z, Q);
169arithmetic_between_types!(Div, div, Z, Q, i64 i32 i16 i8 u64 u32 u16 u8 f32 f64);
170
171#[test]
172fn same() {
173 let a = Z::from(4) / 2;
174 let b = 4 / Z::from(2);
175
176 println!("{a}, {b}");
177
178 assert_eq!(a, b);
179}
180
181impl Div<&Q> for &Z {
182 type Output = Q;
183
184 fn div(self, other: &Q) -> Self::Output {
210 assert!(!other.is_zero(), "Tried to divide {self} by zero.");
211 Q::from(self.clone()) / other
212 }
213}
214
215arithmetic_trait_borrowed_to_owned!(Div, div, Z, Q, Q);
216arithmetic_trait_mixed_borrowed_owned!(Div, div, Z, Q, Q);
217
218#[cfg(test)]
219mod test_div_floor {
220 use super::Z;
221 use crate::integer_mod_q::Modulus;
222
223 #[test]
225 #[allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args)]
226 fn availability() {
227 let value = Z::from(100);
228
229 value.div_floor(3_u8);
230 value.div_floor(3_u16);
231 value.div_floor(3_u32);
232 value.div_floor(3_u64);
233 value.div_floor(3_i8);
234 value.div_floor(3_i16);
235 value.div_floor(3_i32);
236 value.div_floor(3_i64);
237 value.div_floor(Z::from(10));
238 value.div_floor(Modulus::from(10));
239
240 value.div_floor(&3_u8);
241 value.div_floor(&3_u16);
242 value.div_floor(&3_u32);
243 value.div_floor(&3_u64);
244 value.div_floor(&3_i8);
245 value.div_floor(&3_i16);
246 value.div_floor(&3_i32);
247 value.div_floor(&3_i64);
248 value.div_floor(&Z::from(10));
249 value.div_floor(&Modulus::from(10));
250 }
251
252 #[test]
254 fn floored() {
255 let small = Z::from(-11);
256 let large = Z::from(i64::MAX);
257 let divisor = Z::from(2);
258
259 let res_0 = small.div_floor(&divisor);
260 let res_1 = large.div_floor(&divisor);
261
262 assert_eq!(Z::from(-6), res_0);
263 assert_eq!(Z::from(i64::MAX >> 1), res_1);
264 }
265
266 #[test]
268 fn exact() {
269 let small = Z::from(10);
270 let large = Z::from(i64::MIN);
271 let divisor = Z::from(2);
272
273 let res_0 = Z::ZERO.div_floor(&divisor);
274 let res_1 = small.div_floor(&divisor);
275 let res_2 = large.div_floor(&divisor);
276
277 assert_eq!(Z::ZERO, res_0);
278 assert_eq!(Z::from(5), res_1);
279 assert_eq!(Z::from(i64::MIN >> 1), res_2);
280 }
281
282 #[test]
284 #[should_panic]
285 fn division_by_zero() {
286 let a = Z::from(100);
287
288 let _ = a.div_floor(&Z::ZERO);
289 }
290}
291
292#[cfg(test)]
293mod test_div_ceil {
294 use super::Z;
295 use crate::integer_mod_q::Modulus;
296
297 #[test]
299 #[allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args)]
300 fn availability() {
301 let value = Z::from(100);
302
303 value.div_ceil(3_u8);
304 value.div_ceil(3_u16);
305 value.div_ceil(3_u32);
306 value.div_ceil(3_u64);
307 value.div_ceil(3_i8);
308 value.div_ceil(3_i16);
309 value.div_ceil(3_i32);
310 value.div_ceil(3_i64);
311 value.div_ceil(Z::from(10));
312 value.div_ceil(Modulus::from(10));
313
314 value.div_ceil(&3_u8);
315 value.div_ceil(&3_u16);
316 value.div_ceil(&3_u32);
317 value.div_ceil(&3_u64);
318 value.div_ceil(&3_i8);
319 value.div_ceil(&3_i16);
320 value.div_ceil(&3_i32);
321 value.div_ceil(&3_i64);
322 value.div_ceil(&Z::from(10));
323 value.div_ceil(&Modulus::from(10));
324 }
325
326 #[test]
328 fn ceiled() {
329 let small = Z::from(-11);
330 let large = Z::from(i64::MAX);
331 let divisor = Z::from(2);
332
333 let res_0 = small.div_ceil(&divisor);
334 let res_1 = large.div_ceil(&divisor);
335
336 assert_eq!(Z::from(-5), res_0);
337 assert_eq!(Z::from((i64::MAX >> 1) + 1), res_1);
338 }
339
340 #[test]
342 fn exact() {
343 let small = Z::from(10);
344 let large = Z::from(i64::MIN);
345 let divisor = Z::from(2);
346
347 let res_0 = Z::ZERO.div_ceil(&divisor);
348 let res_1 = small.div_ceil(&divisor);
349 let res_2 = large.div_ceil(&divisor);
350
351 assert_eq!(Z::ZERO, res_0);
352 assert_eq!(Z::from(5), res_1);
353 assert_eq!(Z::from(i64::MIN >> 1), res_2);
354 }
355
356 #[test]
358 #[should_panic]
359 fn division_by_zero() {
360 let a = Z::from(100);
361
362 let _ = a.div_ceil(&Z::ZERO);
363 }
364}
365
366#[cfg(test)]
367mod test_div_exact {
368 use super::Z;
369 use crate::integer_mod_q::Modulus;
370
371 #[test]
373 #[allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args)]
374 fn availability() {
375 let value = Z::from(100);
376
377 value.div_exact(3_u8);
378 value.div_exact(3_u16);
379 value.div_exact(3_u32);
380 value.div_exact(3_u64);
381 value.div_exact(3_i8);
382 value.div_exact(3_i16);
383 value.div_exact(3_i32);
384 value.div_exact(3_i64);
385 value.div_exact(Z::from(10));
386 value.div_exact(Modulus::from(10));
387
388 value.div_exact(&3_u8);
389 value.div_exact(&3_u16);
390 value.div_exact(&3_u32);
391 value.div_exact(&3_u64);
392 value.div_exact(&3_i8);
393 value.div_exact(&3_i16);
394 value.div_exact(&3_i32);
395 value.div_exact(&3_i64);
396 value.div_exact(&Z::from(10));
397 value.div_exact(&Modulus::from(10));
398 }
399
400 #[test]
402 fn non_exact() {
403 let small = Z::from(-11);
404 let large = Z::from(i64::MAX);
405 let divisor = Z::from(2);
406
407 let res_0 = small.div_exact(&divisor);
408 let res_1 = large.div_exact(&divisor);
409
410 assert!(res_0.is_none());
411 assert!(res_1.is_none());
412 }
413
414 #[test]
416 fn exact() {
417 let small = Z::from(10);
418 let large = Z::from(i64::MIN);
419 let divisor = Z::from(2);
420
421 let res_0 = Z::ZERO.div_exact(&divisor).unwrap();
422 let res_1 = small.div_exact(&divisor).unwrap();
423 let res_2 = large.div_exact(&divisor).unwrap();
424
425 assert_eq!(Z::ZERO, res_0);
426 assert_eq!(Z::from(5), res_1);
427 assert_eq!(Z::from(i64::MIN >> 1), res_2);
428 }
429
430 #[test]
432 #[should_panic]
433 fn division_by_zero() {
434 let a = Z::from(100);
435
436 let _ = a.div_exact(&Z::ZERO);
437 }
438}
439
440#[cfg(test)]
441mod test_div_between_types {
442 use crate::integer::Z;
443 use crate::rational::Q;
444
445 #[test]
447 #[allow(clippy::op_ref)]
448 fn div() {
449 let a: Z = Z::from(42);
450 let b: u64 = 5;
451 let c: u32 = 5;
452 let d: u16 = 5;
453 let e: u8 = 5;
454 let f: i64 = 5;
455 let g: i32 = 5;
456 let h: i16 = 5;
457 let i: i8 = 5;
458
459 let _: Q = &a / &b;
460 let _: Q = &a / &c;
461 let _: Q = &a / &d;
462 let _: Q = &a / &e;
463 let _: Q = &a / &f;
464 let _: Q = &a / &g;
465 let _: Q = &a / &h;
466 let _: Q = &a / &i;
467
468 let _: Q = &b / &a;
469 let _: Q = &c / &a;
470 let _: Q = &d / &a;
471 let _: Q = &e / &a;
472 let _: Q = &f / &a;
473 let _: Q = &g / &a;
474 let _: Q = &h / &a;
475 let _: Q = &i / &a;
476
477 let _: Q = &a / b;
478 let _: Q = &a / c;
479 let _: Q = &a / d;
480 let _: Q = &a / e;
481 let _: Q = &a / f;
482 let _: Q = &a / g;
483 let _: Q = &a / h;
484 let _: Q = &a / i;
485
486 let _: Q = &b / Z::from(42);
487 let _: Q = &c / Z::from(42);
488 let _: Q = &d / Z::from(42);
489 let _: Q = &e / Z::from(42);
490 let _: Q = &f / Z::from(42);
491 let _: Q = &g / Z::from(42);
492 let _: Q = &h / Z::from(42);
493 let _: Q = &i / Z::from(42);
494
495 let _: Q = Z::from(42) / &b;
496 let _: Q = Z::from(42) / &c;
497 let _: Q = Z::from(42) / &d;
498 let _: Q = Z::from(42) / &e;
499 let _: Q = Z::from(42) / &f;
500 let _: Q = Z::from(42) / &g;
501 let _: Q = Z::from(42) / &h;
502 let _: Q = Z::from(42) / &i;
503
504 let _: Q = b / &a;
505 let _: Q = c / &a;
506 let _: Q = d / &a;
507 let _: Q = e / &a;
508 let _: Q = f / &a;
509 let _: Q = g / &a;
510 let _: Q = h / &a;
511 let _: Q = i / &a;
512
513 let _: Q = Z::from(42) / b;
514 let _: Q = Z::from(42) / c;
515 let _: Q = Z::from(42) / d;
516 let _: Q = Z::from(42) / e;
517 let _: Q = Z::from(42) / f;
518 let _: Q = Z::from(42) / g;
519 let _: Q = Z::from(42) / h;
520 let _: Q = Z::from(42) / i;
521
522 let _: Q = b / Z::from(42);
523 let _: Q = c / Z::from(42);
524 let _: Q = d / Z::from(42);
525 let _: Q = e / Z::from(42);
526 let _: Q = f / Z::from(42);
527 let _: Q = g / Z::from(42);
528 let _: Q = h / Z::from(42);
529 let _: Q = i / Z::from(42);
530 }
531}
532
533#[cfg(test)]
534mod test_div {
535 use super::Z;
536 use crate::rational::Q;
537 use crate::traits::Pow;
538
539 #[test]
541 fn div() {
542 let a: Z = Z::from(42);
543 let b: Z = Z::from(4);
544 let c: Q = a / b;
545 assert_eq!(c, Q::from((21, 2)));
546 }
547
548 #[test]
550 fn div_borrow() {
551 let a: Z = Z::from(42);
552 let b: Z = Z::from(4);
553 let c: Q = &a / &b;
554 assert_eq!(c, Q::from((21, 2)));
555 }
556
557 #[test]
559 fn div_first_borrowed() {
560 let a: Z = Z::from(42);
561 let b: Z = Z::from(4);
562 let c: Q = &a / b;
563 assert_eq!(c, Q::from((21, 2)));
564 }
565
566 #[test]
568 fn div_second_borrowed() {
569 let a: Z = Z::from(42);
570 let b: Z = Z::from(4);
571 let c: Q = a / &b;
572 assert_eq!(c, Q::from((21, 2)));
573 }
574
575 #[test]
577 fn div_large_numbers() {
578 let a: Z = Z::from(i64::MAX as u64 + 1);
579 let b: Z = Z::from(2);
580 let c: Z = Z::from(i64::MIN);
581 let d: Z = Z::from(i64::MAX as u64 + 1);
582
583 let e: Q = a / b;
584 let f: Q = c / d;
585
586 assert_eq!(e, Q::from(2).pow(62).unwrap());
587 assert_eq!(f, Q::MINUS_ONE);
588 }
589}
590
591#[cfg(test)]
592mod test_div_between_z_and_q {
593 use super::Z;
594 use crate::rational::Q;
595
596 #[test]
598 fn availability() {
599 let a: Z = Z::from(42);
600 let b: Q = Q::from((5, 7));
601
602 let _: Q = &a / &b;
603 let _: Q = &a / b.clone();
604 let _: Q = a.clone() / &b;
605 let _: Q = a.clone() / b;
606 let _: Q = &a / 0.5_f32;
607 let _: Q = &a / 0.5_f64;
608 let _: Q = a.clone() / 0.5_f32;
609 let _: Q = a.clone() / 0.5_f64;
610 let _: Q = 0.5_f32 / &a;
611 let _: Q = 0.5_f64 / &a;
612 let _: Q = 0.5_f32 / a.clone();
613 let _: Q = 0.5_f64 / a.clone();
614 }
615
616 #[test]
618 fn order_retained() {
619 let a = Z::from(4);
620
621 assert_eq!(2, &a / 2);
622 assert_eq!(Q::from((1, 2)), 2 / &a);
623 }
624
625 #[test]
627 fn div() {
628 let a: Z = Z::from(4);
629 let b: Q = Q::from((5, 7));
630 let c: Q = a / b;
631 assert_eq!(c, Q::from((28, 5)));
632 }
633
634 #[test]
636 fn div_borrow() {
637 let a: Z = Z::from(4);
638 let b: Q = Q::from((5, 7));
639 let c: Q = &a / &b;
640 assert_eq!(c, Q::from((28, 5)));
641 }
642
643 #[test]
645 fn div_first_borrowed() {
646 let a: Z = Z::from(4);
647 let b: Q = Q::from((5, 7));
648 let c: Q = &a / b;
649 assert_eq!(c, Q::from((28, 5)));
650 }
651
652 #[test]
654 fn div_second_borrowed() {
655 let a: Z = Z::from(4);
656 let b: Q = Q::from((5, 7));
657 let c: Q = a / &b;
658 assert_eq!(c, Q::from((28, 5)));
659 }
660
661 #[test]
663 fn div_large_numbers() {
664 let a: Z = Z::from(u64::MAX);
665 let b: Q = Q::from((1, u64::MAX));
666 let c: Q = Q::from((u64::MAX, 2));
667
668 let d: Q = &a / b;
669 let e: Q = a / c;
670
671 assert_eq!(d, Q::from(u64::MAX) / Q::from((1, u64::MAX)));
672 assert_eq!(e, Q::from(u64::MAX) / Q::from((u64::MAX, 2)));
673 }
674}