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}