malachite_nz/integer/arithmetic/
mod_power_of_2.rs

1// Copyright © 2025 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::natural::Natural;
11use malachite_base::num::arithmetic::traits::{
12    CeilingModPowerOf2, CeilingModPowerOf2Assign, ModPowerOf2, ModPowerOf2Assign, NegModPowerOf2,
13    NegModPowerOf2Assign, RemPowerOf2, RemPowerOf2Assign,
14};
15
16impl ModPowerOf2 for Integer {
17    type Output = Natural;
18
19    /// Divides an [`Integer`] by $2^k$, taking it by value and returning just the remainder. The
20    /// remainder is non-negative.
21    ///
22    /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and
23    /// $0 \leq r < 2^k$.
24    ///
25    /// $$
26    /// f(x, k) = x - 2^k\left \lfloor \frac{x}{2^k} \right \rfloor.
27    /// $$
28    ///
29    /// Unlike
30    /// [`rem_power_of_2`](malachite_base::num::arithmetic::traits::RemPowerOf2::rem_power_of_2),
31    /// this function always returns a non-negative number.
32    ///
33    /// # Worst-case complexity
34    /// $T(n) = O(n)$
35    ///
36    /// $M(n) = O(n)$
37    ///
38    /// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
39    ///
40    /// # Examples
41    /// ```
42    /// use malachite_base::num::arithmetic::traits::ModPowerOf2;
43    /// use malachite_nz::integer::Integer;
44    ///
45    /// // 1 * 2^8 + 4 = 260
46    /// assert_eq!(Integer::from(260).mod_power_of_2(8), 4);
47    ///
48    /// // -101 * 2^4 + 5 = -1611
49    /// assert_eq!(Integer::from(-1611).mod_power_of_2(4), 5);
50    /// ```
51    fn mod_power_of_2(self, pow: u64) -> Natural {
52        if self.sign {
53            self.abs.mod_power_of_2(pow)
54        } else {
55            self.abs.neg_mod_power_of_2(pow)
56        }
57    }
58}
59
60impl ModPowerOf2 for &Integer {
61    type Output = Natural;
62
63    /// Divides an [`Integer`] by $2^k$, taking it by reference and returning just the remainder.
64    /// The remainder is non-negative.
65    ///
66    /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and
67    /// $0 \leq r < 2^k$.
68    ///
69    /// $$
70    /// f(x, k) = x - 2^k\left \lfloor \frac{x}{2^k} \right \rfloor.
71    /// $$
72    ///
73    /// Unlike
74    /// [`rem_power_of_2`](malachite_base::num::arithmetic::traits::RemPowerOf2::rem_power_of_2),
75    /// this function always returns a non-negative number.
76    ///
77    /// # Worst-case complexity
78    /// $T(n) = O(n)$
79    ///
80    /// $M(n) = O(n)$
81    ///
82    /// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
83    ///
84    /// # Examples
85    /// ```
86    /// use malachite_base::num::arithmetic::traits::ModPowerOf2;
87    /// use malachite_nz::integer::Integer;
88    ///
89    /// // 1 * 2^8 + 4 = 260
90    /// assert_eq!((&Integer::from(260)).mod_power_of_2(8), 4);
91    /// // -101 * 2^4 + 5 = -1611
92    /// assert_eq!((&Integer::from(-1611)).mod_power_of_2(4), 5);
93    /// ```
94    fn mod_power_of_2(self, pow: u64) -> Natural {
95        if self.sign {
96            (&self.abs).mod_power_of_2(pow)
97        } else {
98            (&self.abs).neg_mod_power_of_2(pow)
99        }
100    }
101}
102
103impl ModPowerOf2Assign for Integer {
104    /// Divides an [`Integer`] by $2^k$, replacing the [`Integer`] by the remainder. The remainder
105    /// is non-negative.
106    ///
107    /// If the quotient were computed, he quotient and remainder would satisfy $x = q2^k + r$ and $0
108    /// \leq r < 2^k$.
109    ///
110    /// $$
111    /// x \gets x - 2^k\left \lfloor \frac{x}{2^k} \right \rfloor.
112    /// $$
113    ///
114    /// Unlike [`rem_power_of_2_assign`](RemPowerOf2Assign::rem_power_of_2_assign), this function
115    /// always assigns a non-negative number.
116    ///
117    /// # Worst-case complexity
118    /// $T(n) = O(n)$
119    ///
120    /// $M(n) = O(n)$
121    ///
122    /// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
123    ///
124    /// # Examples
125    /// ```
126    /// use malachite_base::num::arithmetic::traits::ModPowerOf2Assign;
127    /// use malachite_nz::integer::Integer;
128    ///
129    /// // 1 * 2^8 + 4 = 260
130    /// let mut x = Integer::from(260);
131    /// x.mod_power_of_2_assign(8);
132    /// assert_eq!(x, 4);
133    ///
134    /// // -101 * 2^4 + 5 = -1611
135    /// let mut x = Integer::from(-1611);
136    /// x.mod_power_of_2_assign(4);
137    /// assert_eq!(x, 5);
138    /// ```
139    fn mod_power_of_2_assign(&mut self, pow: u64) {
140        if self.sign {
141            self.abs.mod_power_of_2_assign(pow);
142        } else {
143            self.sign = true;
144            self.abs.neg_mod_power_of_2_assign(pow);
145        }
146    }
147}
148
149impl RemPowerOf2 for Integer {
150    type Output = Self;
151
152    /// Divides an [`Integer`] by $2^k$, taking it by value and returning just the remainder. The
153    /// remainder has the same sign as the first number.
154    ///
155    /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and
156    /// $0 \leq |r| < 2^k$.
157    ///
158    /// $$
159    /// f(x, k) = x - 2^k\operatorname{sgn}(x)\left \lfloor \frac{|x|}{2^k} \right \rfloor.
160    /// $$
161    ///
162    /// Unlike
163    /// [`mod_power_of_2`](malachite_base::num::arithmetic::traits::ModPowerOf2::mod_power_of_2),
164    /// this function always returns zero or a number with the same sign as `self`.
165    ///
166    /// # Worst-case complexity
167    /// $T(n) = O(n)$
168    ///
169    /// $M(n) = O(n)$
170    ///
171    /// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
172    ///
173    /// # Examples
174    /// ```
175    /// use malachite_base::num::arithmetic::traits::RemPowerOf2;
176    /// use malachite_nz::integer::Integer;
177    ///
178    /// // 1 * 2^8 + 4 = 260
179    /// assert_eq!(Integer::from(260).rem_power_of_2(8), 4);
180    ///
181    /// // -100 * 2^4 + -11 = -1611
182    /// assert_eq!(Integer::from(-1611).rem_power_of_2(4), -11);
183    /// ```
184    fn rem_power_of_2(self, pow: u64) -> Self {
185        let abs_rem = self.abs.mod_power_of_2(pow);
186        Self {
187            sign: self.sign || abs_rem == 0,
188            abs: abs_rem,
189        }
190    }
191}
192
193impl RemPowerOf2 for &Integer {
194    type Output = Integer;
195
196    /// Divides an [`Integer`] by $2^k$, taking it by reference and returning just the remainder.
197    /// The remainder has the same sign as the first number.
198    ///
199    /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and
200    /// $0 \leq |r| < 2^k$.
201    ///
202    /// $$
203    /// f(x, k) = x - 2^k\operatorname{sgn}(x)\left \lfloor \frac{|x|}{2^k} \right \rfloor.
204    /// $$
205    ///
206    /// Unlike
207    /// [`mod_power_of_2`](malachite_base::num::arithmetic::traits::ModPowerOf2::mod_power_of_2),
208    /// this function always returns zero or a number with the same sign as `self`.
209    ///
210    /// # Worst-case complexity
211    /// $T(n) = O(n)$
212    ///
213    /// $M(n) = O(n)$
214    ///
215    /// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
216    ///
217    /// # Examples
218    /// ```
219    /// use malachite_base::num::arithmetic::traits::RemPowerOf2;
220    /// use malachite_nz::integer::Integer;
221    ///
222    /// // 1 * 2^8 + 4 = 260
223    /// assert_eq!((&Integer::from(260)).rem_power_of_2(8), 4);
224    /// // -100 * 2^4 + -11 = -1611
225    /// assert_eq!((&Integer::from(-1611)).rem_power_of_2(4), -11);
226    /// ```
227    fn rem_power_of_2(self, pow: u64) -> Integer {
228        let abs_rem = (&self.abs).mod_power_of_2(pow);
229        Integer {
230            sign: self.sign || abs_rem == 0,
231            abs: abs_rem,
232        }
233    }
234}
235
236impl RemPowerOf2Assign for Integer {
237    /// Divides an [`Integer`] by $2^k$, replacing the [`Integer`] by the remainder. The remainder
238    /// has the same sign as the [`Integer`].
239    ///
240    /// If the quotient were computed, he quotient and remainder would satisfy $x = q2^k + r$ and $0
241    /// \leq r < 2^k$.
242    ///
243    /// $$
244    /// x \gets x - 2^k\operatorname{sgn}(x)\left \lfloor \frac{|x|}{2^k} \right \rfloor.
245    /// $$
246    ///
247    /// Unlike [`mod_power_of_2_assign`](ModPowerOf2Assign::mod_power_of_2_assign), this function
248    /// does never changes the sign of `self`, except possibly to set `self` to 0.
249    ///
250    /// # Worst-case complexity
251    /// $T(n) = O(n)$
252    ///
253    /// $M(n) = O(n)$
254    ///
255    /// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
256    ///
257    /// # Examples
258    /// ```
259    /// use malachite_base::num::arithmetic::traits::RemPowerOf2Assign;
260    /// use malachite_nz::integer::Integer;
261    ///
262    /// // 1 * 2^8 + 4 = 260
263    /// let mut x = Integer::from(260);
264    /// x.rem_power_of_2_assign(8);
265    /// assert_eq!(x, 4);
266    ///
267    /// // -100 * 2^4 + -11 = -1611
268    /// let mut x = Integer::from(-1611);
269    /// x.rem_power_of_2_assign(4);
270    /// assert_eq!(x, -11);
271    /// ```
272    fn rem_power_of_2_assign(&mut self, pow: u64) {
273        self.abs.mod_power_of_2_assign(pow);
274        if self.abs == 0 {
275            self.sign = true;
276        }
277    }
278}
279
280impl CeilingModPowerOf2 for Integer {
281    type Output = Self;
282
283    /// Divides an [`Integer`] by $2^k$, taking it by value and returning just the remainder. The
284    /// remainder is non-positive.
285    ///
286    /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and
287    /// $0 \leq -r < 2^k$.
288    ///
289    /// $$
290    /// f(x, y) =  x - 2^k\left \lceil \frac{x}{2^k} \right \rceil.
291    /// $$
292    ///
293    /// # Worst-case complexity
294    /// $T(n) = O(n)$
295    ///
296    /// $M(n) = O(n)$
297    ///
298    /// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
299    ///
300    /// # Examples
301    /// ```
302    /// use malachite_base::num::arithmetic::traits::CeilingModPowerOf2;
303    /// use malachite_nz::integer::Integer;
304    ///
305    /// // 2 * 2^8 + -252 = 260
306    /// assert_eq!(Integer::from(260).ceiling_mod_power_of_2(8), -252);
307    ///
308    /// // -100 * 2^4 + -11 = -1611
309    /// assert_eq!(Integer::from(-1611).ceiling_mod_power_of_2(4), -11);
310    /// ```
311    fn ceiling_mod_power_of_2(self, pow: u64) -> Self {
312        let abs_mod = if self.sign {
313            self.abs.neg_mod_power_of_2(pow)
314        } else {
315            self.abs.mod_power_of_2(pow)
316        };
317        Self {
318            sign: abs_mod == 0,
319            abs: abs_mod,
320        }
321    }
322}
323
324impl CeilingModPowerOf2 for &Integer {
325    type Output = Integer;
326
327    /// Divides an [`Integer`] by $2^k$, taking it by reference and returning just the remainder.
328    /// The remainder is non-positive.
329    ///
330    /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and
331    /// $0 \leq -r < 2^k$.
332    ///
333    /// $$
334    /// f(x, y) =  x - 2^k\left \lceil \frac{x}{2^k} \right \rceil.
335    /// $$
336    ///
337    /// # Worst-case complexity
338    /// $T(n) = O(n)$
339    ///
340    /// $M(n) = O(n)$
341    ///
342    /// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
343    ///
344    /// # Examples
345    /// ```
346    /// use malachite_base::num::arithmetic::traits::CeilingModPowerOf2;
347    /// use malachite_nz::integer::Integer;
348    ///
349    /// // 2 * 2^8 + -252 = 260
350    /// assert_eq!((&Integer::from(260)).ceiling_mod_power_of_2(8), -252);
351    /// // -100 * 2^4 + -11 = -1611
352    /// assert_eq!((&Integer::from(-1611)).ceiling_mod_power_of_2(4), -11);
353    /// ```
354    fn ceiling_mod_power_of_2(self, pow: u64) -> Integer {
355        let abs_mod = if self.sign {
356            (&self.abs).neg_mod_power_of_2(pow)
357        } else {
358            (&self.abs).mod_power_of_2(pow)
359        };
360        Integer {
361            sign: abs_mod == 0,
362            abs: abs_mod,
363        }
364    }
365}
366
367impl CeilingModPowerOf2Assign for Integer {
368    /// Divides an [`Integer`] by $2^k$, replacing the [`Integer`] by the remainder. The remainder
369    /// is non-positive.
370    ///
371    /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and
372    /// $0 \leq -r < 2^k$.
373    ///
374    /// $$
375    /// x \gets x - 2^k\left \lceil\frac{x}{2^k} \right \rceil.
376    /// $$
377    ///
378    /// # Worst-case complexity
379    /// $T(n) = O(n)$
380    ///
381    /// $M(n) = O(n)$
382    ///
383    /// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
384    ///
385    /// # Examples
386    /// ```
387    /// use malachite_base::num::arithmetic::traits::CeilingModPowerOf2Assign;
388    /// use malachite_nz::integer::Integer;
389    ///
390    /// // 2 * 2^8 + -252 = 260
391    /// let mut x = Integer::from(260);
392    /// x.ceiling_mod_power_of_2_assign(8);
393    /// assert_eq!(x, -252);
394    ///
395    /// // -100 * 2^4 + -11 = -1611
396    /// let mut x = Integer::from(-1611);
397    /// x.ceiling_mod_power_of_2_assign(4);
398    /// assert_eq!(x, -11);
399    /// ```
400    fn ceiling_mod_power_of_2_assign(&mut self, pow: u64) {
401        if self.sign {
402            self.abs.neg_mod_power_of_2_assign(pow);
403        } else {
404            self.abs.mod_power_of_2_assign(pow);
405        };
406        self.sign = self.abs == 0;
407    }
408}