Skip to content

Commit

Permalink
Merge branch 'main' into ci-codecov
Browse files Browse the repository at this point in the history
  • Loading branch information
DaniPopes authored Jun 15, 2024
2 parents 5d908d2 + bd1205b commit d266234
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 58 deletions.
2 changes: 1 addition & 1 deletion src/algorithms/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub use self::{
add::{adc_n, sbb_n},
div::div,
gcd::{gcd, gcd_extended, inv_mod, LehmerMatrix},
mul::{add_nx1, addmul, addmul_n, addmul_nx1, addmul_ref, mul_nx1, submul_nx1},
mul::{add_nx1, addmul, addmul_n, addmul_nx1, mul_nx1, submul_nx1},
ops::{adc, sbb},
shift::{shift_left_small, shift_right_small},
};
Expand Down
88 changes: 43 additions & 45 deletions src/algorithms/mul.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,6 @@

use crate::algorithms::{ops::sbb, DoubleWord};

#[inline]
#[allow(clippy::cast_possible_truncation)] // Intentional truncation.
#[allow(dead_code)] // Used for testing
pub fn addmul_ref(result: &mut [u64], a: &[u64], b: &[u64]) -> bool {
let mut overflow = 0;
for (i, a) in a.iter().copied().enumerate() {
let mut result = result.iter_mut().skip(i);
let mut b = b.iter().copied();
let mut carry = 0_u128;
loop {
match (result.next(), b.next()) {
// Partial product.
(Some(result), Some(b)) => {
carry += u128::from(*result) + u128::from(a) * u128::from(b);
*result = carry as u64;
carry >>= 64;
}
// Carry propagation.
(Some(result), None) => {
carry += u128::from(*result);
*result = carry as u64;
carry >>= 64;
}
// Excess product.
(None, Some(b)) => {
carry += u128::from(a) * u128::from(b);
overflow |= carry as u64;
carry >>= 64;
}
// Fin.
(None, None) => {
break;
}
}
}
overflow |= carry as u64;
}
overflow != 0
}

