@@ -23,6 +23,7 @@ use std::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
23
23
use std:: int;
24
24
use std:: num;
25
25
use std:: num:: { IntConvertible , Zero , One , ToStrRadix , FromStrRadix , Orderable } ;
26
+ use std:: rand:: { Rng , RngUtil } ;
26
27
use std:: str;
27
28
use std:: uint;
28
29
use std:: vec;
@@ -520,6 +521,27 @@ impl FromStrRadix for BigUint {
520
521
}
521
522
}
522
523
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
+
523
545
impl BigUint {
524
546
/// Creates and initializes an BigUint.
525
547
#[ inline]
@@ -1051,6 +1073,22 @@ impl FromStrRadix for BigInt {
1051
1073
}
1052
1074
}
1053
1075
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
+
1054
1092
impl BigInt {
1055
1093
/// Creates and initializes an BigInt.
1056
1094
#[inline]
@@ -1112,6 +1150,7 @@ mod biguint_tests {
1112
1150
use std::cmp::{Less, Equal, Greater};
1113
1151
use std::int;
1114
1152
use std::num::{IntConvertible, Zero, One, FromStrRadix};
1153
+ use std::rand::{task_rng};
1115
1154
use std::str;
1116
1155
use std::uint;
1117
1156
use std::vec;
@@ -1577,6 +1616,12 @@ mod biguint_tests {
1577
1616
check ( 20 , "2432902008176640000" ) ;
1578
1617
check ( 30 , "265252859812191058636308480000000" ) ;
1579
1618
}
1619
+
1620
+ #[ test]
1621
+ fn test_rand ( ) {
1622
+ let mut rng = task_rng ( ) ;
1623
+ rng. gen_bigint ( 137 ) ;
1624
+ }
1580
1625
}
1581
1626
1582
1627
#[ cfg( test) ]
@@ -1586,6 +1631,7 @@ mod bigint_tests {
1586
1631
use std:: cmp:: { Less , Equal , Greater } ;
1587
1632
use std:: int;
1588
1633
use std:: num:: { IntConvertible , Zero , One , FromStrRadix } ;
1634
+ use std:: rand:: { task_rng} ;
1589
1635
use std:: uint;
1590
1636
1591
1637
#[ test]
@@ -2006,6 +2052,13 @@ mod bigint_tests {
2006
2052
let zero: BigInt = Zero :: zero ( ) ;
2007
2053
assert_eq ! ( -zero, zero) ;
2008
2054
}
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
+ }
2009
2062
}
2010
2063
2011
2064
#[ cfg( test) ]
0 commit comments