malachite_base/num/logic/
traits.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 alloc::vec::Vec;
10use core::ops::Index;
11
12/// Defines functions that access or modify individual bits in a number.
13pub trait BitAccess {
14    /// Determines whether a number has a `true` or `false` bit at `index`.
15    fn get_bit(&self, index: u64) -> bool;
16
17    /// Sets the bit at `index` to `true`.
18    fn set_bit(&mut self, index: u64);
19
20    /// Sets the bit at `index` to `false`.
21    fn clear_bit(&mut self, index: u64);
22
23    /// Sets the bit at `index` to whichever value `bit` is.
24    ///
25    /// # Worst-case complexity
26    /// $T(n) = O(\max(T_S(n), T_C(n)))$,
27    ///
28    /// $M(n) = O(\max(M_S(n), M_C(n)))$
29    ///
30    /// where $T$ is time, $M$ is additional memory, $T_S$ and $M_S$ are the complexities of
31    /// [`set_bit`](Self::set_bit), and $T_C$ and $M_C$ are the complexities of
32    /// [`clear_bit`](Self::clear_bit).
33    ///
34    /// # Panics
35    /// See panics for [`set_bit`](Self::set_bit) and [`clear_bit`](Self::clear_bit).
36    #[inline]
37    fn assign_bit(&mut self, index: u64, bit: bool) {
38        if bit {
39            self.set_bit(index);
40        } else {
41            self.clear_bit(index);
42        }
43    }
44
45    /// Sets the bit at `index` to the opposite of its original value.
46    ///
47    /// # Worst-case complexity
48    /// $T(n) = O(T_G(n) + \max(T_S(n), T_C(n)))$,
49    ///
50    /// $M(n) = O(M_G(n) + \max(M_S(n), M_C(n)))$
51    ///
52    /// where $T$ is time, $M$ is additional memory, $T_G$ and $M_G$ are the complexities of
53    /// [`get_bit`](Self::get_bit), $T_S$ and $M_S$ are the complexities of
54    /// [`set_bit`](Self::set_bit), and $T_C$ and $M_C$ are the complexities of
55    /// [`clear_bit`](Self::clear_bit).
56    ///
57    /// # Panics
58    /// See panics for [`get_bit`](Self::get_bit), [`set_bit`](Self::set_bit) and
59    /// [`clear_bit`](Self::clear_bit).
60    #[inline]
61    fn flip_bit(&mut self, index: u64) {
62        if self.get_bit(index) {
63            self.clear_bit(index);
64        } else {
65            self.set_bit(index);
66        }
67    }
68}
69
70/// Defines functions that access or modify blocks of adjacent bits in a number.
71pub trait BitBlockAccess: Sized {
72    type Bits;
73
74    /// Extracts a block of bits whose first index is `start` and last index is `end - 1`.
75    fn get_bits(&self, start: u64, end: u64) -> Self::Bits;
76
77    /// Extracts a block of bits whose first index is `start` and last index is `end - 1`, taking
78    /// ownership of `self`.
79    ///
80    /// # Worst-case complexity
81    /// For the default implementation, same as [`get_bits`](Self::get_bits).
82    ///
83    /// # Panics
84    /// For the default implementation, ee panics for [`get_bits`](Self::get_bits).
85    ///
86    /// # Examples
87    /// ```
88    /// use malachite_base::num::logic::traits::BitBlockAccess;
89    ///
90    /// assert_eq!((-0x5433i16).get_bits_owned(4, 8), 0xc);
91    /// assert_eq!((-0x5433i16).get_bits_owned(5, 9), 14);
92    /// assert_eq!((-0x5433i16).get_bits_owned(5, 5), 0);
93    /// assert_eq!((-0x5433i16).get_bits_owned(100, 104), 0xf);
94    /// ```
95    #[inline]
96    fn get_bits_owned(self, start: u64, end: u64) -> Self::Bits {
97        self.get_bits(start, end)
98    }
99
100    /// Assigns the least-significant `end - start` bits of `bits` to bits `start` through `end - 1`
101    /// (inclusive) of `self`.
102    fn assign_bits(&mut self, start: u64, end: u64, bits: &Self::Bits);
103}
104
105/// Defines functions that express a number as a [`Vec`] of bits or construct a number from an
106/// iterator of bits.
107pub trait BitConvertible {
108    /// Returns a [`Vec`] containing the bits of a number in ascending order: least- to
109    /// most-significant.
110    fn to_bits_asc(&self) -> Vec<bool>;
111
112    /// Returns a [`Vec`] containing the bits of a number in descending order: most- to
113    /// least-significant.
114    fn to_bits_desc(&self) -> Vec<bool>;
115
116    /// Converts an iterator of bits into a number. The input bits are in ascending order: least- to
117    /// most-significant.
118    fn from_bits_asc<I: Iterator<Item = bool>>(bits: I) -> Self;
119
120    /// Converts an iterator of bits into a value. The input bits are in descending order: most- to
121    /// least-significant.
122    fn from_bits_desc<I: Iterator<Item = bool>>(bits: I) -> Self;
123}
124
125/// Defines an iterator over a value's bits.
126pub trait BitIterable {
127    type BitIterator: DoubleEndedIterator<Item = bool> + Index<u64>;
128
129    /// Returns a double-ended iterator over a number's bits. When iterating in the forward
130    /// direction, the iterator ends after the producing the number's most-significant bit.
131    fn bits(self) -> Self::BitIterator;
132}
133
134/// Defines functions that search for the next `true` or `false` bit in a number, starting at a
135/// specified index and searching in the more-significant direction.
136pub trait BitScan {
137    /// Given a number and a starting index, searches the number for the smallest index of a `false`
138    /// bit that is greater than or equal to the starting index.
139    fn index_of_next_false_bit(self, start: u64) -> Option<u64>;
140
141    /// Given a number and a starting index, searches the number for the smallest index of a `true`
142    /// bit that is greater than or equal to the starting index.
143    fn index_of_next_true_bit(self, start: u64) -> Option<u64>;
144}
145
146/// Returns the number of ones in the binary representation of a number.
147pub trait CountOnes {
148    fn count_ones(self) -> u64;
149}
150
151/// Returns the number of zeros in the binary representation of a number.
152pub trait CountZeros {
153    fn count_zeros(self) -> u64;
154}
155
156/// Returns the Hamming distance between two numbers, or the number of bit flips needed to turn one
157/// into the other.
158pub trait HammingDistance<RHS = Self> {
159    fn hamming_distance(self, other: RHS) -> u64;
160}
161
162/// Returns the Hamming distance between two numbers, or the number of bit flips needed to turn one
163/// into the other.
164///
165/// This trait allows for the possibility of the distance being undefined for some pairs of numbers,
166/// in which case [`checked_hamming_distance`](Self::checked_hamming_distance) should return `None`.
167pub trait CheckedHammingDistance<RHS = Self> {
168    fn checked_hamming_distance(self, other: RHS) -> Option<u64>;
169}
170
171/// Returns the number of leading zeros in the binary representation of a number.
172pub trait LeadingZeros {
173    fn leading_zeros(self) -> u64;
174}
175
176/// Returns a number whose least significant $b$ bits are `true` and whose other bits are `false`.
177pub trait LowMask {
178    fn low_mask(bits: u64) -> Self;
179}
180
181/// Replaces a number with its bitwise negation.
182pub trait NotAssign {
183    fn not_assign(&mut self);
184}
185
186// Returns the number of significant bits of a number.
187pub trait SignificantBits {
188    /// The number of bits it takes to represent `self`.
189    fn significant_bits(self) -> u64;
190}
191
192/// Returns the number of trailing zeros in the binary representation of a number.
193pub trait TrailingZeros {
194    fn trailing_zeros(self) -> u64;
195}