malachite_nz/integer/conversion/to_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::natural::Natural;
11use crate::natural::arithmetic::add::limbs_slice_add_limb_in_place;
12use crate::natural::conversion::to_limbs::LimbIterator;
13use crate::natural::logic::not::limbs_not_in_place;
14use crate::platform::Limb;
15use alloc::vec::Vec;
16use malachite_base::num::arithmetic::traits::{IsPowerOf2, UnsignedAbs};
17use malachite_base::num::basic::integers::PrimitiveInt;
18use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom};
19use malachite_base::slices::slice_leading_zeros;
20
21// Given the limbs of the absolute value of an `Integer`, in ascending order, returns the two's
22// complement limbs. The input limbs should not be all zero.
23//
24// # Worst-case complexity
25// $T(n) = O(n)$
26//
27// $M(n) = O(n)$
28//
29// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
30crate_test_fn! {limbs_twos_complement(xs: &[Limb]) -> Vec<Limb> {
31 let i = slice_leading_zeros(xs);
32 let mut result = vec![0; i];
33 if i != xs.len() {
34 result.push(xs[i].wrapping_neg());
35 for x in &xs[i + 1..] {
36 result.push(!x);
37 }
38 }
39 result
40}}
41
42// Given the limbs of a non-negative `Integer`, in ascending order, checks whether the most
43// significant bit is `false`; if it isn't, appends an extra zero bit. This way the `Integer`'s
44// non-negativity is preserved in its limbs.
45//
46// # Worst-case complexity
47// Constant time and additional memory.
48private_test_fn! {limbs_maybe_sign_extend_non_negative_in_place(xs: &mut Vec<Limb>) {
49 if let Some(last) = xs.last() && last.get_highest_bit() {
50 // Sign-extend with an extra 0 limb to indicate a positive Integer
51 xs.push(0);
52 }
53}}
54
55// Given the limbs of the absolute value of an `Integer`, in ascending order, converts the limbs to
56// two's complement. Returns whether there is a carry left over from the two's complement conversion
57// process.
58//
59// # Worst-case complexity
60// $T(n) = O(n)$
61//
62// $M(n) = O(1)$
63//
64// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
65crate_test_fn! {limbs_twos_complement_in_place(xs: &mut [Limb]) -> bool {
66 limbs_not_in_place(xs);
67 limbs_slice_add_limb_in_place(xs, 1)
68}}
69
70// Given the limbs of the absolute value of a negative `Integer`, in ascending order, converts the
71// limbs to two's complement and checks whether the most significant bit is `true`; if it isn't,
72// appends an extra `Limb::MAX` bit. This way the `Integer`'s negativity is preserved in its limbs.
73// The limbs cannot be empty or contain only zeros.
74//
75// # Worst-case complexity
76// $T(n) = O(n)$
77//
78// $M(n) = O(1)$
79//
80// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
81//
82// # Panics
83// Panics if `xs` contains only zeros.
84private_test_fn! {limbs_twos_complement_and_maybe_sign_extend_negative_in_place(
85 xs: &mut Vec<Limb>,
86) {
87 assert!(!limbs_twos_complement_in_place(xs));
88 if let Some(last) = xs.last() && !last.get_highest_bit() {
89 // Sign-extend with an extra !0 limb to indicate a negative Integer
90 xs.push(Limb::MAX);
91 }
92}}
93
94#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
95pub struct NegativeLimbIterator<'a>(NLIterator<'a>);
96
97// A double-ended iterator over the two's complement [limbs](crate#limbs) of the negative of an
98// [`Integer`].
99//
100// The forward order is ascending (least-significant first). There may be at most one
101// most-significant `Limb::MAX` limb.
102#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
103struct NLIterator<'a> {
104 pub(crate) limbs: LimbIterator<'a>,
105 first_nonzero_index: Option<usize>,
106}
107
108impl NLIterator<'_> {
109 fn get_limb(&self, index: u64) -> Limb {
110 let index = usize::exact_from(index);
111 if index >= self.limbs.len() {
112 // We're indexing into the infinite suffix of Limb::MAXs
113 Limb::MAX
114 } else {
115 for i in 0..index {
116 if self.limbs[i] != 0 {
117 return !self.limbs[index];
118 }
119 }
120 self.limbs[index].wrapping_neg()
121 }
122 }
123}
124
125impl Iterator for NLIterator<'_> {
126 type Item = Limb;
127
128 // A function to iterate through the two's complement limbs of the negative of a `Natural` in
129 // ascending order (least-significant first).
130 //
131 // # Worst-case complexity
132 // Constant time and additional memory.
133 fn next(&mut self) -> Option<Limb> {
134 let previous_i = self.limbs.i;
135 self.limbs.next().map(|limb| {
136 if let Some(first_nonzero_index) = self.first_nonzero_index {
137 if previous_i <= u64::wrapping_from(first_nonzero_index) {
138 limb.wrapping_neg()
139 } else {
140 !limb
141 }
142 } else {
143 if limb != 0 {
144 self.first_nonzero_index = Some(usize::exact_from(previous_i));
145 }
146 limb.wrapping_neg()
147 }
148 })
149 }
150
151 // A function that returns the length of the negative limbs iterator; that is, the `Natural`'s
152 // negative limb count (this is the same as its limb count). The format is (lower bound,
153 // Option<upper bound>), but in this case it's trivial to always have an exact bound.
154 //
155 // # Worst-case complexity
156 // Constant time and additional memory.
157 #[inline]
158 fn size_hint(&self) -> (usize, Option<usize>) {
159 self.limbs.size_hint()
160 }
161}
162
163impl DoubleEndedIterator for NLIterator<'_> {
164 // A function to iterate through the two's complement limbs of the negative of a `Natural` in
165 // descending order (most-significant first). This is worst-case linear since the first
166 // `next_back` call needs to determine the index of the least-significant nonzero limb.
167 //
168 // # Worst-case complexity
169 // $T(n) = O(n)$
170 //
171 // $M(n) = O(1)$
172 //
173 // where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
174 fn next_back(&mut self) -> Option<Limb> {
175 let previous_j = self.limbs.j;
176 self.limbs.next_back().map(|limb| {
177 if self.first_nonzero_index.is_none() {
178 let mut i = 0;
179 while self.limbs[i] == 0 {
180 i += 1;
181 }
182 self.first_nonzero_index = Some(i);
183 }
184 let first_nonzero_index = self.first_nonzero_index.unwrap();
185 if previous_j <= u64::wrapping_from(first_nonzero_index) {
186 limb.wrapping_neg()
187 } else {
188 !limb
189 }
190 })
191 }
192}
193
194trait SignExtendedLimbIterator: DoubleEndedIterator<Item = Limb> {
195 const EXTENSION: Limb;
196
197 fn needs_sign_extension(&self) -> bool;
198
199 fn iterate_forward(&mut self, extension_checked: &mut bool) -> Option<Limb> {
200 let next = self.next();
201 if next.is_none() {
202 if *extension_checked {
203 None
204 } else {
205 *extension_checked = true;
206 if self.needs_sign_extension() {
207 Some(Self::EXTENSION)
208 } else {
209 None
210 }
211 }
212 } else {
213 next
214 }
215 }
216
217 fn iterate_backward(&mut self, extension_checked: &mut bool) -> Option<Limb> {
218 if !*extension_checked {
219 *extension_checked = true;
220 if self.needs_sign_extension() {
221 return Some(Self::EXTENSION);
222 }
223 }
224 self.next_back()
225 }
226}
227
228impl SignExtendedLimbIterator for LimbIterator<'_> {
229 const EXTENSION: Limb = 0;
230
231 fn needs_sign_extension(&self) -> bool {
232 self[self.limb_count - 1].get_highest_bit()
233 }
234}
235
236impl SignExtendedLimbIterator for NLIterator<'_> {
237 const EXTENSION: Limb = Limb::MAX;
238
239 fn needs_sign_extension(&self) -> bool {
240 let mut i = 0;
241 while self.limbs[i] == 0 {
242 i += 1;
243 }
244 let last_limb_index = self.limbs.limb_count - 1;
245 let last_limb = self.limbs[last_limb_index];
246 let twos_complement_limb = if i == last_limb_index {
247 last_limb.wrapping_neg()
248 } else {
249 !last_limb
250 };
251 !twos_complement_limb.get_highest_bit()
252 }
253}
254
255/// A double-ended iterator over the twos-complement [limbs](crate#limbs) of an [`Integer`].
256///
257/// The forward order is ascending (least-significant first). The most significant bit of the most
258/// significant limb corresponds to the sign of the [`Integer`]; `false` for non-negative and `true`
259/// for negative. This means that there may be a single most-significant sign-extension limb that is
260/// 0 or `Limb::MAX`.
261///
262/// This struct also supports retrieving limbs by index. This functionality is completely
263/// independent of the iterator's state. Indexing the implicit leading limbs is allowed.
264#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
265pub enum TwosComplementLimbIterator<'a> {
266 Zero,
267 Positive(LimbIterator<'a>, bool),
268 Negative(NegativeLimbIterator<'a>, bool),
269}
270
271impl TwosComplementLimbIterator<'_> {
272 /// A function to retrieve twos-complement [limbs](crate#limbs) by index. Indexing at or above
273 /// the limb count returns zero or `Limb::MAX` limbs, depending on the sign of the `[Integer`].
274 ///
275 /// # Worst-case complexity
276 /// $T(n) = O(n)$
277 ///
278 /// $M(n) = O(1)$
279 ///
280 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
281 ///
282 /// # Examples
283 /// ```
284 /// use malachite_base::num::arithmetic::traits::Pow;
285 /// use malachite_base::num::basic::integers::PrimitiveInt;
286 /// use malachite_base::num::basic::traits::Zero;
287 /// use malachite_nz::integer::Integer;
288 /// use malachite_nz::platform::Limb;
289 ///
290 /// if Limb::WIDTH == u32::WIDTH {
291 /// assert_eq!(Integer::ZERO.twos_complement_limbs().get_limb(0), 0);
292 ///
293 /// // 2^64 - 10^12 = 4294967063 * 2^32 + 727379968
294 /// let negative_trillion = -Integer::from(10u32).pow(12);
295 /// let limbs = negative_trillion.twos_complement_limbs();
296 /// assert_eq!(limbs.get_limb(0), 727379968);
297 /// assert_eq!(limbs.get_limb(1), 4294967063);
298 /// assert_eq!(limbs.get_limb(2), 4294967295);
299 /// assert_eq!(limbs.get_limb(100), 4294967295);
300 /// }
301 /// ```
302 pub fn get_limb(&self, index: u64) -> Limb {
303 match self {
304 Self::Zero => 0,
305 Self::Positive(limbs, _) => limbs[usize::exact_from(index)],
306 Self::Negative(limbs, _) => limbs.0.get_limb(index),
307 }
308 }
309}
310
311impl Iterator for TwosComplementLimbIterator<'_> {
312 type Item = Limb;
313
314 /// A function to iterate through the twos-complement [limbs](crate#limbs) of an [`Integer`] in
315 /// ascending order (least-significant first). The last limb may be a sign-extension limb.
316 ///
317 /// # Worst-case complexity
318 /// Constant time and additional memory.
319 ///
320 /// # Examples
321 /// ```
322 /// use malachite_base::num::arithmetic::traits::Pow;
323 /// use malachite_base::num::basic::integers::PrimitiveInt;
324 /// use malachite_base::num::basic::traits::Zero;
325 /// use malachite_nz::integer::Integer;
326 /// use malachite_nz::platform::Limb;
327 ///
328 /// if Limb::WIDTH == u32::WIDTH {
329 /// assert_eq!(Integer::ZERO.twos_complement_limbs().next(), None);
330 ///
331 /// // 2^64 - 10^12 = 4294967063 * 2^32 + 727379968
332 /// let negative_trillion = -Integer::from(10u32).pow(12);
333 /// let mut limbs = negative_trillion.twos_complement_limbs();
334 /// assert_eq!(limbs.next(), Some(727379968));
335 /// assert_eq!(limbs.next(), Some(4294967063));
336 /// assert_eq!(limbs.next(), None);
337 /// }
338 /// ```
339 fn next(&mut self) -> Option<Limb> {
340 match self {
341 Self::Zero => None,
342 Self::Positive(limbs, extension_checked) => limbs.iterate_forward(extension_checked),
343 Self::Negative(limbs, extension_checked) => limbs.0.iterate_forward(extension_checked),
344 }
345 }
346}
347
348impl DoubleEndedIterator for TwosComplementLimbIterator<'_> {
349 /// A function to iterate through the twos-complement [limbs](crate#limbs) of an [`Integer`] in
350 /// descending order (most-significant first). The first limb may be a sign-extension limb.
351 ///
352 /// # Worst-case complexity
353 /// $T(n) = O(n)$
354 ///
355 /// $M(n) = O(1)$
356 ///
357 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
358 ///
359 /// # Examples
360 /// ```
361 /// use malachite_base::num::arithmetic::traits::Pow;
362 /// use malachite_base::num::basic::integers::PrimitiveInt;
363 /// use malachite_base::num::basic::traits::Zero;
364 /// use malachite_nz::integer::Integer;
365 /// use malachite_nz::platform::Limb;
366 ///
367 /// if Limb::WIDTH == u32::WIDTH {
368 /// assert_eq!(Integer::ZERO.twos_complement_limbs().next_back(), None);
369 ///
370 /// // 2^64 - 10^12 = 4294967063 * 2^32 + 727379968
371 /// let negative_trillion = -Integer::from(10u32).pow(12);
372 /// let mut limbs = negative_trillion.twos_complement_limbs();
373 /// assert_eq!(limbs.next_back(), Some(4294967063));
374 /// assert_eq!(limbs.next_back(), Some(727379968));
375 /// assert_eq!(limbs.next_back(), None);
376 /// }
377 /// ```
378 fn next_back(&mut self) -> Option<Limb> {
379 match self {
380 Self::Zero => None,
381 Self::Positive(limbs, extension_checked) => limbs.iterate_backward(extension_checked),
382 Self::Negative(limbs, extension_checked) => limbs.0.iterate_backward(extension_checked),
383 }
384 }
385}
386
387impl Natural {
388 /// Returns a double-ended iterator over the two's complement limbs of the negative of a
389 /// [`Natural`]. The forward order is ascending, so that less significant limbs appear first.
390 /// There may be at most one trailing `Limb::MAX` limb going forward, or leading `Limb::MAX`
391 /// limb going backward. The [`Natural`] cannot be zero.
392 ///
393 /// # Worst-case complexity
394 /// Constant time and additional memory.
395 fn negative_limbs(&self) -> NegativeLimbIterator<'_> {
396 assert_ne!(*self, 0, "Cannot get negative limbs of 0.");
397 NegativeLimbIterator(NLIterator {
398 limbs: self.limbs(),
399 first_nonzero_index: None,
400 })
401 }
402}
403
404impl Integer {
405 /// Returns the [limbs](crate#limbs) of an [`Integer`], in ascending order, so that less
406 /// significant limbs have lower indices in the output vector.
407 ///
408 /// The limbs are in two's complement, and the most significant bit of the limbs indicates the
409 /// sign; if the bit is zero, the [`Integer`] is positive, and if the bit is one it is negative.
410 /// There are no trailing zero limbs if the [`Integer`] is positive or trailing `Limb::MAX`
411 /// limbs if the [`Integer`] is negative, except as necessary to include the correct sign bit.
412 /// Zero is a special case: it contains no limbs.
413 ///
414 /// This function borrows `self`. If taking ownership of `self` is possible,
415 /// [`into_twos_complement_limbs_asc`](`Self::into_twos_complement_limbs_asc`) is more
416 /// efficient.
417 ///
418 /// This function is more efficient than
419 /// [`to_twos_complement_limbs_desc`](`Self::to_twos_complement_limbs_desc`).
420 ///
421 /// # Worst-case complexity
422 /// $T(n) = O(n)$
423 ///
424 /// $M(n) = O(n)$
425 ///
426 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
427 ///
428 /// # Examples
429 /// ```
430 /// use malachite_base::num::arithmetic::traits::Pow;
431 /// use malachite_base::num::basic::integers::PrimitiveInt;
432 /// use malachite_base::num::basic::traits::Zero;
433 /// use malachite_nz::integer::Integer;
434 /// use malachite_nz::platform::Limb;
435 ///
436 /// if Limb::WIDTH == u32::WIDTH {
437 /// assert!(Integer::ZERO.to_twos_complement_limbs_asc().is_empty());
438 /// assert_eq!(Integer::from(123).to_twos_complement_limbs_asc(), &[123]);
439 /// assert_eq!(
440 /// Integer::from(-123).to_twos_complement_limbs_asc(),
441 /// &[4294967173]
442 /// );
443 /// // 10^12 = 232 * 2^32 + 3567587328
444 /// assert_eq!(
445 /// Integer::from(10u32).pow(12).to_twos_complement_limbs_asc(),
446 /// &[3567587328, 232]
447 /// );
448 /// assert_eq!(
449 /// (-Integer::from(10u32).pow(12)).to_twos_complement_limbs_asc(),
450 /// &[727379968, 4294967063]
451 /// );
452 /// }
453 /// ```
454 pub fn to_twos_complement_limbs_asc(&self) -> Vec<Limb> {
455 let mut limbs = self.abs.to_limbs_asc();
456 if self.sign {
457 limbs_maybe_sign_extend_non_negative_in_place(&mut limbs);
458 } else {
459 limbs_twos_complement_and_maybe_sign_extend_negative_in_place(&mut limbs);
460 }
461 limbs
462 }
463
464 /// Returns the [limbs](crate#limbs) of an [`Integer`], in descending order, so that less
465 /// significant limbs have higher indices in the output vector.
466 ///
467 /// The limbs are in two's complement, and the most significant bit of the limbs indicates the
468 /// sign; if the bit is zero, the [`Integer`] is positive, and if the bit is one it is negative.
469 /// There are no leading zero limbs if the [`Integer`] is non-negative or leading `Limb::MAX`
470 /// limbs if the [`Integer`] is negative, except as necessary to include the correct sign bit.
471 /// Zero is a special case: it contains no limbs.
472 ///
473 /// This is similar to how `BigInteger`s in Java are represented.
474 ///
475 /// This function borrows `self`. If taking ownership of `self` is possible,
476 /// [`into_twos_complement_limbs_desc`](`Self::into_twos_complement_limbs_desc`) is more
477 /// efficient.
478 ///
479 /// This function is less efficient than
480 /// [`to_twos_complement_limbs_asc`](`Self::to_twos_complement_limbs_asc`).
481 ///
482 /// # Worst-case complexity
483 /// $T(n) = O(n)$
484 ///
485 /// $M(n) = O(n)$
486 ///
487 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
488 ///
489 /// # Examples
490 /// ```
491 /// use malachite_base::num::arithmetic::traits::Pow;
492 /// use malachite_base::num::basic::integers::PrimitiveInt;
493 /// use malachite_base::num::basic::traits::Zero;
494 /// use malachite_nz::integer::Integer;
495 /// use malachite_nz::platform::Limb;
496 ///
497 /// if Limb::WIDTH == u32::WIDTH {
498 /// assert!(Integer::ZERO.to_twos_complement_limbs_desc().is_empty());
499 /// assert_eq!(Integer::from(123).to_twos_complement_limbs_desc(), &[123]);
500 /// assert_eq!(
501 /// Integer::from(-123).to_twos_complement_limbs_desc(),
502 /// &[4294967173]
503 /// );
504 /// // 10^12 = 232 * 2^32 + 3567587328
505 /// assert_eq!(
506 /// Integer::from(10u32).pow(12).to_twos_complement_limbs_desc(),
507 /// &[232, 3567587328]
508 /// );
509 /// assert_eq!(
510 /// (-Integer::from(10u32).pow(12)).to_twos_complement_limbs_desc(),
511 /// &[4294967063, 727379968]
512 /// );
513 /// }
514 /// ```
515 pub fn to_twos_complement_limbs_desc(&self) -> Vec<Limb> {
516 let mut xs = self.to_twos_complement_limbs_asc();
517 xs.reverse();
518 xs
519 }
520
521 /// Returns the [limbs](crate#limbs) of an [`Integer`], in ascending order, so that less
522 /// significant limbs have lower indices in the output vector.
523 ///
524 /// The limbs are in two's complement, and the most significant bit of the limbs indicates the
525 /// sign; if the bit is zero, the [`Integer`] is positive, and if the bit is one it is negative.
526 /// There are no trailing zero limbs if the [`Integer`] is positive or trailing `Limb::MAX`
527 /// limbs if the [`Integer`] is negative, except as necessary to include the correct sign bit.
528 /// Zero is a special case: it contains no limbs.
529 ///
530 /// This function takes ownership of `self`. If it's necessary to borrow `self` instead, use
531 /// [`to_twos_complement_limbs_asc`](`Self::to_twos_complement_limbs_asc`).
532 ///
533 /// This function is more efficient than
534 /// [`into_twos_complement_limbs_desc`](`Self::into_twos_complement_limbs_desc`).
535 ///
536 /// # Worst-case complexity
537 /// $T(n) = O(n)$
538 ///
539 /// $M(n) = O(1)$
540 ///
541 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
542 ///
543 /// # Examples
544 /// ```
545 /// use malachite_base::num::arithmetic::traits::Pow;
546 /// use malachite_base::num::basic::integers::PrimitiveInt;
547 /// use malachite_base::num::basic::traits::Zero;
548 /// use malachite_nz::integer::Integer;
549 /// use malachite_nz::platform::Limb;
550 ///
551 /// if Limb::WIDTH == u32::WIDTH {
552 /// assert!(Integer::ZERO.into_twos_complement_limbs_asc().is_empty());
553 /// assert_eq!(Integer::from(123).into_twos_complement_limbs_asc(), &[123]);
554 /// assert_eq!(
555 /// Integer::from(-123).into_twos_complement_limbs_asc(),
556 /// &[4294967173]
557 /// );
558 /// // 10^12 = 232 * 2^32 + 3567587328
559 /// assert_eq!(
560 /// Integer::from(10u32)
561 /// .pow(12)
562 /// .into_twos_complement_limbs_asc(),
563 /// &[3567587328, 232]
564 /// );
565 /// assert_eq!(
566 /// (-Integer::from(10u32).pow(12)).into_twos_complement_limbs_asc(),
567 /// &[727379968, 4294967063]
568 /// );
569 /// }
570 /// ```
571 pub fn into_twos_complement_limbs_asc(self) -> Vec<Limb> {
572 let mut xs = self.abs.into_limbs_asc();
573 if self.sign {
574 limbs_maybe_sign_extend_non_negative_in_place(&mut xs);
575 } else {
576 limbs_twos_complement_and_maybe_sign_extend_negative_in_place(&mut xs);
577 }
578 xs
579 }
580
581 /// Returns the [limbs](crate#limbs) of an [`Integer`], in descending order, so that less
582 /// significant limbs have higher indices in the output vector.
583 ///
584 /// The limbs are in two's complement, and the most significant bit of the limbs indicates the
585 /// sign; if the bit is zero, the [`Integer`] is positive, and if the bit is one it is negative.
586 /// There are no leading zero limbs if the [`Integer`] is non-negative or leading `Limb::MAX`
587 /// limbs if the [`Integer`] is negative, except as necessary to include the correct sign bit.
588 /// Zero is a special case: it contains no limbs.
589 ///
590 /// This is similar to how `BigInteger`s in Java are represented.
591 ///
592 /// This function takes ownership of `self`. If it's necessary to borrow `self` instead, use
593 /// [`to_twos_complement_limbs_desc`](`Self::to_twos_complement_limbs_desc`).
594 ///
595 /// This function is less efficient than
596 /// [`into_twos_complement_limbs_asc`](`Self::into_twos_complement_limbs_asc`).
597 ///
598 /// # Worst-case complexity
599 /// $T(n) = O(n)$
600 ///
601 /// $M(n) = O(1)$
602 ///
603 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
604 ///
605 /// # Examples
606 /// ```
607 /// use malachite_base::num::arithmetic::traits::Pow;
608 /// use malachite_base::num::basic::integers::PrimitiveInt;
609 /// use malachite_base::num::basic::traits::Zero;
610 /// use malachite_nz::integer::Integer;
611 /// use malachite_nz::platform::Limb;
612 ///
613 /// if Limb::WIDTH == u32::WIDTH {
614 /// assert!(Integer::ZERO.into_twos_complement_limbs_desc().is_empty());
615 /// assert_eq!(Integer::from(123).into_twos_complement_limbs_desc(), &[123]);
616 /// assert_eq!(
617 /// Integer::from(-123).into_twos_complement_limbs_desc(),
618 /// &[4294967173]
619 /// );
620 /// // 10^12 = 232 * 2^32 + 3567587328
621 /// assert_eq!(
622 /// Integer::from(10u32)
623 /// .pow(12)
624 /// .into_twos_complement_limbs_desc(),
625 /// &[232, 3567587328]
626 /// );
627 /// assert_eq!(
628 /// (-Integer::from(10u32).pow(12)).into_twos_complement_limbs_desc(),
629 /// &[4294967063, 727379968]
630 /// );
631 /// }
632 /// ```
633 pub fn into_twos_complement_limbs_desc(self) -> Vec<Limb> {
634 let mut xs = self.into_twos_complement_limbs_asc();
635 xs.reverse();
636 xs
637 }
638
639 /// Returns a double-ended iterator over the twos-complement [limbs](crate#limbs) of an
640 /// [`Integer`].
641 ///
642 /// The forward order is ascending, so that less significant limbs appear first. There may be a
643 /// most-significant sign-extension limb.
644 ///
645 /// If it's necessary to get a [`Vec`] of all the twos_complement limbs, consider using
646 /// [`to_twos_complement_limbs_asc`](`Self::to_twos_complement_limbs_asc`),
647 /// [`to_twos_complement_limbs_desc`](`Self::to_twos_complement_limbs_desc`),
648 /// [`into_twos_complement_limbs_asc`](`Self::into_twos_complement_limbs_asc`), or
649 /// [`into_twos_complement_limbs_desc`](`Self::into_twos_complement_limbs_desc`) instead.
650 ///
651 /// # Worst-case complexity
652 /// Constant time and additional memory.
653 ///
654 /// # Examples
655 /// ```
656 /// use itertools::Itertools;
657 /// use malachite_base::num::arithmetic::traits::Pow;
658 /// use malachite_base::num::basic::integers::PrimitiveInt;
659 /// use malachite_base::num::basic::traits::Zero;
660 /// use malachite_nz::integer::Integer;
661 /// use malachite_nz::platform::Limb;
662 ///
663 /// if Limb::WIDTH == u32::WIDTH {
664 /// assert!(Integer::ZERO.twos_complement_limbs().next().is_none());
665 /// assert_eq!(
666 /// Integer::from(123).twos_complement_limbs().collect_vec(),
667 /// &[123]
668 /// );
669 /// assert_eq!(
670 /// Integer::from(-123).twos_complement_limbs().collect_vec(),
671 /// &[4294967173]
672 /// );
673 /// // 10^12 = 232 * 2^32 + 3567587328
674 /// assert_eq!(
675 /// Integer::from(10u32)
676 /// .pow(12)
677 /// .twos_complement_limbs()
678 /// .collect_vec(),
679 /// &[3567587328, 232]
680 /// );
681 /// // Sign-extension for a non-negative `Integer`
682 /// assert_eq!(
683 /// Integer::from(4294967295i64)
684 /// .twos_complement_limbs()
685 /// .collect_vec(),
686 /// &[4294967295, 0]
687 /// );
688 /// assert_eq!(
689 /// (-Integer::from(10u32).pow(12))
690 /// .twos_complement_limbs()
691 /// .collect_vec(),
692 /// &[727379968, 4294967063]
693 /// );
694 /// // Sign-extension for a negative `Integer`
695 /// assert_eq!(
696 /// (-Integer::from(4294967295i64))
697 /// .twos_complement_limbs()
698 /// .collect_vec(),
699 /// &[1, 4294967295]
700 /// );
701 ///
702 /// assert!(Integer::ZERO.twos_complement_limbs().next_back().is_none());
703 /// assert_eq!(
704 /// Integer::from(123)
705 /// .twos_complement_limbs()
706 /// .rev()
707 /// .collect_vec(),
708 /// &[123]
709 /// );
710 /// assert_eq!(
711 /// Integer::from(-123)
712 /// .twos_complement_limbs()
713 /// .rev()
714 /// .collect_vec(),
715 /// &[4294967173]
716 /// );
717 /// // 10^12 = 232 * 2^32 + 3567587328
718 /// assert_eq!(
719 /// Integer::from(10u32)
720 /// .pow(12)
721 /// .twos_complement_limbs()
722 /// .rev()
723 /// .collect_vec(),
724 /// &[232, 3567587328]
725 /// );
726 /// // Sign-extension for a non-negative `Integer`
727 /// assert_eq!(
728 /// Integer::from(4294967295i64)
729 /// .twos_complement_limbs()
730 /// .rev()
731 /// .collect_vec(),
732 /// &[0, 4294967295]
733 /// );
734 /// assert_eq!(
735 /// (-Integer::from(10u32).pow(12))
736 /// .twos_complement_limbs()
737 /// .rev()
738 /// .collect_vec(),
739 /// &[4294967063, 727379968]
740 /// );
741 /// // Sign-extension for a negative `Integer`
742 /// assert_eq!(
743 /// (-Integer::from(4294967295i64))
744 /// .twos_complement_limbs()
745 /// .rev()
746 /// .collect_vec(),
747 /// &[4294967295, 1]
748 /// );
749 /// }
750 /// ```
751 pub fn twos_complement_limbs(&self) -> TwosComplementLimbIterator<'_> {
752 if *self == 0u32 {
753 TwosComplementLimbIterator::Zero
754 } else if self.sign {
755 TwosComplementLimbIterator::Positive(self.abs.limbs(), false)
756 } else {
757 TwosComplementLimbIterator::Negative(self.abs.negative_limbs(), false)
758 }
759 }
760
761 /// Returns the number of twos-complement limbs of an [`Integer`]. There may be a
762 /// most-significant sign-extension limb, which is included in the count.
763 ///
764 /// Zero has 0 limbs.
765 ///
766 /// # Worst-case complexity
767 /// $T(n) = O(n)$
768 ///
769 /// $M(n) = O(1)$
770 ///
771 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
772 ///
773 /// # Examples
774 /// ```
775 /// use malachite_base::num::arithmetic::traits::{Pow, PowerOf2};
776 /// use malachite_base::num::basic::integers::PrimitiveInt;
777 /// use malachite_base::num::basic::traits::{One, Zero};
778 /// use malachite_nz::integer::Integer;
779 /// use malachite_nz::platform::Limb;
780 ///
781 /// if Limb::WIDTH == u32::WIDTH {
782 /// assert_eq!(Integer::ZERO.twos_complement_limb_count(), 0);
783 /// assert_eq!(Integer::from(123u32).twos_complement_limb_count(), 1);
784 /// assert_eq!(Integer::from(10u32).pow(12).twos_complement_limb_count(), 2);
785 ///
786 /// let n = Integer::power_of_2(Limb::WIDTH - 1);
787 /// assert_eq!((&n - Integer::ONE).twos_complement_limb_count(), 1);
788 /// assert_eq!(n.twos_complement_limb_count(), 2);
789 /// assert_eq!((&n + Integer::ONE).twos_complement_limb_count(), 2);
790 /// assert_eq!((-(&n - Integer::ONE)).twos_complement_limb_count(), 1);
791 /// assert_eq!((-&n).twos_complement_limb_count(), 1);
792 /// assert_eq!((-(&n + Integer::ONE)).twos_complement_limb_count(), 2);
793 /// }
794 /// ```
795 pub fn twos_complement_limb_count(&self) -> u64 {
796 if *self == 0u32 {
797 return 0;
798 }
799 let abs_limbs_count = self.unsigned_abs_ref().limb_count();
800 let highest_bit_of_highest_limb =
801 self.unsigned_abs().limbs()[usize::exact_from(abs_limbs_count - 1)].get_highest_bit();
802 if highest_bit_of_highest_limb
803 && (*self > 0u32 || (*self < 0u32 && !self.unsigned_abs_ref().is_power_of_2()))
804 {
805 abs_limbs_count + 1
806 } else {
807 abs_limbs_count
808 }
809 }
810}