From 690aaef5b6d335ef22965f90e8f2eceadc855d81 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 18 Sep 2022 12:55:38 -0700 Subject: [PATCH] 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. --- library/core/src/num/mod.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index ab17aa0c83032..dd4409198e39b 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -113,6 +113,9 @@ macro_rules! widening_impl { /// This returns the low-order (wrapping) bits and the high-order (overflow) bits /// 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 /// /// Basic usage: @@ -148,6 +151,8 @@ macro_rules! widening_impl { /// additional amount of overflow. This allows for chaining together multiple /// 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 /// /// 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, 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), /// except that it gives the value of the overflow instead of just whether one happened: ///