malachite_nz/natural/arithmetic/mod_power_of_2.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MP Library.
4//
5// Copyright © 1991, 1993-1995, 2001, 2002, 2012 Free Software Foundation, Inc.
6//
7// This file is part of Malachite.
8//
9// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
10// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
11// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
12
13use crate::integer::conversion::to_twos_complement_limbs::limbs_twos_complement_in_place;
14use crate::natural::InnerNatural::{Large, Small};
15use crate::natural::{Natural, bit_to_limb_count_ceiling, bit_to_limb_count_floor};
16use crate::platform::Limb;
17use alloc::vec::Vec;
18use malachite_base::num::arithmetic::traits::{
19 ModPowerOf2, ModPowerOf2Assign, NegModPowerOf2, NegModPowerOf2Assign, RemPowerOf2,
20 RemPowerOf2Assign,
21};
22use malachite_base::num::basic::integers::PrimitiveInt;
23use malachite_base::num::basic::traits::Zero;
24use malachite_base::num::conversion::traits::WrappingFrom;
25use malachite_base::slices::slice_set_zero;
26
27// Interpreting a slice of `Limb`s as the limbs (in ascending order) of a `Natural`, returns the
28// limbs of the `Natural` mod two raised to `pow`. Equivalently, retains only the least-significant
29// `pow` bits.
30//
31// # Worst-case complexity
32// $T(n) = O(n)$
33//
34// $M(n) = O(n)$
35//
36// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
37//
38// This is equivalent to `mpz_tdiv_r_2exp` from `mpz/tdiv_r_2exp.c`, GMP 6.2.1, where in is
39// non-negative and the result is returned.
40pub_test! {limbs_mod_power_of_2(xs: &[Limb], pow: u64) -> Vec<Limb> {
41 if pow == 0 {
42 return Vec::new();
43 }
44 let leftover_bits = pow & Limb::WIDTH_MASK;
45 let result_size = bit_to_limb_count_floor(pow);
46 if result_size >= xs.len() {
47 return xs.to_vec();
48 }
49 let mut result = xs[..result_size].to_vec();
50 if leftover_bits != 0 {
51 result.push(xs[result_size].mod_power_of_2(leftover_bits));
52 }
53 result
54}}
55
56// Interpreting a slice of `Limb`s as the limbs (in ascending order) of a `Natural`, writes the
57// limbs of the `Natural` mod two raised to `pow` to the input slice. Equivalently, retains only the
58// least-significant `pow` bits. If the upper limbs of the input slice are no longer needed, they
59// are set to zero.
60//
61// # Worst-case complexity
62// Constant time and additional memory.
63//
64// This is equivalent to `mpz_tdiv_r_2exp` from `mpz/tdiv_r_2exp.c`, GMP 6.2.1, where `in` is
65// non-negative, `res == in`, and instead of possibly being truncated, the high limbs of `res` are
66// possibly filled with zeros.
67pub_crate_test! {limbs_slice_mod_power_of_2_in_place(xs: &mut [Limb], pow: u64) {
68 if pow == 0 {
69 slice_set_zero(xs);
70 return;
71 }
72 let new_size = bit_to_limb_count_ceiling(pow);
73 if new_size > xs.len() {
74 return;
75 }
76 slice_set_zero(&mut xs[new_size..]);
77 let leftover_bits = pow & Limb::WIDTH_MASK;
78 if leftover_bits != 0 {
79 xs[new_size - 1].mod_power_of_2_assign(leftover_bits);
80 }
81}}
82
83// Interpreting a `Vec` of `Limb`s as the limbs (in ascending order) of a `Natural`, writes the
84// limbs of the `Natural` mod two raised to `pow` to the input `Vec`. Equivalently, retains only the
85// least-significant `pow` bits.
86//
87// # Worst-case complexity
88// Constant time and additional memory.
89//
90// This is equivalent to `mpz_tdiv_r_2exp` from `mpz/tdiv_r_2exp.c`, GMP 6.2.1, where `in` is
91// non-negative and `res == in`.
92pub_crate_test! {limbs_vec_mod_power_of_2_in_place(xs: &mut Vec<Limb>, pow: u64) {
93 if pow == 0 {
94 xs.clear();
95 return;
96 }
97 let new_size = bit_to_limb_count_ceiling(pow);
98 if new_size > xs.len() {
99 return;
100 }
101 xs.truncate(new_size);
102 let leftover_bits = pow & Limb::WIDTH_MASK;
103 if leftover_bits != 0 {
104 xs[new_size - 1].mod_power_of_2_assign(leftover_bits);
105 }
106}}
107
108// Interpreting a slice of `Limb`s as the limbs (in ascending order) of a `Natural`, returns the
109// limbs of the negative of the `Natural` mod two raised to `pow`. Equivalently, takes the two's
110// complement and retains only the least-significant `pow` bits.
111//
112// # Worst-case complexity
113// $T(n) = O(n)$
114//
115// $M(n) = O(n)$
116//
117// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
118//
119// This is equivalent to `mpz_tdiv_r_2exp` from `mpz/tdiv_r_2exp.c`, GMP 6.2.1, where `in` is
120// negative and the result is returned. `xs` is the limbs of `-in`.
121pub_crate_test! {limbs_neg_mod_power_of_2(xs: &[Limb], pow: u64) -> Vec<Limb> {
122 let mut result = xs.to_vec();
123 limbs_neg_mod_power_of_2_in_place(&mut result, pow);
124 result
125}}
126
127// Interpreting a `Vec` of `Limb`s as the limbs (in ascending order) of a `Natural`, writes the
128// limbs of the negative of the `Natural` mod two raised to `pow` to the input `Vec`. Equivalently,
129// takes the two's complement and retains only the least-significant `pow` bits.
130//
131// # Worst-case complexity
132// $T(n) = O(n)$
133//
134// $M(n) = O(n)$
135//
136// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
137//
138// This is equivalent to `mpz_tdiv_r_2exp` from `mpz/tdiv_r_2exp.c`, GMP 6.2.1, where `in` is
139// negative and `res == in`. `xs` is the limbs of `-in`.
140pub_crate_test! {limbs_neg_mod_power_of_2_in_place(xs: &mut Vec<Limb>, pow: u64) {
141 let new_size = bit_to_limb_count_ceiling(pow);
142 xs.resize(new_size, 0);
143 limbs_twos_complement_in_place(xs);
144 let leftover_bits = pow & Limb::WIDTH_MASK;
145 if leftover_bits != 0 {
146 xs[new_size - 1].mod_power_of_2_assign(leftover_bits);
147 }
148}}
149
150impl ModPowerOf2 for Natural {
151 type Output = Self;
152
153 /// Divides a [`Natural`] by $2^k$, returning just the remainder. The [`Natural`] is taken by
154 /// value.
155 ///
156 /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and
157 /// $0 \leq r < 2^k$.
158 ///
159 /// $$
160 /// f(x, k) = x - 2^k\left \lfloor \frac{x}{2^k} \right \rfloor.
161 /// $$
162 ///
163 /// # Worst-case complexity
164 /// Constant time and additional memory.
165 ///
166 /// # Examples
167 /// ```
168 /// use malachite_base::num::arithmetic::traits::ModPowerOf2;
169 /// use malachite_nz::natural::Natural;
170 ///
171 /// // 1 * 2^8 + 4 = 260
172 /// assert_eq!(Natural::from(260u32).mod_power_of_2(8), 4);
173 ///
174 /// // 100 * 2^4 + 11 = 1611
175 /// assert_eq!(Natural::from(1611u32).mod_power_of_2(4), 11);
176 /// ```
177 #[inline]
178 fn mod_power_of_2(mut self, pow: u64) -> Self {
179 self.mod_power_of_2_assign(pow);
180 self
181 }
182}
183
184impl ModPowerOf2 for &Natural {
185 type Output = Natural;
186
187 /// Divides a [`Natural`] by $2^k$, returning just the remainder. The [`Natural`] is taken by
188 /// reference.
189 ///
190 /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and
191 /// $0 \leq r < 2^k$.
192 ///
193 /// # Worst-case complexity
194 /// $T(n) = O(n)$
195 ///
196 /// $M(n) = O(n)$
197 ///
198 /// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
199 ///
200 /// # Examples
201 /// ```
202 /// use malachite_base::num::arithmetic::traits::ModPowerOf2;
203 /// use malachite_nz::natural::Natural;
204 ///
205 /// // 1 * 2^8 + 4 = 260
206 /// assert_eq!((&Natural::from(260u32)).mod_power_of_2(8), 4);
207 /// // 100 * 2^4 + 11 = 1611
208 /// assert_eq!((&Natural::from(1611u32)).mod_power_of_2(4), 11);
209 /// ```
210 fn mod_power_of_2(self, pow: u64) -> Natural {
211 match self {
212 Natural(Small(small)) => Natural(Small(small.mod_power_of_2(pow))),
213 Natural(Large(limbs)) => {
214 Natural::from_owned_limbs_asc(limbs_mod_power_of_2(limbs, pow))
215 }
216 }
217 }
218}
219
220impl ModPowerOf2Assign for Natural {
221 /// Divides a [`Natural`]by $2^k$, replacing the [`Natural`] by the remainder.
222 ///
223 /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and
224 /// $0 \leq r < 2^k$.
225 ///
226 /// # Worst-case complexity
227 /// Constant time and additional memory.
228 ///
229 /// # Examples
230 /// ```
231 /// use malachite_base::num::arithmetic::traits::ModPowerOf2Assign;
232 /// use malachite_nz::natural::Natural;
233 ///
234 /// // 1 * 2^8 + 4 = 260
235 /// let mut x = Natural::from(260u32);
236 /// x.mod_power_of_2_assign(8);
237 /// assert_eq!(x, 4);
238 ///
239 /// // 100 * 2^4 + 11 = 1611
240 /// let mut x = Natural::from(1611u32);
241 /// x.mod_power_of_2_assign(4);
242 /// assert_eq!(x, 11);
243 /// ```
244 fn mod_power_of_2_assign(&mut self, pow: u64) {
245 match &mut *self {
246 Self(Small(small)) => small.mod_power_of_2_assign(pow),
247 Self(Large(limbs)) => {
248 limbs_vec_mod_power_of_2_in_place(limbs, pow);
249 self.trim();
250 }
251 }
252 }
253}
254
255impl RemPowerOf2 for Natural {
256 type Output = Self;
257
258 /// Divides a [`Natural`] by $2^k$, returning just the remainder. The [`Natural`] is taken by
259 /// value.
260 ///
261 /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and
262 /// $0 \leq r < 2^k$.
263 ///
264 /// $$
265 /// f(x, k) = x - 2^k\left \lfloor \frac{x}{2^k} \right \rfloor.
266 /// $$
267 ///
268 /// For [`Natural`]s, `rem_power_of_2` is equivalent to
269 /// [`mod_power_of_2`](ModPowerOf2::mod_power_of_2).
270 ///
271 /// # Worst-case complexity
272 /// Constant time and additional memory.
273 ///
274 /// # Examples
275 /// ```
276 /// use malachite_base::num::arithmetic::traits::RemPowerOf2;
277 /// use malachite_nz::natural::Natural;
278 ///
279 /// // 1 * 2^8 + 4 = 260
280 /// assert_eq!(Natural::from(260u32).rem_power_of_2(8), 4);
281 ///
282 /// // 100 * 2^4 + 11 = 1611
283 /// assert_eq!(Natural::from(1611u32).rem_power_of_2(4), 11);
284 /// ```
285 #[inline]
286 fn rem_power_of_2(self, pow: u64) -> Self {
287 self.mod_power_of_2(pow)
288 }
289}
290
291impl RemPowerOf2 for &Natural {
292 type Output = Natural;
293
294 /// Divides a [`Natural`] by $2^k$, returning just the remainder. The [`Natural`] is taken by
295 /// reference.
296 ///
297 /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and
298 /// $0 \leq r < 2^k$.
299 ///
300 /// $$
301 /// f(x, k) = x - 2^k\left \lfloor \frac{x}{2^k} \right \rfloor.
302 /// $$
303 ///
304 /// For [`Natural`]s, `rem_power_of_2` is equivalent to
305 /// [`mod_power_of_2`](ModPowerOf2::mod_power_of_2).
306 ///
307 /// # Worst-case complexity
308 /// $T(n) = O(n)$
309 ///
310 /// $M(n) = O(n)$
311 ///
312 /// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
313 ///
314 /// # Examples
315 /// ```
316 /// use malachite_base::num::arithmetic::traits::RemPowerOf2;
317 /// use malachite_nz::natural::Natural;
318 ///
319 /// // 1 * 2^8 + 4 = 260
320 /// assert_eq!((&Natural::from(260u32)).rem_power_of_2(8), 4);
321 /// // 100 * 2^4 + 11 = 1611
322 /// assert_eq!((&Natural::from(1611u32)).rem_power_of_2(4), 11);
323 /// ```
324 #[inline]
325 fn rem_power_of_2(self, pow: u64) -> Natural {
326 self.mod_power_of_2(pow)
327 }
328}
329
330impl RemPowerOf2Assign for Natural {
331 /// Divides a [`Natural`] by $2^k$, replacing the first [`Natural`] by the remainder.
332 ///
333 /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and
334 /// $0 \leq r < 2^k$.
335 ///
336 /// $$
337 /// x \gets x - 2^k\left \lfloor \frac{x}{2^k} \right \rfloor.
338 /// $$
339 ///
340 /// For [`Natural`]s, `rem_power_of_2_assign` is equivalent to
341 /// [`mod_power_of_2_assign`](ModPowerOf2Assign::mod_power_of_2_assign).
342 ///
343 /// # Worst-case complexity
344 /// Constant time and additional memory.
345 ///
346 /// # Examples
347 /// ```
348 /// use malachite_base::num::arithmetic::traits::RemPowerOf2Assign;
349 /// use malachite_nz::natural::Natural;
350 ///
351 /// // 1 * 2^8 + 4 = 260
352 /// let mut x = Natural::from(260u32);
353 /// x.rem_power_of_2_assign(8);
354 /// assert_eq!(x, 4);
355 ///
356 /// // 100 * 2^4 + 11 = 1611
357 /// let mut x = Natural::from(1611u32);
358 /// x.rem_power_of_2_assign(4);
359 /// assert_eq!(x, 11);
360 /// ```
361 #[inline]
362 fn rem_power_of_2_assign(&mut self, pow: u64) {
363 self.mod_power_of_2_assign(pow);
364 }
365}
366
367impl NegModPowerOf2 for Natural {
368 type Output = Self;
369
370 /// Divides the negative of a [`Natural`] by a $2^k$, returning just the remainder. The
371 /// [`Natural`] is taken by value.
372 ///
373 /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k - r$ and
374 /// $0 \leq r < 2^k$.
375 ///
376 /// $$
377 /// f(x, k) = 2^k\left \lceil \frac{x}{2^k} \right \rceil - x.
378 /// $$
379 ///
380 /// # Worst-case complexity
381 /// $T(n) = O(n)$
382 ///
383 /// $M(n) = O(n)$
384 ///
385 /// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
386 ///
387 /// # Examples
388 /// ```
389 /// use malachite_base::num::arithmetic::traits::NegModPowerOf2;
390 /// use malachite_nz::natural::Natural;
391 ///
392 /// // 2 * 2^8 - 252 = 260
393 /// assert_eq!(Natural::from(260u32).neg_mod_power_of_2(8), 252);
394 ///
395 /// // 101 * 2^4 - 5 = 1611
396 /// assert_eq!(Natural::from(1611u32).neg_mod_power_of_2(4), 5);
397 /// ```
398 #[inline]
399 fn neg_mod_power_of_2(mut self, pow: u64) -> Self {
400 self.neg_mod_power_of_2_assign(pow);
401 self
402 }
403}
404
405impl NegModPowerOf2 for &Natural {
406 type Output = Natural;
407
408 /// Divides the negative of a [`Natural`] by a $2^k$, returning just the remainder. The
409 /// [`Natural`] is taken by reference.
410 ///
411 /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k - r$ and
412 /// $0 \leq r < 2^k$.
413 ///
414 /// $$
415 /// f(x, k) = 2^k\left \lceil \frac{x}{2^k} \right \rceil - x.
416 /// $$
417 ///
418 /// # Worst-case complexity
419 /// $T(n) = O(n)$
420 ///
421 /// $M(n) = O(n)$
422 ///
423 /// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
424 ///
425 /// # Examples
426 /// ```
427 /// use malachite_base::num::arithmetic::traits::NegModPowerOf2;
428 /// use malachite_nz::natural::Natural;
429 ///
430 /// // 2 * 2^8 - 252 = 260
431 /// assert_eq!((&Natural::from(260u32)).neg_mod_power_of_2(8), 252);
432 /// // 101 * 2^4 - 5 = 1611
433 /// assert_eq!((&Natural::from(1611u32)).neg_mod_power_of_2(4), 5);
434 /// ```
435 fn neg_mod_power_of_2(self, pow: u64) -> Natural {
436 match (self, pow) {
437 (&Natural::ZERO, _) => Natural::ZERO,
438 (_, pow) if pow <= Limb::WIDTH => {
439 Natural::from(Limb::wrapping_from(self).neg_mod_power_of_2(pow))
440 }
441 (Natural(Small(small)), pow) => {
442 Natural::from_owned_limbs_asc(limbs_neg_mod_power_of_2(&[*small], pow))
443 }
444 (Natural(Large(limbs)), pow) => {
445 Natural::from_owned_limbs_asc(limbs_neg_mod_power_of_2(limbs, pow))
446 }
447 }
448 }
449}
450
451impl NegModPowerOf2Assign for Natural {
452 /// Divides the negative of a [`Natural`] by $2^k$, returning just the remainder.
453 ///
454 /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k - r$ and
455 /// $0 \leq r < 2^k$.
456 ///
457 /// $$
458 /// x \gets 2^k\left \lceil \frac{x}{2^k} \right \rceil - x.
459 /// $$
460 ///
461 /// # Worst-case complexity
462 /// $T(n) = O(n)$
463 ///
464 /// $M(n) = O(n)$
465 ///
466 /// where $T$ is time, $M$ is additional memory, and $n$ is `pow`.
467 ///
468 /// # Examples
469 /// ```
470 /// use malachite_base::num::arithmetic::traits::NegModPowerOf2Assign;
471 /// use malachite_nz::natural::Natural;
472 ///
473 /// // 2 * 2^8 - 252 = 260
474 /// let mut x = Natural::from(260u32);
475 /// x.neg_mod_power_of_2_assign(8);
476 /// assert_eq!(x, 252);
477 ///
478 /// // 101 * 2^4 - 5 = 1611
479 /// let mut x = Natural::from(1611u32);
480 /// x.neg_mod_power_of_2_assign(4);
481 /// assert_eq!(x, 5);
482 /// ```
483 fn neg_mod_power_of_2_assign(&mut self, pow: u64) {
484 if *self == 0 {
485 } else if pow <= Limb::WIDTH {
486 *self = Self::from(Limb::wrapping_from(&*self).neg_mod_power_of_2(pow));
487 } else {
488 let limbs = self.promote_in_place();
489 limbs_neg_mod_power_of_2_in_place(limbs, pow);
490 self.trim();
491 }
492 }
493}