From bee58ab292d054fa11eda97202077a2a497960f5 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 13 Jan 2020 22:21:11 -0800 Subject: [PATCH] Build rand without default features (no_std) The tests using rand/std have been moved to ci/big_rand/. --- .travis.yml | 2 +- Cargo.toml | 10 ---- ci/big_rand/Cargo.toml | 18 +++++++ tests/rand.rs => ci/big_rand/src/lib.rs | 68 ++++++++++++++++++++++++- {tests => ci/big_rand/src}/torture.rs | 6 --- ci/test_full.sh | 5 +- src/lib.rs | 14 ++--- tests/bigint.rs | 21 -------- tests/roots.rs | 22 -------- 9 files changed, 91 insertions(+), 75 deletions(-) create mode 100644 ci/big_rand/Cargo.toml rename tests/rand.rs => ci/big_rand/src/lib.rs (83%) rename {tests => ci/big_rand/src}/torture.rs (94%) diff --git a/.travis.yml b/.travis.yml index 7667440c..b77d9c8e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,7 @@ matrix: before_script: - rustup target add $TARGET script: - - cargo build --verbose --target $TARGET --no-default-features --features "serde" + - cargo build --verbose --target $TARGET --no-default-features --features "serde rand" - name: "rustfmt" rust: 1.31.0 before_script: diff --git a/Cargo.toml b/Cargo.toml index 64fb07cb..24c3f2fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,6 @@ features = ["i128"] optional = true version = "0.7" default-features = false -features = ["std", "small_rng"] [dependencies.serde] optional = true @@ -65,15 +64,6 @@ optional = true version = "0.9" default-features = false -[dev-dependencies.rand_xorshift] -version = "0.2.0" - -[dev-dependencies.rand_chacha] -version = "0.2.0" - -[dev-dependencies.rand_isaac] -version = "0.2.0" - [features] default = ["std"] std = ["num-integer/std", "num-traits/std"] diff --git a/ci/big_rand/Cargo.toml b/ci/big_rand/Cargo.toml new file mode 100644 index 00000000..99b57c9b --- /dev/null +++ b/ci/big_rand/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "big_rand" +version = "0.1.0" +authors = ["Josh Stone "] + +[dependencies] +num-traits = "0.2.11" +rand_chacha = "0.2" +rand_isaac = "0.2" +rand_xorshift = "0.2" + +[dependencies.num-bigint] +features = ["rand"] +path = "../.." + +[dependencies.rand] +features = ["small_rng"] +version = "0.7" diff --git a/tests/rand.rs b/ci/big_rand/src/lib.rs similarity index 83% rename from tests/rand.rs rename to ci/big_rand/src/lib.rs index fb84b1fd..9dc6f367 100644 --- a/tests/rand.rs +++ b/ci/big_rand/src/lib.rs @@ -1,4 +1,10 @@ -#![cfg(feature = "rand")] +//! Test randomization of `BigUint` and `BigInt` +//! +//! This test is in a completely separate crate so `rand::thread_rng()` +//! can be available without "infecting" the rest of the build with +//! `rand`'s default features, especially not `rand/std`. + +#![cfg(test)] extern crate num_bigint; extern crate num_traits; @@ -7,9 +13,11 @@ extern crate rand_chacha; extern crate rand_isaac; extern crate rand_xorshift; +mod torture; + mod biguint { use num_bigint::{BigUint, RandBigInt, RandomBits}; - use num_traits::Zero; + use num_traits::{Pow, Zero}; use rand::distributions::Uniform; use rand::thread_rng; use rand::{Rng, SeedableRng}; @@ -162,6 +170,44 @@ mod biguint { use rand_xorshift::XorShiftRng; seeded_value_stability::(EXPECTED); } + + #[test] + fn test_roots_rand() { + fn check>(x: T, n: u32) { + let x: BigUint = x.into(); + let root = x.nth_root(n); + println!("check {}.nth_root({}) = {}", x, n, root); + + if n == 2 { + assert_eq!(root, x.sqrt()) + } else if n == 3 { + assert_eq!(root, x.cbrt()) + } + + let lo = root.pow(n); + assert!(lo <= x); + assert_eq!(lo.nth_root(n), root); + if !lo.is_zero() { + assert_eq!((&lo - 1u32).nth_root(n), &root - 1u32); + } + + let hi = (&root + 1u32).pow(n); + assert!(hi > x); + assert_eq!(hi.nth_root(n), &root + 1u32); + assert_eq!((&hi - 1u32).nth_root(n), root); + } + + let mut rng = thread_rng(); + let bit_range = Uniform::new(0, 2048); + let sample_bits: Vec<_> = rng.sample_iter(&bit_range).take(100).collect(); + for bits in sample_bits { + let x = rng.gen_biguint(bits); + for n in 2..11 { + check(x.clone(), n); + } + check(x.clone(), 100); + } + } } mod bigint { @@ -324,4 +370,22 @@ mod bigint { use rand_xorshift::XorShiftRng; seeded_value_stability::(EXPECTED); } + + #[test] + fn test_random_shr() { + use rand::distributions::Standard; + use rand::Rng; + let rng = rand::thread_rng(); + + for p in rng.sample_iter::(&Standard).take(1000) { + let big = BigInt::from(p); + let bigger = &big << 1000; + assert_eq!(&bigger >> 1000, big); + for i in 0..64 { + let answer = BigInt::from(p >> i); + assert_eq!(&big >> i, answer); + assert_eq!(&bigger >> (1000 + i), answer); + } + } + } } diff --git a/tests/torture.rs b/ci/big_rand/src/torture.rs similarity index 94% rename from tests/torture.rs rename to ci/big_rand/src/torture.rs index 88887b70..746128de 100644 --- a/tests/torture.rs +++ b/ci/big_rand/src/torture.rs @@ -1,9 +1,3 @@ -#![cfg(feature = "rand")] - -extern crate num_bigint; -extern crate num_traits; -extern crate rand; - use num_bigint::RandBigInt; use num_traits::Zero; use rand::prelude::*; diff --git a/ci/test_full.sh b/ci/test_full.sh index c56f0fc1..4981b32d 100755 --- a/ci/test_full.sh +++ b/ci/test_full.sh @@ -12,7 +12,7 @@ esac case "$TRAVIS_RUST_VERSION" in 1.3[1-5].*) ;; - *) NO_STD_FEATURES="serde" ;; + *) NO_STD_FEATURES="serde rand" ;; esac # num-bigint should build and test everywhere. @@ -55,5 +55,6 @@ if [[ "$TRAVIS_RUST_VERSION" == "nightly" ]]; then fi case "$STD_FEATURES" in - *serde*) cargo test --manifest-path ci/big_serde/Cargo.toml + *serde*) cargo test --manifest-path ci/big_serde/Cargo.toml ;;& + *rand*) cargo test --manifest-path ci/big_rand/Cargo.toml ;;& esac diff --git a/src/lib.rs b/src/lib.rs index 12dc5af6..6dcc02a6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,14 +46,11 @@ //! //! It's easy to generate large random numbers: //! -//! ```rust -//! # #[cfg(feature = "rand")] +//! ```rust,ignore //! extern crate rand; -//! extern crate num_bigint as bigint; +//! extern crate num_bigint; //! -//! # #[cfg(feature = "rand")] -//! # fn main() { -//! use bigint::{ToBigInt, RandBigInt}; +//! use num_bigint::{ToBigInt, RandBigInt}; //! //! let mut rng = rand::thread_rng(); //! let a = rng.gen_bigint(1000); @@ -64,11 +61,6 @@ //! //! // Probably an even larger number. //! println!("{}", a * b); -//! # } -//! -//! # #[cfg(not(feature = "rand"))] -//! # fn main() { -//! # } //! ``` //! //! See the "Features" section for instructions for enabling random number generation. diff --git a/tests/bigint.rs b/tests/bigint.rs index 34020bf6..f179dce0 100644 --- a/tests/bigint.rs +++ b/tests/bigint.rs @@ -1,8 +1,6 @@ extern crate num_bigint; extern crate num_integer; extern crate num_traits; -#[cfg(feature = "rand")] -extern crate rand; use num_bigint::BigUint; use num_bigint::Sign::{Minus, NoSign, Plus}; @@ -1083,25 +1081,6 @@ fn test_negative_shr() { assert_eq!(BigInt::from(-3) >> 2, BigInt::from(-1)); } -#[test] -#[cfg(feature = "rand")] -fn test_random_shr() { - use rand::distributions::Standard; - use rand::Rng; - let rng = rand::thread_rng(); - - for p in rng.sample_iter::(&Standard).take(1000) { - let big = BigInt::from(p); - let bigger = &big << 1000; - assert_eq!(&bigger >> 1000, big); - for i in 0..64 { - let answer = BigInt::from(p >> i); - assert_eq!(&big >> i, answer); - assert_eq!(&bigger >> (1000 + i), answer); - } - } -} - #[test] fn test_iter_sum() { let result: BigInt = FromPrimitive::from_isize(-1234567).unwrap(); diff --git a/tests/roots.rs b/tests/roots.rs index 39201fa9..bb52e827 100644 --- a/tests/roots.rs +++ b/tests/roots.rs @@ -2,9 +2,6 @@ extern crate num_bigint; extern crate num_integer; extern crate num_traits; -#[cfg(feature = "rand")] -extern crate rand; - mod biguint { use num_bigint::BigUint; use num_traits::{One, Pow, Zero}; @@ -101,25 +98,6 @@ mod biguint { assert!(x.nth_root(u32::MAX).is_one()); } - #[cfg(feature = "rand")] - #[test] - fn test_roots_rand() { - use num_bigint::RandBigInt; - use rand::distributions::Uniform; - use rand::{thread_rng, Rng}; - - let mut rng = thread_rng(); - let bit_range = Uniform::new(0, 2048); - let sample_bits: Vec<_> = rng.sample_iter(&bit_range).take(100).collect(); - for bits in sample_bits { - let x = rng.gen_biguint(bits); - for n in 2..11 { - check(x.clone(), n); - } - check(x.clone(), 100); - } - } - #[test] fn test_roots_rand1() { // A random input that found regressions