/// ⚠️ Computes `result += a * b` and checks for overflow.
///
/// **Warning.** This function is not part of the stable API.
Expand All @@ -62,7 +22,7 @@ pub fn addmul_ref(result: &mut [u64], a: &[u64], b: &[u64]) -> bool {
/// assert_eq!(overflow, false);
/// assert_eq!(result, [12]);
/// ```
#[inline]
#[inline(always)]
pub fn addmul(mut lhs: &mut [u64], mut a: &[u64], mut b: &[u64]) -> bool {
// Trim zeros from `a`
while let [0, rest @ ..] = a {
Expand Down Expand Up @@ -116,7 +76,7 @@ pub fn addmul(mut lhs: &mut [u64], mut a: &[u64], mut b: &[u64]) -> bool {
}

/// Computes `lhs += a` and returns the carry.
#[inline]
#[inline(always)]
pub fn add_nx1(lhs: &mut [u64], mut a: u64) -> u64 {
if a == 0 {
return 0;
Expand Down Expand Up @@ -223,7 +183,7 @@ fn mac(lhs: &mut u64, a: u64, b: u64, c: u64) -> u64 {
}

/// Computes `lhs *= a` and returns the carry.
#[inline]
#[inline(always)]
pub fn mul_nx1(lhs: &mut [u64], a: u64) -> u64 {
let mut carry = 0;
for lhs in &mut *lhs {
Expand All @@ -244,7 +204,7 @@ pub fn mul_nx1(lhs: &mut [u64], a: u64) -> u64 {
/// \\\\ \mathsf{carry} &= \floor{\frac{\mathsf{lhs} + \mathsf{a} ⋅ \mathsf{b}
/// }{2^{64⋅N}}} \end{aligned}
/// $$
#[inline]
#[inline(always)]
pub fn addmul_nx1(lhs: &mut [u64], a: &[u64], b: u64) -> u64 {
debug_assert_eq!(lhs.len(), a.len());
let mut carry = 0;
Expand All @@ -267,7 +227,7 @@ pub fn addmul_nx1(lhs: &mut [u64], a: &[u64], b: u64) -> u64 {
/// \mathsf{lhs}}{2^{64⋅N}}} \end{aligned}
/// $$
// OPT: `carry` and `borrow` can probably be merged into a single var.
#[inline]
#[inline(always)]
pub fn submul_nx1(lhs: &mut [u64], a: &[u64], b: u64) -> u64 {
debug_assert_eq!(lhs.len(), a.len());
let mut carry = 0;
Expand All @@ -293,6 +253,44 @@ mod tests {
use super::*;
use proptest::{collection, num::u64, proptest};

#[allow(clippy::cast_possible_truncation)] // Intentional truncation.
fn addmul_ref(result: &mut [u64], a: &[u64], b: &[u64]) -> bool {
let mut overflow = 0;
for (i, a) in a.iter().copied().enumerate() {
let mut result = result.iter_mut().skip(i);
let mut b = b.iter().copied();
let mut carry = 0_u128;
loop {
match (result.next(), b.next()) {
// Partial product.
(Some(result), Some(b)) => {
carry += u128::from(*result) + u128::from(a) * u128::from(b);
*result = carry as u64;
carry >>= 64;
}
// Carry propagation.
(Some(result), None) => {
carry += u128::from(*result);
*result = carry as u64;
carry >>= 64;
}
// Excess product.
(None, Some(b)) => {
carry += u128::from(a) * u128::from(b);
overflow |= carry as u64;
carry >>= 64;
}
// Fin.
(None, None) => {
break;
}
}
}
overflow |= carry as u64;
}
overflow != 0
}

#[test]
fn test_addmul() {
let any_vec = collection::vec(u64::ANY, 0..10);
Expand Down
8 changes: 3 additions & 5 deletions src/div.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
#[must_use]
#[allow(clippy::missing_const_for_fn)] // False positive
pub fn checked_div(self, rhs: Self) -> Option<Self> {
if rhs == Self::ZERO {
if rhs.is_zero() {
return None;
}
Some(self.div(rhs))
Expand All @@ -18,7 +18,7 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
#[must_use]
#[allow(clippy::missing_const_for_fn)] // False positive
pub fn checked_rem(self, rhs: Self) -> Option<Self> {
if rhs == Self::ZERO {
if rhs.is_zero() {
return None;
}
Some(self.rem(rhs))
Expand All @@ -33,9 +33,8 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
#[must_use]
#[track_caller]
pub fn div_ceil(self, rhs: Self) -> Self {
assert!(rhs != Self::ZERO, "Division by zero");
let (q, r) = self.div_rem(rhs);
if r == Self::ZERO {
if r.is_zero() {
q
} else {
q + Self::from(1)
Expand All @@ -51,7 +50,6 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
#[must_use]
#[track_caller]
pub fn div_rem(mut self, mut rhs: Self) -> (Self, Self) {
assert!(rhs != Self::ZERO, "Division by zero");
algorithms::div(&mut self.limbs, &mut rhs.limbs);
(self, rhs)
}
Expand Down
2 changes: 1 addition & 1 deletion src/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
#[inline]
#[must_use]
pub fn checked_log(self, base: Self) -> Option<usize> {
if base < Self::from(2) || self == Self::ZERO {
if base < Self::from(2) || self.is_zero() {
return None;
}
Some(self.log(base))
Expand Down
6 changes: 3 additions & 3 deletions src/modular.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
#[inline]
#[must_use]
pub fn reduce_mod(mut self, modulus: Self) -> Self {
if modulus == Self::ZERO {
if modulus.is_zero() {
return Self::ZERO;
}
if self >= modulus {
Expand Down Expand Up @@ -53,7 +53,7 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
#[inline]
#[must_use]
pub fn mul_mod(self, rhs: Self, mut modulus: Self) -> Self {
if modulus == Self::ZERO {
if modulus.is_zero() {
return Self::ZERO;
}

Expand Down Expand Up @@ -84,7 +84,7 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
#[inline]
#[must_use]
pub fn pow_mod(mut self, mut exp: Self, modulus: Self) -> Self {
if modulus == Self::ZERO || modulus <= Self::from(1) {
if modulus.is_zero() || modulus <= Self::from(1) {
// Also covers Self::BITS == 0
return Self::ZERO;
}
Expand Down
2 changes: 1 addition & 1 deletion src/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
assert!(degree > 0, "degree must be greater than zero");

// Handle zero case (including BITS == 0).
if self == Self::ZERO {
if self.is_zero() {
return Self::ZERO;
}

Expand Down
4 changes: 2 additions & 2 deletions src/special.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
#[inline]
#[must_use]
pub fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
if rhs == Self::ZERO {
if rhs.is_zero() {
return None;
}
let (q, r) = self.div_rem(rhs);
if r == Self::ZERO {
if r.is_zero() {
return Some(self);
}
let q = q.checked_add(Self::from(1))?;
Expand Down

0 comments on commit d266234

Please sign in to comment.