Add scalar division to BigInt
This commit is contained in:
parent
8b1288ea01
commit
9b0392d235
|
@ -508,6 +508,26 @@ impl<'a, 'b> Div<&'b BigInt> for &'a BigInt {
|
|||
}
|
||||
}
|
||||
|
||||
forward_all_scalar_binop_to_val_val!(impl Div<BigDigit> for BigInt, div);
|
||||
|
||||
impl Div<BigDigit> for BigInt {
|
||||
type Output = BigInt;
|
||||
|
||||
#[inline]
|
||||
fn div(self, other: BigDigit) -> BigInt {
|
||||
BigInt::from_biguint(self.sign, self.data / other)
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<BigInt> for BigDigit {
|
||||
type Output = BigInt;
|
||||
|
||||
#[inline]
|
||||
fn div(self, other: BigInt) -> BigInt {
|
||||
BigInt::from_biguint(other.sign, self / other.data)
|
||||
}
|
||||
}
|
||||
|
||||
forward_all_binop_to_ref_ref!(impl Rem for BigInt, rem);
|
||||
|
||||
impl<'a, 'b> Rem<&'b BigInt> for &'a BigInt {
|
||||
|
@ -520,6 +540,26 @@ impl<'a, 'b> Rem<&'b BigInt> for &'a BigInt {
|
|||
}
|
||||
}
|
||||
|
||||
forward_all_scalar_binop_to_val_val!(impl Rem<BigDigit> for BigInt, rem);
|
||||
|
||||
impl Rem<BigDigit> for BigInt {
|
||||
type Output = BigInt;
|
||||
|
||||
#[inline]
|
||||
fn rem(self, other: BigDigit) -> BigInt {
|
||||
BigInt::from_biguint(self.sign, self.data % other)
|
||||
}
|
||||
}
|
||||
|
||||
impl Rem<BigInt> for BigDigit {
|
||||
type Output = BigInt;
|
||||
|
||||
#[inline]
|
||||
fn rem(self, other: BigInt) -> BigInt {
|
||||
BigInt::from_biguint(Plus, self % other.data)
|
||||
}
|
||||
}
|
||||
|
||||
impl Neg for BigInt {
|
||||
type Output = BigInt;
|
||||
|
||||
|
|
|
@ -832,6 +832,59 @@ fn test_div_rem() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scalar_div_rem() {
|
||||
fn check_sub(a: &BigInt, b: BigDigit, ans_q: &BigInt, ans_r: &BigInt) {
|
||||
let (q, r) = (a / b, a % b);
|
||||
if !r.is_zero() {
|
||||
assert_eq!(r.sign, a.sign);
|
||||
}
|
||||
assert!(r.abs() <= From::from(b));
|
||||
assert!(*a == b * &q + &r);
|
||||
assert!(q == *ans_q);
|
||||
assert!(r == *ans_r);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
fn check(a: &BigInt, b: BigDigit, q: &BigInt, r: &BigInt) {
|
||||
check_sub(a, b, q, r);
|
||||
check_sub(&a.neg(), b, &q.neg(), &r.neg());
|
||||
}
|
||||
|
||||
for elm in MUL_TRIPLES.iter() {
|
||||
let (a_vec, b_vec, c_vec) = *elm;
|
||||
let a = BigInt::from_slice(Plus, a_vec);
|
||||
let b = BigInt::from_slice(Plus, b_vec);
|
||||
let c = BigInt::from_slice(Plus, c_vec);
|
||||
|
||||
if a_vec.len() == 1 && a_vec[0] != 0 {
|
||||
let a = a_vec[0];
|
||||
check(&c, a, &b, &Zero::zero());
|
||||
}
|
||||
|
||||
if b_vec.len() == 1 && b_vec[0] != 0 {
|
||||
let b = b_vec[0];
|
||||
check(&c, b, &a, &Zero::zero());
|
||||
}
|
||||
}
|
||||
|
||||
for elm in DIV_REM_QUADRUPLES.iter() {
|
||||
let (a_vec, b_vec, c_vec, d_vec) = *elm;
|
||||
let a = BigInt::from_slice(Plus, a_vec);
|
||||
let c = BigInt::from_slice(Plus, c_vec);
|
||||
let d = BigInt::from_slice(Plus, d_vec);
|
||||
|
||||
if b_vec.len() == 1 && b_vec[0] != 0 {
|
||||
let b = b_vec[0];
|
||||
check(&a, b, &c, &d);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_checked_add() {
|
||||
for elm in SUM_TRIPLES.iter() {
|
||||
|
|
Loading…
Reference in New Issue