diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index cb7642281553..3738c914ca9a 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -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; @@ -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 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] @@ -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 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] @@ -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; @@ -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)] @@ -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] @@ -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)]