Skip to main content

malachite_base/unsigned_vector/arithmetic/
div_exact.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::num::arithmetic::traits::{DivExact, DivExactAssign};
10use crate::num::basic::unsigneds::PrimitiveUnsigned;
11use crate::unsigned_vector::UnsignedVector;
12
13impl<T: PrimitiveUnsigned> DivExact<T> for UnsignedVector<T> {
14    type Output = Self;
15
16    /// Divides every element of an [`UnsignedVector`] by a `T`, taking it by value. Every element
17    /// must be exactly divisible by the `T`.
18    ///
19    /// If some element is not exactly divisible by `c`, this function may panic or return a
20    /// meaningless result. Dividing by 1 returns the vector unchanged.
21    ///
22    /// $f(v, c) = v/c$.
23    ///
24    /// # Worst-case complexity
25    /// $T(n) = O(n)$
26    ///
27    /// $M(n) = O(1)$
28    ///
29    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
30    ///
31    /// # Panics
32    /// Panics if `c` is zero.
33    ///
34    /// # Examples
35    /// See [here](super::div_exact#div_exact).
36    #[inline]
37    fn div_exact(mut self, c: T) -> Self {
38        self.div_exact_assign(c);
39        self
40    }
41}
42
43impl<T: PrimitiveUnsigned> DivExact<T> for &UnsignedVector<T> {
44    type Output = UnsignedVector<T>;
45
46    /// Divides every element of an [`UnsignedVector`] by a `T`, taking it by reference. Every
47    /// element must be exactly divisible by the `T`.
48    ///
49    /// If some element is not exactly divisible by `c`, this function may panic or return a
50    /// meaningless result. Dividing by 1 returns the vector unchanged.
51    ///
52    /// $f(v, c) = v/c$.
53    ///
54    /// # Worst-case complexity
55    /// $T(n) = O(n)$
56    ///
57    /// $M(n) = O(n)$
58    ///
59    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
60    ///
61    /// # Panics
62    /// Panics if `c` is zero.
63    ///
64    /// # Examples
65    /// See [here](super::div_exact#div_exact).
66    fn div_exact(self, c: T) -> UnsignedVector<T> {
67        assert!(c != T::ZERO, "division by zero");
68        UnsignedVector {
69            elements: if c == T::ONE {
70                self.elements.clone()
71            } else {
72                self.elements.iter().map(|&x| x.div_exact(c)).collect()
73            },
74        }
75    }
76}
77
78impl<T: PrimitiveUnsigned> DivExactAssign<T> for UnsignedVector<T> {
79    /// Divides every element of an [`UnsignedVector`] by a `T`, in place. Every element must be
80    /// exactly divisible by the `T`.
81    ///
82    /// If some element is not exactly divisible by `c`, this function may panic or return a
83    /// meaningless result. Dividing by 1 returns the vector unchanged.
84    ///
85    /// $v \gets v/c$.
86    ///
87    /// # Worst-case complexity
88    /// $T(n) = O(n)$
89    ///
90    /// $M(n) = O(1)$
91    ///
92    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
93    ///
94    /// # Panics
95    /// Panics if `c` is zero.
96    ///
97    /// # Examples
98    /// See [here](super::div_exact#div_exact_assign).
99    fn div_exact_assign(&mut self, c: T) {
100        assert!(c != T::ZERO, "division by zero");
101        if c != T::ONE {
102            for x in &mut self.elements {
103                x.div_exact_assign(c);
104            }
105        }
106    }
107}