Skip to main content

malachite_nz/gaussian_integer/comparison/
cmp_abs_primitive_int.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::gaussian_integer::GaussianInteger;
10use crate::integer::Integer;
11use core::cmp::Ordering::{self, Greater};
12use malachite_base::num::arithmetic::traits::AbsSquared;
13use malachite_base::num::comparison::traits::PartialOrdAbs;
14
15macro_rules! impl_unsigned {
16    ($t: ident) => {
17        impl PartialOrdAbs<$t> for GaussianInteger {
18            /// Compares the absolute values of a [`GaussianInteger`] and an unsigned primitive
19            /// integer.
20            ///
21            /// # Worst-case complexity
22            /// $T(n) = O(n \log n \log\log n)$
23            ///
24            /// $M(n) = O(n \log n)$
25            ///
26            /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of
27            /// significant bits of the real and imaginary parts of `self`.
28            ///
29            /// # Examples
30            /// See [here](super::cmp_abs_primitive_int#partial_cmp_abs).
31            fn partial_cmp_abs(&self, other: &$t) -> Option<Ordering> {
32                if self.imaginary == 0u32 {
33                    self.real.partial_cmp_abs(other)
34                } else if self.real == 0u32 {
35                    self.imaginary.partial_cmp_abs(other)
36                } else if !self.real.lt_abs(other) || !self.imaginary.lt_abs(other) {
37                    Some(Greater)
38                } else {
39                    Some(self.abs_squared().cmp(&Integer::from(*other).abs_squared()))
40                }
41            }
42        }
43
44        impl PartialOrdAbs<GaussianInteger> for $t {
45            /// Compares the absolute values of an unsigned primitive integer and a
46            /// [`GaussianInteger`].
47            ///
48            /// # Worst-case complexity
49            /// $T(n) = O(n \log n \log\log n)$
50            ///
51            /// $M(n) = O(n \log n)$
52            ///
53            /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of
54            /// significant bits of the real and imaginary parts of `other`.
55            ///
56            /// # Examples
57            /// See [here](super::cmp_abs_primitive_int#partial_cmp_abs).
58            #[inline]
59            fn partial_cmp_abs(&self, other: &GaussianInteger) -> Option<Ordering> {
60                other.partial_cmp_abs(self).map(Ordering::reverse)
61            }
62        }
63    };
64}
65apply_to_unsigneds!(impl_unsigned);
66
67macro_rules! impl_signed {
68    ($t: ident) => {
69        impl PartialOrdAbs<$t> for GaussianInteger {
70            /// Compares the absolute values of a [`GaussianInteger`] and a signed primitive
71            /// integer.
72            ///
73            /// # Worst-case complexity
74            /// $T(n) = O(n \log n \log\log n)$
75            ///
76            /// $M(n) = O(n \log n)$
77            ///
78            /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of
79            /// significant bits of the real and imaginary parts of `self`.
80            ///
81            /// # Examples
82            /// See [here](super::cmp_abs_primitive_int#partial_cmp_abs).
83            fn partial_cmp_abs(&self, other: &$t) -> Option<Ordering> {
84                if self.imaginary == 0u32 {
85                    self.real.partial_cmp_abs(other)
86                } else if self.real == 0u32 {
87                    self.imaginary.partial_cmp_abs(other)
88                } else if !self.real.lt_abs(other) || !self.imaginary.lt_abs(other) {
89                    Some(Greater)
90                } else {
91                    Some(self.abs_squared().cmp(&Integer::from(*other).abs_squared()))
92                }
93            }
94        }
95
96        impl PartialOrdAbs<GaussianInteger> for $t {
97            /// Compares the absolute values of a signed primitive integer and a
98            /// [`GaussianInteger`].
99            ///
100            /// # Worst-case complexity
101            /// $T(n) = O(n \log n \log\log n)$
102            ///
103            /// $M(n) = O(n \log n)$
104            ///
105            /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of
106            /// significant bits of the real and imaginary parts of `other`.
107            ///
108            /// # Examples
109            /// See [here](super::cmp_abs_primitive_int#partial_cmp_abs).
110            #[inline]
111            fn partial_cmp_abs(&self, other: &GaussianInteger) -> Option<Ordering> {
112                other.partial_cmp_abs(self).map(Ordering::reverse)
113            }
114        }
115    };
116}
117apply_to_signeds!(impl_signed);