Skip to main content

malachite_nz/gaussian_integer/arithmetic/
div.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::gaussian_integer::arithmetic::div_rem::quotient_or_zero;
11use core::ops::{Div, DivAssign};
12use malachite_base::num::arithmetic::traits::CheckedDiv;
13use malachite_base::num::basic::traits::Zero;
14
15fn div_ref_ref(x: &GaussianInteger, y: &GaussianInteger) -> GaussianInteger {
16    quotient_or_zero(x, y).unwrap_or(GaussianInteger::ZERO)
17}
18
19impl Div<Self> for GaussianInteger {
20    type Output = Self;
21
22    /// Divides a [`GaussianInteger`] by another [`GaussianInteger`], taking both by value.
23    ///
24    /// The quotient is the Gaussian integer nearest to the exact quotient, with each part rounded
25    /// to the nearest integer and ties rounded up. The quotient and remainder (which is not
26    /// computed) satisfy $x = qy + r$ and $N(r) \leq N(y) / 2$, where $N$ is the norm. To get both
27    /// at once, use [`div_rem`](malachite_base::num::arithmetic::traits::DivRem::div_rem).
28    ///
29    /// $$
30    /// f(x, y) = \left \lfloor \frac{x \bar{y}}{N(y)} + \frac{1 + i}{2} \right \rfloor,
31    /// $$
32    /// where the floor is taken on each part.
33    ///
34    /// # Worst-case complexity
35    /// $T(n) = O(n \log n \log\log n)$
36    ///
37    /// $M(n) = O(n \log n)$
38    ///
39    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
40    /// bits of the real and imaginary parts of `self` and `other`.
41    ///
42    /// # Panics
43    /// Panics if `other` is zero.
44    ///
45    /// # Examples
46    /// ```
47    /// use malachite_nz::gaussian_integer::GaussianInteger;
48    /// use std::str::FromStr;
49    ///
50    /// // (2+i)(3) + (-1) = 5+3i
51    /// let x = GaussianInteger::from_str("5+3i").unwrap();
52    /// let y = GaussianInteger::from_str("2+i").unwrap();
53    /// assert_eq!((x / y).to_string(), "3");
54    /// ```
55    #[inline]
56    fn div(self, other: Self) -> Self {
57        div_ref_ref(&self, &other)
58    }
59}
60
61impl Div<&Self> for GaussianInteger {
62    type Output = Self;
63
64    /// Divides a [`GaussianInteger`] by another [`GaussianInteger`], taking the first by value and
65    /// the second by reference.
66    ///
67    /// The quotient is the Gaussian integer nearest to the exact quotient, with each part rounded
68    /// to the nearest integer and ties rounded up. The quotient and remainder (which is not
69    /// computed) satisfy $x = qy + r$ and $N(r) \leq N(y) / 2$, where $N$ is the norm. To get both
70    /// at once, use [`div_rem`](malachite_base::num::arithmetic::traits::DivRem::div_rem).
71    ///
72    /// $$
73    /// f(x, y) = \left \lfloor \frac{x \bar{y}}{N(y)} + \frac{1 + i}{2} \right \rfloor,
74    /// $$
75    /// where the floor is taken on each part.
76    ///
77    /// # Worst-case complexity
78    /// $T(n) = O(n \log n \log\log n)$
79    ///
80    /// $M(n) = O(n \log n)$
81    ///
82    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
83    /// bits of the real and imaginary parts of `self` and `other`.
84    ///
85    /// # Panics
86    /// Panics if `other` is zero.
87    ///
88    /// # Examples
89    /// ```
90    /// use malachite_nz::gaussian_integer::GaussianInteger;
91    /// use std::str::FromStr;
92    ///
93    /// // (2+i)(3) + (-1) = 5+3i
94    /// let x = GaussianInteger::from_str("5+3i").unwrap();
95    /// let y = GaussianInteger::from_str("2+i").unwrap();
96    /// assert_eq!((x / &y).to_string(), "3");
97    /// ```
98    #[inline]
99    fn div(self, other: &Self) -> Self {
100        div_ref_ref(&self, other)
101    }
102}
103
104impl Div<GaussianInteger> for &GaussianInteger {
105    type Output = GaussianInteger;
106
107    /// Divides a [`GaussianInteger`] by another [`GaussianInteger`], taking the first by reference
108    /// and the second by value.
109    ///
110    /// The quotient is the Gaussian integer nearest to the exact quotient, with each part rounded
111    /// to the nearest integer and ties rounded up. The quotient and remainder (which is not
112    /// computed) satisfy $x = qy + r$ and $N(r) \leq N(y) / 2$, where $N$ is the norm. To get both
113    /// at once, use [`div_rem`](malachite_base::num::arithmetic::traits::DivRem::div_rem).
114    ///
115    /// $$
116    /// f(x, y) = \left \lfloor \frac{x \bar{y}}{N(y)} + \frac{1 + i}{2} \right \rfloor,
117    /// $$
118    /// where the floor is taken on each part.
119    ///
120    /// # Worst-case complexity
121    /// $T(n) = O(n \log n \log\log n)$
122    ///
123    /// $M(n) = O(n \log n)$
124    ///
125    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
126    /// bits of the real and imaginary parts of `self` and `other`.
127    ///
128    /// # Panics
129    /// Panics if `other` is zero.
130    ///
131    /// # Examples
132    /// ```
133    /// use malachite_nz::gaussian_integer::GaussianInteger;
134    /// use std::str::FromStr;
135    ///
136    /// // (2+i)(3) + (-1) = 5+3i
137    /// let x = GaussianInteger::from_str("5+3i").unwrap();
138    /// let y = GaussianInteger::from_str("2+i").unwrap();
139    /// assert_eq!((&x / y).to_string(), "3");
140    /// ```
141    #[inline]
142    fn div(self, other: GaussianInteger) -> GaussianInteger {
143        div_ref_ref(self, &other)
144    }
145}
146
147impl Div<&GaussianInteger> for &GaussianInteger {
148    type Output = GaussianInteger;
149
150    /// Divides a [`GaussianInteger`] by another [`GaussianInteger`], taking both by reference.
151    ///
152    /// The quotient is the Gaussian integer nearest to the exact quotient, with each part rounded
153    /// to the nearest integer and ties rounded up. The quotient and remainder (which is not
154    /// computed) satisfy $x = qy + r$ and $N(r) \leq N(y) / 2$, where $N$ is the norm. To get both
155    /// at once, use [`div_rem`](malachite_base::num::arithmetic::traits::DivRem::div_rem).
156    ///
157    /// $$
158    /// f(x, y) = \left \lfloor \frac{x \bar{y}}{N(y)} + \frac{1 + i}{2} \right \rfloor,
159    /// $$
160    /// where the floor is taken on each part.
161    ///
162    /// # Worst-case complexity
163    /// $T(n) = O(n \log n \log\log n)$
164    ///
165    /// $M(n) = O(n \log n)$
166    ///
167    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
168    /// bits of the real and imaginary parts of `self` and `other`.
169    ///
170    /// # Panics
171    /// Panics if `other` is zero.
172    ///
173    /// # Examples
174    /// ```
175    /// use malachite_nz::gaussian_integer::GaussianInteger;
176    /// use std::str::FromStr;
177    ///
178    /// // (2+i)(3) + (-1) = 5+3i
179    /// let x = GaussianInteger::from_str("5+3i").unwrap();
180    /// let y = GaussianInteger::from_str("2+i").unwrap();
181    /// assert_eq!((&x / &y).to_string(), "3");
182    /// ```
183    #[inline]
184    fn div(self, other: &GaussianInteger) -> GaussianInteger {
185        div_ref_ref(self, other)
186    }
187}
188
189impl DivAssign<Self> for GaussianInteger {
190    /// Divides a [`GaussianInteger`] by another [`GaussianInteger`] in place, taking the
191    /// [`GaussianInteger`] on the right-hand side by value.
192    ///
193    /// The quotient is the Gaussian integer nearest to the exact quotient, with each part rounded
194    /// to the nearest integer and ties rounded up. The quotient and remainder (which is not
195    /// computed) satisfy $x = qy + r$ and $N(r) \leq N(y) / 2$, where $N$ is the norm. To get both
196    /// at once, use [`div_rem`](malachite_base::num::arithmetic::traits::DivRem::div_rem).
197    ///
198    /// $$
199    /// x \gets \left \lfloor \frac{x \bar{y}}{N(y)} + \frac{1 + i}{2} \right \rfloor,
200    /// $$
201    /// where the floor is taken on each part.
202    ///
203    /// # Worst-case complexity
204    /// $T(n) = O(n \log n \log\log n)$
205    ///
206    /// $M(n) = O(n \log n)$
207    ///
208    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
209    /// bits of the real and imaginary parts of `self` and `other`.
210    ///
211    /// # Panics
212    /// Panics if `other` is zero.
213    ///
214    /// # Examples
215    /// ```
216    /// use malachite_nz::gaussian_integer::GaussianInteger;
217    /// use std::str::FromStr;
218    ///
219    /// // (2+i)(3) + (-1) = 5+3i
220    /// let mut x = GaussianInteger::from_str("5+3i").unwrap();
221    /// x /= GaussianInteger::from_str("2+i").unwrap();
222    /// assert_eq!(x.to_string(), "3");
223    /// ```
224    #[inline]
225    fn div_assign(&mut self, other: Self) {
226        *self = div_ref_ref(&*self, &other);
227    }
228}
229
230impl DivAssign<&Self> for GaussianInteger {
231    /// Divides a [`GaussianInteger`] by another [`GaussianInteger`] in place, taking the
232    /// [`GaussianInteger`] on the right-hand side by reference.
233    ///
234    /// The quotient is the Gaussian integer nearest to the exact quotient, with each part rounded
235    /// to the nearest integer and ties rounded up. The quotient and remainder (which is not
236    /// computed) satisfy $x = qy + r$ and $N(r) \leq N(y) / 2$, where $N$ is the norm. To get both
237    /// at once, use [`div_rem`](malachite_base::num::arithmetic::traits::DivRem::div_rem).
238    ///
239    /// $$
240    /// x \gets \left \lfloor \frac{x \bar{y}}{N(y)} + \frac{1 + i}{2} \right \rfloor,
241    /// $$
242    /// where the floor is taken on each part.
243    ///
244    /// # Worst-case complexity
245    /// $T(n) = O(n \log n \log\log n)$
246    ///
247    /// $M(n) = O(n \log n)$
248    ///
249    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
250    /// bits of the real and imaginary parts of `self` and `other`.
251    ///
252    /// # Panics
253    /// Panics if `other` is zero.
254    ///
255    /// # Examples
256    /// ```
257    /// use malachite_nz::gaussian_integer::GaussianInteger;
258    /// use std::str::FromStr;
259    ///
260    /// // (2+i)(3) + (-1) = 5+3i
261    /// let mut x = GaussianInteger::from_str("5+3i").unwrap();
262    /// x /= &GaussianInteger::from_str("2+i").unwrap();
263    /// assert_eq!(x.to_string(), "3");
264    /// ```
265    #[inline]
266    fn div_assign(&mut self, other: &Self) {
267        *self = div_ref_ref(&*self, other);
268    }
269}
270
271impl CheckedDiv<Self> for GaussianInteger {
272    type Output = Self;
273
274    /// Divides a [`GaussianInteger`] by another [`GaussianInteger`], taking both by value. Returns
275    /// `None` when the second [`GaussianInteger`] is zero.
276    ///
277    /// The quotient is the Gaussian integer nearest to the exact quotient, with each part rounded
278    /// to the nearest integer and ties rounded up. The quotient and remainder (which is not
279    /// computed) satisfy $x = qy + r$ and $N(r) \leq N(y) / 2$, where $N$ is the norm. To get both
280    /// at once, use [`div_rem`](malachite_base::num::arithmetic::traits::DivRem::div_rem).
281    ///
282    /// $$
283    /// f(x, y) = \left \lfloor \frac{x \bar{y}}{N(y)} + \frac{1 + i}{2} \right \rfloor,
284    /// $$
285    /// where the floor is taken on each part.
286    ///
287    /// # Worst-case complexity
288    /// $T(n) = O(n \log n \log\log n)$
289    ///
290    /// $M(n) = O(n \log n)$
291    ///
292    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
293    /// bits of the real and imaginary parts of `self` and `other`.
294    ///
295    /// # Examples
296    /// ```
297    /// use malachite_base::num::arithmetic::traits::CheckedDiv;
298    /// use malachite_base::num::basic::traits::Zero;
299    /// use malachite_nz::gaussian_integer::GaussianInteger;
300    /// use std::str::FromStr;
301    ///
302    /// // (2+i)(3) + (-1) = 5+3i
303    /// let x = GaussianInteger::from_str("5+3i").unwrap();
304    /// let y = GaussianInteger::from_str("2+i").unwrap();
305    /// assert_eq!((x.clone().checked_div(y)).unwrap().to_string(), "3");
306    /// assert_eq!((x.clone().checked_div(GaussianInteger::ZERO)), None);
307    /// ```
308    #[inline]
309    fn checked_div(self, other: Self) -> Option<Self> {
310        if other.real == 0u32 && other.imaginary == 0u32 {
311            None
312        } else {
313            Some(self / other)
314        }
315    }
316}
317
318impl CheckedDiv<&Self> for GaussianInteger {
319    type Output = Self;
320
321    /// Divides a [`GaussianInteger`] by another [`GaussianInteger`], taking the first by value and
322    /// the second by reference. Returns `None` when the second [`GaussianInteger`] is zero.
323    ///
324    /// The quotient is the Gaussian integer nearest to the exact quotient, with each part rounded
325    /// to the nearest integer and ties rounded up. The quotient and remainder (which is not
326    /// computed) satisfy $x = qy + r$ and $N(r) \leq N(y) / 2$, where $N$ is the norm. To get both
327    /// at once, use [`div_rem`](malachite_base::num::arithmetic::traits::DivRem::div_rem).
328    ///
329    /// $$
330    /// f(x, y) = \left \lfloor \frac{x \bar{y}}{N(y)} + \frac{1 + i}{2} \right \rfloor,
331    /// $$
332    /// where the floor is taken on each part.
333    ///
334    /// # Worst-case complexity
335    /// $T(n) = O(n \log n \log\log n)$
336    ///
337    /// $M(n) = O(n \log n)$
338    ///
339    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
340    /// bits of the real and imaginary parts of `self` and `other`.
341    ///
342    /// # Examples
343    /// ```
344    /// use malachite_base::num::arithmetic::traits::CheckedDiv;
345    /// use malachite_base::num::basic::traits::Zero;
346    /// use malachite_nz::gaussian_integer::GaussianInteger;
347    /// use std::str::FromStr;
348    ///
349    /// // (2+i)(3) + (-1) = 5+3i
350    /// let x = GaussianInteger::from_str("5+3i").unwrap();
351    /// let y = GaussianInteger::from_str("2+i").unwrap();
352    /// assert_eq!((x.clone().checked_div(&y)).unwrap().to_string(), "3");
353    /// assert_eq!((x.clone().checked_div(&GaussianInteger::ZERO)), None);
354    /// ```
355    #[inline]
356    fn checked_div(self, other: &Self) -> Option<Self> {
357        if other.real == 0u32 && other.imaginary == 0u32 {
358            None
359        } else {
360            Some(self / other)
361        }
362    }
363}
364
365impl CheckedDiv<GaussianInteger> for &GaussianInteger {
366    type Output = GaussianInteger;
367
368    /// Divides a [`GaussianInteger`] by another [`GaussianInteger`], taking the first by reference
369    /// and the second by value. Returns `None` when the second [`GaussianInteger`] is zero.
370    ///
371    /// The quotient is the Gaussian integer nearest to the exact quotient, with each part rounded
372    /// to the nearest integer and ties rounded up. The quotient and remainder (which is not
373    /// computed) satisfy $x = qy + r$ and $N(r) \leq N(y) / 2$, where $N$ is the norm. To get both
374    /// at once, use [`div_rem`](malachite_base::num::arithmetic::traits::DivRem::div_rem).
375    ///
376    /// $$
377    /// f(x, y) = \left \lfloor \frac{x \bar{y}}{N(y)} + \frac{1 + i}{2} \right \rfloor,
378    /// $$
379    /// where the floor is taken on each part.
380    ///
381    /// # Worst-case complexity
382    /// $T(n) = O(n \log n \log\log n)$
383    ///
384    /// $M(n) = O(n \log n)$
385    ///
386    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
387    /// bits of the real and imaginary parts of `self` and `other`.
388    ///
389    /// # Examples
390    /// ```
391    /// use malachite_base::num::arithmetic::traits::CheckedDiv;
392    /// use malachite_base::num::basic::traits::Zero;
393    /// use malachite_nz::gaussian_integer::GaussianInteger;
394    /// use std::str::FromStr;
395    ///
396    /// // (2+i)(3) + (-1) = 5+3i
397    /// let x = GaussianInteger::from_str("5+3i").unwrap();
398    /// let y = GaussianInteger::from_str("2+i").unwrap();
399    /// assert_eq!(((&x).checked_div(y)).unwrap().to_string(), "3");
400    /// assert_eq!(((&x).checked_div(GaussianInteger::ZERO)), None);
401    /// ```
402    #[inline]
403    fn checked_div(self, other: GaussianInteger) -> Option<GaussianInteger> {
404        if other.real == 0u32 && other.imaginary == 0u32 {
405            None
406        } else {
407            Some(self / other)
408        }
409    }
410}
411
412impl CheckedDiv<&GaussianInteger> for &GaussianInteger {
413    type Output = GaussianInteger;
414
415    /// Divides a [`GaussianInteger`] by another [`GaussianInteger`], taking both by reference.
416    /// Returns `None` when the second [`GaussianInteger`] is zero.
417    ///
418    /// The quotient is the Gaussian integer nearest to the exact quotient, with each part rounded
419    /// to the nearest integer and ties rounded up. The quotient and remainder (which is not
420    /// computed) satisfy $x = qy + r$ and $N(r) \leq N(y) / 2$, where $N$ is the norm. To get both
421    /// at once, use [`div_rem`](malachite_base::num::arithmetic::traits::DivRem::div_rem).
422    ///
423    /// $$
424    /// f(x, y) = \left \lfloor \frac{x \bar{y}}{N(y)} + \frac{1 + i}{2} \right \rfloor,
425    /// $$
426    /// where the floor is taken on each part.
427    ///
428    /// # Worst-case complexity
429    /// $T(n) = O(n \log n \log\log n)$
430    ///
431    /// $M(n) = O(n \log n)$
432    ///
433    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
434    /// bits of the real and imaginary parts of `self` and `other`.
435    ///
436    /// # Examples
437    /// ```
438    /// use malachite_base::num::arithmetic::traits::CheckedDiv;
439    /// use malachite_base::num::basic::traits::Zero;
440    /// use malachite_nz::gaussian_integer::GaussianInteger;
441    /// use std::str::FromStr;
442    ///
443    /// // (2+i)(3) + (-1) = 5+3i
444    /// let x = GaussianInteger::from_str("5+3i").unwrap();
445    /// let y = GaussianInteger::from_str("2+i").unwrap();
446    /// assert_eq!(((&x).checked_div(&y)).unwrap().to_string(), "3");
447    /// assert_eq!(((&x).checked_div(&GaussianInteger::ZERO)), None);
448    /// ```
449    #[inline]
450    fn checked_div(self, other: &GaussianInteger) -> Option<GaussianInteger> {
451        if other.real == 0u32 && other.imaginary == 0u32 {
452            None
453        } else {
454            Some(self / other)
455        }
456    }
457}