diff --git a/Cargo.lock b/Cargo.lock
index 3a9193535489..9485e1674448 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3520,11 +3520,11 @@ dependencies = [
[[package]]
name = "num-bigint"
-version = "0.2.3"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a"
+checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
dependencies = [
- "autocfg 0.1.6",
+ "autocfg 1.0.1",
"num-integer",
"num-traits",
]
@@ -3542,11 +3542,11 @@ dependencies = [
[[package]]
name = "num-integer"
-version = "0.1.41"
+version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
+checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
- "autocfg 0.1.6",
+ "autocfg 1.0.1",
"num-traits",
]
diff --git a/third_party/rust/num-bigint/.cargo-checksum.json b/third_party/rust/num-bigint/.cargo-checksum.json
index 288114fb2c67..390f95e39fef 100644
--- a/third_party/rust/num-bigint/.cargo-checksum.json
+++ b/third_party/rust/num-bigint/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"ba1041ccca008388ab7d7432ae63b811d8e744c8fa9e50f371bfbeb78acd1995","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"25f684f15b0ed6ea216c3831e567a9b5dc02b78ff7e579e0d7323305db75218c","RELEASES.md":"5a3045437dc1850ae4e39acd14f2660ed7bace9b0c4d7dae3950f049dbfd4d65","benches/bigint.rs":"252c0dc1f220a6fbdc151e729069260c2f5909516467ceb873e412e5691d7042","benches/factorial.rs":"d536f5584987847f10321b94175a0d8fd2beb14b7c814ec28eef1f96ca081fbe","benches/gcd.rs":"7ec5ce7174e1d31bd08ccc5670f5a32a5c084f258d7980cd6d02e0a8bb5562c4","benches/roots.rs":"3f87db894c379122aee5cd8520c7c759c26d8a9649ac47f45d1bf4d560e1cb07","benches/shootout-pidigits.rs":"985b76d6dba05c396efe4da136c6a0bb2c02bcf5b05cbb346f0f802a891629bb","bors.toml":"1c81ede536a37edd30fe4e622ff0531b25372403ac9475a5d6c50f14156565a2","build.rs":"56d4fbb7a55750e61d2074df2735a31995c1decbd988c0e722926235e0fed487","ci/rustup.sh":"c976bb2756da3876363b01fdbf06c13de20df421e5add45e4017c4df42ed06a6","ci/test_full.sh":"a0ac26b85809eb43edd813c9dc88f34a1a8227b7618f4bede89c8f2ac9a4c05a","src/algorithms.rs":"8827c46df051214d1d0e7670680ca9f4834eae678ed340c86b5ea32fddbc7c3c","src/bigint.rs":"7f113fdc034c566bc8475ff0a7d136aa8250cae047b4356084e6797a15f968e1","src/bigrand.rs":"d2f72b8833f367dd8990b4b026f302d838144c5a4de942135d39a3a9932f137d","src/biguint.rs":"b95bfcf84e3f831fb07982aa4b058cd16a524eaa493946eed8e8c5fb8d65797a","src/lib.rs":"d5cc50306f73f07555e7d3413edd2ca5c7d54cbc80a2e83844d77fb8750ae314","src/macros.rs":"2e763517922d960c06e3ac4d319b1d81e66dffadfde8fdf300ff8b8bb95bd8cd","src/monty.rs":"6a867846b7f6af9115add2fd59fccd0651c71dd7f2316e8fb9c812ff3c27da12","tests/bigint.rs":"f7df454f085a862ad5a98e3a802303a3fdf06275a7a1b92074b40b76a715bed2","tests/bigint_bitwise.rs":"dc9436c8f200f2b0ac08cefb23bb8e39c4e688e9026a506a678416c3d573128b","tests/bigint_scalar.rs":"aa176ed102cafd425a215a93460806914d8f3ac288c98ec3e56772fa17379838","tests/biguint.rs":"9ae79f96d1a3beca5be95dffe9d79dc3436f886edc6cae51faf4203c3e0c4681","tests/biguint_scalar.rs":"9cc6f2bf2fe77f34b09eb2266c23aded3b27a60dc1859eb60d3013164292467e","tests/consts/mod.rs":"f9ea5f40733e2f5f432803d830be9db929d91e5e5efd8510b07c6ced2fe554be","tests/macros/mod.rs":"2789b680dd14a770d5ceef430018be0ada85098d69e218c61c17214084c4f763","tests/modpow.rs":"f14cdea11e355a371b314cc866dfa13281a3226706ab2cf01c1485273afde300","tests/quickcheck.rs":"6d6c1ec244b2384a8b34e989870aef8bcedccf6cc46e2626b29a032703bef03c","tests/rand.rs":"08370135bd78432660cfcd708a9ea852022d555bc92c1f3c482fabd17faa64a0","tests/roots.rs":"9ec1bdb0cd1c72402a41e5470325a5276af75979b7fc0f0b63e7bbbb9f3505b2","tests/serde.rs":"79d7a0347207b3a3666af67d2ed97fa34f2922732121a3cb8f5b9f990846acfa","tests/torture.rs":"9fe4897580c0ebe2b7062f5b0b890b4b03510daa45c9236f0edba7144f9eb6f8"},"package":"f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a"}
\ No newline at end of file
+{"files":{"Cargo.toml":"e10df83bce937fc2d2ee258af173fee42891dc2d5bc3217955935669bdcc6dfb","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"00ff4891b409b25220a0f863c772a786c81cf291fab894963a2c8d7a251f67fd","RELEASES.md":"e712d5bdd58cc82a34f15f7926b4a7a65022ededc3069375fc54ab63eba2d133","benches/bigint.rs":"252c0dc1f220a6fbdc151e729069260c2f5909516467ceb873e412e5691d7042","benches/factorial.rs":"d536f5584987847f10321b94175a0d8fd2beb14b7c814ec28eef1f96ca081fbe","benches/gcd.rs":"7ec5ce7174e1d31bd08ccc5670f5a32a5c084f258d7980cd6d02e0a8bb5562c4","benches/roots.rs":"3f87db894c379122aee5cd8520c7c759c26d8a9649ac47f45d1bf4d560e1cb07","benches/shootout-pidigits.rs":"985b76d6dba05c396efe4da136c6a0bb2c02bcf5b05cbb346f0f802a891629bb","bors.toml":"1c81ede536a37edd30fe4e622ff0531b25372403ac9475a5d6c50f14156565a2","build.rs":"b4b2d0df90ca7570a339ca4d84a72e4ef00d9dced8927350424e666790c752d7","ci/rustup.sh":"c976bb2756da3876363b01fdbf06c13de20df421e5add45e4017c4df42ed06a6","ci/test_full.sh":"a0ac26b85809eb43edd813c9dc88f34a1a8227b7618f4bede89c8f2ac9a4c05a","src/algorithms.rs":"96220e32bd2496fbcba07ba35ef21e08e12a38d85d9724b33877c078040caf99","src/bigint.rs":"5d4888db1d8487a5c73bd4ee23967f4ba04f6f6edb4c3212902297e61f628141","src/bigrand.rs":"025b795928efa69592da2a7f54a60b0b72105ec6bae652f1f1b6402d6ca7bf3a","src/biguint.rs":"068abe461e9ba0582a2a18aede236ffdfe0cffc39fae9688f6a0873af6935b9b","src/lib.rs":"0f4280a9ffd3b8465ecaf9a7c99087bf18e5242b31d0311ac15bec4e995e5a41","src/macros.rs":"327691e39e31ac2d708e2bb02b50338d57cb0d3ca7107a30117df391bf781714","src/monty.rs":"ecdacb02e7d0a64b249a3395bf33c26f62b1ca05908f2eab0edd7f8f7a2ad7ae","tests/bigint.rs":"f7df454f085a862ad5a98e3a802303a3fdf06275a7a1b92074b40b76a715bed2","tests/bigint_bitwise.rs":"dc9436c8f200f2b0ac08cefb23bb8e39c4e688e9026a506a678416c3d573128b","tests/bigint_scalar.rs":"fddaa72911cd22cd34df130fee65dc1a1447ddbd9dfe5491b15e7a5868ee49e7","tests/biguint.rs":"9ae79f96d1a3beca5be95dffe9d79dc3436f886edc6cae51faf4203c3e0c4681","tests/biguint_scalar.rs":"4601e36b78bb177893f3abbd0a4050030eb8a65d3e57cdf005aea0a5b811adde","tests/consts/mod.rs":"f9ea5f40733e2f5f432803d830be9db929d91e5e5efd8510b07c6ced2fe554be","tests/macros/mod.rs":"5e73339e8baa9fc2c3f5b9097f9909091b5e4b47f905ffdf7da81d4647c6141c","tests/modpow.rs":"e21e46a97fc5da7eed1db5d6a52ac7ba50b78532f1a97aa46d41867d4848282c","tests/quickcheck.rs":"a3c68279b50cc35ec2856b74ac3f3265457dd788ed6138a14dd16a32868f22ba","tests/rand.rs":"08370135bd78432660cfcd708a9ea852022d555bc92c1f3c482fabd17faa64a0","tests/roots.rs":"9ec1bdb0cd1c72402a41e5470325a5276af75979b7fc0f0b63e7bbbb9f3505b2","tests/serde.rs":"79d7a0347207b3a3666af67d2ed97fa34f2922732121a3cb8f5b9f990846acfa","tests/torture.rs":"9fe4897580c0ebe2b7062f5b0b890b4b03510daa45c9236f0edba7144f9eb6f8"},"package":"090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"}
\ No newline at end of file
diff --git a/third_party/rust/num-bigint/Cargo.toml b/third_party/rust/num-bigint/Cargo.toml
index d8403a5659fc..9b99bae63f42 100644
--- a/third_party/rust/num-bigint/Cargo.toml
+++ b/third_party/rust/num-bigint/Cargo.toml
@@ -12,7 +12,7 @@
[package]
name = "num-bigint"
-version = "0.2.3"
+version = "0.2.6"
authors = ["The Rust Project Developers"]
build = "build.rs"
description = "Big integer implementation for Rust"
@@ -42,11 +42,11 @@ name = "roots"
name = "shootout-pidigits"
harness = false
[dependencies.num-integer]
-version = "0.1.39"
+version = "0.1.42"
default-features = false
[dependencies.num-traits]
-version = "0.2.7"
+version = "0.2.11"
default-features = false
[dependencies.quickcheck]
@@ -73,7 +73,7 @@ default-features = false
[dev-dependencies.serde_test]
version = "1.0"
[build-dependencies.autocfg]
-version = "0.1.2"
+version = "1"
[features]
default = ["std"]
diff --git a/third_party/rust/num-bigint/README.md b/third_party/rust/num-bigint/README.md
index f7eefed87e69..4691c9a72505 100644
--- a/third_party/rust/num-bigint/README.md
+++ b/third_party/rust/num-bigint/README.md
@@ -33,6 +33,19 @@ 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
mandatory by enabling the `i128` crate feature.
+### Random Generation
+
+`num-bigint` supports the generation of random big integers when the `rand`
+feature is enabled. To enable it include rand as
+
+```toml
+rand = "0.5"
+num-bigint = { version = "0.2", features = ["rand"] }
+```
+
+Note that you must use the version of `rand` that `num-bigint` is compatible
+with: `0.5`.
+
## Releases
Release notes are available in [RELEASES.md](RELEASES.md).
diff --git a/third_party/rust/num-bigint/RELEASES.md b/third_party/rust/num-bigint/RELEASES.md
index 911dd7835f87..358534ec0a92 100644
--- a/third_party/rust/num-bigint/RELEASES.md
+++ b/third_party/rust/num-bigint/RELEASES.md
@@ -1,3 +1,35 @@
+# Release 0.2.6 (2020-01-27)
+
+- [Fix the promotion of negative `isize` in `BigInt` assign-ops][133].
+
+**Contributors**: @cuviper, @HactarCE
+
+[133]: https://github.com/rust-num/num-bigint/pull/133
+
+# Release 0.2.5 (2020-01-09)
+
+- [Updated the `autocfg` build dependency to 1.0][126].
+
+**Contributors**: @cuviper, @tspiteri
+
+[126]: https://github.com/rust-num/num-bigint/pull/126
+
+# Release 0.2.4 (2020-01-01)
+
+- [The new `BigUint::to_u32_digits` method][104] returns the number as a
+ little-endian vector of base-232 digits. The same method on
+ `BigInt` also returns the sign.
+- [`BigUint::modpow` now applies a modulus even for exponent 1][113], which
+ also affects `BigInt::modpow`.
+- [`BigInt::modpow` now returns the correct sign for negative bases with even
+ exponents][114].
+
+[104]: https://github.com/rust-num/num-bigint/pull/104
+[113]: https://github.com/rust-num/num-bigint/pull/113
+[114]: https://github.com/rust-num/num-bigint/pull/114
+
+**Contributors**: @alex-ozdemir, @cuviper, @dingelish, @Speedy37, @youknowone
+
# Release 0.2.3 (2019-09-03)
- [`Pow` is now implemented for `BigUint` exponents][77].
diff --git a/third_party/rust/num-bigint/build.rs b/third_party/rust/num-bigint/build.rs
index 15590bbc12bb..e483c15fd7f6 100644
--- a/third_party/rust/num-bigint/build.rs
+++ b/third_party/rust/num-bigint/build.rs
@@ -10,5 +10,5 @@ fn main() {
panic!("i128 support was not detected!");
}
- autocfg::rerun_path(file!());
+ autocfg::rerun_path("build.rs");
}
diff --git a/third_party/rust/num-bigint/src/algorithms.rs b/third_party/rust/num-bigint/src/algorithms.rs
index 26f29b81546f..223f051a6aab 100644
--- a/third_party/rust/num-bigint/src/algorithms.rs
+++ b/third_party/rust/num-bigint/src/algorithms.rs
@@ -470,17 +470,17 @@ fn mac3(acc: &mut [BigDigit], b: &[BigDigit], c: &[BigDigit]) {
let mut comp1: BigInt = (r1 - &r2) / 2;
let mut comp2: BigInt = r2 - &r0;
comp3 = (&comp2 - comp3) / 2 + &r4 * 2;
- comp2 = comp2 + &comp1 - &r4;
- comp1 = comp1 - &comp3;
+ comp2 += &comp1 - &r4;
+ comp1 -= &comp3;
// Recomposition. The coefficients of the polynomial are now known.
//
// Evaluate at w(t) where t is our given base to get the result.
let result = r0
- + (comp1 << 32 * i)
- + (comp2 << 2 * 32 * i)
- + (comp3 << 3 * 32 * i)
- + (r4 << 4 * 32 * i);
+ + (comp1 << (32 * i))
+ + (comp2 << (2 * 32 * i))
+ + (comp3 << (3 * 32 * i))
+ + (r4 << (4 * 32 * i));
let result_pos = result.to_biguint().unwrap();
add2(&mut acc[..], &result_pos.data);
}
@@ -656,8 +656,8 @@ fn div_rem_core(mut a: BigUint, b: &BigUint) -> (BigUint, BigUint) {
while cmp_slice(&prod.data[..], &a.data[j..]) == Greater {
let one: BigUint = One::one();
- q0 = q0 - one;
- prod = prod - b;
+ q0 -= one;
+ prod -= b;
}
add2(&mut q.data[j..], &q0.data[..]);
@@ -667,7 +667,7 @@ fn div_rem_core(mut a: BigUint, b: &BigUint) -> (BigUint, BigUint) {
tmp = q0;
}
- debug_assert!(&a < b);
+ debug_assert!(a < *b);
(q.normalized(), a)
}
@@ -759,7 +759,7 @@ pub fn cmp_slice(a: &[BigDigit], b: &[BigDigit]) -> Ordering {
return Greater;
}
}
- return Equal;
+ Equal
}
#[cfg(test)]
diff --git a/third_party/rust/num-bigint/src/bigint.rs b/third_party/rust/num-bigint/src/bigint.rs
index 93c72be6af49..bd74e7d32396 100644
--- a/third_party/rust/num-bigint/src/bigint.rs
+++ b/third_party/rust/num-bigint/src/bigint.rs
@@ -2097,21 +2097,21 @@ impl<'a> Neg for &'a BigInt {
impl CheckedAdd for BigInt {
#[inline]
fn checked_add(&self, v: &BigInt) -> Option {
- return Some(self.add(v));
+ Some(self.add(v))
}
}
impl CheckedSub for BigInt {
#[inline]
fn checked_sub(&self, v: &BigInt) -> Option {
- return Some(self.sub(v));
+ Some(self.sub(v))
}
}
impl CheckedMul for BigInt {
#[inline]
fn checked_mul(&self, v: &BigInt) -> Option {
- return Some(self.mul(v));
+ Some(self.mul(v))
}
}
@@ -2121,7 +2121,7 @@ impl CheckedDiv for BigInt {
if v.is_zero() {
return None;
}
- return Some(self.div(v));
+ Some(self.div(v))
}
}
@@ -2195,7 +2195,7 @@ impl Integer for BigInt {
/// Deprecated, use `is_multiple_of` instead.
#[inline]
fn divides(&self, other: &BigInt) -> bool {
- return self.is_multiple_of(other);
+ self.is_multiple_of(other)
}
/// Returns `true` if the number is a multiple of `other`.
@@ -2572,7 +2572,7 @@ impl_to_bigint!(f64, FromPrimitive::from_f64);
impl BigInt {
/// Creates and initializes a BigInt.
///
- /// The digits are in little-endian base 232.
+ /// The base 232 digits are ordered least significant digit first.
#[inline]
pub fn new(sign: Sign, digits: Vec) -> BigInt {
BigInt::from_biguint(sign, BigUint::new(digits))
@@ -2580,7 +2580,7 @@ impl BigInt {
/// Creates and initializes a `BigInt`.
///
- /// The digits are in little-endian base 232.
+ /// The base 232 digits are ordered least significant digit first.
#[inline]
pub fn from_biguint(mut sign: Sign, mut data: BigUint) -> BigInt {
if sign == NoSign {
@@ -2596,12 +2596,16 @@ impl BigInt {
}
/// Creates and initializes a `BigInt`.
+ ///
+ /// The base 232 digits are ordered least significant digit first.
#[inline]
pub fn from_slice(sign: Sign, slice: &[u32]) -> BigInt {
BigInt::from_biguint(sign, BigUint::from_slice(slice))
}
/// Reinitializes a `BigInt`.
+ ///
+ /// The base 232 digits are ordered least significant digit first.
#[inline]
pub fn assign_from_slice(&mut self, sign: Sign, slice: &[u32]) {
if sign == NoSign {
@@ -2778,7 +2782,26 @@ impl BigInt {
(self.sign, self.data.to_bytes_le())
}
- /// Returns the two's complement byte representation of the `BigInt` in big-endian byte order.
+ /// Returns the sign and the `u32` digits representation of the `BigInt` ordered least
+ /// significant digit first.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_bigint::{BigInt, Sign};
+ ///
+ /// assert_eq!(BigInt::from(-1125).to_u32_digits(), (Sign::Minus, vec![1125]));
+ /// assert_eq!(BigInt::from(4294967295u32).to_u32_digits(), (Sign::Plus, vec![4294967295]));
+ /// assert_eq!(BigInt::from(4294967296u64).to_u32_digits(), (Sign::Plus, vec![0, 1]));
+ /// assert_eq!(BigInt::from(-112500000000i64).to_u32_digits(), (Sign::Minus, vec![830850304, 26]));
+ /// assert_eq!(BigInt::from(112500000000i64).to_u32_digits(), (Sign::Plus, vec![830850304, 26]));
+ /// ```
+ #[inline]
+ pub fn to_u32_digits(&self) -> (Sign, Vec) {
+ (self.sign, self.data.to_u32_digits())
+ }
+
+ /// Returns the two's-complement byte representation of the `BigInt` in big-endian byte order.
///
/// # Examples
///
@@ -2791,7 +2814,7 @@ impl BigInt {
#[inline]
pub fn to_signed_bytes_be(&self) -> Vec {
let mut bytes = self.data.to_bytes_be();
- let first_byte = bytes.first().map(|v| *v).unwrap_or(0);
+ let first_byte = bytes.first().cloned().unwrap_or(0);
if first_byte > 0x7f
&& !(first_byte == 0x80
&& bytes.iter().skip(1).all(Zero::is_zero)
@@ -2806,7 +2829,7 @@ impl BigInt {
bytes
}
- /// Returns the two's complement byte representation of the `BigInt` in little-endian byte order.
+ /// Returns the two's-complement byte representation of the `BigInt` in little-endian byte order.
///
/// # Examples
///
@@ -2819,7 +2842,7 @@ impl BigInt {
#[inline]
pub fn to_signed_bytes_le(&self) -> Vec {
let mut bytes = self.data.to_bytes_le();
- let last_byte = bytes.last().map(|v| *v).unwrap_or(0);
+ let last_byte = bytes.last().cloned().unwrap_or(0);
if last_byte > 0x7f
&& !(last_byte == 0x80
&& bytes.iter().rev().skip(1).all(Zero::is_zero)
@@ -2930,17 +2953,17 @@ impl BigInt {
#[inline]
pub fn checked_add(&self, v: &BigInt) -> Option {
- return Some(self.add(v));
+ Some(self.add(v))
}
#[inline]
pub fn checked_sub(&self, v: &BigInt) -> Option {
- return Some(self.sub(v));
+ Some(self.sub(v))
}
#[inline]
pub fn checked_mul(&self, v: &BigInt) -> Option {
- return Some(self.mul(v));
+ Some(self.mul(v))
}
#[inline]
@@ -2948,7 +2971,7 @@ impl BigInt {
if v.is_zero() {
return None;
}
- return Some(self.div(v));
+ Some(self.div(v))
}
/// Returns `(self ^ exponent) mod modulus`
@@ -2972,7 +2995,10 @@ impl BigInt {
}
// The sign of the result follows the modulus, like `mod_floor`.
- let (sign, mag) = match (self.is_negative(), modulus.is_negative()) {
+ let (sign, mag) = match (
+ self.is_negative() && exponent.is_odd(),
+ modulus.is_negative(),
+ ) {
(false, false) => (Plus, result),
(true, false) => (Plus, &modulus.data - result),
(false, true) => (Minus, &modulus.data - result),
diff --git a/third_party/rust/num-bigint/src/bigrand.rs b/third_party/rust/num-bigint/src/bigrand.rs
index 4a13b29df48b..69564dd13a94 100644
--- a/third_party/rust/num-bigint/src/bigrand.rs
+++ b/third_party/rust/num-bigint/src/bigrand.rs
@@ -14,6 +14,9 @@ use bigint::{into_magnitude, magnitude};
use integer::Integer;
use traits::Zero;
+/// A trait for sampling random big integers.
+///
+/// The `rand` feature must be enabled to use this. See crate-level documentation for details.
pub trait RandBigInt {
/// Generate a random `BigUint` of the given bit size.
fn gen_biguint(&mut self, bit_size: usize) -> BigUint;
@@ -191,6 +194,8 @@ impl SampleUniform for BigInt {
}
/// A random distribution for `BigUint` and `BigInt` values of a particular bit size.
+///
+/// The `rand` feature must be enabled to use this. See crate-level documentation for details.
#[derive(Clone, Copy, Debug)]
pub struct RandomBits {
bits: usize,
diff --git a/third_party/rust/num-bigint/src/biguint.rs b/third_party/rust/num-bigint/src/biguint.rs
index e6e9fbcce5ab..68363424ffc4 100644
--- a/third_party/rust/num-bigint/src/biguint.rs
+++ b/third_party/rust/num-bigint/src/biguint.rs
@@ -61,7 +61,7 @@ impl Arbitrary for BigUint {
#[allow(bare_trait_objects)] // `dyn` needs Rust 1.27 to parse, even when cfg-disabled
fn shrink(&self) -> Box> {
// Use shrinker from Vec
- Box::new(self.data.shrink().map(|x| BigUint::new(x)))
+ Box::new(self.data.shrink().map(BigUint::new))
}
}
@@ -600,7 +600,7 @@ impl AddAssign for BigUint {
#[inline]
fn add_assign(&mut self, other: u32) {
if other != 0 {
- if self.data.len() == 0 {
+ if self.data.is_empty() {
self.data.push(0);
}
@@ -745,7 +745,7 @@ impl Sub for u32 {
#[inline]
fn sub(self, mut other: BigUint) -> BigUint {
- if other.data.len() == 0 {
+ if other.data.is_empty() {
other.data.push(self as BigDigit);
} else {
sub2rev(&[self as BigDigit], &mut other.data[..]);
@@ -1225,7 +1225,7 @@ impl<'a> Neg for &'a BigUint {
impl CheckedAdd for BigUint {
#[inline]
fn checked_add(&self, v: &BigUint) -> Option {
- return Some(self.add(v));
+ Some(self.add(v))
}
}
@@ -1243,7 +1243,7 @@ impl CheckedSub for BigUint {
impl CheckedMul for BigUint {
#[inline]
fn checked_mul(&self, v: &BigUint) -> Option {
- return Some(self.mul(v));
+ Some(self.mul(v))
}
}
@@ -1253,7 +1253,7 @@ impl CheckedDiv for BigUint {
if v.is_zero() {
return None;
}
- return Some(self.div(v));
+ Some(self.div(v))
}
}
@@ -1678,9 +1678,9 @@ impl FromPrimitive for BigUint {
let mut ret = BigUint::from(mantissa);
if exponent > 0 {
- ret = ret << exponent as usize;
+ ret <<= exponent as usize;
} else if exponent < 0 {
- ret = ret >> (-exponent) as usize;
+ ret >>= (-exponent) as usize;
}
Some(ret)
}
@@ -1915,7 +1915,7 @@ pub fn to_str_radix_reversed(u: &BigUint, radix: u32) -> Vec {
impl BigUint {
/// Creates and initializes a `BigUint`.
///
- /// The digits are in little-endian base 232.
+ /// The base 232 digits are ordered least significant digit first.
#[inline]
pub fn new(digits: Vec) -> BigUint {
BigUint { data: digits }.normalized()
@@ -1923,7 +1923,7 @@ impl BigUint {
/// Creates and initializes a `BigUint`.
///
- /// The digits are in little-endian base 232.
+ /// The base 232 digits are ordered least significant digit first.
#[inline]
pub fn from_slice(slice: &[u32]) -> BigUint {
BigUint::new(slice.to_vec())
@@ -1931,7 +1931,7 @@ impl BigUint {
/// Assign a value to a `BigUint`.
///
- /// The digits are in little-endian base 232.
+ /// The base 232 digits are ordered least significant digit first.
#[inline]
pub fn assign_from_slice(&mut self, slice: &[u32]) {
self.data.resize(slice.len(), 0);
@@ -2125,6 +2125,24 @@ impl BigUint {
}
}
+ /// Returns the `u32` digits representation of the `BigUint` ordered least significant digit
+ /// first.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_bigint::BigUint;
+ ///
+ /// assert_eq!(BigUint::from(1125u32).to_u32_digits(), vec![1125]);
+ /// assert_eq!(BigUint::from(4294967295u32).to_u32_digits(), vec![4294967295]);
+ /// assert_eq!(BigUint::from(4294967296u64).to_u32_digits(), vec![0, 1]);
+ /// assert_eq!(BigUint::from(112500000000u64).to_u32_digits(), vec![830850304, 26]);
+ /// ```
+ #[inline]
+ pub fn to_u32_digits(&self) -> Vec {
+ self.data.clone()
+ }
+
/// Returns the integer formatted as a string in the given radix.
/// `radix` must be in the range `2...36`.
///
@@ -2190,7 +2208,7 @@ impl BigUint {
return 0;
}
let zeros = self.data.last().unwrap().leading_zeros();
- return self.data.len() * big_digit::BITS - zeros as usize;
+ self.data.len() * big_digit::BITS - zeros as usize
}
/// Strips off trailing zero bigdigits - comparisons require the last element in the vector to
@@ -2251,7 +2269,7 @@ fn plain_modpow(base: &BigUint, exp_data: &[BigDigit], modulus: &BigUint) -> Big
Some(i) => i,
};
- let mut base = base.clone();
+ let mut base = base % modulus;
for _ in 0..i {
for _ in 0..big_digit::BITS {
base = &base * &base % modulus;
diff --git a/third_party/rust/num-bigint/src/lib.rs b/third_party/rust/num-bigint/src/lib.rs
index dece7bab0070..837870a6265d 100644
--- a/third_party/rust/num-bigint/src/lib.rs
+++ b/third_party/rust/num-bigint/src/lib.rs
@@ -71,6 +71,33 @@
//! # }
//! ```
//!
+//! See the "Features" section for instructions for enabling random number generation.
+//!
+//! ## 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.
+//!
+//! 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
+//! mandatory by enabling the `i128` crate feature.
+//!
+//! ### Random Generation
+//!
+//! `num-bigint` supports the generation of random big integers when the `rand`
+//! feature is enabled. To enable it include rand as
+//!
+//! ```toml
+//! rand = "0.5"
+//! num-bigint = { version = "0.2", features = ["rand"] }
+//! ```
+//!
+//! Note that you must use the version of `rand` that `num-bigint` is compatible
+//! with: `0.5`.
+//!
+//!
//! ## Compatibility
//!
//! The `num-bigint` crate is tested for rustc 1.15 and greater.
diff --git a/third_party/rust/num-bigint/src/macros.rs b/third_party/rust/num-bigint/src/macros.rs
index 0ba6e48c72fe..735cfcb9f36c 100644
--- a/third_party/rust/num-bigint/src/macros.rs
+++ b/third_party/rust/num-bigint/src/macros.rs
@@ -344,7 +344,7 @@ macro_rules! promote_signed_scalars {
macro_rules! promote_signed_scalars_assign {
(impl $imp:ident for $res:ty, $method:ident) => {
promote_scalars_assign!(impl $imp for $res, $method, i8, i16);
- promote_scalars_assign!(impl $imp for $res, $method, isize);
+ promote_scalars_assign!(impl $imp for $res, $method, isize);
}
}
diff --git a/third_party/rust/num-bigint/src/monty.rs b/third_party/rust/num-bigint/src/monty.rs
index 72a4ab53eb68..62f59b38fc54 100644
--- a/third_party/rust/num-bigint/src/monty.rs
+++ b/third_party/rust/num-bigint/src/monty.rs
@@ -84,7 +84,7 @@ fn monty_redc(a: BigUint, mr: &MontyReducer) -> BigUint {
let ret = BigUint::new(c[n_size..].to_vec());
// 5: if R >= β^n then return R-N else return R.
- if &ret < mr.n {
+ if ret < *mr.n {
ret
} else {
ret - mr.n
@@ -121,7 +121,7 @@ pub fn monty_modpow(a: &BigUint, exp: &BigUint, modulus: &BigUint) -> BigUint {
ans = monty_mult(ans, &apri, &mr);
}
apri = monty_sqr(apri, &mr);
- e = e >> 1;
+ e >>= 1;
}
// Map the result back to the residues domain
diff --git a/third_party/rust/num-bigint/tests/bigint_scalar.rs b/third_party/rust/num-bigint/tests/bigint_scalar.rs
index ae9a6d7aa22f..6a1601eaa947 100644
--- a/third_party/rust/num-bigint/tests/bigint_scalar.rs
+++ b/third_party/rust/num-bigint/tests/bigint_scalar.rs
@@ -18,6 +18,7 @@ fn test_scalar_add() {
fn check(x: &BigInt, y: &BigInt, z: &BigInt) {
let (x, y, z) = (x.clone(), y.clone(), z.clone());
assert_signed_scalar_op!(x + y == z);
+ assert_signed_scalar_assign_op!(x += y == z);
}
for elm in SUM_TRIPLES.iter() {
@@ -43,6 +44,7 @@ fn test_scalar_sub() {
fn check(x: &BigInt, y: &BigInt, z: &BigInt) {
let (x, y, z) = (x.clone(), y.clone(), z.clone());
assert_signed_scalar_op!(x - y == z);
+ assert_signed_scalar_assign_op!(x -= y == z);
}
for elm in SUM_TRIPLES.iter() {
@@ -68,6 +70,7 @@ fn test_scalar_mul() {
fn check(x: &BigInt, y: &BigInt, z: &BigInt) {
let (x, y, z) = (x.clone(), y.clone(), z.clone());
assert_signed_scalar_op!(x * y == z);
+ assert_signed_scalar_assign_op!(x *= y == z);
}
for elm in MUL_TRIPLES.iter() {
@@ -98,15 +101,18 @@ fn test_scalar_div_rem() {
assert!(q == *ans_q);
assert!(r == *ans_r);
+ let b = BigInt::from(b);
let (a, b, ans_q, ans_r) = (a.clone(), b.clone(), ans_q.clone(), ans_r.clone());
- assert_op!(a / b == ans_q);
- assert_op!(a % b == ans_r);
+ assert_signed_scalar_op!(a / b == ans_q);
+ assert_signed_scalar_op!(a % b == ans_r);
+ assert_signed_scalar_assign_op!(a /= b == ans_q);
+ assert_signed_scalar_assign_op!(a %= b == ans_r);
- if b <= i32::max_value() as u32 {
- let nb = -(b as i32);
- assert_op!(a / nb == -ans_q.clone());
- assert_op!(a % nb == ans_r);
- }
+ let nb = -b;
+ assert_signed_scalar_op!(a / nb == -ans_q.clone());
+ assert_signed_scalar_op!(a % nb == ans_r);
+ assert_signed_scalar_assign_op!(a /= nb == -ans_q.clone());
+ assert_signed_scalar_assign_op!(a %= nb == ans_r);
}
fn check(a: &BigInt, b: u32, q: &BigInt, r: &BigInt) {
diff --git a/third_party/rust/num-bigint/tests/biguint_scalar.rs b/third_party/rust/num-bigint/tests/biguint_scalar.rs
index fb8fbf0357af..452277357d5f 100644
--- a/third_party/rust/num-bigint/tests/biguint_scalar.rs
+++ b/third_party/rust/num-bigint/tests/biguint_scalar.rs
@@ -15,6 +15,7 @@ fn test_scalar_add() {
fn check(x: &BigUint, y: &BigUint, z: &BigUint) {
let (x, y, z) = (x.clone(), y.clone(), z.clone());
assert_unsigned_scalar_op!(x + y == z);
+ assert_unsigned_scalar_assign_op!(x += y == z);
}
for elm in SUM_TRIPLES.iter() {
@@ -33,6 +34,7 @@ fn test_scalar_sub() {
fn check(x: &BigUint, y: &BigUint, z: &BigUint) {
let (x, y, z) = (x.clone(), y.clone(), z.clone());
assert_unsigned_scalar_op!(x - y == z);
+ assert_unsigned_scalar_assign_op!(x -= y == z);
}
for elm in SUM_TRIPLES.iter() {
@@ -51,6 +53,7 @@ fn test_scalar_mul() {
fn check(x: &BigUint, y: &BigUint, z: &BigUint) {
let (x, y, z) = (x.clone(), y.clone(), z.clone());
assert_unsigned_scalar_op!(x * y == z);
+ assert_unsigned_scalar_assign_op!(x *= y == z);
}
for elm in MUL_TRIPLES.iter() {
@@ -76,6 +79,8 @@ fn test_scalar_div_rem() {
let (x, y, z, r) = (x.clone(), y.clone(), z.clone(), r.clone());
assert_unsigned_scalar_op!(x / y == z);
assert_unsigned_scalar_op!(x % y == r);
+ assert_unsigned_scalar_assign_op!(x /= y == z);
+ assert_unsigned_scalar_assign_op!(x %= y == r);
}
for elm in MUL_TRIPLES.iter() {
@@ -104,6 +109,8 @@ fn test_scalar_div_rem() {
check(&a, &b, &c, &d);
assert_unsigned_scalar_op!(a / b == c);
assert_unsigned_scalar_op!(a % b == d);
+ assert_unsigned_scalar_assign_op!(a /= b == c);
+ assert_unsigned_scalar_assign_op!(a %= b == d);
}
}
}
diff --git a/third_party/rust/num-bigint/tests/macros/mod.rs b/third_party/rust/num-bigint/tests/macros/mod.rs
index d848b29b35ee..946534a374a8 100644
--- a/third_party/rust/num-bigint/tests/macros/mod.rs
+++ b/third_party/rust/num-bigint/tests/macros/mod.rs
@@ -68,3 +68,49 @@ macro_rules! assert_signed_scalar_op {
$left $op $right == $expected);
};
}
+
+/// Assert that an op works for scalar right
+macro_rules! assert_scalar_assign_op {
+ (($($to:ident),*) $left:ident $op:tt $right:ident == $expected:expr) => {
+ $(
+ if let Some(right) = $right.$to() {
+ let mut left = $left.clone();
+ assert_eq!({ left $op right; left}, $expected);
+ }
+ )*
+ };
+}
+
+#[cfg(not(has_i128))]
+macro_rules! assert_unsigned_scalar_assign_op {
+ ($left:ident $op:tt $right:ident == $expected:expr) => {
+ assert_scalar_assign_op!((to_u8, to_u16, to_u32, to_u64, to_usize)
+ $left $op $right == $expected);
+ };
+}
+
+#[cfg(has_i128)]
+macro_rules! assert_unsigned_scalar_assign_op {
+ ($left:ident $op:tt $right:ident == $expected:expr) => {
+ assert_scalar_assign_op!((to_u8, to_u16, to_u32, to_u64, to_usize, to_u128)
+ $left $op $right == $expected);
+ };
+}
+
+#[cfg(not(has_i128))]
+macro_rules! assert_signed_scalar_assign_op {
+ ($left:ident $op:tt $right:ident == $expected:expr) => {
+ assert_scalar_assign_op!((to_u8, to_u16, to_u32, to_u64, to_usize,
+ to_i8, to_i16, to_i32, to_i64, to_isize)
+ $left $op $right == $expected);
+ };
+}
+
+#[cfg(has_i128)]
+macro_rules! assert_signed_scalar_assign_op {
+ ($left:ident $op:tt $right:ident == $expected:expr) => {
+ assert_scalar_assign_op!((to_u8, to_u16, to_u32, to_u64, to_usize, to_u128,
+ to_i8, to_i16, to_i32, to_i64, to_isize, to_i128)
+ $left $op $right == $expected);
+ };
+}
diff --git a/third_party/rust/num-bigint/tests/modpow.rs b/third_party/rust/num-bigint/tests/modpow.rs
index b7a992c863ad..a5f8b9289016 100644
--- a/third_party/rust/num-bigint/tests/modpow.rs
+++ b/third_party/rust/num-bigint/tests/modpow.rs
@@ -81,6 +81,19 @@ mod biguint {
check_modpow::(0, 15, 11, 0);
check_modpow::(3, 7, 11, 9);
check_modpow::(5, 117, 19, 1);
+ check_modpow::(20, 1, 2, 0);
+ check_modpow::(20, 1, 3, 2);
+ }
+
+ #[test]
+ fn test_modpow_small() {
+ for b in 0u64..11 {
+ for e in 0u64..11 {
+ for m in 1..11 {
+ check_modpow::(b, e, m, b.pow(e as u32) % m);
+ }
+ }
+ }
}
#[test]
@@ -102,7 +115,7 @@ mod biguint {
mod bigint {
use num_bigint::BigInt;
use num_integer::Integer;
- use num_traits::{Num, One, Signed, Zero};
+ use num_traits::{Num, One, Signed};
fn check_modpow>(b: T, e: T, m: T, r: T) {
fn check(b: &BigInt, e: &BigInt, m: &BigInt, r: &BigInt) {
@@ -122,12 +135,18 @@ mod bigint {
let m: BigInt = m.into();
let r: BigInt = r.into();
- let neg_r = if r.is_zero() { BigInt::zero() } else { &m - &r };
+ let neg_b_r = if e.is_odd() {
+ (-&r).mod_floor(&m)
+ } else {
+ r.clone()
+ };
+ let neg_m_r = r.mod_floor(&-&m);
+ let neg_bm_r = neg_b_r.mod_floor(&-&m);
check(&b, &e, &m, &r);
- check(&-&b, &e, &m, &neg_r);
- check(&b, &e, &-&m, &-neg_r);
- check(&-b, &e, &-m, &-r);
+ check(&-&b, &e, &m, &neg_b_r);
+ check(&b, &e, &-&m, &neg_m_r);
+ check(&-b, &e, &-&m, &neg_bm_r);
}
#[test]
@@ -136,6 +155,22 @@ mod bigint {
check_modpow(0, 15, 11, 0);
check_modpow(3, 7, 11, 9);
check_modpow(5, 117, 19, 1);
+ check_modpow(-20, 1, 2, 0);
+ check_modpow(-20, 1, 3, 1);
+ }
+
+ #[test]
+ fn test_modpow_small() {
+ for b in -10i64..11 {
+ for e in 0i64..11 {
+ for m in -10..11 {
+ if m == 0 {
+ continue;
+ }
+ check_modpow(b, e, m, b.pow(e as u32).mod_floor(&m));
+ }
+ }
+ }
}
#[test]
diff --git a/third_party/rust/num-bigint/tests/quickcheck.rs b/third_party/rust/num-bigint/tests/quickcheck.rs
index 6bb251fa9031..a9e7b04b5256 100644
--- a/third_party/rust/num-bigint/tests/quickcheck.rs
+++ b/third_party/rust/num-bigint/tests/quickcheck.rs
@@ -10,7 +10,8 @@ extern crate quickcheck;
extern crate quickcheck_macros;
use num_bigint::{BigInt, BigUint};
-use num_traits::{Num, One, Pow, Zero};
+use num_integer::Integer;
+use num_traits::{Num, One, Pow, Signed, Zero};
use quickcheck::{QuickCheck, StdThreadGen, TestResult};
#[quickcheck]
@@ -315,3 +316,46 @@ fn quicktest_shift() {
qc.quickcheck(test_shl_unsigned as fn(u32, u8) -> TestResult);
qc.quickcheck(test_shl_signed as fn(i32, u8) -> TestResult);
}
+
+#[test]
+fn quickcheck_modpow() {
+ let gen = StdThreadGen::new(usize::max_value());
+ let mut qc = QuickCheck::with_gen(gen);
+
+ fn simple_modpow(base: &BigInt, exponent: &BigInt, modulus: &BigInt) -> BigInt {
+ assert!(!exponent.is_negative());
+ let mut result = BigInt::one().mod_floor(modulus);
+ let mut base = base.mod_floor(modulus);
+ let mut exponent = exponent.clone();
+ while !exponent.is_zero() {
+ if exponent.is_odd() {
+ result = (result * &base).mod_floor(modulus);
+ }
+ base = (&base * &base).mod_floor(modulus);
+ exponent >>= 1;
+ }
+ result
+ }
+
+ fn test_modpow(base: i128, exponent: u128, modulus: i128) -> TestResult {
+ if modulus.is_zero() {
+ TestResult::discard()
+ } else {
+ let base = BigInt::from(base);
+ let exponent = BigInt::from(exponent);
+ let modulus = BigInt::from(modulus);
+ let modpow = base.modpow(&exponent, &modulus);
+ let simple = simple_modpow(&base, &exponent, &modulus);
+ if modpow != simple {
+ eprintln!("{}.modpow({}, {})", base, exponent, modulus);
+ eprintln!(" expected {}", simple);
+ eprintln!(" actual {}", modpow);
+ TestResult::failed()
+ } else {
+ TestResult::passed()
+ }
+ }
+ }
+
+ qc.quickcheck(test_modpow as fn(i128, u128, i128) -> TestResult);
+}
diff --git a/third_party/rust/num-integer/.cargo-checksum.json b/third_party/rust/num-integer/.cargo-checksum.json
index 1b932b50ba54..7732a7dba78e 100644
--- a/third_party/rust/num-integer/.cargo-checksum.json
+++ b/third_party/rust/num-integer/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"54f4df5d505f0f8581a9455d2ea52bc385f003f97116c3d13b0e8e0cc491903f","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"7ad5fb625f7ef61595a2180f3b26715457552faa8bb08526c70b416da29b2533","RELEASES.md":"ea8b30468b1d1c16ebe9e148a62df378cb9d3198bb4095c889fe521245690f9d","benches/gcd.rs":"9b5c0ae8ccd6c7fc8f8384fb351d10cfdd0be5fbea9365f9ea925d8915b015bf","benches/roots.rs":"79b4ab2d8fe7bbf43fe65314d2e1bc206165bc4cb34b3ceaa899f9ea7af31c09","build.rs":"56d4fbb7a55750e61d2074df2735a31995c1decbd988c0e722926235e0fed487","src/lib.rs":"937d6a77d6542b47aafb872df7181dcafc1ab596df0e5d78b2e6577ae9463dd0","src/roots.rs":"2a9b908bd3666b5cffc58c1b37d329e46ed02f71ad6d5deea1e8440c10660e1a","tests/roots.rs":"a0caa4142899ec8cb806a7a0d3410c39d50de97cceadc4c2ceca707be91b1ddd"},"package":"b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"}
\ No newline at end of file
+{"files":{"Cargo.toml":"bf0e4a51897e9586cffa4897f69bf7caee769cc9b0292f3dd7ebd4fd5ddcb8f3","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"68f533703554b9130ea902776bd9eb20d1a2d32b213ebadebcd49ed0f1ef9728","RELEASES.md":"658b382f2358d6f6733021ecfdcc1fc1faf89d7106e0f72d0f3b34d35442d71b","benches/average.rs":"2a30b4ccd8ece8663d17583ae2e3623e654b5f401babef90f1634722824e6c2b","benches/gcd.rs":"9b5c0ae8ccd6c7fc8f8384fb351d10cfdd0be5fbea9365f9ea925d8915b015bf","benches/roots.rs":"79b4ab2d8fe7bbf43fe65314d2e1bc206165bc4cb34b3ceaa899f9ea7af31c09","build.rs":"575b157527243fe355a7c8d7d874a1f790c3fb0177beba9032076a7803c5b9dd","src/average.rs":"a66cf6a49f893e60697c17b2540258e69daa15ab97d8d444c6f2e8cac2f01ae9","src/lib.rs":"bf0ce9a09f92f606ca038288cde7a29670ccca480d42ec97e88f3c56b117e33c","src/roots.rs":"2a9b908bd3666b5cffc58c1b37d329e46ed02f71ad6d5deea1e8440c10660e1a","tests/average.rs":"5f26a31be042626e9af66f7b751798621561fa090da48b1ec5ab63e388288a91","tests/roots.rs":"a0caa4142899ec8cb806a7a0d3410c39d50de97cceadc4c2ceca707be91b1ddd"},"package":"d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"}
\ No newline at end of file
diff --git a/third_party/rust/num-integer/Cargo.toml b/third_party/rust/num-integer/Cargo.toml
index 3937fa1477ac..8f72e395981c 100644
--- a/third_party/rust/num-integer/Cargo.toml
+++ b/third_party/rust/num-integer/Cargo.toml
@@ -12,25 +12,25 @@
[package]
name = "num-integer"
-version = "0.1.41"
+version = "0.1.44"
authors = ["The Rust Project Developers"]
build = "build.rs"
-exclude = ["/ci/*", "/.travis.yml", "/bors.toml"]
+exclude = ["/bors.toml", "/ci/*", "/.github/*"]
description = "Integer traits and functions"
homepage = "https://github.com/rust-num/num-integer"
documentation = "https://docs.rs/num-integer"
readme = "README.md"
keywords = ["mathematics", "numerics"]
categories = ["algorithms", "science", "no-std"]
-license = "MIT/Apache-2.0"
+license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-num/num-integer"
[package.metadata.docs.rs]
features = ["std"]
[dependencies.num-traits]
-version = "0.2.4"
+version = "0.2.11"
default-features = false
[build-dependencies.autocfg]
-version = "0.1.3"
+version = "1"
[features]
default = ["std"]
diff --git a/third_party/rust/num-integer/README.md b/third_party/rust/num-integer/README.md
index 4b3d42e7218d..5f638cd0f42b 100644
--- a/third_party/rust/num-integer/README.md
+++ b/third_party/rust/num-integer/README.md
@@ -2,8 +2,8 @@
[![crate](https://img.shields.io/crates/v/num-integer.svg)](https://crates.io/crates/num-integer)
[![documentation](https://docs.rs/num-integer/badge.svg)](https://docs.rs/num-integer)
-![minimum rustc 1.8](https://img.shields.io/badge/rustc-1.8+-red.svg)
-[![Travis status](https://travis-ci.org/rust-num/num-integer.svg?branch=master)](https://travis-ci.org/rust-num/num-integer)
+[![minimum rustc 1.8](https://img.shields.io/badge/rustc-1.8+-red.svg)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html)
+[![build status](https://github.com/rust-num/num-integer/workflows/master/badge.svg)](https://github.com/rust-num/num-integer/actions)
`Integer` trait and functions for Rust.
@@ -40,7 +40,6 @@ 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
mandatory by enabling the `i128` crate feature.
-
## Releases
Release notes are available in [RELEASES.md](RELEASES.md).
@@ -48,3 +47,18 @@ Release notes are available in [RELEASES.md](RELEASES.md).
## Compatibility
The `num-integer` crate is tested for rustc 1.8 and greater.
+
+## License
+
+Licensed under either of
+
+ * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+ * [MIT license](http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
diff --git a/third_party/rust/num-integer/RELEASES.md b/third_party/rust/num-integer/RELEASES.md
index ebc19f76cd51..05be073c35bd 100644
--- a/third_party/rust/num-integer/RELEASES.md
+++ b/third_party/rust/num-integer/RELEASES.md
@@ -1,3 +1,30 @@
+# Release 0.1.44 (2020-10-29)
+
+- [The "i128" feature now bypasses compiler probing][35]. The build script
+ used to probe anyway and panic if requested support wasn't found, but
+ sometimes this ran into bad corner cases with `autocfg`.
+
+**Contributors**: @cuviper
+
+[35]: https://github.com/rust-num/num-integer/pull/35
+
+# Release 0.1.43 (2020-06-11)
+
+- [The new `Average` trait][31] computes fast integer averages, rounded up or
+ down, without any risk of overflow.
+
+**Contributors**: @althonos, @cuviper
+
+[31]: https://github.com/rust-num/num-integer/pull/31
+
+# Release 0.1.42 (2020-01-09)
+
+- [Updated the `autocfg` build dependency to 1.0][29].
+
+**Contributors**: @cuviper, @dingelish
+
+[29]: https://github.com/rust-num/num-integer/pull/29
+
# Release 0.1.41 (2019-05-21)
- [Fixed feature detection on `no_std` targets][25].
diff --git a/third_party/rust/num-integer/benches/average.rs b/third_party/rust/num-integer/benches/average.rs
new file mode 100644
index 000000000000..05d824c840ec
--- /dev/null
+++ b/third_party/rust/num-integer/benches/average.rs
@@ -0,0 +1,414 @@
+//! Benchmark sqrt and cbrt
+
+#![feature(test)]
+
+extern crate num_integer;
+extern crate num_traits;
+extern crate test;
+
+use num_integer::Integer;
+use num_traits::{AsPrimitive, PrimInt, WrappingAdd, WrappingMul};
+use std::cmp::{max, min};
+use std::fmt::Debug;
+use test::{black_box, Bencher};
+
+// --- Utilities for RNG ----------------------------------------------------
+
+trait BenchInteger: Integer + PrimInt + WrappingAdd + WrappingMul + 'static {}
+
+impl BenchInteger for T where T: Integer + PrimInt + WrappingAdd + WrappingMul + 'static {}
+
+// Simple PRNG so we don't have to worry about rand compatibility
+fn lcg(x: T) -> T
+where
+ u32: AsPrimitive,
+ T: BenchInteger,
+{
+ // LCG parameters from Numerical Recipes
+ // (but we're applying it to arbitrary sizes)
+ const LCG_A: u32 = 1664525;
+ const LCG_C: u32 = 1013904223;
+ x.wrapping_mul(&LCG_A.as_()).wrapping_add(&LCG_C.as_())
+}
+
+// --- Alt. Implementations -------------------------------------------------
+
+trait NaiveAverage {
+ fn naive_average_ceil(&self, other: &Self) -> Self;
+ fn naive_average_floor(&self, other: &Self) -> Self;
+}
+
+trait UncheckedAverage {
+ fn unchecked_average_ceil(&self, other: &Self) -> Self;
+ fn unchecked_average_floor(&self, other: &Self) -> Self;
+}
+
+trait ModuloAverage {
+ fn modulo_average_ceil(&self, other: &Self) -> Self;
+ fn modulo_average_floor(&self, other: &Self) -> Self;
+}
+
+macro_rules! naive_average {
+ ($T:ident) => {
+ impl super::NaiveAverage for $T {
+ fn naive_average_floor(&self, other: &$T) -> $T {
+ match self.checked_add(*other) {
+ Some(z) => z.div_floor(&2),
+ None => {
+ if self > other {
+ let diff = self - other;
+ other + diff.div_floor(&2)
+ } else {
+ let diff = other - self;
+ self + diff.div_floor(&2)
+ }
+ }
+ }
+ }
+ fn naive_average_ceil(&self, other: &$T) -> $T {
+ match self.checked_add(*other) {
+ Some(z) => z.div_ceil(&2),
+ None => {
+ if self > other {
+ let diff = self - other;
+ self - diff.div_floor(&2)
+ } else {
+ let diff = other - self;
+ other - diff.div_floor(&2)
+ }
+ }
+ }
+ }
+ }
+ };
+}
+
+macro_rules! unchecked_average {
+ ($T:ident) => {
+ impl super::UncheckedAverage for $T {
+ fn unchecked_average_floor(&self, other: &$T) -> $T {
+ self.wrapping_add(*other) / 2
+ }
+ fn unchecked_average_ceil(&self, other: &$T) -> $T {
+ (self.wrapping_add(*other) / 2).wrapping_add(1)
+ }
+ }
+ };
+}
+
+macro_rules! modulo_average {
+ ($T:ident) => {
+ impl super::ModuloAverage for $T {
+ fn modulo_average_ceil(&self, other: &$T) -> $T {
+ let (q1, r1) = self.div_mod_floor(&2);
+ let (q2, r2) = other.div_mod_floor(&2);
+ q1 + q2 + (r1 | r2)
+ }
+ fn modulo_average_floor(&self, other: &$T) -> $T {
+ let (q1, r1) = self.div_mod_floor(&2);
+ let (q2, r2) = other.div_mod_floor(&2);
+ q1 + q2 + (r1 * r2)
+ }
+ }
+ };
+}
+
+// --- Bench functions ------------------------------------------------------
+
+fn bench_unchecked(b: &mut Bencher, v: &[(T, T)], f: F)
+where
+ T: Integer + Debug + Copy,
+ F: Fn(&T, &T) -> T,
+{
+ b.iter(|| {
+ for (x, y) in v {
+ black_box(f(x, y));
+ }
+ });
+}
+
+fn bench_ceil(b: &mut Bencher, v: &[(T, T)], f: F)
+where
+ T: Integer + Debug + Copy,
+ F: Fn(&T, &T) -> T,
+{
+ for &(i, j) in v {
+ let rt = f(&i, &j);
+ let (a, b) = (min(i, j), max(i, j));
+ // if both number are the same sign, check rt is in the middle
+ if (a < T::zero()) == (b < T::zero()) {
+ if (b - a).is_even() {
+ assert_eq!(rt - a, b - rt);
+ } else {
+ assert_eq!(rt - a, b - rt + T::one());
+ }
+ // if both number have a different sign,
+ } else {
+ if (a + b).is_even() {
+ assert_eq!(rt, (a + b) / (T::one() + T::one()))
+ } else {
+ assert_eq!(rt, (a + b + T::one()) / (T::one() + T::one()))
+ }
+ }
+ }
+ bench_unchecked(b, v, f);
+}
+
+fn bench_floor(b: &mut Bencher, v: &[(T, T)], f: F)
+where
+ T: Integer + Debug + Copy,
+ F: Fn(&T, &T) -> T,
+{
+ for &(i, j) in v {
+ let rt = f(&i, &j);
+ let (a, b) = (min(i, j), max(i, j));
+ // if both number are the same sign, check rt is in the middle
+ if (a < T::zero()) == (b < T::zero()) {
+ if (b - a).is_even() {
+ assert_eq!(rt - a, b - rt);
+ } else {
+ assert_eq!(rt - a + T::one(), b - rt);
+ }
+ // if both number have a different sign,
+ } else {
+ if (a + b).is_even() {
+ assert_eq!(rt, (a + b) / (T::one() + T::one()))
+ } else {
+ assert_eq!(rt, (a + b - T::one()) / (T::one() + T::one()))
+ }
+ }
+ }
+ bench_unchecked(b, v, f);
+}
+
+// --- Bench implementation -------------------------------------------------
+
+macro_rules! bench_average {
+ ($($T:ident),*) => {$(
+ mod $T {
+ use test::Bencher;
+ use num_integer::{Average, Integer};
+ use super::{UncheckedAverage, NaiveAverage, ModuloAverage};
+ use super::{bench_ceil, bench_floor, bench_unchecked};
+
+ naive_average!($T);
+ unchecked_average!($T);
+ modulo_average!($T);
+
+ const SIZE: $T = 30;
+
+ fn overflowing() -> Vec<($T, $T)> {
+ (($T::max_value()-SIZE)..$T::max_value())
+ .flat_map(|x| -> Vec<_> {
+ (($T::max_value()-100)..($T::max_value()-100+SIZE))
+ .map(|y| (x, y))
+ .collect()
+ })
+ .collect()
+ }
+
+ fn small() -> Vec<($T, $T)> {
+ (0..SIZE)
+ .flat_map(|x| -> Vec<_> {(0..SIZE).map(|y| (x, y)).collect()})
+ .collect()
+ }
+
+ fn rand() -> Vec<($T, $T)> {
+ small()
+ .into_iter()
+ .map(|(x, y)| (super::lcg(x), super::lcg(y)))
+ .collect()
+ }
+
+ mod ceil {
+
+ use super::*;
+
+ mod small {
+
+ use super::*;
+
+ #[bench]
+ fn optimized(b: &mut Bencher) {
+ let v = small();
+ bench_ceil(b, &v, |x: &$T, y: &$T| x.average_ceil(y));
+ }
+
+ #[bench]
+ fn naive(b: &mut Bencher) {
+ let v = small();
+ bench_ceil(b, &v, |x: &$T, y: &$T| x.naive_average_ceil(y));
+ }
+
+ #[bench]
+ fn unchecked(b: &mut Bencher) {
+ let v = small();
+ bench_unchecked(b, &v, |x: &$T, y: &$T| x.unchecked_average_ceil(y));
+ }
+
+ #[bench]
+ fn modulo(b: &mut Bencher) {
+ let v = small();
+ bench_ceil(b, &v, |x: &$T, y: &$T| x.modulo_average_ceil(y));
+ }
+ }
+
+ mod overflowing {
+
+ use super::*;
+
+ #[bench]
+ fn optimized(b: &mut Bencher) {
+ let v = overflowing();
+ bench_ceil(b, &v, |x: &$T, y: &$T| x.average_ceil(y));
+ }
+
+ #[bench]
+ fn naive(b: &mut Bencher) {
+ let v = overflowing();
+ bench_ceil(b, &v, |x: &$T, y: &$T| x.naive_average_ceil(y));
+ }
+
+ #[bench]
+ fn unchecked(b: &mut Bencher) {
+ let v = overflowing();
+ bench_unchecked(b, &v, |x: &$T, y: &$T| x.unchecked_average_ceil(y));
+ }
+
+ #[bench]
+ fn modulo(b: &mut Bencher) {
+ let v = overflowing();
+ bench_ceil(b, &v, |x: &$T, y: &$T| x.modulo_average_ceil(y));
+ }
+ }
+
+ mod rand {
+
+ use super::*;
+
+ #[bench]
+ fn optimized(b: &mut Bencher) {
+ let v = rand();
+ bench_ceil(b, &v, |x: &$T, y: &$T| x.average_ceil(y));
+ }
+
+ #[bench]
+ fn naive(b: &mut Bencher) {
+ let v = rand();
+ bench_ceil(b, &v, |x: &$T, y: &$T| x.naive_average_ceil(y));
+ }
+
+ #[bench]
+ fn unchecked(b: &mut Bencher) {
+ let v = rand();
+ bench_unchecked(b, &v, |x: &$T, y: &$T| x.unchecked_average_ceil(y));
+ }
+
+ #[bench]
+ fn modulo(b: &mut Bencher) {
+ let v = rand();
+ bench_ceil(b, &v, |x: &$T, y: &$T| x.modulo_average_ceil(y));
+ }
+ }
+
+ }
+
+ mod floor {
+
+ use super::*;
+
+ mod small {
+
+ use super::*;
+
+ #[bench]
+ fn optimized(b: &mut Bencher) {
+ let v = small();
+ bench_floor(b, &v, |x: &$T, y: &$T| x.average_floor(y));
+ }
+
+ #[bench]
+ fn naive(b: &mut Bencher) {
+ let v = small();
+ bench_floor(b, &v, |x: &$T, y: &$T| x.naive_average_floor(y));
+ }
+
+ #[bench]
+ fn unchecked(b: &mut Bencher) {
+ let v = small();
+ bench_unchecked(b, &v, |x: &$T, y: &$T| x.unchecked_average_floor(y));
+ }
+
+ #[bench]
+ fn modulo(b: &mut Bencher) {
+ let v = small();
+ bench_floor(b, &v, |x: &$T, y: &$T| x.modulo_average_floor(y));
+ }
+ }
+
+ mod overflowing {
+
+ use super::*;
+
+ #[bench]
+ fn optimized(b: &mut Bencher) {
+ let v = overflowing();
+ bench_floor(b, &v, |x: &$T, y: &$T| x.average_floor(y));
+ }
+
+ #[bench]
+ fn naive(b: &mut Bencher) {
+ let v = overflowing();
+ bench_floor(b, &v, |x: &$T, y: &$T| x.naive_average_floor(y));
+ }
+
+ #[bench]
+ fn unchecked(b: &mut Bencher) {
+ let v = overflowing();
+ bench_unchecked(b, &v, |x: &$T, y: &$T| x.unchecked_average_floor(y));
+ }
+
+ #[bench]
+ fn modulo(b: &mut Bencher) {
+ let v = overflowing();
+ bench_floor(b, &v, |x: &$T, y: &$T| x.modulo_average_floor(y));
+ }
+ }
+
+ mod rand {
+
+ use super::*;
+
+ #[bench]
+ fn optimized(b: &mut Bencher) {
+ let v = rand();
+ bench_floor(b, &v, |x: &$T, y: &$T| x.average_floor(y));
+ }
+
+ #[bench]
+ fn naive(b: &mut Bencher) {
+ let v = rand();
+ bench_floor(b, &v, |x: &$T, y: &$T| x.naive_average_floor(y));
+ }
+
+ #[bench]
+ fn unchecked(b: &mut Bencher) {
+ let v = rand();
+ bench_unchecked(b, &v, |x: &$T, y: &$T| x.unchecked_average_floor(y));
+ }
+
+ #[bench]
+ fn modulo(b: &mut Bencher) {
+ let v = rand();
+ bench_floor(b, &v, |x: &$T, y: &$T| x.modulo_average_floor(y));
+ }
+ }
+
+ }
+
+ }
+ )*}
+}
+
+bench_average!(i8, i16, i32, i64, i128, isize);
+bench_average!(u8, u16, u32, u64, u128, usize);
diff --git a/third_party/rust/num-integer/build.rs b/third_party/rust/num-integer/build.rs
index 15590bbc12bb..37c985766a38 100644
--- a/third_party/rust/num-integer/build.rs
+++ b/third_party/rust/num-integer/build.rs
@@ -3,12 +3,11 @@ extern crate autocfg;
use std::env;
fn main() {
- 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!");
+ // If the "i128" feature is explicity requested, don't bother probing for it.
+ // It will still cause a build error if that was set improperly.
+ if env::var_os("CARGO_FEATURE_I128").is_some() || autocfg::new().probe_type("i128") {
+ autocfg::emit("has_i128");
}
- autocfg::rerun_path(file!());
+ autocfg::rerun_path("build.rs");
}
diff --git a/third_party/rust/num-integer/src/average.rs b/third_party/rust/num-integer/src/average.rs
new file mode 100644
index 000000000000..29cd11e3fec6
--- /dev/null
+++ b/third_party/rust/num-integer/src/average.rs
@@ -0,0 +1,78 @@
+use core::ops::{BitAnd, BitOr, BitXor, Shr};
+use Integer;
+
+/// Provides methods to compute the average of two integers, without overflows.
+pub trait Average: Integer {
+ /// Returns the ceiling value of the average of `self` and `other`.
+ /// -- `⌈(self + other)/2⌉`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_integer::Average;
+ ///
+ /// assert_eq!(( 3).average_ceil(&10), 7);
+ /// assert_eq!((-2).average_ceil(&-5), -3);
+ /// assert_eq!(( 4).average_ceil(& 4), 4);
+ ///
+ /// assert_eq!(u8::max_value().average_ceil(&2), 129);
+ /// assert_eq!(i8::min_value().average_ceil(&-1), -64);
+ /// assert_eq!(i8::min_value().average_ceil(&i8::max_value()), 0);
+ /// ```
+ ///
+ fn average_ceil(&self, other: &Self) -> Self;
+
+ /// Returns the floor value of the average of `self` and `other`.
+ /// -- `⌊(self + other)/2⌋`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_integer::Average;
+ ///
+ /// assert_eq!(( 3).average_floor(&10), 6);
+ /// assert_eq!((-2).average_floor(&-5), -4);
+ /// assert_eq!(( 4).average_floor(& 4), 4);
+ ///
+ /// assert_eq!(u8::max_value().average_floor(&2), 128);
+ /// assert_eq!(i8::min_value().average_floor(&-1), -65);
+ /// assert_eq!(i8::min_value().average_floor(&i8::max_value()), -1);
+ /// ```
+ ///
+ fn average_floor(&self, other: &Self) -> Self;
+}
+
+impl Average for I
+where
+ I: Integer + Shr,
+ for<'a, 'b> &'a I:
+ BitAnd<&'b I, Output = I> + BitOr<&'b I, Output = I> + BitXor<&'b I, Output = I>,
+{
+ // The Henry Gordon Dietz implementation as shown in the Hacker's Delight,
+ // see http://aggregate.org/MAGIC/#Average%20of%20Integers
+
+ /// Returns the floor value of the average of `self` and `other`.
+ #[inline]
+ fn average_floor(&self, other: &I) -> I {
+ (self & other) + ((self ^ other) >> 1)
+ }
+
+ /// Returns the ceil value of the average of `self` and `other`.
+ #[inline]
+ fn average_ceil(&self, other: &I) -> I {
+ (self | other) - ((self ^ other) >> 1)
+ }
+}
+
+/// Returns the floor value of the average of `x` and `y` --
+/// see [Average::average_floor](trait.Average.html#tymethod.average_floor).
+#[inline]
+pub fn average_floor(x: T, y: T) -> T {
+ x.average_floor(&y)
+}
+/// Returns the ceiling value of the average of `x` and `y` --
+/// see [Average::average_ceil](trait.Average.html#tymethod.average_ceil).
+#[inline]
+pub fn average_ceil(x: T, y: T) -> T {
+ x.average_ceil(&y)
+}
diff --git a/third_party/rust/num-integer/src/lib.rs b/third_party/rust/num-integer/src/lib.rs
index aa12ba68c4bb..02819541b958 100644
--- a/third_party/rust/num-integer/src/lib.rs
+++ b/third_party/rust/num-integer/src/lib.rs
@@ -30,6 +30,10 @@ mod roots;
pub use roots::Roots;
pub use roots::{cbrt, nth_root, sqrt};
+mod average;
+pub use average::Average;
+pub use average::{average_ceil, average_floor};
+
pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
/// Floored integer division.
///
@@ -257,7 +261,6 @@ pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
/// assert_eq!((-1).div_rem( &2), ( 0, -1));
/// assert_eq!((-1).div_rem(&-2), ( 0, -1));
/// ~~~
- #[inline]
fn div_rem(&self, other: &Self) -> (Self, Self);
/// Simultaneous floored integer division and modulus.
diff --git a/third_party/rust/num-integer/tests/average.rs b/third_party/rust/num-integer/tests/average.rs
new file mode 100644
index 000000000000..9fd8cf18f4ea
--- /dev/null
+++ b/third_party/rust/num-integer/tests/average.rs
@@ -0,0 +1,100 @@
+extern crate num_integer;
+extern crate num_traits;
+
+macro_rules! test_average {
+ ($I:ident, $U:ident) => {
+ mod $I {
+ mod ceil {
+ use num_integer::Average;
+
+ #[test]
+ fn same_sign() {
+ assert_eq!((14 as $I).average_ceil(&16), 15 as $I);
+ assert_eq!((14 as $I).average_ceil(&17), 16 as $I);
+
+ let max = $crate::std::$I::MAX;
+ assert_eq!((max - 3).average_ceil(&(max - 1)), max - 2);
+ assert_eq!((max - 3).average_ceil(&(max - 2)), max - 2);
+ }
+
+ #[test]
+ fn different_sign() {
+ assert_eq!((14 as $I).average_ceil(&-4), 5 as $I);
+ assert_eq!((14 as $I).average_ceil(&-5), 5 as $I);
+
+ let min = $crate::std::$I::MIN;
+ let max = $crate::std::$I::MAX;
+ assert_eq!(min.average_ceil(&max), 0 as $I);
+ }
+ }
+
+ mod floor {
+ use num_integer::Average;
+
+ #[test]
+ fn same_sign() {
+ assert_eq!((14 as $I).average_floor(&16), 15 as $I);
+ assert_eq!((14 as $I).average_floor(&17), 15 as $I);
+
+ let max = $crate::std::$I::MAX;
+ assert_eq!((max - 3).average_floor(&(max - 1)), max - 2);
+ assert_eq!((max - 3).average_floor(&(max - 2)), max - 3);
+ }
+
+ #[test]
+ fn different_sign() {
+ assert_eq!((14 as $I).average_floor(&-4), 5 as $I);
+ assert_eq!((14 as $I).average_floor(&-5), 4 as $I);
+
+ let min = $crate::std::$I::MIN;
+ let max = $crate::std::$I::MAX;
+ assert_eq!(min.average_floor(&max), -1 as $I);
+ }
+ }
+ }
+
+ mod $U {
+ mod ceil {
+ use num_integer::Average;
+
+ #[test]
+ fn bounded() {
+ assert_eq!((14 as $U).average_ceil(&16), 15 as $U);
+ assert_eq!((14 as $U).average_ceil(&17), 16 as $U);
+ }
+
+ #[test]
+ fn overflow() {
+ let max = $crate::std::$U::MAX;
+ assert_eq!((max - 3).average_ceil(&(max - 1)), max - 2);
+ assert_eq!((max - 3).average_ceil(&(max - 2)), max - 2);
+ }
+ }
+
+ mod floor {
+ use num_integer::Average;
+
+ #[test]
+ fn bounded() {
+ assert_eq!((14 as $U).average_floor(&16), 15 as $U);
+ assert_eq!((14 as $U).average_floor(&17), 15 as $U);
+ }
+
+ #[test]
+ fn overflow() {
+ let max = $crate::std::$U::MAX;
+ assert_eq!((max - 3).average_floor(&(max - 1)), max - 2);
+ assert_eq!((max - 3).average_floor(&(max - 2)), max - 3);
+ }
+ }
+ }
+ };
+}
+
+test_average!(i8, u8);
+test_average!(i16, u16);
+test_average!(i32, u32);
+test_average!(i64, u64);
+#[cfg(has_i128)]
+test_average!(i128, u128);
+test_average!(isize, usize);