Add another example for uN::carrying_mul

The prose talked about doing this, so might as well add a simple code example of it too.
This commit is contained in:
Scott McMurray 2022-09-18 12:55:38 -07:00
parent c773c134c9
commit 690aaef5b6

View File

@ -113,6 +113,9 @@ macro_rules! widening_impl {
/// This returns the low-order (wrapping) bits and the high-order (overflow) bits /// This returns the low-order (wrapping) bits and the high-order (overflow) bits
/// of the result as two separate values, in that order. /// of the result as two separate values, in that order.
/// ///
/// If you also need to add a carry to the wide result, then you want
/// [`Self::carrying_mul`] instead.
///
/// # Examples /// # Examples
/// ///
/// Basic usage: /// Basic usage:
@ -148,6 +151,8 @@ macro_rules! widening_impl {
/// additional amount of overflow. This allows for chaining together multiple /// additional amount of overflow. This allows for chaining together multiple
/// multiplications to create "big integers" which represent larger values. /// multiplications to create "big integers" which represent larger values.
/// ///
/// If you don't need the `carry`, then you can use [`Self::widening_mul`] instead.
///
/// # Examples /// # Examples
/// ///
/// Basic usage: /// Basic usage:
@ -167,6 +172,31 @@ macro_rules! widening_impl {
)] )]
/// ``` /// ```
/// ///
/// This is the core operation needed for scalar multiplication when
/// implementing it for wider-than-native types.
///
/// ```
/// #![feature(bigint_helper_methods)]
/// fn scalar_mul_eq(little_endian_digits: &mut Vec<u16>, multiplicand: u16) {
/// let mut carry = 0;
/// for d in little_endian_digits.iter_mut() {
/// (*d, carry) = d.carrying_mul(multiplicand, carry);
/// }
/// if carry != 0 {
/// little_endian_digits.push(carry);
/// }
/// }
///
/// let mut v = vec![10, 20];
/// scalar_mul_eq(&mut v, 3);
/// assert_eq!(v, [30, 60]);
///
/// assert_eq!(0x87654321_u64 * 0xFEED, 0x86D3D159E38D);
/// let mut v = vec![0x4321, 0x8765];
/// scalar_mul_eq(&mut v, 0xFEED);
/// assert_eq!(v, [0xE38D, 0xD159, 0x86D3]);
/// ```
///
/// If `carry` is zero, this is similar to [`overflowing_mul`](Self::overflowing_mul), /// If `carry` is zero, this is similar to [`overflowing_mul`](Self::overflowing_mul),
/// except that it gives the value of the overflow instead of just whether one happened: /// except that it gives the value of the overflow instead of just whether one happened:
/// ///