diff --git a/Cargo.toml b/Cargo.toml index 24e3fae6..b63bed04 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,11 +16,6 @@ autobenches = false [package.metadata.docs.rs] features = ["std", "serde", "rand", "prime"] -[[bench]] -harness = false -name = "bench_main" -required-features = ["prime"] - [dependencies] [dependencies.smallvec] @@ -43,37 +38,47 @@ default-features = false optional = true version = "0.6" default-features = false -features = ["std"] [dependencies.zeroize] version = "0.6" optional = true +default-features = false +features = ["zeroize_derive"] [dependencies.serde] optional = true version = "1.0" default-features = false -features = ["std"] + +[dependencies.libm] +version = "0.1.4" [dependencies.lazy_static] version = "1.2.0" +default-features = false +# no_std feature is an anti-pattern. Why, lazy_static, why? +# See https://github.com/rust-lang-nursery/lazy-static.rs/issues/150 +features = ["spin_no_std"] [dependencies.byteorder] version = "1.2.7" +default-features = false [dev-dependencies] -criterion = "0.2" rand_chacha = "0.1" rand_xorshift = "0.1" rand_isaac = "0.1" +[build-dependencies] +autocfg = "0.1.5" + [dev-dependencies.serde_test] version = "1.0" [features] default = ["std", "i128", "u64_digit"] i128 = ["num-integer/i128", "num-traits/i128"] -std = ["num-integer/std", "num-traits/std", "smallvec/std", "rand/std"] +std = ["num-integer/std", "num-traits/std", "smallvec/std", "rand/std", "serde/std", "zeroize/std"] u64_digit = [] prime = ["rand"] nightly = ["zeroize/nightly", "rand/nightly"] diff --git a/README.md b/README.md index 6e131509..7788bfcd 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,14 @@ extern crate num_bigint_dig as num_bigint; ## Features -The `std` crate feature is mandatory and enabled by default. If you depend on -`num-bigint` with `default-features = false`, you must manually enable the -`std` feature yourself. In the future, we hope to support `#![no_std]` with -the `alloc` crate when `std` is not enabled. +The `std` feature is enabled by default and mandatory to compile on older rust +version. + +On Rust 1.36 and later, it is possible to use this crate on no_std target. If +you wish to compile for a target that does not have an `std` crate, you should +use `num-bigint` with `default-features = false`. All other sub-features should +be compatible with no_std. Note that in this mode, `num-bigint` still relies on +the alloc crate, so make sure you define a `global_allocator`. Implementations for `i128` and `u128` are only available with Rust 1.26 and later. The build script automatically detects this, but you can make it diff --git a/benchmark_crate/Cargo.toml b/benchmark_crate/Cargo.toml new file mode 100644 index 00000000..6b5b73b9 --- /dev/null +++ b/benchmark_crate/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "num-bigint-dig-benchmark" +version = "0.0.0" +autobenches = false +publish = false + +[[bench]] +harness = false +name = "bench_main" + +[dependencies] +num-bigint-dig = { path = "../", features = ["prime", "rand"] } +num-integer = "0.1.39" +num-traits = "0.2.4" +rand = "0.6" +rand_chacha = "0.1" + +[dev-dependencies] +criterion = "0.2" \ No newline at end of file diff --git a/benches/bench_main.rs b/benchmark_crate/benches/bench_main.rs similarity index 100% rename from benches/bench_main.rs rename to benchmark_crate/benches/bench_main.rs diff --git a/benches/benchmarks/bigint.rs b/benchmark_crate/benches/benchmarks/bigint.rs similarity index 100% rename from benches/benchmarks/bigint.rs rename to benchmark_crate/benches/benchmarks/bigint.rs diff --git a/benches/benchmarks/egcd.rs b/benchmark_crate/benches/benchmarks/egcd.rs similarity index 100% rename from benches/benchmarks/egcd.rs rename to benchmark_crate/benches/benchmarks/egcd.rs diff --git a/benches/benchmarks/factorial.rs b/benchmark_crate/benches/benchmarks/factorial.rs similarity index 100% rename from benches/benchmarks/factorial.rs rename to benchmark_crate/benches/benchmarks/factorial.rs diff --git a/benches/benchmarks/gcd.rs b/benchmark_crate/benches/benchmarks/gcd.rs similarity index 100% rename from benches/benchmarks/gcd.rs rename to benchmark_crate/benches/benchmarks/gcd.rs diff --git a/benches/benchmarks/mod.rs b/benchmark_crate/benches/benchmarks/mod.rs similarity index 100% rename from benches/benchmarks/mod.rs rename to benchmark_crate/benches/benchmarks/mod.rs diff --git a/benches/benchmarks/prime_benches.rs b/benchmark_crate/benches/benchmarks/prime_benches.rs similarity index 100% rename from benches/benchmarks/prime_benches.rs rename to benchmark_crate/benches/benchmarks/prime_benches.rs diff --git a/benches/benchmarks/roots.rs b/benchmark_crate/benches/benchmarks/roots.rs similarity index 99% rename from benches/benchmarks/roots.rs rename to benchmark_crate/benches/benchmarks/roots.rs index 2f377452..5aefb8b0 100644 --- a/benches/benchmarks/roots.rs +++ b/benchmark_crate/benches/benchmarks/roots.rs @@ -1,5 +1,3 @@ -#![cfg(feature = "rand")] - use criterion::Criterion; use num_bigint::{BigUint, RandBigInt}; use num_traits::Pow; diff --git a/benches/shootout-pidigits.rs b/benchmark_crate/benches/shootout-pidigits.rs similarity index 100% rename from benches/shootout-pidigits.rs rename to benchmark_crate/benches/shootout-pidigits.rs diff --git a/benchmark_crate/src/lib.rs b/benchmark_crate/src/lib.rs new file mode 100644 index 00000000..e69de29b diff --git a/build.rs b/build.rs index fd608665..997df66a 100644 --- a/build.rs +++ b/build.rs @@ -1,35 +1,12 @@ +extern crate autocfg; use std::env; -use std::io::Write; -use std::process::{Command, Stdio}; fn main() { - if probe("fn main() { 0i128; }") { + let ac = autocfg::new(); + + if ac.probe_type("i128") { println!("cargo:rustc-cfg=has_i128"); } else if env::var_os("CARGO_FEATURE_I128").is_some() { panic!("i128 support was not detected!"); } -} - -/// Test if a code snippet can be compiled -fn probe(code: &str) -> bool { - let rustc = env::var_os("RUSTC").unwrap_or_else(|| "rustc".into()); - let out_dir = env::var_os("OUT_DIR").expect("environment variable OUT_DIR"); - - let mut child = Command::new(rustc) - .arg("--out-dir") - .arg(out_dir) - .arg("--emit=obj") - .arg("-") - .stdin(Stdio::piped()) - .spawn() - .expect("rustc probe"); - - child - .stdin - .as_mut() - .expect("rustc stdin") - .write_all(code.as_bytes()) - .expect("write rustc stdin"); - - child.wait().expect("rustc probe").success() -} +} \ No newline at end of file diff --git a/ci/test_full.sh b/ci/test_full.sh index 5ce2ce96..9ab42b45 100755 --- a/ci/test_full.sh +++ b/ci/test_full.sh @@ -16,10 +16,27 @@ cargo test --verbose cargo build --no-default-features --features="std" cargo test --no-default-features --features="std" +# It should build in no_std +if [[ "$TRAVIS_RUST_VERSION" == "nightly" ]]; then + rustup target add thumbv7m-none-eabi + cargo build --no-default-features --target=thumbv7m-none-eabi + + # It should work in no_std on nightly. + # Note: Doctest might show an error: https://github.com/rust-lang/rust/issues/54010 + # The "error" is wrong however, the doctests still run. + cargo test --no-default-features +fi + # Each isolated feature should also work everywhere. for feature in $FEATURES; do cargo build --verbose --no-default-features --features="std $feature" cargo test --verbose --no-default-features --features="std $feature" + + # Ensure that feature also works in nostd context on nightly. + if [[ "$TRAVIS_RUST_VERSION" == "nightly" ]]; then + cargo build --verbose --no-default-features --features="$feature" + cargo test --verbose --no-default-features --features="$feature" + fi done # test all supported features together @@ -28,5 +45,6 @@ cargo test --features="std $FEATURES" # make sure benchmarks can be built if [[ "$TRAVIS_RUST_VERSION" == "nightly" ]]; then + cd benchmark_crate cargo bench --all-features --no-run fi diff --git a/src/algorithms/bits.rs b/src/algorithms/bits.rs index a053a350..970aff58 100644 --- a/src/algorithms/bits.rs +++ b/src/algorithms/bits.rs @@ -1,4 +1,4 @@ -use std::mem; +use core::mem; /// Find last set bit /// fls(0) == 0, fls(u32::MAX) == 32 @@ -9,3 +9,12 @@ pub fn fls(v: T) -> usize { pub fn ilog2(v: T) -> usize { fls(v) - 1 } + +/// Divide two integers, and ceil the result. +pub fn idiv_ceil(a: T, b: T) -> T { + if a % b != T::zero() { + a / b + T::one() + } else { + a / b + } +} diff --git a/src/algorithms/cmp.rs b/src/algorithms/cmp.rs index d14bb147..24af8ae9 100644 --- a/src/algorithms/cmp.rs +++ b/src/algorithms/cmp.rs @@ -1,4 +1,4 @@ -use std::cmp::Ordering::{self, Equal, Greater, Less}; +use core::cmp::Ordering::{self, Equal, Greater, Less}; use crate::big_digit::BigDigit; diff --git a/src/algorithms/div.rs b/src/algorithms/div.rs index 5a8b211b..96bdf916 100644 --- a/src/algorithms/div.rs +++ b/src/algorithms/div.rs @@ -1,6 +1,6 @@ use num_traits::{One, Zero}; use smallvec::SmallVec; -use std::cmp::Ordering; +use core::cmp::Ordering; use crate::algorithms::{add2, cmp_slice, sub2}; use crate::big_digit::{self, BigDigit, DoubleBigDigit}; diff --git a/src/algorithms/gcd.rs b/src/algorithms/gcd.rs index 420556ca..a4ae75a6 100644 --- a/src/algorithms/gcd.rs +++ b/src/algorithms/gcd.rs @@ -4,8 +4,8 @@ use crate::bigint::{BigInt, ToBigInt}; use crate::biguint::{BigUint, IntDigits}; use integer::Integer; use num_traits::{One, Signed, Zero}; -use std::borrow::Cow; -use std::ops::Neg; +use alloc::borrow::Cow; +use core::ops::Neg; /// XGCD sets z to the greatest common divisor of a and b and returns z. /// If extended is true, XGCD returns their value such that z = a*x + b*y. @@ -98,8 +98,8 @@ fn lehmer_gcd( // Ensure that a >= b if a < b { - std::mem::swap(&mut a, &mut b); - std::mem::swap(&mut ua, &mut ub); + core::mem::swap(&mut a, &mut b); + core::mem::swap(&mut ua, &mut ub); } // loop invariant A >= B @@ -277,8 +277,8 @@ pub fn extended_gcd( // Ensure that a >= b if a < b { - std::mem::swap(&mut a, &mut b); - std::mem::swap(&mut ua, &mut ub); + core::mem::swap(&mut a, &mut b); + core::mem::swap(&mut ua, &mut ub); } let mut q: BigInt = 0.into(); @@ -527,8 +527,8 @@ fn euclid_udpate( *q = q_new; *r = r_new; - std::mem::swap(a, b); - std::mem::swap(b, r); + core::mem::swap(a, b); + core::mem::swap(b, r); if extended { // ua, ub = ub, ua - q * ub @@ -546,7 +546,7 @@ fn euclid_udpate( #[cfg(test)] mod tests { use super::*; - use std::str::FromStr; + use core::str::FromStr; use num_traits::FromPrimitive; @@ -574,11 +574,11 @@ mod tests { while !r.is_zero() { let quotient = &old_r / &r; old_r = old_r - "ient * &r; - std::mem::swap(&mut old_r, &mut r); + core::mem::swap(&mut old_r, &mut r); old_s = old_s - "ient * &s; - std::mem::swap(&mut old_s, &mut s); + core::mem::swap(&mut old_s, &mut s); old_t = old_t - quotient * &t; - std::mem::swap(&mut old_t, &mut t); + core::mem::swap(&mut old_t, &mut t); } (old_r, old_s, old_t) diff --git a/src/algorithms/mac.rs b/src/algorithms/mac.rs index 4e6c3d18..4a42a266 100644 --- a/src/algorithms/mac.rs +++ b/src/algorithms/mac.rs @@ -1,5 +1,5 @@ -use std::cmp; -use std::iter::repeat; +use core::cmp; +use core::iter::repeat; use crate::algorithms::{adc, add2, sub2, sub_sign}; use crate::big_digit::{BigDigit, DoubleBigDigit, BITS}; @@ -310,7 +310,7 @@ mod tests { #[cfg(feature = "u64_digit")] #[test] fn test_mac3_regression() { - let b: Vec = vec![ + let b = [ 6871754923702299421, 18286959765922425554, 16443042141374662930, @@ -657,7 +657,7 @@ mod tests { 17511662813348858473, 12, ]; - let c: Vec = vec![ + let c = [ 13147625290258353449, 13817956093586917764, 18028234882233861888, @@ -1655,18 +1655,18 @@ mod tests { 1305238720762, ]; - let mut a1: Vec = vec![0; 1341]; - let mut a2: Vec = vec![0; 1341]; - let mut a3: Vec = vec![0; 1341]; + let mut a1 = &mut [0; 1341]; + let mut a2 = &mut [0; 1341]; + let mut a3 = &mut [0; 1341]; //print!("{} {}", b.len(), c.len()); - long(&mut a1, &b, &c); - karatsuba(&mut a2, &b, &c); + long(a1, &b, &c); + karatsuba(a2, &b, &c); - assert_eq!(a1, a2); + assert_eq!(&a1[..], &a2[..]); // println!("res: {:?}", &a1); - toom3(&mut a3, &b, &c); - assert_eq!(a1, a3); + toom3(a3, &b, &c); + assert_eq!(&a1[..], &a3[..]); } } diff --git a/src/algorithms/mod_inverse.rs b/src/algorithms/mod_inverse.rs index 03321f8c..b028133b 100644 --- a/src/algorithms/mod_inverse.rs +++ b/src/algorithms/mod_inverse.rs @@ -1,4 +1,4 @@ -use std::borrow::Cow; +use alloc::borrow::Cow; use num_traits::{One, Signed}; diff --git a/src/algorithms/shl.rs b/src/algorithms/shl.rs index 32fbaad4..6e2cfcc9 100644 --- a/src/algorithms/shl.rs +++ b/src/algorithms/shl.rs @@ -1,5 +1,5 @@ -use std::borrow::Cow; -use std::iter::repeat; +use alloc::borrow::Cow; +use core::iter::repeat; use smallvec::SmallVec; diff --git a/src/algorithms/shr.rs b/src/algorithms/shr.rs index 9afe2bb3..a4e2fe95 100644 --- a/src/algorithms/shr.rs +++ b/src/algorithms/shr.rs @@ -1,4 +1,4 @@ -use std::borrow::Cow; +use alloc::borrow::Cow; use num_traits::Zero; use smallvec::SmallVec; diff --git a/src/algorithms/sub.rs b/src/algorithms/sub.rs index c5c8c0cb..0b9bcc0c 100644 --- a/src/algorithms/sub.rs +++ b/src/algorithms/sub.rs @@ -1,5 +1,5 @@ -use std::cmp; -use std::cmp::Ordering::*; +use core::cmp; +use core::cmp::Ordering::*; use num_traits::Zero; use smallvec::SmallVec; diff --git a/src/bigint.rs b/src/bigint.rs index 54aa2502..6db713b6 100644 --- a/src/bigint.rs +++ b/src/bigint.rs @@ -1,19 +1,21 @@ #![allow(clippy::suspicious_arithmetic_impl)] #[allow(deprecated, unused_imports)] -use std::borrow::Cow; -use std::cmp::Ordering::{self, Equal, Greater, Less}; -use std::default::Default; -use std::hash::{Hash, Hasher}; -use std::iter::{Product, Sum}; -use std::ops::{ +use alloc::borrow::Cow; +use alloc::vec::Vec; +use alloc::string::String; +use core::cmp::Ordering::{self, Equal, Greater, Less}; +use core::default::Default; +use core::hash::{Hash, Hasher}; +use core::iter::{Product, Sum}; +use core::ops::{ Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign, }; -use std::str::{self, FromStr}; -use std::{fmt, mem}; +use core::str::{self, FromStr}; +use core::{fmt, mem}; #[cfg(has_i128)] -use std::{i128, u128}; -use std::{i64, u64}; +use core::{i128, u128}; +use core::{i64, u64}; #[cfg(feature = "serde")] use serde; diff --git a/src/bigrand.rs b/src/bigrand.rs index f4b9aa7d..54e23b38 100644 --- a/src/bigrand.rs +++ b/src/bigrand.rs @@ -270,7 +270,8 @@ impl Distribution for RandomBits { /// to provide actually random primes. /// /// # Example -/// ``` +#[cfg_attr(feature = "std", doc = " ```")] +#[cfg_attr(not(feature = "std"), doc = " ```ignore")] /// extern crate rand; /// extern crate num_bigint_dig as num_bigint; /// diff --git a/src/biguint.rs b/src/biguint.rs index 5d906066..9bff1511 100644 --- a/src/biguint.rs +++ b/src/biguint.rs @@ -1,18 +1,22 @@ #[allow(deprecated, unused_imports)] -use std::ascii::AsciiExt; -use std::borrow::Cow; -use std::cmp::Ordering::{self, Equal, Greater, Less}; -use std::default::Default; -use std::hash::{Hash, Hasher}; -use std::iter::{Product, Sum}; -use std::ops::{ +use alloc::borrow::Cow; +use alloc::vec::Vec; +use alloc::string::String; +use core::cmp::Ordering::{self, Equal, Greater, Less}; +use core::default::Default; +use core::hash::{Hash, Hasher}; +use core::iter::{Product, Sum}; +use core::ops::{ Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign, }; -use std::str::{self, FromStr}; -use std::{cmp, fmt, mem}; -use std::{f32, f64}; -use std::{u64, u8}; +use core::str::{self, FromStr}; +use core::{cmp, fmt, mem}; +use core::{f32, f64}; +use core::{u64, u32, u8}; + +#[cfg(not(feature = "std"))] +use libm::F64Ext; #[cfg(feature = "serde")] use serde; @@ -22,9 +26,11 @@ use zeroize::Zeroize; use integer::{Integer, Roots}; use num_traits::{ - CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, Float, FromPrimitive, Num, One, Pow, + CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, FromPrimitive, Num, One, Pow, ToPrimitive, Unsigned, Zero, }; +use num_traits::float::FloatCore; + use BigInt; use big_digit::{self, BigDigit}; @@ -38,7 +44,7 @@ use self::monty::monty_modpow; use super::VEC_SIZE; use crate::algorithms::{__add2, __sub2rev, add2, sub2, sub2rev}; use crate::algorithms::{biguint_shl, biguint_shr}; -use crate::algorithms::{cmp_slice, fls, ilog2}; +use crate::algorithms::{cmp_slice, fls, ilog2, idiv_ceil}; use crate::algorithms::{div_rem, div_rem_digit, mac_with_carry, mul3, scalar_mul}; use crate::algorithms::{extended_gcd, mod_inverse}; use crate::traits::{ExtendedGcd, ModInverse}; @@ -194,9 +200,9 @@ fn from_radix_digits_be(v: &[u8], radix: u32) -> BigUint { debug_assert!(v.iter().all(|&c| (c as u32) < radix)); // Estimate how big the result will be, so we can pre-allocate it. - let bits = (radix as f64).log2() * v.len() as f64; - let big_digits = (bits / big_digit::BITS as f64).ceil(); - let mut data = SmallVec::with_capacity(big_digits as usize); + let bits = ilog2(radix) * v.len(); + let big_digits = idiv_ceil(bits, big_digit::BITS); + let mut data = SmallVec::with_capacity(big_digits); let (base, power) = get_radix_base(radix); let radix = radix as BigDigit; @@ -1713,14 +1719,14 @@ impl FromPrimitive for BigUint { } // match the rounding of casting from float to int - n = n.trunc(); + n = FloatCore::trunc(n); // handle 0.x, -0.x if n.is_zero() { return Some(BigUint::zero()); } - let (mantissa, exponent, sign) = Float::integer_decode(n); + let (mantissa, exponent, sign) = FloatCore::integer_decode(n); if sign == -1 { return None; @@ -1925,7 +1931,8 @@ fn to_radix_digits_le(u: &BigUint, radix: u32) -> Vec { debug_assert!(!u.is_zero() && !radix.is_power_of_two()); // Estimate how big the result will be, so we can pre-allocate it. - let radix_digits = ((u.bits() as f64) / (radix as f64).log2()).ceil(); + let bits = ilog2(radix); + let radix_digits = idiv_ceil(u.bits(), bits); let mut res = Vec::with_capacity(radix_digits as usize); let mut digits = u.clone(); @@ -2518,7 +2525,7 @@ impl serde::Serialize for BigUint { .iter() .enumerate() .flat_map(|(i, n)| { - if i == last && n < &(::std::u32::MAX as u64) { + if i == last && n < &(u32::MAX as u64) { vec![*n as u32] } else { vec![*n as u32, (n >> 32) as u32] diff --git a/src/lib.rs b/src/lib.rs index 05f17702..a9efa60a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,7 +50,9 @@ //! //! It's easy to generate large random numbers: //! -//! ```rust +#![cfg_attr(feature = "std", doc = " ```")] +#![cfg_attr(not(feature = "std"), doc = " ```ignore")] +//! //! # #[cfg(feature = "rand")] //! extern crate rand; //! extern crate num_bigint_dig as bigint; @@ -78,12 +80,37 @@ //! ## Compatibility //! //! The `num-bigint` crate is tested for rustc 1.15 and greater. +//! +//! ## `no_std` compatibility +//! +//! This crate is compatible with `no_std` environments from Rust 1.36. Note +//! however that it still requires the `alloc` crate, so the user should ensure +//! that they set a `global_allocator`. +//! +//! To use in no_std environment, add the crate as such in your `Cargo.toml` +//! file: +//! +//! ```toml +//! [dependencies] +//! num-bigint = { version = "0.3", default-features=false } +//! ``` +//! +//! Every features should be compatible with no_std environment, so feel free to +//! add features like `prime`, `i128`, etc... #![doc(html_root_url = "https://docs.rs/num-bigint/0.2")] -// We don't actually support `no_std` yet, and probably won't until `alloc` is stable. We're just -// reserving this ability with the "std" feature now, and compilation will fail without. #![cfg_attr(not(feature = "std"), no_std)] +#[cfg(not(feature = "std"))] +#[macro_use] +extern crate alloc; + +#[cfg(feature = "std")] +use std as alloc; + +#[cfg(feature = "std")] +extern crate core; + #[cfg(feature = "rand")] extern crate rand; #[cfg(all(test, feature = "rand"))] @@ -113,8 +140,11 @@ extern crate num_traits; #[cfg(feature = "prime")] extern crate byteorder; +extern crate libm; + +#[cfg(feature = "std")] use std::error::Error; -use std::fmt; +use core::fmt; #[macro_use] mod macros; @@ -182,6 +212,7 @@ impl fmt::Display for ParseBigIntError { } } +#[cfg(feature = "std")] impl Error for ParseBigIntError { fn description(&self) -> &str { self.__description() diff --git a/src/monty.rs b/src/monty.rs index ffaa9708..3066ace4 100644 --- a/src/monty.rs +++ b/src/monty.rs @@ -1,7 +1,8 @@ #![allow(clippy::many_single_char_names)] use num_traits::{One, Zero}; -use std::ops::Shl; +use core::ops::Shl; +use alloc::vec::Vec; use big_digit::{self, BigDigit, DoubleBigDigit, SignedDoubleBigDigit}; use biguint::BigUint; @@ -193,7 +194,7 @@ pub fn monty_modpow(x: &BigUint, y: &BigUint, m: &BigUint) -> BigUint { mr.n0inv, num_words, ); - ::std::mem::swap(&mut z, &mut zz); + core::mem::swap(&mut z, &mut zz); yi <<= n; j += n; } diff --git a/src/prime.rs b/src/prime.rs index 34e4a0dd..882c833c 100644 --- a/src/prime.rs +++ b/src/prime.rs @@ -388,7 +388,7 @@ pub fn probably_prime_lucas(n: &BigUint) -> bool { let mut t2 = &vk1 << 1; if t1 < t2 { - ::std::mem::swap(&mut t1, &mut t2); + core::mem::swap(&mut t1, &mut t2); } t1 -= t2; @@ -440,6 +440,7 @@ fn get_bit(x: &BigUint, i: usize) -> u8 { #[cfg(test)] mod tests { use super::*; + use alloc::vec::Vec; // use RandBigInt; use crate::biguint::ToBigUint; diff --git a/tests/bigint.rs b/tests/bigint.rs index 28908749..ec1739e0 100644 --- a/tests/bigint.rs +++ b/tests/bigint.rs @@ -20,7 +20,8 @@ use std::{i16, i32, i64, i8, isize}; use std::{u16, u32, u64, u8, usize}; use num_integer::Integer; -use num_traits::{Float, FromPrimitive, Num, One, Pow, Signed, ToPrimitive, Zero}; +use num_traits::{FromPrimitive, Num, One, Pow, Signed, ToPrimitive, Zero}; +use num_traits::float::FloatCore; mod consts; use consts::*; @@ -1119,9 +1120,22 @@ fn test_negative_shr() { #[test] #[cfg(feature = "rand")] fn test_random_shr() { - use rand::distributions::Standard; + + #[cfg(feature = "std")] + fn thread_rng() -> impl rand::Rng { + rand::thread_rng() + } + #[cfg(not(feature = "std"))] + fn thread_rng() -> impl rand::Rng { + use rand::SeedableRng; + // Chosen by fair dice roll + rand::rngs::StdRng::seed_from_u64(4) + } + use rand::Rng; - let mut rng = rand::thread_rng(); + use rand::distributions::Standard; + + let mut rng = thread_rng(); for p in rng.sample_iter::(&Standard).take(1000) { let big = BigInt::from(p); diff --git a/tests/biguint.rs b/tests/biguint.rs index 6a1921ed..41c5c3b8 100644 --- a/tests/biguint.rs +++ b/tests/biguint.rs @@ -20,10 +20,12 @@ use std::{i128, u128}; use std::{u16, u32, u64, u8, usize}; use num_traits::{ - CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, Float, FromPrimitive, Num, One, Pow, + CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, FromPrimitive, Num, One, Pow, ToPrimitive, Zero, }; +use num_traits::float::FloatCore; + mod consts; use consts::*; diff --git a/tests/rand.rs b/tests/rand.rs index 17fb83af..78609078 100644 --- a/tests/rand.rs +++ b/tests/rand.rs @@ -11,9 +11,18 @@ mod biguint { use num_bigint::{BigUint, RandBigInt, RandomBits}; use num_traits::Zero; use rand::distributions::Uniform; - use rand::thread_rng; use rand::{Rng, SeedableRng}; + #[cfg(feature = "std")] + fn thread_rng() -> impl Rng { + rand::thread_rng() + } + #[cfg(not(feature = "std"))] + fn thread_rng() -> impl Rng { + // Chosen by fair dice roll + rand::StdRng::seed_from_u64(4) + } + #[test] fn test_rand() { let mut rng = thread_rng(); @@ -216,9 +225,18 @@ mod bigint { use num_bigint::{BigInt, RandBigInt, RandomBits}; use num_traits::Zero; use rand::distributions::Uniform; - use rand::thread_rng; use rand::{Rng, SeedableRng}; + #[cfg(feature = "std")] + fn thread_rng() -> impl Rng { + rand::thread_rng() + } + #[cfg(not(feature = "std"))] + fn thread_rng() -> impl Rng { + // Chosen by fair dice roll + rand::rngs::StdRng::seed_from_u64(4) + } + #[test] fn test_rand() { let mut rng = thread_rng(); diff --git a/tests/roots.rs b/tests/roots.rs index ae2f9ec6..d9c93c9f 100644 --- a/tests/roots.rs +++ b/tests/roots.rs @@ -104,9 +104,21 @@ mod biguint { #[cfg(feature = "rand")] #[test] fn test_roots_rand() { + + #[cfg(feature = "std")] + fn thread_rng() -> impl rand::Rng { + rand::thread_rng() + } + #[cfg(not(feature = "std"))] + fn thread_rng() -> impl rand::Rng { + use rand::SeedableRng; + // Chosen by fair dice roll + rand::rngs::StdRng::seed_from_u64(4) + } + use num_bigint::RandBigInt; + use rand::Rng; use rand::distributions::Uniform; - use rand::{thread_rng, Rng}; let mut rng = thread_rng(); let bit_range = Uniform::new(0, 2048);