diff options
| author | Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> | 2022-09-21 19:01:07 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-09-21 19:01:07 +0530 |
| commit | 9b24a1f9a0b60ff7cd1e089d25a0c4b0f20a923d (patch) | |
| tree | 52a8ef19cf0f0cb0721f8e729bd3db1219e9f30a | |
| parent | 5377c3112288a759d29f9b9e916fb45da35f51c3 (diff) | |
| parent | 690aaef5b6d335ef22965f90e8f2eceadc855d81 (diff) | |
| download | rust-9b24a1f9a0b60ff7cd1e089d25a0c4b0f20a923d.tar.gz rust-9b24a1f9a0b60ff7cd1e089d25a0c4b0f20a923d.zip | |
Rollup merge of #101995 - scottmcm:carrying-mul-example, r=Mark-Simulacrum
Add another example for `uN::carrying_mul` The prose talks about doing this, so might as well add a simple code example of it too.
| -rw-r--r-- | library/core/src/num/mod.rs | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index ab17aa0c830..dd4409198e3 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<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), /// except that it gives the value of the overflow instead of just whether one happened: /// |
