Skip to content

Commit 3d735e4

Browse files
committed
Generate random BigUints and BigInts
1 parent d84a7b5 commit 3d735e4

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

src/libextra/num/bigint.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use std::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
2323
use std::int;
2424
use std::num;
2525
use std::num::{IntConvertible, Zero, One, ToStrRadix, FromStrRadix, Orderable};
26+
use std::rand::{Rng, RngUtil};
2627
use std::str;
2728
use std::uint;
2829
use std::vec;
@@ -520,6 +521,27 @@ impl FromStrRadix for BigUint {
520521
}
521522
}
522523

524+
trait RandBigUInt {
525+
/// Generate a random BigUint of the given bit size.
526+
fn gen_biguint(&mut self, bit_size: uint) -> BigUint;
527+
}
528+
529+
impl<R: RngUtil> RandBigUInt for R {
530+
/// Generate a random BigUint of the given bit size.
531+
fn gen_biguint(&mut self, bit_size: uint) -> BigUint {
532+
let (digits, rem) = bit_size.div_rem(&BigDigit::bits);
533+
let mut data = vec::with_capacity(digits+1);
534+
for _ in range(0, digits) {
535+
data.push(self.gen());
536+
}
537+
if rem > 0 {
538+
let final_digit: BigDigit = self.gen();
539+
data.push(final_digit >> (BigDigit::bits - rem));
540+
}
541+
return BigUint::new(data);
542+
}
543+
}
544+
523545
impl BigUint {
524546
/// Creates and initializes an BigUint.
525547
#[inline]
@@ -1051,6 +1073,22 @@ impl FromStrRadix for BigInt {
10511073
}
10521074
}
10531075
1076+
trait RandBigInt {
1077+
/// Generate a random BigInt of the given bit size.
1078+
fn gen_bigint(&mut self, bit_size: uint) -> BigInt;
1079+
}
1080+
1081+
impl<R: RngUtil> RandBigInt for R {
1082+
/// Generate a random BigUint of the given bit size.
1083+
fn gen_bigint(&mut self, bit_size: uint) -> BigInt {
1084+
let biguint = self.gen_biguint(bit_size);
1085+
let sign = if biguint.is_zero() { Zero }
1086+
else if self.gen() { Plus }
1087+
else { Minus };
1088+
return BigInt::from_biguint(sign, biguint);
1089+
}
1090+
}
1091+
10541092
impl BigInt {
10551093
/// Creates and initializes an BigInt.
10561094
#[inline]
@@ -1112,6 +1150,7 @@ mod biguint_tests {
11121150
use std::cmp::{Less, Equal, Greater};
11131151
use std::int;
11141152
use std::num::{IntConvertible, Zero, One, FromStrRadix};
1153+
use std::rand::{task_rng};
11151154
use std::str;
11161155
use std::uint;
11171156
use std::vec;
@@ -1577,6 +1616,12 @@ mod biguint_tests {
15771616
check(20, "2432902008176640000");
15781617
check(30, "265252859812191058636308480000000");
15791618
}
1619+
1620+
#[test]
1621+
fn test_rand() {
1622+
let mut rng = task_rng();
1623+
rng.gen_bigint(137);
1624+
}
15801625
}
15811626

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

15911637
#[test]
@@ -2006,6 +2052,13 @@ mod bigint_tests {
20062052
let zero: BigInt = Zero::zero();
20072053
assert_eq!(-zero, zero);
20082054
}
2055+
2056+
#[test]
2057+
fn test_rand() {
2058+
let mut rng = task_rng();
2059+
rng.gen_bigint(137);
2060+
assert!(rng.gen_bigint(0).is_zero());
2061+
}
20092062
}
20102063

20112064
#[cfg(test)]

0 commit comments

Comments
 (0)