Skip to content

Commit

Permalink
Merge #192
Browse files Browse the repository at this point in the history
192: Add iter_u32_digits , iter_u64_digits, to_u64_digits to both BigInt and BigUint r=cuviper a=cuviper

This is a rebase of #158, and I also addressed my last review comments there. I did rename the iterators to `U32Digits` and `U64Digits`, but I left the `iter_` prefix on the methods so they're not confused with the similar `to_` methods.

Co-authored-by: Vincent Rouillé <vincent@speedy37.fr>
Co-authored-by: Vincent Rouillé <v.rouille@clikengo.com>
Co-authored-by: Vincent Rouillé <vincent@speedy37.fr>
Co-authored-by: Josh Stone <cuviper@gmail.com>
  • Loading branch information
4 people committed Feb 24, 2021
2 parents 7492eec + 0037a7f commit d9287a4
Show file tree
Hide file tree
Showing 4 changed files with 428 additions and 31 deletions.
32 changes: 32 additions & 0 deletions benches/bigint.rs
Expand Up @@ -393,3 +393,35 @@ fn modpow_even(b: &mut Bencher) {

b.iter(|| base.modpow(&e, &m));
}

#[bench]
fn to_u32_digits(b: &mut Bencher) {
let mut rng = get_rng();
let n = rng.gen_biguint(2048);

b.iter(|| n.to_u32_digits());
}

#[bench]
fn iter_u32_digits(b: &mut Bencher) {
let mut rng = get_rng();
let n = rng.gen_biguint(2048);

b.iter(|| n.iter_u32_digits().max());
}

#[bench]
fn to_u64_digits(b: &mut Bencher) {
let mut rng = get_rng();
let n = rng.gen_biguint(2048);

b.iter(|| n.to_u64_digits());
}

#[bench]
fn iter_u64_digits(b: &mut Bencher) {
let mut rng = get_rng();
let n = rng.gen_biguint(2048);

b.iter(|| n.iter_u64_digits().max());
}
61 changes: 60 additions & 1 deletion src/bigint.rs
Expand Up @@ -31,7 +31,7 @@ use self::Sign::{Minus, NoSign, Plus};
use crate::big_digit::{self, BigDigit, DoubleBigDigit};
use crate::biguint;
use crate::biguint::to_str_radix_reversed;
use crate::biguint::{BigUint, IntDigits};
use crate::biguint::{BigUint, IntDigits, U32Digits, U64Digits};
use crate::ParseBigIntError;
#[cfg(has_try_from)]
use crate::TryFromBigIntError;
Expand Down Expand Up @@ -2981,6 +2981,65 @@ impl BigInt {
(self.sign, self.data.to_u32_digits())
}

/// Returns the sign and the `u64` digits representation of the `BigInt` ordered least
/// significant digit first.
///
/// # Examples
///
/// ```
/// use num_bigint::{BigInt, Sign};
///
/// assert_eq!(BigInt::from(-1125).to_u64_digits(), (Sign::Minus, vec![1125]));
/// assert_eq!(BigInt::from(4294967295u32).to_u64_digits(), (Sign::Plus, vec![4294967295]));
/// assert_eq!(BigInt::from(4294967296u64).to_u64_digits(), (Sign::Plus, vec![4294967296]));
/// assert_eq!(BigInt::from(-112500000000i64).to_u64_digits(), (Sign::Minus, vec![112500000000]));
/// assert_eq!(BigInt::from(112500000000i64).to_u64_digits(), (Sign::Plus, vec![112500000000]));
/// assert_eq!(BigInt::from(1u128 << 64).to_u64_digits(), (Sign::Plus, vec![0, 1]));
/// ```
#[inline]
pub fn to_u64_digits(&self) -> (Sign, Vec<u64>) {
(self.sign, self.data.to_u64_digits())
}

/// Returns an iterator of `u32` digits representation of the `BigInt` ordered least
/// significant digit first.
///
/// # Examples
///
/// ```
/// use num_bigint::BigInt;
///
/// assert_eq!(BigInt::from(-1125).iter_u32_digits().collect::<Vec<u32>>(), vec![1125]);
/// assert_eq!(BigInt::from(4294967295u32).iter_u32_digits().collect::<Vec<u32>>(), vec![4294967295]);
/// assert_eq!(BigInt::from(4294967296u64).iter_u32_digits().collect::<Vec<u32>>(), vec![0, 1]);
/// assert_eq!(BigInt::from(-112500000000i64).iter_u32_digits().collect::<Vec<u32>>(), vec![830850304, 26]);
/// assert_eq!(BigInt::from(112500000000i64).iter_u32_digits().collect::<Vec<u32>>(), vec![830850304, 26]);
/// ```
#[inline]
pub fn iter_u32_digits(&self) -> U32Digits<'_> {
self.data.iter_u32_digits()
}

/// Returns an iterator of `u64` digits representation of the `BigInt` ordered least
/// significant digit first.
///
/// # Examples
///
/// ```
/// use num_bigint::BigInt;
///
/// assert_eq!(BigInt::from(-1125).iter_u64_digits().collect::<Vec<u64>>(), vec![1125u64]);
/// assert_eq!(BigInt::from(4294967295u32).iter_u64_digits().collect::<Vec<u64>>(), vec![4294967295u64]);
/// assert_eq!(BigInt::from(4294967296u64).iter_u64_digits().collect::<Vec<u64>>(), vec![4294967296u64]);
/// assert_eq!(BigInt::from(-112500000000i64).iter_u64_digits().collect::<Vec<u64>>(), vec![112500000000u64]);
/// assert_eq!(BigInt::from(112500000000i64).iter_u64_digits().collect::<Vec<u64>>(), vec![112500000000u64]);
/// assert_eq!(BigInt::from(1u128 << 64).iter_u64_digits().collect::<Vec<u64>>(), vec![0, 1]);
/// ```
#[inline]
pub fn iter_u64_digits(&self) -> U64Digits<'_> {
self.data.iter_u64_digits()
}

/// Returns the two's-complement byte representation of the `BigInt` in big-endian byte order.
///
/// # Examples
Expand Down

0 comments on commit d9287a4

Please sign in to comment.