@@ -697,6 +697,13 @@ impl BigUint {
697697 }
698698 return BigUint :: new ( shifted) ;
699699 }
700+
701+ /// Determines the fewest bits necessary to express the BigUint.
702+ pub fn bits ( & self ) -> uint {
703+ if self . is_zero ( ) { return 0 ; }
704+ let zeros = self . data . last ( ) . leading_zeros ( ) ;
705+ return self . data . len ( ) * BigDigit :: bits - ( zeros as uint ) ;
706+ }
700707}
701708
702709#[ cfg( target_word_size = "64" ) ]
@@ -1115,10 +1122,23 @@ trait RandBigInt {
11151122
11161123 /// Generate a random BigInt of the given bit size.
11171124 fn gen_bigint(&mut self, bit_size: uint) -> BigInt;
1125+
1126+ /// Generate a random BigUint less than the given bound. Fails
1127+ /// when the bound is zero.
1128+ fn gen_biguint_below(&mut self, bound: &BigUint) -> BigUint;
1129+
1130+ /// Generate a random BigUint within the given range. The lower
1131+ /// bound is inclusive; the upper bound is exclusive. Fails when
1132+ /// the upper bound is not greater than the lower bound.
1133+ fn gen_biguint_range(&mut self, lbound: &BigUint, ubound: &BigUint) -> BigUint;
1134+
1135+ /// Generate a random BigInt within the given range. The lower
1136+ /// bound is inclusive; the upper bound is exclusive. Fails when
1137+ /// the upper bound is not greater than the lower bound.
1138+ fn gen_bigint_range(&mut self, lbound: &BigInt, ubound: &BigInt) -> BigInt;
11181139}
11191140
11201141impl<R: Rng> RandBigInt for R {
1121- /// Generate a random BigUint of the given bit size.
11221142 fn gen_biguint(&mut self, bit_size: uint) -> BigUint {
11231143 let (digits, rem) = bit_size.div_rem(&BigDigit::bits);
11241144 let mut data = vec::with_capacity(digits+1);
@@ -1132,7 +1152,6 @@ impl<R: Rng> RandBigInt for R {
11321152 return BigUint::new(data);
11331153 }
11341154
1135- /// Generate a random BigInt of the given bit size.
11361155 fn gen_bigint(&mut self, bit_size: uint) -> BigInt {
11371156 // Generate a random BigUint...
11381157 let biguint = self.gen_biguint(bit_size);
@@ -1154,6 +1173,32 @@ impl<R: Rng> RandBigInt for R {
11541173 };
11551174 return BigInt::from_biguint(sign, biguint);
11561175 }
1176+
1177+ fn gen_biguint_below(&mut self, bound: &BigUint) -> BigUint {
1178+ assert!(!bound.is_zero());
1179+ let bits = bound.bits();
1180+ loop {
1181+ let n = self.gen_biguint(bits);
1182+ if n < *bound { return n; }
1183+ }
1184+ }
1185+
1186+ fn gen_biguint_range(&mut self,
1187+ lbound: &BigUint,
1188+ ubound: &BigUint)
1189+ -> BigUint {
1190+ assert!(*lbound < *ubound);
1191+ return *lbound + self.gen_biguint_below(&(*ubound - *lbound));
1192+ }
1193+
1194+ fn gen_bigint_range(&mut self,
1195+ lbound: &BigInt,
1196+ ubound: &BigInt)
1197+ -> BigInt {
1198+ assert!(*lbound < *ubound);
1199+ let delta = (*ubound - *lbound).to_biguint();
1200+ return *lbound + self.gen_biguint_below(&delta).to_bigint();
1201+ }
11571202}
11581203
11591204impl BigInt {
@@ -1780,12 +1825,63 @@ mod biguint_tests {
17801825 check ( 30 , "265252859812191058636308480000000" ) ;
17811826 }
17821827
1828+ #[ test]
1829+ fn test_bits ( ) {
1830+ assert_eq ! ( BigUint :: new( ~[ 0 , 0 , 0 , 0 ] ) . bits( ) , 0 ) ;
1831+ assert_eq ! ( BigUint :: from_uint( 0 ) . bits( ) , 0 ) ;
1832+ assert_eq ! ( BigUint :: from_uint( 1 ) . bits( ) , 1 ) ;
1833+ assert_eq ! ( BigUint :: from_uint( 3 ) . bits( ) , 2 ) ;
1834+ let n: BigUint = FromStrRadix :: from_str_radix ( "4000000000" , 16 ) . unwrap ( ) ;
1835+ assert_eq ! ( n. bits( ) , 39 ) ;
1836+ let one: BigUint = One :: one ( ) ;
1837+ assert_eq ! ( ( one << 426 ) . bits( ) , 427 ) ;
1838+ }
1839+
17831840 #[ test]
17841841 fn test_rand ( ) {
17851842 let mut rng = task_rng ( ) ;
17861843 let _n: BigUint = rng. gen_biguint ( 137 ) ;
17871844 assert ! ( rng. gen_biguint( 0 ) . is_zero( ) ) ;
17881845 }
1846+
1847+ #[ test]
1848+ fn test_rand_range ( ) {
1849+ let mut rng = task_rng ( ) ;
1850+
1851+ do 10 . times {
1852+ assert_eq ! ( rng. gen_bigint_range( & BigInt :: from_uint( 236 ) ,
1853+ & BigInt :: from_uint( 237 ) ) ,
1854+ BigInt :: from_uint( 236 ) ) ;
1855+ }
1856+
1857+ let l = BigUint :: from_uint ( 403469000 + 2352 ) ;
1858+ let u = BigUint :: from_uint ( 403469000 + 3513 ) ;
1859+ do 1000 . times {
1860+ let n: BigUint = rng. gen_biguint_below ( & u) ;
1861+ assert ! ( n < u) ;
1862+
1863+ let n: BigUint = rng. gen_biguint_range ( & l, & u) ;
1864+ assert ! ( n >= l) ;
1865+ assert ! ( n < u) ;
1866+ }
1867+ }
1868+
1869+ #[ test]
1870+ #[ should_fail]
1871+ fn test_zero_rand_range ( ) {
1872+ task_rng ( ) . gen_biguint_range ( & BigUint :: from_uint ( 54 ) ,
1873+ & BigUint :: from_uint ( 54 ) ) ;
1874+ }
1875+
1876+ #[ test]
1877+ #[ should_fail]
1878+ fn test_negative_rand_range ( ) {
1879+ let mut rng = task_rng ( ) ;
1880+ let l = BigUint :: from_uint ( 2352 ) ;
1881+ let u = BigUint :: from_uint ( 3513 ) ;
1882+ // Switching u and l should fail:
1883+ let _n: BigUint = rng. gen_biguint_range ( & u, & l) ;
1884+ }
17891885}
17901886
17911887#[ cfg( test) ]
@@ -2237,6 +2333,48 @@ mod bigint_tests {
22372333 let _n: BigInt = rng. gen_bigint ( 137 ) ;
22382334 assert ! ( rng. gen_bigint( 0 ) . is_zero( ) ) ;
22392335 }
2336+
2337+ #[ test]
2338+ fn test_rand_range ( ) {
2339+ let mut rng = task_rng ( ) ;
2340+
2341+ do 10 . times {
2342+ assert_eq ! ( rng. gen_bigint_range( & BigInt :: from_uint( 236 ) ,
2343+ & BigInt :: from_uint( 237 ) ) ,
2344+ BigInt :: from_uint( 236 ) ) ;
2345+ }
2346+
2347+ fn check ( l : BigInt , u : BigInt ) {
2348+ let mut rng = task_rng ( ) ;
2349+ do 1000 . times {
2350+ let n: BigInt = rng. gen_bigint_range ( & l, & u) ;
2351+ assert ! ( n >= l) ;
2352+ assert ! ( n < u) ;
2353+ }
2354+ }
2355+ let l = BigInt :: from_uint ( 403469000 + 2352 ) ;
2356+ let u = BigInt :: from_uint ( 403469000 + 3513 ) ;
2357+ check ( l. clone ( ) , u. clone ( ) ) ;
2358+ check ( -l. clone ( ) , u. clone ( ) ) ;
2359+ check ( -u. clone ( ) , -l. clone ( ) ) ;
2360+ }
2361+
2362+ #[ test]
2363+ #[ should_fail]
2364+ fn test_zero_rand_range ( ) {
2365+ task_rng ( ) . gen_bigint_range ( & IntConvertible :: from_int ( 54 ) ,
2366+ & IntConvertible :: from_int ( 54 ) ) ;
2367+ }
2368+
2369+ #[ test]
2370+ #[ should_fail]
2371+ fn test_negative_rand_range ( ) {
2372+ let mut rng = task_rng ( ) ;
2373+ let l = BigInt :: from_uint ( 2352 ) ;
2374+ let u = BigInt :: from_uint ( 3513 ) ;
2375+ // Switching u and l should fail:
2376+ let _n: BigInt = rng. gen_bigint_range ( & u, & l) ;
2377+ }
22402378}
22412379
22422380#[ cfg( test) ]
0 commit comments