Skip to main content

malachite_nz/integer/conversion/
from_twos_complement_limbs.rs

1// Copyright © 2026 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::integer::conversion::to_twos_complement_limbs::{
11    limbs_twos_complement, limbs_twos_complement_in_place,
12};
13use crate::natural::Natural;
14use crate::platform::Limb;
15use alloc::vec::Vec;
16use malachite_base::num::basic::integers::PrimitiveInt;
17use malachite_base::num::basic::traits::Zero;
18
19impl Integer {
20    /// Converts a slice of [limbs](crate#limbs) to an [`Integer`], in ascending order, so that less
21    /// significant limbs have lower indices in the input slice.
22    ///
23    /// The limbs are in two's complement, and the most significant bit of the limbs indicates the
24    /// sign; if the bit is zero, the [`Integer`] is non-negative, and if the bit is one it is
25    /// negative. If the slice is empty, zero is returned.
26    ///
27    /// This function borrows a slice. If taking ownership of a [`Vec`] is possible instead,
28    /// [`from_owned_twos_complement_limbs_asc`](`Self::from_owned_twos_complement_limbs_asc`) is
29    /// more efficient.
30    ///
31    /// This function is more efficient than
32    /// [`from_twos_complement_limbs_desc`](`Self::from_twos_complement_limbs_desc`).
33    ///
34    /// # Worst-case complexity
35    /// $T(n) = O(n)$
36    ///
37    /// $M(n) = O(n)$
38    ///
39    /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
40    ///
41    /// # Examples
42    /// ```
43    /// use malachite_base::num::basic::integers::PrimitiveInt;
44    /// use malachite_nz::integer::Integer;
45    /// use malachite_nz::platform::Limb;
46    ///
47    /// if Limb::WIDTH == u32::WIDTH {
48    ///     assert_eq!(Integer::from_twos_complement_limbs_asc(&[]), 0);
49    ///     assert_eq!(Integer::from_twos_complement_limbs_asc(&[123]), 123);
50    ///     assert_eq!(Integer::from_twos_complement_limbs_asc(&[4294967173]), -123);
51    ///     // 10^12 = 232 * 2^32 + 3567587328
52    ///     assert_eq!(
53    ///         Integer::from_twos_complement_limbs_asc(&[3567587328, 232]),
54    ///         1000000000000u64
55    ///     );
56    ///     assert_eq!(
57    ///         Integer::from_twos_complement_limbs_asc(&[727379968, 4294967063]),
58    ///         -1000000000000i64
59    ///     );
60    /// }
61    /// ```
62    pub fn from_twos_complement_limbs_asc(xs: &[Limb]) -> Self {
63        match xs {
64            &[] => Self::ZERO,
65            &[.., last] if !last.get_highest_bit() => Self::from(Natural::from_limbs_asc(xs)),
66            xs => -Natural::from_owned_limbs_asc(limbs_twos_complement(xs)),
67        }
68    }
69
70    /// Converts a slice of [limbs](crate#limbs) to an [`Integer`], in descending order, so that
71    /// less significant limbs have higher indices in the input slice.
72    ///
73    /// The limbs are in two's complement, and the most significant bit of the limbs indicates the
74    /// sign; if the bit is zero, the [`Integer`] is non-negative, and if the bit is one it is
75    /// negative. If the slice is empty, zero is returned.
76    ///
77    /// This function borrows a slice. If taking ownership of a [`Vec`] is possible instead,
78    /// [`from_owned_twos_complement_limbs_desc`](`Self::from_owned_twos_complement_limbs_desc`) is
79    /// more efficient.
80    ///
81    /// This function is less efficient than
82    /// [`from_twos_complement_limbs_asc`](`Self::from_twos_complement_limbs_asc`).
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 `xs.len()`.
90    ///
91    /// # Examples
92    /// ```
93    /// use malachite_base::num::basic::integers::PrimitiveInt;
94    /// use malachite_nz::integer::Integer;
95    /// use malachite_nz::platform::Limb;
96    ///
97    /// if Limb::WIDTH == u32::WIDTH {
98    ///     assert_eq!(Integer::from_twos_complement_limbs_desc(&[]), 0);
99    ///     assert_eq!(Integer::from_twos_complement_limbs_desc(&[123]), 123);
100    ///     assert_eq!(
101    ///         Integer::from_twos_complement_limbs_desc(&[4294967173]),
102    ///         -123
103    ///     );
104    ///     // 10^12 = 232 * 2^32 + 3567587328
105    ///     assert_eq!(
106    ///         Integer::from_twos_complement_limbs_desc(&[232, 3567587328]),
107    ///         1000000000000u64
108    ///     );
109    ///     assert_eq!(
110    ///         Integer::from_twos_complement_limbs_desc(&[4294967063, 727379968]),
111    ///         -1000000000000i64
112    ///     );
113    /// }
114    /// ```
115    #[inline]
116    pub fn from_twos_complement_limbs_desc(xs: &[Limb]) -> Self {
117        Self::from_owned_twos_complement_limbs_asc(xs.iter().copied().rev().collect())
118    }
119
120    /// Converts a slice of [limbs](crate#limbs) to an [`Integer`], in ascending order, so that less
121    /// significant limbs have lower indices in the input slice.
122    ///
123    /// The limbs are in two's complement, and the most significant bit of the limbs indicates the
124    /// sign; if the bit is zero, the [`Integer`] is non-negative, and if the bit is one it is
125    /// negative. If the slice is empty, zero is returned.
126    ///
127    /// This function takes ownership of a [`Vec`]. If it's necessary to borrow a slice instead, use
128    /// [`from_twos_complement_limbs_asc`](`Self::from_twos_complement_limbs_asc`)
129    ///
130    /// This function is more efficient than
131    /// [`from_owned_twos_complement_limbs_desc`](`Self::from_owned_twos_complement_limbs_desc`).
132    ///
133    /// # Worst-case complexity
134    /// $T(n) = O(n)$
135    ///
136    /// $M(n) = O(1)$
137    ///
138    /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
139    ///
140    /// # Examples
141    /// ```
142    /// use malachite_base::num::basic::integers::PrimitiveInt;
143    /// use malachite_nz::integer::Integer;
144    /// use malachite_nz::platform::Limb;
145    ///
146    /// if Limb::WIDTH == u32::WIDTH {
147    ///     assert_eq!(Integer::from_owned_twos_complement_limbs_asc(vec![]), 0);
148    ///     assert_eq!(
149    ///         Integer::from_owned_twos_complement_limbs_asc(vec![123]),
150    ///         123
151    ///     );
152    ///     assert_eq!(
153    ///         Integer::from_owned_twos_complement_limbs_asc(vec![4294967173]),
154    ///         -123
155    ///     );
156    ///     // 10^12 = 232 * 2^32 + 3567587328
157    ///     assert_eq!(
158    ///         Integer::from_owned_twos_complement_limbs_asc(vec![3567587328, 232]),
159    ///         1000000000000i64
160    ///     );
161    ///     assert_eq!(
162    ///         Integer::from_owned_twos_complement_limbs_asc(vec![727379968, 4294967063]),
163    ///         -1000000000000i64
164    ///     );
165    /// }
166    /// ```
167    pub fn from_owned_twos_complement_limbs_asc(mut xs: Vec<Limb>) -> Self {
168        match *xs.as_slice() {
169            [] => Self::ZERO,
170            [.., last] if !last.get_highest_bit() => Self::from(Natural::from_owned_limbs_asc(xs)),
171            _ => {
172                assert!(!limbs_twos_complement_in_place(&mut xs));
173                -Natural::from_owned_limbs_asc(xs)
174            }
175        }
176    }
177
178    /// Converts a slice of [limbs](crate#limbs) to an [`Integer`], in descending order, so that
179    /// less significant limbs have higher indices in the input slice.
180    ///
181    /// The limbs are in two's complement, and the most significant bit of the limbs indicates the
182    /// sign; if the bit is zero, the [`Integer`] is non-negative, and if the bit is one it is
183    /// negative. If the slice is empty, zero is returned.
184    ///
185    /// This function takes ownership of a [`Vec`]. If it's necessary to borrow a slice instead, use
186    /// [`from_twos_complement_limbs_desc`](`Self::from_twos_complement_limbs_desc`).
187    ///
188    /// This function is less efficient than
189    /// [`from_owned_twos_complement_limbs_asc`](`Self::from_owned_twos_complement_limbs_asc`).
190    ///
191    /// # Worst-case complexity
192    /// $T(n) = O(n)$
193    ///
194    /// $M(n) = O(1)$
195    ///
196    /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
197    ///
198    /// # Examples
199    /// ```
200    /// use malachite_base::num::basic::integers::PrimitiveInt;
201    /// use malachite_nz::integer::Integer;
202    /// use malachite_nz::platform::Limb;
203    ///
204    /// if Limb::WIDTH == u32::WIDTH {
205    ///     assert_eq!(Integer::from_owned_twos_complement_limbs_desc(vec![]), 0);
206    ///     assert_eq!(
207    ///         Integer::from_owned_twos_complement_limbs_desc(vec![123]),
208    ///         123
209    ///     );
210    ///     assert_eq!(
211    ///         Integer::from_owned_twos_complement_limbs_desc(vec![4294967173]),
212    ///         -123
213    ///     );
214    ///     // 10^12 = 232 * 2^32 + 3567587328
215    ///     assert_eq!(
216    ///         Integer::from_owned_twos_complement_limbs_desc(vec![232, 3567587328]),
217    ///         1000000000000i64
218    ///     );
219    ///     assert_eq!(
220    ///         Integer::from_owned_twos_complement_limbs_desc(vec![4294967063, 727379968]),
221    ///         -1000000000000i64
222    ///     );
223    /// }
224    /// ```
225    pub fn from_owned_twos_complement_limbs_desc(mut xs: Vec<Limb>) -> Self {
226        xs.reverse();
227        Self::from_owned_twos_complement_limbs_asc(xs)
228    }
229}