Skip to content

Commit

Permalink
Generate random BigUints and BigInts
Browse files Browse the repository at this point in the history
  • Loading branch information
dcrewi committed Sep 6, 2013
1 parent d84a7b5 commit 3d735e4
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions src/libextra/num/bigint.rs
Expand Up @@ -23,6 +23,7 @@ use std::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
use std::int;
use std::num;
use std::num::{IntConvertible, Zero, One, ToStrRadix, FromStrRadix, Orderable};
use std::rand::{Rng, RngUtil};
use std::str;
use std::uint;
use std::vec;
Expand Down Expand Up @@ -520,6 +521,27 @@ impl FromStrRadix for BigUint {
}
}

trait RandBigUInt {
/// Generate a random BigUint of the given bit size.
fn gen_biguint(&mut self, bit_size: uint) -> BigUint;
}

impl<R: RngUtil> RandBigUInt for R {
/// Generate a random BigUint of the given bit size.
fn gen_biguint(&mut self, bit_size: uint) -> BigUint {
let (digits, rem) = bit_size.div_rem(&BigDigit::bits);
let mut data = vec::with_capacity(digits+1);
for _ in range(0, digits) {
data.push(self.gen());
}
if rem > 0 {
let final_digit: BigDigit = self.gen();
data.push(final_digit >> (BigDigit::bits - rem));
}
return BigUint::new(data);
}
}

impl BigUint {
/// Creates and initializes an BigUint.
#[inline]
Expand Down Expand Up @@ -1051,6 +1073,22 @@ impl FromStrRadix for BigInt {
}
}
trait RandBigInt {
/// Generate a random BigInt of the given bit size.
fn gen_bigint(&mut self, bit_size: uint) -> BigInt;
}
impl<R: RngUtil> RandBigInt for R {
/// Generate a random BigUint of the given bit size.
fn gen_bigint(&mut self, bit_size: uint) -> BigInt {
let biguint = self.gen_biguint(bit_size);
let sign = if biguint.is_zero() { Zero }
else if self.gen() { Plus }
else { Minus };
return BigInt::from_biguint(sign, biguint);
}
}
impl BigInt {
/// Creates and initializes an BigInt.
#[inline]
Expand Down Expand Up @@ -1112,6 +1150,7 @@ mod biguint_tests {
use std::cmp::{Less, Equal, Greater};
use std::int;
use std::num::{IntConvertible, Zero, One, FromStrRadix};
use std::rand::{task_rng};
use std::str;
use std::uint;
use std::vec;
Expand Down Expand Up @@ -1577,6 +1616,12 @@ mod biguint_tests {
check(20, "2432902008176640000");
check(30, "265252859812191058636308480000000");
}

#[test]
fn test_rand() {
let mut rng = task_rng();
rng.gen_bigint(137);
}
}

#[cfg(test)]
Expand All @@ -1586,6 +1631,7 @@ mod bigint_tests {
use std::cmp::{Less, Equal, Greater};
use std::int;
use std::num::{IntConvertible, Zero, One, FromStrRadix};
use std::rand::{task_rng};
use std::uint;

#[test]
Expand Down Expand Up @@ -2006,6 +2052,13 @@ mod bigint_tests {
let zero: BigInt = Zero::zero();
assert_eq!(-zero, zero);
}

#[test]
fn test_rand() {
let mut rng = task_rng();
rng.gen_bigint(137);
assert!(rng.gen_bigint(0).is_zero());
}
}

#[cfg(test)]
Expand Down

0 comments on commit 3d735e4

Please sign in to comment.