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}