malachite_nz/integer/logic/bit_iterable.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 crate::natural::logic::bit_iterable::NaturalBitIterator;
12use core::ops::Index;
13use malachite_base::num::logic::traits::{BitAccess, BitIterable};
14
15/// A double-ended iterator over the two's complement bits of the negative of an [`Integer`].
16///
17/// The forward order is ascending (least-significant first). There may be at most one implicit
18/// most-significant `true` bit.
19#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
20pub struct NegativeBitIterator<'a> {
21 pub(crate) bits: NaturalBitIterator<'a>,
22 i: u64,
23 j: u64,
24 first_true_index: Option<u64>,
25}
26
27impl Iterator for NegativeBitIterator<'_> {
28 type Item = bool;
29
30 fn next(&mut self) -> Option<bool> {
31 let previous_i = self.i;
32 self.bits.next().map(|bit| {
33 self.i += 1;
34 if let Some(first_true_index) = self.first_true_index {
35 if previous_i <= first_true_index {
36 bit
37 } else {
38 !bit
39 }
40 } else {
41 if bit {
42 self.first_true_index = Some(previous_i);
43 }
44 bit
45 }
46 })
47 }
48
49 #[inline]
50 fn size_hint(&self) -> (usize, Option<usize>) {
51 self.bits.size_hint()
52 }
53}
54
55impl DoubleEndedIterator for NegativeBitIterator<'_> {
56 fn next_back(&mut self) -> Option<bool> {
57 let previous_j = self.j;
58 self.bits.next_back().map(|bit| {
59 if self.j != 0 {
60 self.j -= 1;
61 }
62 if self.first_true_index.is_none() {
63 let mut i = 0;
64 while !self.bits[i] {
65 i += 1;
66 }
67 self.first_true_index = Some(i);
68 }
69 let first_true_index = self.first_true_index.unwrap();
70 if previous_j <= first_true_index {
71 bit
72 } else {
73 !bit
74 }
75 })
76 }
77}
78
79impl ExactSizeIterator for NegativeBitIterator<'_> {}
80
81trait SignExtendedBitIterator: DoubleEndedIterator<Item = bool> {
82 const EXTENSION: bool;
83
84 fn needs_sign_extension(&self) -> bool;
85
86 fn iterate_forward(&mut self, extension_checked: &mut bool) -> Option<bool> {
87 let next = self.next();
88 if next.is_none() {
89 if *extension_checked {
90 None
91 } else {
92 *extension_checked = true;
93 if self.needs_sign_extension() {
94 Some(Self::EXTENSION)
95 } else {
96 None
97 }
98 }
99 } else {
100 next
101 }
102 }
103
104 fn iterate_backward(&mut self, extension_checked: &mut bool) -> Option<bool> {
105 if !*extension_checked {
106 *extension_checked = true;
107 if self.needs_sign_extension() {
108 return Some(Self::EXTENSION);
109 }
110 }
111 self.next_back()
112 }
113}
114
115impl SignExtendedBitIterator for NaturalBitIterator<'_> {
116 const EXTENSION: bool = false;
117
118 fn needs_sign_extension(&self) -> bool {
119 self[self.significant_bits - 1]
120 }
121}
122
123impl SignExtendedBitIterator for NegativeBitIterator<'_> {
124 const EXTENSION: bool = true;
125
126 fn needs_sign_extension(&self) -> bool {
127 let mut i = 0;
128 while !self.bits[i] {
129 i += 1;
130 }
131 let last_bit_index = self.bits.significant_bits - 1;
132 if i == last_bit_index {
133 !self.bits[last_bit_index]
134 } else {
135 self.bits[last_bit_index]
136 }
137 }
138}
139
140/// A double-ended iterator over the twos-complement bits of an [`Integer`].
141///
142/// The forward order is ascending (least-significant first). The most significant bit corresponds
143/// to the sign of the [`Integer`]; `false` for non-negative and `true` for negative. This means
144/// that there may be a single most-significant sign-extension bit.
145///
146/// This `struct` is created by [`BitIterable::bits`]; see its documentation for more.
147#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
148pub enum IntegerBitIterator<'a> {
149 Zero,
150 Positive(NaturalBitIterator<'a>, bool),
151 Negative(NegativeBitIterator<'a>, bool),
152}
153
154impl Iterator for IntegerBitIterator<'_> {
155 type Item = bool;
156
157 fn next(&mut self) -> Option<bool> {
158 match self {
159 Self::Zero => None,
160 Self::Positive(bits, extension_checked) => bits.iterate_forward(extension_checked),
161 Self::Negative(bits, extension_checked) => bits.iterate_forward(extension_checked),
162 }
163 }
164}
165
166impl DoubleEndedIterator for IntegerBitIterator<'_> {
167 fn next_back(&mut self) -> Option<bool> {
168 match self {
169 Self::Zero => None,
170 Self::Positive(bits, extension_checked) => bits.iterate_backward(extension_checked),
171 Self::Negative(bits, extension_checked) => bits.iterate_backward(extension_checked),
172 }
173 }
174}
175
176impl Index<u64> for IntegerBitIterator<'_> {
177 type Output = bool;
178
179 /// A function to retrieve an [`Integer`]'s two's complement bits by index. Indexing at or above
180 /// the significant bit count returns `false` or `true` bits, depending on the [`Integer`]'s
181 /// sign.
182 ///
183 /// This is equivalent to [`get_bit`](malachite_base::num::logic::traits::BitAccess::get_bit).
184 ///
185 /// # Examples
186 /// ```
187 /// use malachite_base::num::basic::traits::Zero;
188 /// use malachite_base::num::logic::traits::BitIterable;
189 /// use malachite_nz::integer::Integer;
190 ///
191 /// assert_eq!(Integer::ZERO.bits()[0], false);
192 ///
193 /// // -105 = 10010111 in two's complement
194 /// let n = Integer::from(-105);
195 /// let bits = n.bits();
196 /// assert_eq!(bits[0], true);
197 /// assert_eq!(bits[1], true);
198 /// assert_eq!(bits[2], true);
199 /// assert_eq!(bits[3], false);
200 /// assert_eq!(bits[4], true);
201 /// assert_eq!(bits[5], false);
202 /// assert_eq!(bits[6], false);
203 /// assert_eq!(bits[7], true);
204 /// assert_eq!(bits[100], true);
205 /// ```
206 fn index(&self, index: u64) -> &bool {
207 let bit = match self {
208 Self::Zero => false,
209 Self::Positive(bits, _) => bits.limbs.n.get_bit(index),
210 Self::Negative(bits, _) => bits.bits.limbs.n.get_bit_neg(index),
211 };
212 if bit { &true } else { &false }
213 }
214}
215
216impl Natural {
217 // Returns a double-ended iterator over the two's complement bits of the negative of a
218 // `Natural`. The forward order is ascending, so that less significant bits appear first. There
219 // may be at most one trailing `true` bit going forward, or leading `true` bit going backward.
220 // The `Natural` cannot be zero.
221 //
222 // # Worst-case complexity
223 // Constant time and additional memory.
224 fn negative_bits(&self) -> NegativeBitIterator<'_> {
225 assert_ne!(*self, 0, "Cannot get negative bits of 0.");
226 let bits = self.bits();
227 NegativeBitIterator {
228 bits,
229 first_true_index: None,
230 i: 0,
231 j: bits.significant_bits - 1,
232 }
233 }
234}
235
236impl<'a> BitIterable for &'a Integer {
237 type BitIterator = IntegerBitIterator<'a>;
238
239 /// Returns a double-ended iterator over the bits of an [`Integer`].
240 ///
241 /// The forward order is ascending, so that less significant bits appear first. There are no
242 /// trailing false bits going forward, or leading falses going backward, except for possibly a
243 /// most-significant sign-extension bit.
244 ///
245 /// If it's necessary to get a [`Vec`] of all the bits, consider using
246 /// [`to_bits_asc`](malachite_base::num::logic::traits::BitConvertible::to_bits_asc) or
247 /// [`to_bits_desc`](malachite_base::num::logic::traits::BitConvertible::to_bits_desc) instead.
248 ///
249 /// # Worst-case complexity
250 /// Constant time and additional memory.
251 ///
252 /// # Examples
253 /// ```
254 /// use itertools::Itertools;
255 /// use malachite_base::num::basic::traits::Zero;
256 /// use malachite_base::num::logic::traits::BitIterable;
257 /// use malachite_nz::integer::Integer;
258 ///
259 /// assert_eq!(Integer::ZERO.bits().next(), None);
260 /// // 105 = 01101001b, with a leading false bit to indicate sign
261 /// assert_eq!(
262 /// Integer::from(105).bits().collect_vec(),
263 /// &[true, false, false, true, false, true, true, false]
264 /// );
265 /// // -105 = 10010111 in two's complement, with a leading true bit to indicate sign
266 /// assert_eq!(
267 /// Integer::from(-105).bits().collect_vec(),
268 /// &[true, true, true, false, true, false, false, true]
269 /// );
270 ///
271 /// assert_eq!(Integer::ZERO.bits().next_back(), None);
272 /// // 105 = 01101001b, with a leading false bit to indicate sign
273 /// assert_eq!(
274 /// Integer::from(105).bits().rev().collect_vec(),
275 /// &[false, true, true, false, true, false, false, true]
276 /// );
277 /// // -105 = 10010111 in two's complement, with a leading true bit to indicate sign
278 /// assert_eq!(
279 /// Integer::from(-105).bits().rev().collect_vec(),
280 /// &[true, false, false, true, false, true, true, true]
281 /// );
282 /// ```
283 fn bits(self) -> IntegerBitIterator<'a> {
284 if *self == 0 {
285 IntegerBitIterator::Zero
286 } else if self.sign {
287 IntegerBitIterator::Positive(self.abs.bits(), false)
288 } else {
289 IntegerBitIterator::Negative(self.abs.negative_bits(), false)
290 }
291 }
292}