num_bigint_dig/algorithms/
add.rs

1use crate::big_digit::{BigDigit, DoubleBigDigit, BITS};
2
3// Add with carry:
4#[inline]
5pub fn adc(a: BigDigit, b: BigDigit, acc: &mut DoubleBigDigit) -> BigDigit {
6    *acc += a as DoubleBigDigit;
7    *acc += b as DoubleBigDigit;
8    let lo = *acc as BigDigit;
9    *acc >>= BITS;
10    lo
11}
12
13// Only for the Add impl:
14#[inline]
15pub fn __add2(a: &mut [BigDigit], b: &[BigDigit]) -> BigDigit {
16    debug_assert!(a.len() >= b.len());
17
18    let mut carry = 0;
19    let (a_lo, a_hi) = a.split_at_mut(b.len());
20
21    for (a, b) in a_lo.iter_mut().zip(b) {
22        *a = adc(*a, *b, &mut carry);
23    }
24
25    if carry != 0 {
26        for a in a_hi {
27            *a = adc(*a, 0, &mut carry);
28            if carry == 0 {
29                break;
30            }
31        }
32    }
33
34    carry as BigDigit
35}
36
37/// /Two argument addition of raw slices:
38/// a += b
39///
40/// The caller _must_ ensure that a is big enough to store the result - typically this means
41/// resizing a to max(a.len(), b.len()) + 1, to fit a possible carry.
42pub fn add2(a: &mut [BigDigit], b: &[BigDigit]) {
43    let carry = __add2(a, b);
44
45    debug_assert!(carry == 0);
46}