@@ -23,6 +23,7 @@ use std::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
2323use std:: int;
2424use std:: num;
2525use std:: num:: { IntConvertible , Zero , One , ToStrRadix , FromStrRadix , Orderable } ;
26+ use std:: rand:: { Rng , RngUtil } ;
2627use std:: str;
2728use std:: uint;
2829use 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+
523545impl 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+
10541092impl 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