Skip to main content

malachite_nz/integer_polynomial/arithmetic/
mod_op.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::integer::Integer;
10use crate::integer_polynomial::IntegerPolynomial;
11use crate::natural::Natural;
12use crate::natural_polynomial::NaturalPolynomial;
13use alloc::vec::Vec;
14use core::ops::{Rem, RemAssign};
15use malachite_base::num::arithmetic::traits::{Mod, NegMod};
16use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
17use malachite_base::num::conversion::traits::ExactFrom;
18use malachite_base::polynomial::Polynomial;
19use malachite_base::unsigned_polynomial::UnsignedPolynomial;
20
21impl Mod<Natural> for IntegerPolynomial {
22    type Output = NaturalPolynomial;
23
24    /// Divides every coefficient of an [`IntegerPolynomial`] by a [`Natural`], keeping the
25    /// remainders as a [`NaturalPolynomial`], taking the polynomial by value and the modulus by
26    /// value.
27    ///
28    /// Each remainder is taken in $[0, m)$, the way [`Mod`] does for [`Integer`]s, so a negative
29    /// coefficient $c$ that is not a multiple of $m$ becomes $m - (-c \bmod m)$. The result is
30    /// therefore reduced modulo $m$, which is to say that
31    /// [`mod_is_reduced`](malachite_base::num::arithmetic::traits::ModIsReduced::mod_is_reduced)
32    /// returns `true` for it, and every coefficient of the result is congruent to the corresponding
33    /// coefficient of the input.
34    ///
35    /// Reducing can lower the degree, and can even give the zero polynomial: a leading coefficient
36    /// that is a multiple of $m$ becomes zero, and a polynomial does not hold trailing zero
37    /// coefficients. So $-6x^2 + 3x - 1$ modulo $3$ is the constant $2$.
38    ///
39    /// $$
40    /// f(p, m) = q, \quad \text{where} \quad q_i = p_i - m \left \lfloor \frac{p_i}{m}
41    /// \right \rfloor.
42    /// $$
43    ///
44    /// # Worst-case complexity
45    /// $T(n) = O(n \log n \log\log n)$
46    ///
47    /// $M(n) = O(n \log n)$
48    ///
49    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
50    /// polynomial's coefficients.
51    ///
52    /// # Panics
53    /// Panics if `m` is zero.
54    ///
55    /// # Examples
56    /// ```
57    /// use core::str::FromStr;
58    /// use malachite_base::num::arithmetic::traits::Mod;
59    /// use malachite_nz::integer_polynomial::IntegerPolynomial;
60    /// use malachite_nz::natural::Natural;
61    ///
62    /// // Every coefficient is taken modulo 3, and negative ones become non-negative.
63    /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
64    /// assert_eq!(
65    ///     p.clone().mod_op(Natural::from(3u32)).to_string(),
66    ///     "x^2+2*x+1"
67    /// );
68    ///
69    /// // Reducing the leading coefficient to zero lowers the degree.
70    /// let p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
71    /// assert_eq!(p.clone().mod_op(Natural::from(3u32)).to_string(), "2");
72    /// ```
73    #[inline]
74    fn mod_op(self, m: Natural) -> NaturalPolynomial {
75        self.mod_op(&m)
76    }
77}
78
79impl<'a> Mod<&'a Natural> for IntegerPolynomial {
80    type Output = NaturalPolynomial;
81
82    /// Divides every coefficient of an [`IntegerPolynomial`] by a [`Natural`], keeping the
83    /// remainders as a [`NaturalPolynomial`], taking the polynomial by value and the modulus by
84    /// reference.
85    ///
86    /// See the documentation for the [`Mod`] implementation on [`IntegerPolynomial`] that takes
87    /// both arguments by value for details, including how negative coefficients are handled and how
88    /// reducing can lower the degree.
89    ///
90    /// # Worst-case complexity
91    /// $T(n) = O(n \log n \log\log n)$
92    ///
93    /// $M(n) = O(n \log n)$
94    ///
95    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
96    /// polynomial's coefficients.
97    ///
98    /// # Panics
99    /// Panics if `m` is zero.
100    ///
101    /// # Examples
102    /// ```
103    /// use core::str::FromStr;
104    /// use malachite_base::num::arithmetic::traits::Mod;
105    /// use malachite_nz::integer_polynomial::IntegerPolynomial;
106    /// use malachite_nz::natural::Natural;
107    ///
108    /// // Every coefficient is taken modulo 3, and negative ones become non-negative.
109    /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
110    /// assert_eq!(
111    ///     p.clone().mod_op(&Natural::from(3u32)).to_string(),
112    ///     "x^2+2*x+1"
113    /// );
114    ///
115    /// // Reducing the leading coefficient to zero lowers the degree.
116    /// let p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
117    /// assert_eq!(p.clone().mod_op(&Natural::from(3u32)).to_string(), "2");
118    /// ```
119    fn mod_op(self, m: &'a Natural) -> NaturalPolynomial {
120        assert_ne!(*m, 0u32, "division by zero");
121        NaturalPolynomial::from_coefficients_asc(
122            self.coefficients
123                .into_iter()
124                .map(|Integer { sign, abs }| if sign { abs % m } else { abs.neg_mod(m) })
125                .collect::<Vec<_>>(),
126        )
127    }
128}
129
130impl Mod<Natural> for &IntegerPolynomial {
131    type Output = NaturalPolynomial;
132
133    /// Divides every coefficient of an [`IntegerPolynomial`] by a [`Natural`], keeping the
134    /// remainders as a [`NaturalPolynomial`], taking the polynomial by reference and the modulus by
135    /// value.
136    ///
137    /// See the documentation for the [`Mod`] implementation on [`IntegerPolynomial`] that takes
138    /// both arguments by value for details, including how negative coefficients are handled and how
139    /// reducing can lower the degree.
140    ///
141    /// # Worst-case complexity
142    /// $T(n) = O(n \log n \log\log n)$
143    ///
144    /// $M(n) = O(n \log n)$
145    ///
146    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
147    /// polynomial's coefficients.
148    ///
149    /// # Panics
150    /// Panics if `m` is zero.
151    ///
152    /// # Examples
153    /// ```
154    /// use core::str::FromStr;
155    /// use malachite_base::num::arithmetic::traits::Mod;
156    /// use malachite_nz::integer_polynomial::IntegerPolynomial;
157    /// use malachite_nz::natural::Natural;
158    ///
159    /// // Every coefficient is taken modulo 3, and negative ones become non-negative.
160    /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
161    /// assert_eq!((&p).mod_op(Natural::from(3u32)).to_string(), "x^2+2*x+1");
162    ///
163    /// // Reducing the leading coefficient to zero lowers the degree.
164    /// let p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
165    /// assert_eq!((&p).mod_op(Natural::from(3u32)).to_string(), "2");
166    /// ```
167    #[inline]
168    fn mod_op(self, m: Natural) -> NaturalPolynomial {
169        self.mod_op(&m)
170    }
171}
172
173impl<'a> Mod<&'a Natural> for &IntegerPolynomial {
174    type Output = NaturalPolynomial;
175
176    /// Divides every coefficient of an [`IntegerPolynomial`] by a [`Natural`], keeping the
177    /// remainders as a [`NaturalPolynomial`], taking the polynomial by reference and the modulus by
178    /// reference.
179    ///
180    /// See the documentation for the [`Mod`] implementation on [`IntegerPolynomial`] that takes
181    /// both arguments by value for details, including how negative coefficients are handled and how
182    /// reducing can lower the degree.
183    ///
184    /// # Worst-case complexity
185    /// $T(n) = O(n \log n \log\log n)$
186    ///
187    /// $M(n) = O(n \log n)$
188    ///
189    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
190    /// polynomial's coefficients.
191    ///
192    /// # Panics
193    /// Panics if `m` is zero.
194    ///
195    /// # Examples
196    /// ```
197    /// use core::str::FromStr;
198    /// use malachite_base::num::arithmetic::traits::Mod;
199    /// use malachite_nz::integer_polynomial::IntegerPolynomial;
200    /// use malachite_nz::natural::Natural;
201    ///
202    /// // Every coefficient is taken modulo 3, and negative ones become non-negative.
203    /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
204    /// assert_eq!((&p).mod_op(&Natural::from(3u32)).to_string(), "x^2+2*x+1");
205    ///
206    /// // Reducing the leading coefficient to zero lowers the degree.
207    /// let p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
208    /// assert_eq!((&p).mod_op(&Natural::from(3u32)).to_string(), "2");
209    /// ```
210    fn mod_op(self, m: &'a Natural) -> NaturalPolynomial {
211        assert_ne!(*m, 0u32, "division by zero");
212        // `from_coefficients_asc` trims, which is what makes the degree fall when the leading
213        // coefficient reduces to zero.
214        NaturalPolynomial::from_coefficients_asc(
215            self.coefficients
216                .iter()
217                .map(|c| {
218                    if c.sign {
219                        &c.abs % m
220                    } else {
221                        (&c.abs).neg_mod(m)
222                    }
223                })
224                .collect::<Vec<_>>(),
225        )
226    }
227}
228
229impl<T: PrimitiveUnsigned + for<'a> ExactFrom<&'a Natural>> Mod<T> for &IntegerPolynomial
230where
231    Natural: From<T>,
232{
233    type Output = UnsignedPolynomial<T>;
234
235    /// Divides every coefficient of an [`IntegerPolynomial`] by a value of an unsigned primitive
236    /// integer type, keeping the remainders as an [`UnsignedPolynomial`] with that coefficient
237    /// type, taking the polynomial by reference.
238    ///
239    /// Each remainder is taken in $[0, m)$, so negative coefficients become non-negative, and every
240    /// remainder fits in `m`'s type. Apart from the result's type, this is the same operation as
241    /// reducing modulo `Natural::from(m)`; see the documentation for the [`Mod`] implementation on
242    /// [`IntegerPolynomial`] that takes both arguments by value for details, including how reducing
243    /// can lower the degree.
244    ///
245    /// The result is reduced modulo $m$, which is to say that
246    /// [`mod_is_reduced`](malachite_base::num::arithmetic::traits::ModIsReduced::mod_is_reduced)
247    /// returns `true` for it.
248    ///
249    /// # Worst-case complexity
250    /// $T(n) = O(n)$
251    ///
252    /// $M(n) = O(m)$
253    ///
254    /// where $T$ is time, $M$ is additional memory, $n$ is the total number of bits in the
255    /// polynomial's coefficients, and $m$ is the number of coefficients.
256    ///
257    /// # Panics
258    /// Panics if `m` is zero.
259    ///
260    /// # Examples
261    /// ```
262    /// use core::str::FromStr;
263    /// use malachite_base::num::arithmetic::traits::Mod;
264    /// use malachite_base::unsigned_polynomial::UnsignedPolynomial;
265    /// use malachite_nz::integer_polynomial::IntegerPolynomial;
266    ///
267    /// let p = IntegerPolynomial::from_str("-1000000000001*x^2+2000000000003*x-5").unwrap();
268    /// let q: UnsignedPolynomial<u8> = (&p).mod_op(7u8);
269    /// assert_eq!(q.to_string(), "5*x^2+5*x+2");
270    ///
271    /// // Reducing the leading coefficient to zero lowers the degree.
272    /// let p = IntegerPolynomial::from_str("-1024*x^2-3").unwrap();
273    /// assert_eq!((&p).mod_op(4u64).to_string(), "1");
274    /// ```
275    fn mod_op(self, m: T) -> UnsignedPolynomial<T> {
276        assert_ne!(m, T::ZERO, "division by zero");
277        let m = Natural::from(m);
278        // `from_coefficients_asc` trims, which is what makes the degree fall when the leading
279        // coefficient reduces to zero.
280        UnsignedPolynomial::from_coefficients_asc(
281            self.coefficients
282                .iter()
283                .map(|c| {
284                    T::exact_from(&if c.sign {
285                        &c.abs % &m
286                    } else {
287                        (&c.abs).neg_mod(&m)
288                    })
289                })
290                .collect::<Vec<_>>(),
291        )
292    }
293}
294
295impl<T: PrimitiveUnsigned + for<'a> ExactFrom<&'a Natural>> Mod<T> for IntegerPolynomial
296where
297    Natural: From<T>,
298{
299    type Output = UnsignedPolynomial<T>;
300
301    /// Divides every coefficient of an [`IntegerPolynomial`] by a value of an unsigned primitive
302    /// integer type, keeping the remainders as an [`UnsignedPolynomial`] with that coefficient
303    /// type, taking the polynomial by value.
304    ///
305    /// Taking the polynomial by value saves nothing, since the remainders go into new storage
306    /// either way. See the documentation for the [`Mod`] implementation that takes the polynomial
307    /// by reference for details.
308    ///
309    /// # Worst-case complexity
310    /// $T(n) = O(n)$
311    ///
312    /// $M(n) = O(m)$
313    ///
314    /// where $T$ is time, $M$ is additional memory, $n$ is the total number of bits in the
315    /// polynomial's coefficients, and $m$ is the number of coefficients.
316    ///
317    /// # Panics
318    /// Panics if `m` is zero.
319    ///
320    /// # Examples
321    /// ```
322    /// use core::str::FromStr;
323    /// use malachite_base::num::arithmetic::traits::Mod;
324    /// use malachite_nz::integer_polynomial::IntegerPolynomial;
325    ///
326    /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
327    /// assert_eq!(p.mod_op(3u32).to_string(), "x^2+2*x+1");
328    /// ```
329    #[inline]
330    fn mod_op(self, m: T) -> UnsignedPolynomial<T> {
331        (&self).mod_op(m)
332    }
333}
334
335impl Rem<Integer> for IntegerPolynomial {
336    type Output = Self;
337
338    /// Divides every coefficient of an [`IntegerPolynomial`] by an [`Integer`], keeping the
339    /// remainders, taking the polynomial by value and the modulus by value.
340    ///
341    /// Each remainder has the sign of its coefficient and a smaller absolute value than $m$, as
342    /// with [`Rem`] for [`Integer`]s, so the sign of $m$ makes no difference. This is the remainder
343    /// of truncating division: with the coefficient-wise quotient $q_i = \operatorname{
344    /// sgn}(p_im)\lfloor |p_i/m| \rfloor$, $p = mq + r$ holds exactly. For a remainder that is
345    /// always non-negative, and a [`NaturalPolynomial`] result, use [`Mod`].
346    ///
347    /// Reducing can lower the degree, and can even give the zero polynomial: a leading coefficient
348    /// that is a multiple of $m$ becomes zero, and a polynomial does not hold trailing zero
349    /// coefficients. So $-6x^2 + 3x - 1$ modulo $3$ is the constant $-1$.
350    ///
351    /// $$
352    /// f(p, m) = r, \quad \text{where} \quad r_i = p_i - m \operatorname{sgn}(p_im)
353    ///     \left \lfloor \left | \frac{p_i}{m} \right | \right \rfloor.
354    /// $$
355    ///
356    /// # Worst-case complexity
357    /// $T(n) = O(n \log n \log\log n)$
358    ///
359    /// $M(n) = O(n \log n)$
360    ///
361    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
362    /// polynomial's coefficients.
363    ///
364    /// # Panics
365    /// Panics if `m` is zero.
366    ///
367    /// # Examples
368    /// ```
369    /// use core::str::FromStr;
370    /// use malachite_nz::integer::Integer;
371    /// use malachite_nz::integer_polynomial::IntegerPolynomial;
372    ///
373    /// // Every coefficient is taken modulo 3, keeping its sign.
374    /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
375    /// assert_eq!((p.clone() % Integer::from(3)).to_string(), "x^2-x-2");
376    ///
377    /// // The sign of the modulus makes no difference, and reducing the leading coefficient to zero
378    /// // lowers the degree.
379    /// let p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
380    /// assert_eq!((p % Integer::from(-3)).to_string(), "-1");
381    /// ```
382    #[inline]
383    fn rem(mut self, m: Integer) -> Self {
384        self %= m;
385        self
386    }
387}
388
389impl<'a> Rem<&'a Integer> for IntegerPolynomial {
390    type Output = Self;
391
392    /// Divides every coefficient of an [`IntegerPolynomial`] by an [`Integer`], keeping the
393    /// remainders, taking the polynomial by value and the modulus by reference.
394    ///
395    /// See the documentation for the [`Rem`] implementation on [`IntegerPolynomial`] that takes
396    /// both arguments by value for details, including the signs of the remainders and how reducing
397    /// can lower the degree.
398    ///
399    /// # Worst-case complexity
400    /// $T(n) = O(n \log n \log\log n)$
401    ///
402    /// $M(n) = O(n \log n)$
403    ///
404    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
405    /// polynomial's coefficients.
406    ///
407    /// # Panics
408    /// Panics if `m` is zero.
409    ///
410    /// # Examples
411    /// ```
412    /// use core::str::FromStr;
413    /// use malachite_nz::integer::Integer;
414    /// use malachite_nz::integer_polynomial::IntegerPolynomial;
415    ///
416    /// // Every coefficient is taken modulo 3, keeping its sign.
417    /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
418    /// assert_eq!((p.clone() % &Integer::from(3)).to_string(), "x^2-x-2");
419    ///
420    /// // The sign of the modulus makes no difference, and reducing the leading coefficient to zero
421    /// // lowers the degree.
422    /// let p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
423    /// assert_eq!((p % &Integer::from(-3)).to_string(), "-1");
424    /// ```
425    #[inline]
426    fn rem(mut self, m: &'a Integer) -> Self {
427        self %= m;
428        self
429    }
430}
431
432impl Rem<Integer> for &IntegerPolynomial {
433    type Output = IntegerPolynomial;
434
435    /// Divides every coefficient of an [`IntegerPolynomial`] by an [`Integer`], keeping the
436    /// remainders, taking the polynomial by reference and the modulus by value.
437    ///
438    /// See the documentation for the [`Rem`] implementation on [`IntegerPolynomial`] that takes
439    /// both arguments by value for details, including the signs of the remainders and how reducing
440    /// can lower the degree.
441    ///
442    /// # Worst-case complexity
443    /// $T(n) = O(n \log n \log\log n)$
444    ///
445    /// $M(n) = O(n \log n)$
446    ///
447    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
448    /// polynomial's coefficients.
449    ///
450    /// # Panics
451    /// Panics if `m` is zero.
452    ///
453    /// # Examples
454    /// ```
455    /// use core::str::FromStr;
456    /// use malachite_nz::integer::Integer;
457    /// use malachite_nz::integer_polynomial::IntegerPolynomial;
458    ///
459    /// // Every coefficient is taken modulo 3, keeping its sign.
460    /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
461    /// assert_eq!((&p % Integer::from(3)).to_string(), "x^2-x-2");
462    ///
463    /// // The sign of the modulus makes no difference, and reducing the leading coefficient to zero
464    /// // lowers the degree.
465    /// let p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
466    /// assert_eq!((&p % Integer::from(-3)).to_string(), "-1");
467    /// // The polynomial is left alone.
468    /// assert_eq!(p.to_string(), "-6*x^2+3*x-1");
469    /// ```
470    #[inline]
471    fn rem(self, m: Integer) -> IntegerPolynomial {
472        self % &m
473    }
474}
475
476impl<'a> Rem<&'a Integer> for &IntegerPolynomial {
477    type Output = IntegerPolynomial;
478
479    /// Divides every coefficient of an [`IntegerPolynomial`] by an [`Integer`], keeping the
480    /// remainders, taking the polynomial by reference and the modulus by reference.
481    ///
482    /// See the documentation for the [`Rem`] implementation on [`IntegerPolynomial`] that takes
483    /// both arguments by value for details, including the signs of the remainders and how reducing
484    /// can lower the degree.
485    ///
486    /// # Worst-case complexity
487    /// $T(n) = O(n \log n \log\log n)$
488    ///
489    /// $M(n) = O(n \log n)$
490    ///
491    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
492    /// polynomial's coefficients.
493    ///
494    /// # Panics
495    /// Panics if `m` is zero.
496    ///
497    /// # Examples
498    /// ```
499    /// use core::str::FromStr;
500    /// use malachite_nz::integer::Integer;
501    /// use malachite_nz::integer_polynomial::IntegerPolynomial;
502    ///
503    /// // Every coefficient is taken modulo 3, keeping its sign.
504    /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
505    /// assert_eq!((&p % &Integer::from(3)).to_string(), "x^2-x-2");
506    ///
507    /// // The sign of the modulus makes no difference, and reducing the leading coefficient to zero
508    /// // lowers the degree.
509    /// let p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
510    /// assert_eq!((&p % &Integer::from(-3)).to_string(), "-1");
511    /// // The polynomial is left alone.
512    /// assert_eq!(p.to_string(), "-6*x^2+3*x-1");
513    /// ```
514    fn rem(self, m: &'a Integer) -> IntegerPolynomial {
515        assert_ne!(*m, 0u32, "division by zero");
516        // `from_coefficients_asc` trims, which is what makes the degree fall when the leading
517        // coefficient reduces to zero.
518        IntegerPolynomial::from_coefficients_asc(
519            self.coefficients.iter().map(|c| c % m).collect::<Vec<_>>(),
520        )
521    }
522}
523
524impl RemAssign<Integer> for IntegerPolynomial {
525    /// Divides every coefficient of an [`IntegerPolynomial`] by an [`Integer`], replacing the
526    /// polynomial by the one whose coefficients are the remainders, taking the modulus by value.
527    ///
528    /// See the documentation for the [`Rem`] implementation on [`IntegerPolynomial`] that takes
529    /// both arguments by value for details, including the signs of the remainders and how reducing
530    /// can lower the degree.
531    ///
532    /// # Worst-case complexity
533    /// $T(n) = O(n \log n \log\log n)$
534    ///
535    /// $M(n) = O(n \log n)$
536    ///
537    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
538    /// polynomial's coefficients.
539    ///
540    /// # Panics
541    /// Panics if `m` is zero.
542    ///
543    /// # Examples
544    /// ```
545    /// use core::str::FromStr;
546    /// use malachite_nz::integer::Integer;
547    /// use malachite_nz::integer_polynomial::IntegerPolynomial;
548    ///
549    /// let mut p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
550    /// p %= Integer::from(3);
551    /// assert_eq!(p.to_string(), "x^2-x-2");
552    ///
553    /// let mut p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
554    /// p %= Integer::from(-3);
555    /// assert_eq!(p.to_string(), "-1");
556    /// ```
557    #[inline]
558    fn rem_assign(&mut self, m: Integer) {
559        *self %= &m;
560    }
561}
562
563impl<'a> RemAssign<&'a Integer> for IntegerPolynomial {
564    /// Divides every coefficient of an [`IntegerPolynomial`] by an [`Integer`], replacing the
565    /// polynomial by the one whose coefficients are the remainders, taking the modulus by
566    /// reference.
567    ///
568    /// See the documentation for the [`Rem`] implementation on [`IntegerPolynomial`] that takes
569    /// both arguments by value for details, including the signs of the remainders and how reducing
570    /// can lower the degree.
571    ///
572    /// # Worst-case complexity
573    /// $T(n) = O(n \log n \log\log n)$
574    ///
575    /// $M(n) = O(n \log n)$
576    ///
577    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
578    /// polynomial's coefficients.
579    ///
580    /// # Panics
581    /// Panics if `m` is zero.
582    ///
583    /// # Examples
584    /// ```
585    /// use core::str::FromStr;
586    /// use malachite_nz::integer::Integer;
587    /// use malachite_nz::integer_polynomial::IntegerPolynomial;
588    ///
589    /// let mut p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
590    /// p %= &Integer::from(3);
591    /// assert_eq!(p.to_string(), "x^2-x-2");
592    ///
593    /// let mut p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
594    /// p %= &Integer::from(-3);
595    /// assert_eq!(p.to_string(), "-1");
596    /// ```
597    fn rem_assign(&mut self, m: &'a Integer) {
598        assert_ne!(*m, 0u32, "division by zero");
599        for c in &mut self.coefficients {
600            *c %= m;
601        }
602        self.trim();
603    }
604}