All variants of dividing BigUint by BigDigit
Allow the division to occur with either operand order and with any combination of owned and borrowed arguments.
This commit is contained in:
parent
51408a9b3b
commit
d0bfb54eee
|
@ -503,6 +503,8 @@ impl<'a, 'b> Div<&'b BigUint> for &'a BigUint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forward_all_scalar_binop_to_val_val!(impl Div<BigDigit> for BigUint, div);
|
||||||
|
|
||||||
impl Div<BigDigit> for BigUint {
|
impl Div<BigDigit> for BigUint {
|
||||||
type Output = BigUint;
|
type Output = BigUint;
|
||||||
|
|
||||||
|
@ -513,6 +515,20 @@ impl Div<BigDigit> for BigUint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Div<BigUint> for BigDigit {
|
||||||
|
type Output = BigUint;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div(self, mut other: BigUint) -> BigUint {
|
||||||
|
other = other.normalize();
|
||||||
|
match other.data.len() {
|
||||||
|
0 => panic!(),
|
||||||
|
1 => From::from(self / other.data[0]),
|
||||||
|
_ => Zero::zero()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
forward_all_binop_to_ref_ref!(impl Rem for BigUint, rem);
|
forward_all_binop_to_ref_ref!(impl Rem for BigUint, rem);
|
||||||
|
|
||||||
impl<'a, 'b> Rem<&'b BigUint> for &'a BigUint {
|
impl<'a, 'b> Rem<&'b BigUint> for &'a BigUint {
|
||||||
|
@ -525,13 +541,29 @@ impl<'a, 'b> Rem<&'b BigUint> for &'a BigUint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forward_all_scalar_binop_to_val_val!(impl Rem<BigDigit> for BigUint, rem);
|
||||||
|
|
||||||
impl Rem<BigDigit> for BigUint {
|
impl Rem<BigDigit> for BigUint {
|
||||||
type Output = BigDigit;
|
type Output = BigUint;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rem(self, other: BigDigit) -> BigDigit {
|
fn rem(self, other: BigDigit) -> BigUint {
|
||||||
let (_, r) = div_rem_digit(self, other);
|
let (_, r) = div_rem_digit(self, other);
|
||||||
r
|
From::from(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rem<BigUint> for BigDigit {
|
||||||
|
type Output = BigUint;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn rem(self, mut other: BigUint) -> BigUint {
|
||||||
|
other = other.normalize();
|
||||||
|
match other.data.len() {
|
||||||
|
0 => panic!(),
|
||||||
|
1 => From::from(self % other.data[0]),
|
||||||
|
_ => other
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -692,22 +692,22 @@ fn test_add() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_scalar_add() {
|
fn test_scalar_add() {
|
||||||
for elm in SUM_TRIPLES.iter() {
|
for elm in SUM_TRIPLES.iter() {
|
||||||
let (a_vec, b_vec, c_vec) = *elm;
|
let (a_vec, b_vec, c_vec) = *elm;
|
||||||
let c = BigUint::from_slice(c_vec);
|
let a = BigUint::from_slice(a_vec);
|
||||||
|
let b = BigUint::from_slice(b_vec);
|
||||||
|
let c = BigUint::from_slice(c_vec);
|
||||||
|
|
||||||
if a_vec.len() == 1 {
|
if a_vec.len() == 1 {
|
||||||
let a = a_vec[0];
|
let a = a_vec[0];
|
||||||
let b = BigUint::from_slice(b_vec);
|
assert_op!(a + b == c);
|
||||||
assert_op!(a + b == c);
|
assert_op!(b + a == c);
|
||||||
assert_op!(b + a == c);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if b_vec.len() == 1 {
|
if b_vec.len() == 1 {
|
||||||
let a = BigUint::from_slice(a_vec);
|
let b = b_vec[0];
|
||||||
let b = b_vec[0];
|
assert_op!(a + b == c);
|
||||||
assert_op!(a + b == c);
|
assert_op!(b + a == c);
|
||||||
assert_op!(b + a == c);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -729,24 +729,21 @@ fn test_sub() {
|
||||||
fn test_scalar_sub() {
|
fn test_scalar_sub() {
|
||||||
for elm in SUM_TRIPLES.iter() {
|
for elm in SUM_TRIPLES.iter() {
|
||||||
let (a_vec, b_vec, c_vec) = *elm;
|
let (a_vec, b_vec, c_vec) = *elm;
|
||||||
|
let a = BigUint::from_slice(a_vec);
|
||||||
|
let b = BigUint::from_slice(b_vec);
|
||||||
|
let c = BigUint::from_slice(c_vec);
|
||||||
|
|
||||||
if a_vec.len() == 1 {
|
if a_vec.len() == 1 {
|
||||||
let a = a_vec[0];
|
let a = a_vec[0];
|
||||||
let b = BigUint::from_slice(b_vec);
|
|
||||||
let c = BigUint::from_slice(c_vec);
|
|
||||||
assert_op!(c - a == b);
|
assert_op!(c - a == b);
|
||||||
}
|
}
|
||||||
|
|
||||||
if b_vec.len() == 1 {
|
if b_vec.len() == 1 {
|
||||||
let a = BigUint::from_slice(a_vec);
|
|
||||||
let b = b_vec[0];
|
let b = b_vec[0];
|
||||||
let c = BigUint::from_slice(c_vec);
|
|
||||||
assert_op!(c - b == a);
|
assert_op!(c - b == a);
|
||||||
}
|
}
|
||||||
|
|
||||||
if c_vec.len() == 1 {
|
if c_vec.len() == 1 {
|
||||||
let a = BigUint::from_slice(a_vec);
|
|
||||||
let b = BigUint::from_slice(b_vec);
|
|
||||||
let c = c_vec[0];
|
let c = c_vec[0];
|
||||||
assert_op!(c - a == b);
|
assert_op!(c - a == b);
|
||||||
assert_op!(c - b == a);
|
assert_op!(c - b == a);
|
||||||
|
@ -792,6 +789,7 @@ const DIV_REM_QUADRUPLES: &'static [(&'static [BigDigit],
|
||||||
&'static [BigDigit],
|
&'static [BigDigit],
|
||||||
&'static [BigDigit],
|
&'static [BigDigit],
|
||||||
&'static [BigDigit])] = &[(&[1], &[2], &[], &[1]),
|
&'static [BigDigit])] = &[(&[1], &[2], &[], &[1]),
|
||||||
|
(&[3], &[2], &[1], &[1]),
|
||||||
(&[1, 1], &[2], &[M / 2 + 1], &[1]),
|
(&[1, 1], &[2], &[M / 2 + 1], &[1]),
|
||||||
(&[1, 1, 1], &[2], &[M / 2 + 1, M / 2 + 1], &[1]),
|
(&[1, 1, 1], &[2], &[M / 2 + 1, M / 2 + 1], &[1]),
|
||||||
(&[0, 1], &[N1], &[1], &[1]),
|
(&[0, 1], &[N1], &[1], &[1]),
|
||||||
|
@ -825,17 +823,17 @@ fn test_mul() {
|
||||||
fn test_scalar_mul() {
|
fn test_scalar_mul() {
|
||||||
for elm in MUL_TRIPLES.iter() {
|
for elm in MUL_TRIPLES.iter() {
|
||||||
let (a_vec, b_vec, c_vec) = *elm;
|
let (a_vec, b_vec, c_vec) = *elm;
|
||||||
|
let a = BigUint::from_slice(a_vec);
|
||||||
|
let b = BigUint::from_slice(b_vec);
|
||||||
let c = BigUint::from_slice(c_vec);
|
let c = BigUint::from_slice(c_vec);
|
||||||
|
|
||||||
if a_vec.len() == 1 {
|
if a_vec.len() == 1 {
|
||||||
let b = BigUint::from_slice(b_vec);
|
|
||||||
let a = a_vec[0];
|
let a = a_vec[0];
|
||||||
assert_op!(a * b == c);
|
assert_op!(a * b == c);
|
||||||
assert_op!(b * a == c);
|
assert_op!(b * a == c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if b_vec.len() == 1 {
|
if b_vec.len() == 1 {
|
||||||
let a = BigUint::from_slice(a_vec);
|
|
||||||
let b = b_vec[0];
|
let b = b_vec[0];
|
||||||
assert_op!(a * b == c);
|
assert_op!(a * b == c);
|
||||||
assert_op!(b * a == c);
|
assert_op!(b * a == c);
|
||||||
|
@ -882,33 +880,52 @@ fn test_div_rem() {
|
||||||
fn test_scalar_div_rem() {
|
fn test_scalar_div_rem() {
|
||||||
for elm in MUL_TRIPLES.iter() {
|
for elm in MUL_TRIPLES.iter() {
|
||||||
let (a_vec, b_vec, c_vec) = *elm;
|
let (a_vec, b_vec, c_vec) = *elm;
|
||||||
|
let a = BigUint::from_slice(a_vec);
|
||||||
|
let b = BigUint::from_slice(b_vec);
|
||||||
let c = BigUint::from_slice(c_vec);
|
let c = BigUint::from_slice(c_vec);
|
||||||
|
|
||||||
if a_vec.len() == 1 && a_vec[0] != 0 {
|
if a_vec.len() == 1 && a_vec[0] != 0 {
|
||||||
let a = a_vec[0];
|
let a = a_vec[0];
|
||||||
let b = BigUint::from_slice(b_vec);
|
assert_op!(c / a == b);
|
||||||
assert!(c.clone() / a == b);
|
assert_op!(c % a == Zero::zero());
|
||||||
assert!(c.clone() % a == Zero::zero());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if b_vec.len() == 1 && b_vec[0] != 0 {
|
if b_vec.len() == 1 && b_vec[0] != 0 {
|
||||||
let a = BigUint::from_slice(a_vec);
|
|
||||||
let b = b_vec[0];
|
let b = b_vec[0];
|
||||||
assert!(c.clone() / b == a);
|
assert_op!(c / b == a);
|
||||||
assert!(c.clone() % b == Zero::zero());
|
assert_op!(c % b == Zero::zero());
|
||||||
|
}
|
||||||
|
|
||||||
|
if c_vec.len() == 1 {
|
||||||
|
let c = c_vec[0];
|
||||||
|
if !a.is_zero() {
|
||||||
|
assert_op!(c / a == b);
|
||||||
|
assert_op!(c % a == Zero::zero());
|
||||||
|
}
|
||||||
|
if !b.is_zero() {
|
||||||
|
assert_op!(c / b == a);
|
||||||
|
assert_op!(c % b == Zero::zero());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for elm in DIV_REM_QUADRUPLES.iter() {
|
for elm in DIV_REM_QUADRUPLES.iter() {
|
||||||
let (a_vec, b_vec, c_vec, d_vec) = *elm;
|
let (a_vec, b_vec, c_vec, d_vec) = *elm;
|
||||||
let a = BigUint::from_slice(a_vec);
|
let a = BigUint::from_slice(a_vec);
|
||||||
|
let b = BigUint::from_slice(b_vec);
|
||||||
let c = BigUint::from_slice(c_vec);
|
let c = BigUint::from_slice(c_vec);
|
||||||
|
let d = BigUint::from_slice(d_vec);
|
||||||
|
|
||||||
if b_vec.len() == 1 && b_vec[0] != 0 {
|
if b_vec.len() == 1 && b_vec[0] != 0 {
|
||||||
let b = b_vec[0];
|
let b = b_vec[0];
|
||||||
let d = d_vec[0];
|
assert_op!(a / b == c);
|
||||||
assert!(a.clone() / b == c);
|
assert_op!(a % b == d);
|
||||||
assert!(a.clone() % b == d);
|
}
|
||||||
|
|
||||||
|
if a_vec.len() == 1 && !b.is_zero() {
|
||||||
|
let a = a_vec[0];
|
||||||
|
assert_op!(a / b == c);
|
||||||
|
assert_op!(a % b == d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue