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}