malachite_base/num/logic/low_mask.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::num::basic::signeds::PrimitiveSigned;
10use crate::num::basic::unsigneds::PrimitiveUnsigned;
11use crate::num::logic::traits::LowMask;
12
13fn low_mask_unsigned<T: PrimitiveUnsigned>(bits: u64) -> T {
14 assert!(bits <= T::WIDTH);
15 if bits == T::WIDTH {
16 T::MAX
17 } else {
18 T::power_of_2(bits) - T::ONE
19 }
20}
21
22macro_rules! impl_low_mask_unsigned {
23 ($t:ident) => {
24 impl LowMask for $t {
25 /// Returns a number whose least significant $b$ bits are `true` and whose other bits
26 /// are `false`.
27 ///
28 /// $f(b) = 2^b - 1$.
29 ///
30 /// # Worst-case complexity
31 /// Constant time and additional memory.
32 ///
33 /// # Panics
34 /// Panics if `bits` is greater than the width of of the type.
35 ///
36 /// # Examples
37 /// See [here](super::low_mask#low_mask).
38 #[inline]
39 fn low_mask(bits: u64) -> $t {
40 low_mask_unsigned(bits)
41 }
42 }
43 };
44}
45apply_to_unsigneds!(impl_low_mask_unsigned);
46
47fn low_mask_signed<T: PrimitiveSigned>(bits: u64) -> T {
48 assert!(bits <= T::WIDTH);
49 if bits == T::WIDTH {
50 T::NEGATIVE_ONE
51 } else if bits == T::WIDTH - 1 {
52 T::MAX
53 } else {
54 T::power_of_2(bits) - T::ONE
55 }
56}
57
58macro_rules! impl_low_mask_signed {
59 ($t:ident) => {
60 impl LowMask for $t {
61 /// Returns a number whose least significant $b$ bits are `true` and whose other bits
62 /// are `false`.
63 ///
64 /// $$
65 /// f(b) = \\begin{cases}
66 /// 2^b - 1 & \text{if} \\quad 0 \leq n < W, \\\\
67 /// -1 & \text{if} \\quad n = W,
68 /// \\end{cases}
69 /// $$
70 /// where $W$ is the width of the type.
71 ///
72 /// # Worst-case complexity
73 /// Constant time and additional memory.
74 ///
75 /// # Panics
76 /// Panics if `bits` is greater than the width of the type.
77 ///
78 /// # Examples
79 /// See [here](super::low_mask#low_mask).
80 #[inline]
81 fn low_mask(bits: u64) -> $t {
82 low_mask_signed(bits)
83 }
84 }
85 };
86}
87apply_to_signeds!(impl_low_mask_signed);