| use crate::big_digit::{BigDigit, DoubleBigDigit, BITS}; |
| |
| // Add with carry: |
| #[inline] |
| pub fn adc(a: BigDigit, b: BigDigit, acc: &mut DoubleBigDigit) -> BigDigit { |
| *acc += a as DoubleBigDigit; |
| *acc += b as DoubleBigDigit; |
| let lo = *acc as BigDigit; |
| *acc >>= BITS; |
| lo |
| } |
| |
| // Only for the Add impl: |
| #[inline] |
| pub fn __add2(a: &mut [BigDigit], b: &[BigDigit]) -> BigDigit { |
| debug_assert!(a.len() >= b.len()); |
| |
| let mut carry = 0; |
| let (a_lo, a_hi) = a.split_at_mut(b.len()); |
| |
| for (a, b) in a_lo.iter_mut().zip(b) { |
| *a = adc(*a, *b, &mut carry); |
| } |
| |
| if carry != 0 { |
| for a in a_hi { |
| *a = adc(*a, 0, &mut carry); |
| if carry == 0 { |
| break; |
| } |
| } |
| } |
| |
| carry as BigDigit |
| } |
| |
| /// /Two argument addition of raw slices: |
| /// a += b |
| /// |
| /// The caller _must_ ensure that a is big enough to store the result - typically this means |
| /// resizing a to max(a.len(), b.len()) + 1, to fit a possible carry. |
| pub fn add2(a: &mut [BigDigit], b: &[BigDigit]) { |
| let carry = __add2(a, b); |
| |
| debug_assert!(carry == 0); |
| } |