about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorDavid Creswick <dcrewi@gyrae.net>2013-09-05 19:03:54 -0500
committerDavid Creswick <dcrewi@gyrae.net>2013-09-05 19:40:07 -0500
commit3d735e4a63e49ca43d09f4bb9cfe19b3a7ce9407 (patch)
tree1cbf74957a83090ebb386405c73126a6a8fce3a8 /src
parentd84a7b5ae3b3a820fb0a26292632856ceb959b3e (diff)
downloadrust-3d735e4a63e49ca43d09f4bb9cfe19b3a7ce9407.tar.gz
rust-3d735e4a63e49ca43d09f4bb9cfe19b3a7ce9407.zip
Generate random BigUints and BigInts
Diffstat (limited to 'src')
-rw-r--r--src/libextra/num/bigint.rs53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs
index cb764228155..3738c914ca9 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<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]
@@ -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]
@@ -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)]