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}