Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
2dcb722007
|
@ -10,6 +10,9 @@ repository = "https://github.com/rust-num/num"
|
|||
name = "num"
|
||||
version = "0.1.40"
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "rust-num/num" }
|
||||
|
||||
[[bench]]
|
||||
name = "bigint"
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# num
|
||||
|
||||
[![](https://travis-ci.org/rust-num/num.svg)](https://travis-ci.org/rust-num/num)
|
||||
|
||||
A collection of numeric types and traits for Rust.
|
||||
|
||||
This includes new types for big integers, rationals, and complex numbers,
|
||||
|
|
|
@ -118,7 +118,7 @@ pub fn div_rem_digit(mut a: BigUint, b: BigDigit) -> (BigUint, BigDigit) {
|
|||
rem = r;
|
||||
}
|
||||
|
||||
(a.normalize(), rem)
|
||||
(a.normalized(), rem)
|
||||
}
|
||||
|
||||
// Only for the Add impl:
|
||||
|
@ -339,7 +339,7 @@ fn mac3(acc: &mut [BigDigit], b: &[BigDigit], c: &[BigDigit]) {
|
|||
mac3(&mut p.data[..], x1, y1);
|
||||
|
||||
// Not required, but the adds go faster if we drop any unneeded 0s from the end:
|
||||
p = p.normalize();
|
||||
p.normalize();
|
||||
|
||||
add2(&mut acc[b..], &p.data[..]);
|
||||
add2(&mut acc[b * 2..], &p.data[..]);
|
||||
|
@ -350,7 +350,7 @@ fn mac3(acc: &mut [BigDigit], b: &[BigDigit], c: &[BigDigit]) {
|
|||
|
||||
// p0 = x0 * y0
|
||||
mac3(&mut p.data[..], x0, y0);
|
||||
p = p.normalize();
|
||||
p.normalize();
|
||||
|
||||
add2(&mut acc[..], &p.data[..]);
|
||||
add2(&mut acc[b..], &p.data[..]);
|
||||
|
@ -366,7 +366,7 @@ fn mac3(acc: &mut [BigDigit], b: &[BigDigit], c: &[BigDigit]) {
|
|||
p.data.extend(repeat(0).take(len));
|
||||
|
||||
mac3(&mut p.data[..], &j0.data[..], &j1.data[..]);
|
||||
p = p.normalize();
|
||||
p.normalize();
|
||||
|
||||
sub2(&mut acc[b..], &p.data[..]);
|
||||
},
|
||||
|
@ -383,7 +383,7 @@ pub fn mul3(x: &[BigDigit], y: &[BigDigit]) -> BigUint {
|
|||
let mut prod = BigUint { data: vec![0; len] };
|
||||
|
||||
mac3(&mut prod.data[..], x, y);
|
||||
prod.normalize()
|
||||
prod.normalized()
|
||||
}
|
||||
|
||||
pub fn scalar_mul(a: &mut [BigDigit], b: BigDigit) -> BigDigit {
|
||||
|
@ -480,14 +480,14 @@ pub fn div_rem(u: &BigUint, d: &BigUint) -> (BigUint, BigUint) {
|
|||
|
||||
add2(&mut q.data[j..], &q0.data[..]);
|
||||
sub2(&mut a.data[j..], &prod.data[..]);
|
||||
a = a.normalize();
|
||||
a.normalize();
|
||||
|
||||
tmp = q0;
|
||||
}
|
||||
|
||||
debug_assert!(a < b);
|
||||
|
||||
(q.normalize(), a >> shift)
|
||||
(q.normalized(), a >> shift)
|
||||
}
|
||||
|
||||
/// Find last set bit
|
||||
|
|
|
@ -1376,13 +1376,13 @@ impl BigInt {
|
|||
///
|
||||
/// The digits are in little-endian base 2^32.
|
||||
#[inline]
|
||||
pub fn from_biguint(sign: Sign, data: BigUint) -> BigInt {
|
||||
if sign == NoSign || data.is_zero() {
|
||||
return BigInt {
|
||||
sign: NoSign,
|
||||
data: Zero::zero(),
|
||||
};
|
||||
pub fn from_biguint(mut sign: Sign, mut data: BigUint) -> BigInt {
|
||||
if sign == NoSign {
|
||||
data.assign_from_slice(&[]);
|
||||
} else if data.is_zero() {
|
||||
sign = NoSign;
|
||||
}
|
||||
|
||||
BigInt {
|
||||
sign: sign,
|
||||
data: data,
|
||||
|
@ -1395,6 +1395,21 @@ impl BigInt {
|
|||
BigInt::from_biguint(sign, BigUint::from_slice(slice))
|
||||
}
|
||||
|
||||
/// Reinitializes a `BigInt`.
|
||||
#[inline]
|
||||
pub fn assign_from_slice(&mut self, sign: Sign, slice: &[BigDigit]) {
|
||||
if sign == NoSign {
|
||||
self.data.assign_from_slice(&[]);
|
||||
self.sign = NoSign;
|
||||
} else {
|
||||
self.data.assign_from_slice(slice);
|
||||
self.sign = match self.data.is_zero() {
|
||||
true => NoSign,
|
||||
false => sign,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates and initializes a `BigInt`.
|
||||
///
|
||||
/// The bytes are in big-endian byte order.
|
||||
|
|
|
@ -449,7 +449,7 @@ impl<'a> Sub<&'a BigUint> for BigUint {
|
|||
|
||||
fn sub(mut self, other: &BigUint) -> BigUint {
|
||||
sub2(&mut self.data[..], &other.data[..]);
|
||||
self.normalize()
|
||||
self.normalized()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -463,7 +463,7 @@ impl<'a> Sub<BigUint> for &'a BigUint {
|
|||
}
|
||||
|
||||
sub2rev(&self.data[..], &mut other.data[..]);
|
||||
other.normalize()
|
||||
other.normalized()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -477,7 +477,7 @@ impl Sub<BigDigit> for BigUint {
|
|||
#[inline]
|
||||
fn sub(mut self, other: BigDigit) -> BigUint {
|
||||
sub2(&mut self.data[..], &[other]);
|
||||
self.normalize()
|
||||
self.normalized()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -491,7 +491,7 @@ impl Sub<BigUint> for BigDigit {
|
|||
}
|
||||
|
||||
sub2rev(&[self], &mut other.data[..]);
|
||||
other.normalize()
|
||||
other.normalized()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -502,7 +502,7 @@ impl Sub<DoubleBigDigit> for BigUint {
|
|||
fn sub(mut self, other: DoubleBigDigit) -> BigUint {
|
||||
let (hi, lo) = big_digit::from_doublebigdigit(other);
|
||||
sub2(&mut self.data[..], &[lo, hi]);
|
||||
self.normalize()
|
||||
self.normalized()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -517,7 +517,7 @@ impl Sub<BigUint> for DoubleBigDigit {
|
|||
|
||||
let (hi, lo) = big_digit::from_doublebigdigit(self);
|
||||
sub2rev(&[lo, hi], &mut other.data[..]);
|
||||
other.normalize()
|
||||
other.normalized()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1175,7 +1175,7 @@ impl BigUint {
|
|||
/// The digits are in little-endian base 2^32.
|
||||
#[inline]
|
||||
pub fn new(digits: Vec<BigDigit>) -> BigUint {
|
||||
BigUint { data: digits }.normalize()
|
||||
BigUint { data: digits }.normalized()
|
||||
}
|
||||
|
||||
/// Creates and initializes a `BigUint`.
|
||||
|
@ -1186,6 +1186,16 @@ impl BigUint {
|
|||
BigUint::new(slice.to_vec())
|
||||
}
|
||||
|
||||
/// Assign a value to a `BigUint`.
|
||||
///
|
||||
/// The digits are in little-endian base 2^32.
|
||||
#[inline]
|
||||
pub fn assign_from_slice(&mut self, slice: &[BigDigit]) {
|
||||
self.data.resize(slice.len(), 0);
|
||||
self.data.clone_from_slice(slice);
|
||||
self.normalize();
|
||||
}
|
||||
|
||||
/// Creates and initializes a `BigUint`.
|
||||
///
|
||||
/// The bytes are in big-endian byte order.
|
||||
|
@ -1436,10 +1446,16 @@ impl BigUint {
|
|||
/// Strips off trailing zero bigdigits - comparisons require the last element in the vector to
|
||||
/// be nonzero.
|
||||
#[inline]
|
||||
fn normalize(mut self) -> BigUint {
|
||||
fn normalize(&mut self) {
|
||||
while let Some(&0) = self.data.last() {
|
||||
self.data.pop();
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a normalized `BigUint`.
|
||||
#[inline]
|
||||
fn normalized(mut self) -> BigUint {
|
||||
self.normalize();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,39 @@ fn test_from_biguint() {
|
|||
check(NoSign, 1, NoSign, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_slice() {
|
||||
fn check(inp_s: Sign, inp_n: u32, ans_s: Sign, ans_n: u32) {
|
||||
let inp = BigInt::from_slice(inp_s, &[inp_n]);
|
||||
let ans = BigInt {
|
||||
sign: ans_s,
|
||||
data: FromPrimitive::from_u32(ans_n).unwrap(),
|
||||
};
|
||||
assert_eq!(inp, ans);
|
||||
}
|
||||
check(Plus, 1, Plus, 1);
|
||||
check(Plus, 0, NoSign, 0);
|
||||
check(Minus, 1, Minus, 1);
|
||||
check(NoSign, 1, NoSign, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_assign_from_slice() {
|
||||
fn check(inp_s: Sign, inp_n: u32, ans_s: Sign, ans_n: u32) {
|
||||
let mut inp = BigInt::from_slice(Minus, &[2627_u32, 0_u32, 9182_u32, 42_u32]);
|
||||
inp.assign_from_slice(inp_s, &[inp_n]);
|
||||
let ans = BigInt {
|
||||
sign: ans_s,
|
||||
data: FromPrimitive::from_u32(ans_n).unwrap(),
|
||||
};
|
||||
assert_eq!(inp, ans);
|
||||
}
|
||||
check(Plus, 1, Plus, 1);
|
||||
check(Plus, 0, NoSign, 0);
|
||||
check(Minus, 1, Minus, 1);
|
||||
check(NoSign, 1, NoSign, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_bytes_be() {
|
||||
fn check(s: &str, result: &str) {
|
||||
|
|
|
@ -56,6 +56,21 @@ fn test_from_slice() {
|
|||
check(&[-1i32 as BigDigit], &[-1i32 as BigDigit]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_assign_from_slice() {
|
||||
fn check(slice: &[BigDigit], data: &[BigDigit]) {
|
||||
let mut p = BigUint::from_slice(&[2627_u32, 0_u32, 9182_u32, 42_u32]);
|
||||
p.assign_from_slice(slice);
|
||||
assert!(p.data == data);
|
||||
}
|
||||
check(&[1], &[1]);
|
||||
check(&[0, 0, 0], &[]);
|
||||
check(&[1, 2, 0, 0], &[1, 2]);
|
||||
check(&[0, 0, 1, 2], &[0, 0, 1, 2]);
|
||||
check(&[0, 0, 1, 2, 0, 0], &[0, 0, 1, 2]);
|
||||
check(&[-1i32 as BigDigit], &[-1i32 as BigDigit]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_bytes_be() {
|
||||
fn check(s: &str, result: &str) {
|
||||
|
|
|
@ -8,14 +8,14 @@ categories = [ "algorithms", "data-structures", "science" ]
|
|||
license = "MIT/Apache-2.0"
|
||||
name = "num-complex"
|
||||
repository = "https://github.com/rust-num/num"
|
||||
version = "0.1.39"
|
||||
version = "0.1.40"
|
||||
|
||||
[dependencies]
|
||||
|
||||
[dependencies.num-traits]
|
||||
optional = false
|
||||
path = "../traits"
|
||||
version = "0.1.32"
|
||||
version = "0.1.39"
|
||||
|
||||
[dependencies.rustc-serialize]
|
||||
optional = true
|
||||
|
|
Loading…
Reference in New Issue