Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to rand 0.5 #48

Merged
merged 9 commits into from
May 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
language: rust
rust:
- 1.15.0
- 1.20.0
- 1.25.0
- 1.22.0
- 1.26.0
- stable
- beta
- nightly
Expand Down
9 changes: 5 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ publish = false
readme = "README.md"
build = "build.rs"

[package.metadata.docs.rs]
features = ["std", "serde", "rand"]

[[bench]]
name = "bigint"

Expand All @@ -38,8 +41,9 @@ default-features = false

[dependencies.rand]
optional = true
version = "0.4"
version = "0.5"
default-features = false
features = ["std"]

[dependencies.serde]
optional = true
Expand All @@ -50,9 +54,6 @@ features = ["std"]
[dev-dependencies.serde_test]
version = "1.0"

[dev-dependencies.rand]
version = "0.4"

[features]
default = ["std"]
i128 = ["num-integer/i128", "num-traits/i128"]
Expand Down
9 changes: 6 additions & 3 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@
- [`BigInt` now supports assignment operators][41] like `AddAssign`.
- [`BigInt` and `BigUint` now support conversions with `i128` and `u128`][44],
if sufficient compiler support is detected.
- [`BigInt` and `BigUint` now implement rand's `SampleUniform` trait][48].
- The release also includes other miscellaneous improvements to performance.

### Breaking Changes

- [`num-bigint` now requires rustc 1.15 or greater][23].
- [The crate now has a `std` feature, and won't build without it][46]. This is
in preparation for someday supporting `#![no_std]` with `alloc`.
- [The `rand` and `serde` dependencies have been updated to 0.4 and 1.0][24]
respectively, and neither are enabled by default. The `rustc-serialize` crate
is no longer supported by `num-bigint`.
- [The `serde` dependency has been updated to 1.0][24], still disabled by
default. The `rustc-serialize` crate is no longer supported by `num-bigint`.
- [The `rand` dependency has been updated to 0.5][48], now disabled by default.
This requires rustc 1.22 or greater for `rand`'s own requirement.
- [`Shr for BigInt` now rounds down][8] rather than toward zero, matching the
behavior of the primitive integers for negative values.
- [`ParseBigIntError` is now an opaque type][37].
Expand All @@ -41,6 +43,7 @@
[41]: https://github.com/rust-num/num-bigint/pull/41
[44]: https://github.com/rust-num/num-bigint/pull/44
[46]: https://github.com/rust-num/num-bigint/pull/46
[48]: https://github.com/rust-num/num-bigint/pull/48

# Release 0.1.44

Expand Down
4 changes: 2 additions & 2 deletions ci/rustup.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#!/bin/sh
# Use rustup to locally run the same suite of tests as .travis.yml.
# (You should first install/update 1.15.0, stable, beta, and nightly.)
# (You should first install/update all versions listed below.)

set -ex

export TRAVIS_RUST_VERSION
for TRAVIS_RUST_VERSION in 1.15.0 1.20.0 1.25.0 stable beta nightly; do
for TRAVIS_RUST_VERSION in 1.15.0 1.22.0 1.26.0 stable beta nightly; do
run="rustup run $TRAVIS_RUST_VERSION"
$run cargo build --verbose
$run $PWD/ci/test_full.sh
Expand Down
7 changes: 5 additions & 2 deletions ci/test_full.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ set -ex

echo Testing num-bigint on rustc ${TRAVIS_RUST_VERSION}

FEATURES="rand serde"
if [[ "$TRAVIS_RUST_VERSION" =~ ^(nightly|beta|stable)$ ]]; then
FEATURES="serde"
if [[ "$TRAVIS_RUST_VERSION" =~ ^(nightly|beta|stable|1.26.0|1.22.0)$ ]]; then
FEATURES="$FEATURES rand"
fi
if [[ "$TRAVIS_RUST_VERSION" =~ ^(nightly|beta|stable|1.26.0)$ ]]; then
FEATURES="$FEATURES i128"
fi

Expand Down
105 changes: 16 additions & 89 deletions src/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,6 @@ use std::iter::{Product, Sum};
#[cfg(feature = "serde")]
use serde;

// Some of the tests of non-RNG-based functionality are randomized using the
// RNG-based functionality, so the RNG-based functionality needs to be enabled
// for tests.
#[cfg(any(feature = "rand", test))]
use rand::Rng;

use integer::Integer;
use traits::{ToPrimitive, FromPrimitive, Num, CheckedAdd, CheckedSub,
CheckedMul, CheckedDiv, Signed, Zero, One};
Expand Down Expand Up @@ -115,6 +109,22 @@ pub struct BigInt {
data: BigUint,
}

/// Return the magnitude of a `BigInt`.
///
/// This is in a private module, pseudo pub(crate)
#[cfg(feature = "rand")]
pub fn magnitude(i: &BigInt) -> &BigUint {
&i.data
}

/// Return the owned magnitude of a `BigInt`.
///
/// This is in a private module, pseudo pub(crate)
#[cfg(feature = "rand")]
pub fn into_magnitude(i: BigInt) -> BigUint {
i.data
}

impl PartialEq for BigInt {
#[inline]
fn eq(&self, other: &BigInt) -> bool {
Expand Down Expand Up @@ -2130,89 +2140,6 @@ impl_to_bigint!(u128, FromPrimitive::from_u128);
impl_to_bigint!(f32, FromPrimitive::from_f32);
impl_to_bigint!(f64, FromPrimitive::from_f64);

pub trait RandBigInt {
/// Generate a random `BigUint` of the given bit size.
fn gen_biguint(&mut self, bit_size: usize) -> BigUint;

/// Generate a random BigInt of the given bit size.
fn gen_bigint(&mut self, bit_size: usize) -> BigInt;

/// Generate a random `BigUint` less than the given bound. Fails
/// when the bound is zero.
fn gen_biguint_below(&mut self, bound: &BigUint) -> BigUint;

/// Generate a random `BigUint` within the given range. The lower
/// bound is inclusive; the upper bound is exclusive. Fails when
/// the upper bound is not greater than the lower bound.
fn gen_biguint_range(&mut self, lbound: &BigUint, ubound: &BigUint) -> BigUint;

/// Generate a random `BigInt` within the given range. The lower
/// bound is inclusive; the upper bound is exclusive. Fails when
/// the upper bound is not greater than the lower bound.
fn gen_bigint_range(&mut self, lbound: &BigInt, ubound: &BigInt) -> BigInt;
}

#[cfg(any(feature = "rand", test))]
impl<R: Rng> RandBigInt for R {
fn gen_biguint(&mut self, bit_size: usize) -> BigUint {
use super::big_digit::BITS;
let (digits, rem) = bit_size.div_rem(&BITS);
let mut data = Vec::with_capacity(digits + 1);
for _ in 0..digits {
data.push(self.gen());
}
if rem > 0 {
let final_digit: BigDigit = self.gen();
data.push(final_digit >> (BITS - rem));
}
BigUint::new(data)
}

fn gen_bigint(&mut self, bit_size: usize) -> BigInt {
// Generate a random BigUint...
let biguint = self.gen_biguint(bit_size);
// ...and then randomly assign it a Sign...
let sign = if biguint.is_zero() {
// ...except that if the BigUint is zero, we need to try
// again with probability 0.5. This is because otherwise,
// the probability of generating a zero BigInt would be
// double that of any other number.
if self.gen() {
return self.gen_bigint(bit_size);
} else {
NoSign
}
} else if self.gen() {
Plus
} else {
Minus
};
BigInt::from_biguint(sign, biguint)
}

fn gen_biguint_below(&mut self, bound: &BigUint) -> BigUint {
assert!(!bound.is_zero());
let bits = bound.bits();
loop {
let n = self.gen_biguint(bits);
if n < *bound {
return n;
}
}
}

fn gen_biguint_range(&mut self, lbound: &BigUint, ubound: &BigUint) -> BigUint {
assert!(*lbound < *ubound);
return lbound + self.gen_biguint_below(&(ubound - lbound));
}

fn gen_bigint_range(&mut self, lbound: &BigInt, ubound: &BigInt) -> BigInt {
assert!(*lbound < *ubound);
let delta = (ubound - lbound).to_biguint().unwrap();
return lbound + self.gen_biguint_below(&delta).to_bigint().unwrap();
}
}

impl BigInt {
/// Creates and initializes a BigInt.
///
Expand Down
Loading