diff --git a/bigint/src/bigint.rs b/bigint/src/bigint.rs index 69937ad..858b977 100644 --- a/bigint/src/bigint.rs +++ b/bigint/src/bigint.rs @@ -508,6 +508,26 @@ impl<'a, 'b> Div<&'b BigInt> for &'a BigInt { } } +forward_all_scalar_binop_to_val_val!(impl Div for BigInt, div); + +impl Div for BigInt { + type Output = BigInt; + + #[inline] + fn div(self, other: BigDigit) -> BigInt { + BigInt::from_biguint(self.sign, self.data / other) + } +} + +impl Div 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 for BigInt, rem); + +impl Rem for BigInt { + type Output = BigInt; + + #[inline] + fn rem(self, other: BigDigit) -> BigInt { + BigInt::from_biguint(self.sign, self.data % other) + } +} + +impl Rem 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; diff --git a/bigint/src/tests/bigint.rs b/bigint/src/tests/bigint.rs index a24cb3e..b8a48dc 100644 --- a/bigint/src/tests/bigint.rs +++ b/bigint/src/tests/bigint.rs @@ -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() {