malachite_base/num/logic/bit_convertible.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::conversion::traits::WrappingFrom;
12use crate::num::logic::traits::{BitConvertible, LeadingZeros};
13use alloc::vec::Vec;
14
15fn to_bits_asc_unsigned<T: PrimitiveUnsigned>(x: &T) -> Vec<bool> {
16 let mut bits = Vec::new();
17 let mut x = *x;
18 while x != T::ZERO {
19 bits.push(x.odd());
20 x >>= 1;
21 }
22 bits
23}
24
25fn to_bits_desc_unsigned<T: PrimitiveUnsigned>(x: &T) -> Vec<bool> {
26 let mut bits = Vec::new();
27 if *x == T::ZERO {
28 return bits;
29 }
30 bits.push(true);
31 if *x == T::ONE {
32 return bits;
33 }
34 let mut mask = T::power_of_2(T::WIDTH - LeadingZeros::leading_zeros(*x) - 2);
35 while mask != T::ZERO {
36 bits.push(*x & mask != T::ZERO);
37 mask >>= 1;
38 }
39 bits
40}
41
42fn from_bits_asc_unsigned<T: PrimitiveUnsigned, I: Iterator<Item = bool>>(bits: I) -> T {
43 let mut n = T::ZERO;
44 let mut mask = T::ONE;
45 for bit in bits {
46 if mask == T::ZERO {
47 assert!(!bit, "Bits cannot fit in integer of type {}", T::NAME);
48 } else {
49 if bit {
50 n |= mask;
51 }
52 mask <<= 1;
53 }
54 }
55 n
56}
57
58#[inline]
59fn from_bits_desc_unsigned<T: PrimitiveUnsigned, I: Iterator<Item = bool>>(bits: I) -> T {
60 let mut n = T::ZERO;
61 let high_mask = T::power_of_2(T::WIDTH - 1);
62 for bit in bits {
63 assert!(
64 n & high_mask == T::ZERO,
65 "Bits cannot fit in integer of type {}",
66 T::NAME
67 );
68 n <<= 1;
69 if bit {
70 n |= T::ONE;
71 }
72 }
73 n
74}
75
76macro_rules! impl_bit_convertible_unsigned {
77 ($t:ident) => {
78 impl BitConvertible for $t {
79 /// Returns a [`Vec`] containing the bits of a number in ascending order: least- to
80 /// most-significant.
81 ///
82 /// If the number is 0, the [`Vec`] is empty; otherwise, it ends with `true`.
83 ///
84 /// # Worst-case complexity
85 /// $T(n) = O(n)$
86 ///
87 /// $M(n) = O(n)$
88 ///
89 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
90 ///
91 /// # Examples
92 /// See [here](super::bit_convertible#to_bits_asc).
93 #[inline]
94 fn to_bits_asc(&self) -> Vec<bool> {
95 to_bits_asc_unsigned(self)
96 }
97
98 /// Returns a [`Vec`] containing the bits of a number in descending order: most- to
99 /// least-significant.
100 ///
101 /// If the number is 0, the [`Vec`] is empty; otherwise, it begins with `true`.
102 ///
103 /// # Worst-case complexity
104 /// $T(n) = O(n)$
105 ///
106 /// $M(n) = O(n)$
107 ///
108 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
109 ///
110 /// # Examples
111 /// See [here](super::bit_convertible#to_bits_desc).
112 #[inline]
113 fn to_bits_desc(&self) -> Vec<bool> {
114 to_bits_desc_unsigned(self)
115 }
116
117 /// Converts an iterator of bits into a number. The bits should be in ascending order
118 /// (least- to most-significant).
119 ///
120 /// The function panics if the input represents a number that can't fit in the output
121 /// type.
122 ///
123 /// $$
124 /// f((b_i)_ {i=0}^{k-1}) = \sum_{i=0}^{k-1}2^i \[b_i\],
125 /// $$
126 /// where braces denote the Iverson bracket, which converts a bit to 0 or 1.
127 ///
128 /// # Worst-case complexity
129 /// $T(n) = O(n)$
130 ///
131 /// $M(n) = O(1)$
132 ///
133 /// where $T$ is time, $M$ is additional memory, and $n$ is `bits.count()`.
134 ///
135 /// # Panics
136 /// Panics if the bits represent a value that isn't representable by the output type.
137 ///
138 /// # Examples
139 /// See [here](super::bit_convertible#from_bits_asc).
140 #[inline]
141 fn from_bits_asc<I: Iterator<Item = bool>>(bits: I) -> $t {
142 from_bits_asc_unsigned(bits)
143 }
144
145 /// Converts an iterator of bits into a number. The bits should be in descending order
146 /// (most- to least-significant).
147 ///
148 /// The function panics if the input represents a number that can't fit in the output
149 /// type.
150 ///
151 /// $$
152 /// f((b_i)_ {i=0}^{k-1}) = \sum_{i=0}^{k-1}2^{k-i-1} \[b_i\],
153 /// $$
154 /// where braces denote the Iverson bracket, which converts a bit to 0 or 1.
155 ///
156 /// # Worst-case complexity
157 /// $T(n) = O(n)$
158 ///
159 /// $M(n) = O(1)$
160 ///
161 /// where $T$ is time, $M$ is additional memory, and $n$ is `bits.count()`.
162 ///
163 /// # Panics
164 /// Panics if the bits represent a value that isn't representable by the output type.
165 ///
166 /// # Examples
167 /// See [here](super::bit_convertible#from_bits_desc).
168 #[inline]
169 fn from_bits_desc<I: Iterator<Item = bool>>(bits: I) -> $t {
170 from_bits_desc_unsigned(bits)
171 }
172 }
173 };
174}
175apply_to_unsigneds!(impl_bit_convertible_unsigned);
176
177fn to_bits_asc_signed<T: PrimitiveSigned>(x: &T) -> Vec<bool> {
178 let mut bits = Vec::new();
179 let mut x = *x;
180 if x >= T::ZERO {
181 while x != T::ZERO {
182 bits.push(x.odd());
183 x >>= 1;
184 }
185 if !bits.is_empty() {
186 bits.push(false);
187 }
188 } else {
189 while x != T::NEGATIVE_ONE {
190 bits.push(x.odd());
191 x >>= 1;
192 }
193 bits.push(true);
194 }
195 bits
196}
197
198fn to_bits_desc_signed<T: PrimitiveSigned>(x: &T) -> Vec<bool> {
199 let mut bits = Vec::new();
200 if *x >= T::ZERO {
201 if *x == T::ZERO {
202 return bits;
203 }
204 bits.push(false);
205 bits.push(true);
206 if *x == T::ONE {
207 return bits;
208 }
209 let mut mask = T::power_of_2(T::WIDTH - LeadingZeros::leading_zeros(*x) - 2);
210 while mask != T::ZERO {
211 bits.push(*x & mask != T::ZERO);
212 mask >>= 1;
213 }
214 } else {
215 bits.push(true);
216 if *x == T::NEGATIVE_ONE {
217 return bits;
218 }
219 bits.push(false);
220 if *x == T::NEGATIVE_ONE << 1 {
221 return bits;
222 }
223 let mut mask = T::power_of_2(T::WIDTH - LeadingZeros::leading_zeros(!*x) - 2);
224 while mask != T::ZERO {
225 bits.push(*x & mask != T::ZERO);
226 mask >>= 1;
227 }
228 }
229 bits
230}
231
232fn from_bits_asc_signed<
233 U: PrimitiveUnsigned,
234 S: PrimitiveSigned + WrappingFrom<U>,
235 I: Iterator<Item = bool>,
236>(
237 bits: I,
238) -> S {
239 let mut n = U::ZERO;
240 let mut mask = U::ONE;
241 let mut last_bit = false;
242 for bit in bits {
243 if mask == U::ZERO {
244 assert_eq!(
245 bit,
246 last_bit,
247 "Bits cannot fit in integer of type {}",
248 S::NAME
249 );
250 } else {
251 if bit {
252 n |= mask;
253 }
254 mask <<= 1;
255 last_bit = bit;
256 }
257 }
258 if last_bit {
259 S::wrapping_from(n | mask.wrapping_neg())
260 } else {
261 S::wrapping_from(n)
262 }
263}
264
265#[inline]
266fn from_bits_desc_signed<
267 U: PrimitiveUnsigned,
268 S: PrimitiveSigned + WrappingFrom<U>,
269 I: Iterator<Item = bool>,
270>(
271 bits: I,
272) -> S {
273 let mut n = U::ZERO;
274 let high_mask = U::power_of_2(U::WIDTH - 2);
275 let mut first = true;
276 let mut sign_bit = false;
277 for bit in bits {
278 if first {
279 sign_bit = bit;
280 first = false;
281 } else {
282 assert!(
283 n & high_mask == U::ZERO,
284 "Bits cannot fit in integer of type {}",
285 S::NAME
286 );
287 n <<= 1;
288 if bit != sign_bit {
289 n |= U::ONE;
290 }
291 }
292 }
293 if sign_bit {
294 S::wrapping_from(!n)
295 } else {
296 S::wrapping_from(n)
297 }
298}
299
300macro_rules! impl_bit_convertible_signed {
301 ($u:ident, $s:ident) => {
302 impl BitConvertible for $s {
303 /// Returns a [`Vec`] containing the bits of a number in ascending order: least- to
304 /// most-significant.
305 ///
306 /// If the number is 0, the [`Vec`] is empty; otherwise, the last bit is the sign bit:
307 /// `false` if the number is non-negative and `true` if it is negative.
308 ///
309 /// # Worst-case complexity
310 /// $T(n) = O(n)$
311 ///
312 /// $M(n) = O(n)$
313 ///
314 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
315 ///
316 /// # Examples
317 /// See [here](super::bit_convertible#to_bits_asc).
318 #[inline]
319 fn to_bits_asc(&self) -> Vec<bool> {
320 to_bits_asc_signed(self)
321 }
322
323 /// Returns a [`Vec`] containing the bits of a number in ascending order: most- to
324 /// least-significant.
325 ///
326 /// If the number is 0, the [`Vec`] is empty; otherwise, the first bit is the sign bit:
327 /// `false` if the number is non-negative and `true` if it is negative.
328 ///
329 /// # Worst-case complexity
330 /// $T(n) = O(n)$
331 ///
332 /// $M(n) = O(n)$
333 ///
334 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
335 ///
336 /// # Examples
337 /// See [here](super::bit_convertible#to_bits_desc).
338 #[inline]
339 fn to_bits_desc(&self) -> Vec<bool> {
340 to_bits_desc_signed(self)
341 }
342
343 /// Converts an iterator of bits into a value. The bits should be in ascending order
344 /// (least- to most-significant).
345 ///
346 /// The bits are interpreted as in twos-complement, and the last bit is the sign bit; if
347 /// it is `false`, the number is non-negative, and if it is `true`, the number is
348 /// negative.
349 ///
350 /// The function panics if the input represents a number that can't fit in the output
351 /// type.
352 ///
353 /// Let $k$ be `bits.count()`. If $k = 0$ or $b_{k-1}$ is `false`, then
354 /// $$
355 /// f((b_i)_ {i=0}^{k-1}) = \sum_{i=0}^{k-1}2^i \[b_i\],
356 /// $$
357 /// where braces denote the Iverson bracket, which converts a bit to 0 or 1.
358 ///
359 /// If $b_{k-1}$ is `true`, then
360 /// $$
361 /// f((b_i)_ {i=0}^{k-1}) = \left ( \sum_{i=0}^{k-1}2^i \[b_i\] \right ) - 2^k.
362 /// $$
363 ///
364 /// # Worst-case complexity
365 /// $T(n) = O(n)$
366 ///
367 /// $M(n) = O(1)$
368 ///
369 /// where $T$ is time, $M$ is additional memory, and $n$ is `bits.count()`.
370 ///
371 /// # Panics
372 /// Panics if the bits represent a value that doesn't fit in the output type.
373 ///
374 /// # Examples
375 /// See [here](super::bit_convertible#from_bits_asc).
376 #[inline]
377 fn from_bits_asc<I: Iterator<Item = bool>>(bits: I) -> $s {
378 from_bits_asc_signed::<$u, $s, _>(bits)
379 }
380
381 /// Converts an iterator of bits into a value. The bits should be in descending order
382 /// (most- to least-significant).
383 ///
384 /// The bits are interpreted as in twos-complement, and the first bit is the sign bit;
385 /// if it is `false`, the number is non-negative, and if it is `true`, the number is
386 /// negative.
387 ///
388 /// The function panics if the input represents a number that can't fit in the output
389 /// type.
390 ///
391 /// If `bits` is empty or $b_0$ is `false`, then
392 /// $$
393 /// f((b_i)_ {i=0}^{k-1}) = \sum_{i=0}^{k-1}2^{k-i-1} \[b_i\],
394 /// $$
395 /// where braces denote the Iverson bracket, which converts a bit to 0 or 1.
396 ///
397 /// If $b_0$ is `true`, then
398 /// $$
399 /// f((b_i)_ {i=0}^{k-1}) = \left ( \sum_{i=0}^{k-1}2^{k-i-1} \[b_i\] \right ) - 2^k.
400 /// $$
401 ///
402 /// # Examples
403 /// See [here](super::bit_convertible#from_bits_desc).
404 #[inline]
405 fn from_bits_desc<I: Iterator<Item = bool>>(bits: I) -> $s {
406 from_bits_desc_signed::<$u, $s, _>(bits)
407 }
408 }
409 };
410}
411apply_to_unsigned_signed_pairs!(impl_bit_convertible_signed);