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