malachite_base/num/logic/mod.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
9/// [`BitAccess`](traits::BitAccess), a trait for getting and setting individual bits of a number.
10///
11/// # get_bit
12/// ```
13/// use malachite_base::num::logic::traits::BitAccess;
14///
15/// assert_eq!(123u8.get_bit(2), false);
16/// assert_eq!(123u16.get_bit(3), true);
17/// assert_eq!(123u32.get_bit(100), false);
18/// assert_eq!(1000000000000u64.get_bit(12), true);
19/// assert_eq!(1000000000000u64.get_bit(100), false);
20///
21/// assert_eq!(123i8.get_bit(2), false);
22/// assert_eq!(123i16.get_bit(3), true);
23/// assert_eq!(123i32.get_bit(100), false);
24/// assert_eq!((-123i8).get_bit(0), true);
25/// assert_eq!((-123i16).get_bit(1), false);
26/// assert_eq!((-123i32).get_bit(100), true);
27/// assert_eq!(1000000000000i64.get_bit(12), true);
28/// assert_eq!(1000000000000i64.get_bit(100), false);
29/// assert_eq!((-1000000000000i64).get_bit(12), true);
30/// assert_eq!((-1000000000000i64).get_bit(100), true);
31/// ```
32///
33/// # set_bit
34/// ```
35/// use malachite_base::num::logic::traits::BitAccess;
36///
37/// let mut x = 0u8;
38/// x.set_bit(2);
39/// x.set_bit(5);
40/// x.set_bit(6);
41/// assert_eq!(x, 100);
42///
43/// let mut x = 0i8;
44/// x.set_bit(2);
45/// x.set_bit(5);
46/// x.set_bit(6);
47/// assert_eq!(x, 100);
48///
49/// let mut x = -0x100i16;
50/// x.set_bit(2);
51/// x.set_bit(5);
52/// x.set_bit(6);
53/// assert_eq!(x, -156);
54/// ```
55///
56/// # clear_bit
57/// ```
58/// use malachite_base::num::logic::traits::BitAccess;
59///
60/// let mut x = 0x7fu8;
61/// x.clear_bit(0);
62/// x.clear_bit(1);
63/// x.clear_bit(3);
64/// x.clear_bit(4);
65/// assert_eq!(x, 100);
66///
67/// let mut x = 0x7fi8;
68/// x.clear_bit(0);
69/// x.clear_bit(1);
70/// x.clear_bit(3);
71/// x.clear_bit(4);
72/// assert_eq!(x, 100);
73///
74/// let mut x = -156i16;
75/// x.clear_bit(2);
76/// x.clear_bit(5);
77/// x.clear_bit(6);
78/// assert_eq!(x, -256);
79/// ```
80///
81/// # assign_bit
82/// ```
83/// use malachite_base::num::logic::traits::BitAccess;
84///
85/// let mut x = 0;
86/// x.assign_bit(2, true);
87/// x.assign_bit(5, true);
88/// x.assign_bit(6, true);
89/// assert_eq!(x, 100);
90/// x.assign_bit(2, false);
91/// x.assign_bit(5, false);
92/// x.assign_bit(6, false);
93/// assert_eq!(x, 0);
94///
95/// x.assign_bit(2, true);
96/// x.assign_bit(5, true);
97/// x.assign_bit(6, true);
98/// assert_eq!(x, 100);
99/// x.assign_bit(2, false);
100/// x.assign_bit(5, false);
101/// x.assign_bit(6, false);
102/// assert_eq!(x, 0);
103///
104/// let mut x = -0x100i16;
105/// x.assign_bit(2, true);
106/// x.assign_bit(5, true);
107/// x.assign_bit(6, true);
108/// assert_eq!(x, -156);
109/// x.assign_bit(2, false);
110/// x.assign_bit(5, false);
111/// x.assign_bit(6, false);
112/// assert_eq!(x, -256);
113/// ```
114///
115/// # flip_bit
116/// ```
117/// use malachite_base::num::logic::traits::BitAccess;
118///
119/// let mut x = 0u64;
120/// x.flip_bit(10);
121/// assert_eq!(x, 1024);
122/// x.flip_bit(10);
123/// assert_eq!(x, 0);
124///
125/// let mut x = 0i32;
126/// x.flip_bit(10);
127/// assert_eq!(x, 1024);
128/// x.flip_bit(10);
129/// assert_eq!(x, 0);
130///
131/// let mut x = -1i64;
132/// x.flip_bit(10);
133/// assert_eq!(x, -1025);
134/// x.flip_bit(10);
135/// assert_eq!(x, -1);
136/// ```
137pub mod bit_access;
138/// [`BitBlockAccess`](traits::BitBlockAccess), a trait for getting and setting adjacent blocks of
139/// bits in a number.
140///
141/// # get_bits
142/// ```
143/// use malachite_base::num::logic::traits::BitBlockAccess;
144///
145/// assert_eq!(0xabcdu16.get_bits(4, 8), 0xc);
146/// assert_eq!(0xabcdu16.get_bits(12, 100), 0xa);
147/// assert_eq!(0xabcdu16.get_bits(5, 9), 14);
148/// assert_eq!(0xabcdu16.get_bits(5, 5), 0);
149/// assert_eq!(0xabcdu16.get_bits(100, 200), 0);
150///
151/// assert_eq!((-0x5433i16).get_bits(4, 8), 0xc);
152/// assert_eq!((-0x5433i16).get_bits(5, 9), 14);
153/// assert_eq!((-0x5433i16).get_bits(5, 5), 0);
154/// assert_eq!((-0x5433i16).get_bits(100, 104), 0xf);
155/// ```
156///
157/// # assign_bits
158/// ```
159/// use malachite_base::num::logic::traits::BitBlockAccess;
160///
161/// let mut x = 0xab5du16;
162/// x.assign_bits(4, 8, &0xc);
163/// assert_eq!(x, 0xabcd);
164///
165/// let mut x = 0xabcdu16;
166/// x.assign_bits(100, 200, &0);
167/// assert_eq!(x, 0xabcd);
168///
169/// let mut x = 0xabcdu16;
170/// x.assign_bits(0, 100, &0x1234);
171/// assert_eq!(x, 0x1234);
172///
173/// let mut x = 0x2b5di16;
174/// x.assign_bits(4, 8, &0xc);
175/// assert_eq!(x, 0x2bcd);
176///
177/// let mut x = -0x5413i16;
178/// x.assign_bits(4, 8, &0xc);
179/// assert_eq!(x, -0x5433);
180///
181/// let mut x = -0x5433i16;
182/// x.assign_bits(100, 104, &0xf);
183/// assert_eq!(x, -0x5433);
184/// ```
185pub mod bit_block_access;
186/// [`BitConvertible`](traits::BitConvertible), a trait for extracting all bits from a number or
187/// constructing a number from bits.
188///
189/// # to_bits_asc
190/// ```
191/// use malachite_base::num::logic::traits::BitConvertible;
192///
193/// assert_eq!(0u8.to_bits_asc(), &[]);
194/// assert_eq!(2u16.to_bits_asc(), &[false, true]);
195/// assert_eq!(
196/// 123u32.to_bits_asc(),
197/// &[true, true, false, true, true, true, true]
198/// );
199///
200/// assert_eq!(0i8.to_bits_asc(), &[]);
201/// assert_eq!(2i16.to_bits_asc(), &[false, true, false]);
202/// assert_eq!(
203/// (-123i32).to_bits_asc(),
204/// &[true, false, true, false, false, false, false, true]
205/// );
206/// ```
207///
208/// # to_bits_desc
209/// ```
210/// use malachite_base::num::logic::traits::BitConvertible;
211///
212/// assert_eq!(0u8.to_bits_desc(), &[]);
213/// assert_eq!(2u16.to_bits_desc(), &[true, false]);
214/// assert_eq!(
215/// 123u32.to_bits_desc(),
216/// &[true, true, true, true, false, true, true]
217/// );
218///
219/// assert_eq!(0i8.to_bits_desc(), &[]);
220/// assert_eq!(2i16.to_bits_desc(), &[false, true, false]);
221/// assert_eq!(
222/// (-123i32).to_bits_desc(),
223/// &[true, false, false, false, false, true, false, true]
224/// );
225/// ```
226///
227/// # from_bits_asc
228/// ```
229/// use malachite_base::num::logic::traits::BitConvertible;
230/// use std::iter::empty;
231///
232/// assert_eq!(u8::from_bits_asc(empty()), 0);
233/// assert_eq!(u16::from_bits_asc([false, true, false].iter().cloned()), 2);
234/// assert_eq!(
235/// u32::from_bits_asc([true, true, false, true, true, true, true].iter().cloned()),
236/// 123
237/// );
238///
239/// assert_eq!(i8::from_bits_asc(empty()), 0);
240/// assert_eq!(i16::from_bits_asc([false, true, false].iter().cloned()), 2);
241/// assert_eq!(
242/// i32::from_bits_asc(
243/// [true, false, true, false, false, false, false, true]
244/// .iter()
245/// .cloned()
246/// ),
247/// -123
248/// );
249/// ```
250///
251/// # from_bits_desc
252/// ```
253/// use malachite_base::num::logic::traits::BitConvertible;
254/// use std::iter::empty;
255///
256/// assert_eq!(u8::from_bits_desc(empty()), 0);
257/// assert_eq!(u16::from_bits_desc([false, true, false].iter().cloned()), 2);
258/// assert_eq!(
259/// u32::from_bits_desc([true, true, true, true, false, true, true].iter().cloned()),
260/// 123
261/// );
262///
263/// assert_eq!(i8::from_bits_desc(empty()), 0);
264/// assert_eq!(i16::from_bits_desc([false, true, false].iter().cloned()), 2);
265/// assert_eq!(
266/// i32::from_bits_desc(
267/// [true, false, false, false, false, true, false, true]
268/// .iter()
269/// .cloned()
270/// ),
271/// -123
272/// );
273/// ```
274pub mod bit_convertible;
275/// [`BitIterable`](traits::BitIterable), a trait for producing a double-ended iterator over a
276/// number's bits.
277///
278/// # bits
279/// ```
280/// use itertools::Itertools;
281/// use malachite_base::num::logic::traits::BitIterable;
282///
283/// assert!(0u8.bits().next().is_none());
284/// // 105 = 1101001b
285/// assert_eq!(
286/// 105u32.bits().collect_vec(),
287/// &[true, false, false, true, false, true, true]
288/// );
289///
290/// assert!(0u8.bits().next_back().is_none());
291/// // 105 = 1101001b
292/// assert_eq!(
293/// 105u32.bits().rev().collect_vec(),
294/// &[true, true, false, true, false, false, true]
295/// );
296///
297/// assert_eq!(0i8.bits().next(), None);
298/// // 105 = 01101001b, with a leading false bit to indicate sign
299/// assert_eq!(
300/// 105i32.bits().collect_vec(),
301/// &[true, false, false, true, false, true, true, false]
302/// );
303/// // -105 = 10010111 in two's complement, with a leading true bit to indicate sign
304/// assert_eq!(
305/// (-105i32).bits().collect_vec(),
306/// &[true, true, true, false, true, false, false, true]
307/// );
308///
309/// assert_eq!(0i8.bits().next_back(), None);
310/// // 105 = 01101001b, with a leading false bit to indicate sign
311/// assert_eq!(
312/// 105i32.bits().rev().collect_vec(),
313/// &[false, true, true, false, true, false, false, true]
314/// );
315/// // -105 = 10010111 in two's complement, with a leading true bit to indicate sign
316/// assert_eq!(
317/// (-105i32).bits().rev().collect_vec(),
318/// &[true, false, false, true, false, true, true, true]
319/// );
320/// ```
321pub mod bit_iterable;
322/// [`BitScan`](traits::BitScan), a trait for finding the next `true` or `false` bit in a number
323/// after a provided index.
324///
325/// # index_of_next_false_bit
326/// ```
327/// use malachite_base::num::logic::traits::BitScan;
328///
329/// assert_eq!(0xb00000000u64.index_of_next_false_bit(0), Some(0));
330/// assert_eq!(0xb00000000u64.index_of_next_false_bit(20), Some(20));
331/// assert_eq!(0xb00000000u64.index_of_next_false_bit(31), Some(31));
332/// assert_eq!(0xb00000000u64.index_of_next_false_bit(32), Some(34));
333/// assert_eq!(0xb00000000u64.index_of_next_false_bit(33), Some(34));
334/// assert_eq!(0xb00000000u64.index_of_next_false_bit(34), Some(34));
335/// assert_eq!(0xb00000000u64.index_of_next_false_bit(35), Some(36));
336/// assert_eq!(0xb00000000u64.index_of_next_false_bit(100), Some(100));
337///
338/// assert_eq!((-0x500000000i64).index_of_next_false_bit(0), Some(0));
339/// assert_eq!((-0x500000000i64).index_of_next_false_bit(20), Some(20));
340/// assert_eq!((-0x500000000i64).index_of_next_false_bit(31), Some(31));
341/// assert_eq!((-0x500000000i64).index_of_next_false_bit(32), Some(34));
342/// assert_eq!((-0x500000000i64).index_of_next_false_bit(33), Some(34));
343/// assert_eq!((-0x500000000i64).index_of_next_false_bit(34), Some(34));
344/// assert_eq!((-0x500000000i64).index_of_next_false_bit(35), None);
345/// assert_eq!((-0x500000000i64).index_of_next_false_bit(100), None);
346/// ```
347///
348/// # index_of_next_true_bit
349/// ```
350/// use malachite_base::num::logic::traits::BitScan;
351///
352/// assert_eq!(0xb00000000u64.index_of_next_true_bit(0), Some(32));
353/// assert_eq!(0xb00000000u64.index_of_next_true_bit(20), Some(32));
354/// assert_eq!(0xb00000000u64.index_of_next_true_bit(31), Some(32));
355/// assert_eq!(0xb00000000u64.index_of_next_true_bit(32), Some(32));
356/// assert_eq!(0xb00000000u64.index_of_next_true_bit(33), Some(33));
357/// assert_eq!(0xb00000000u64.index_of_next_true_bit(34), Some(35));
358/// assert_eq!(0xb00000000u64.index_of_next_true_bit(35), Some(35));
359/// assert_eq!(0xb00000000u64.index_of_next_true_bit(36), None);
360/// assert_eq!(0xb00000000u64.index_of_next_true_bit(100), None);
361///
362/// assert_eq!((-0x500000000i64).index_of_next_true_bit(0), Some(32));
363/// assert_eq!((-0x500000000i64).index_of_next_true_bit(20), Some(32));
364/// assert_eq!((-0x500000000i64).index_of_next_true_bit(31), Some(32));
365/// assert_eq!((-0x500000000i64).index_of_next_true_bit(32), Some(32));
366/// assert_eq!((-0x500000000i64).index_of_next_true_bit(33), Some(33));
367/// assert_eq!((-0x500000000i64).index_of_next_true_bit(34), Some(35));
368/// assert_eq!((-0x500000000i64).index_of_next_true_bit(35), Some(35));
369/// assert_eq!((-0x500000000i64).index_of_next_true_bit(36), Some(36));
370/// assert_eq!((-0x500000000i64).index_of_next_true_bit(100), Some(100));
371/// ```
372pub mod bit_scan;
373/// [`CountOnes`](traits::CountOnes), a trait for counting the number of ones in the binary
374/// representation of a number.
375pub mod count_ones;
376/// [`CountZeros`](traits::CountZeros), a trait for counting the number of ones in the binary
377/// representation of a number.
378pub mod count_zeros;
379/// [`HammingDistance`](traits::HammingDistance) and
380/// [`CheckedHammingDistance`](traits::CheckedHammingDistance), traits for computing the Hamming
381/// distance between two numbers.
382///
383/// # hamming_distance
384/// ```
385/// use malachite_base::num::logic::traits::HammingDistance;
386///
387/// assert_eq!(123u32.hamming_distance(456), 6);
388/// assert_eq!(0u8.hamming_distance(255), 8);
389/// ```
390///
391/// # checked_hamming_distance
392/// ```
393/// use malachite_base::num::logic::traits::CheckedHammingDistance;
394///
395/// assert_eq!(123i32.checked_hamming_distance(456), Some(6));
396/// assert_eq!(0i8.checked_hamming_distance(127), Some(7));
397/// assert_eq!(0i8.checked_hamming_distance(-1), None);
398/// ```
399pub mod hamming_distance;
400/// [`LeadingZeros`](traits::LeadingZeros), a trait for determining the number of zeros that a
401/// number starts with, when written in binary using $W$ bits, $W$ being the type width.
402pub mod leading_zeros;
403/// [`LowMask`](traits::LowMask), a trait for generating a low bit mask (a number in which only the
404/// $k$ least-significant bits are 1).
405///
406/// # low_mask
407/// ```
408/// use malachite_base::num::logic::traits::LowMask;
409///
410/// assert_eq!(u16::low_mask(0), 0);
411/// assert_eq!(u8::low_mask(3), 0x7);
412/// assert_eq!(u8::low_mask(8), 0xff);
413/// assert_eq!(u64::low_mask(40), 0xffffffffff);
414///
415/// assert_eq!(i16::low_mask(0), 0);
416/// assert_eq!(i8::low_mask(3), 0x7);
417/// assert_eq!(i8::low_mask(8), -1);
418/// assert_eq!(i64::low_mask(40), 0xffffffffff);
419/// ```
420pub mod low_mask;
421/// [`NotAssign`](traits::NotAssign), a trait for replacing a number with its bitwise negation.
422///
423/// # not_assign
424/// ```
425/// use malachite_base::num::logic::traits::NotAssign;
426///
427/// let mut x = 123u16;
428/// x.not_assign();
429/// assert_eq!(x, 65412);
430/// ```
431pub mod not;
432/// [`SignificantBits`](traits::SignificantBits), a trait for determining how many significant bits
433/// a number has.
434///
435/// # significant_bits
436/// ```
437/// use malachite_base::num::logic::traits::SignificantBits;
438///
439/// assert_eq!(0u8.significant_bits(), 0);
440/// assert_eq!(100u64.significant_bits(), 7);
441///
442/// assert_eq!(0i8.significant_bits(), 0);
443/// assert_eq!((-100i64).significant_bits(), 7);
444/// ```
445pub mod significant_bits;
446/// [`TrailingZeros`](traits::TrailingZeros), a trait for determining the number of zeros that a
447/// number ends with when written in binary.
448pub mod trailing_zeros;
449/// Various traits for performing logic or bitwise operations on numbers.
450pub mod traits;