Rollup merge of #101889 - tspiteri:redoc-uint-adc-sbb, r=m-ou-se

doc: rewrite doc for uint::{carrying_add,borrowing_sub}

Reword the documentation for bigint helper methods `uint::{carrying_add,borrowing_sub}` (#85532).

The examples were also rewritten to demonstrate how the methods can be used in bignum arithmetic. No loops are used in the examples, but the variable names were chosen to include indices so that it is clear how this can be used in a loop if required.

Also, previously `carrying_add` had an example to say that if the input carry is false, the method is equivalent to `overflowing_add`. While the note was kept, the example was removed and an extra note was added to make sure this equivalence is not assumed for signed integers as well.
This commit is contained in:
Matthias Krüger 2022-10-18 21:18:46 +02:00 committed by GitHub
commit d2644e538c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1469,37 +1469,42 @@ pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
(a as Self, b) (a as Self, b)
} }
/// Calculates `self + rhs + carry` without the ability to overflow. /// Calculates `self` + `rhs` + `carry` and returns a tuple containing
/// the sum and the output carry.
/// ///
/// Performs "ternary addition" which takes in an extra bit to add, and may return an /// Performs "ternary addition" of two integer operands and a carry-in
/// additional bit of overflow. This allows for chaining together multiple additions /// bit, and returns an output integer and a carry-out bit. This allows
/// to create "big integers" which represent larger values. /// chaining together multiple additions to create a wider addition, and
/// can be useful for bignum addition.
/// ///
#[doc = concat!("This can be thought of as a ", stringify!($BITS), "-bit \"full adder\", in the electronics sense.")] #[doc = concat!("This can be thought of as a ", stringify!($BITS), "-bit \"full adder\", in the electronics sense.")]
/// ///
/// If the input carry is false, this method is equivalent to
/// [`overflowing_add`](Self::overflowing_add), and the output carry is
/// equal to the overflow flag. Note that although carry and overflow
/// flags are similar for unsigned integers, they are different for
/// signed integers.
///
/// # Examples /// # Examples
/// ///
/// Basic usage
///
/// ``` /// ```
/// #![feature(bigint_helper_methods)] /// #![feature(bigint_helper_methods)]
#[doc = concat!("assert_eq!(5", stringify!($SelfT), ".carrying_add(2, false), (7, false));")]
#[doc = concat!("assert_eq!(5", stringify!($SelfT), ".carrying_add(2, true), (8, false));")]
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(1, false), (0, true));")]
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(0, true), (0, true));")]
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(1, true), (1, true));")]
#[doc = concat!("assert_eq!(",
stringify!($SelfT), "::MAX.carrying_add(", stringify!($SelfT), "::MAX, true), ",
"(", stringify!($SelfT), "::MAX, true));"
)]
/// ```
/// ///
/// If `carry` is false, this method is equivalent to [`overflowing_add`](Self::overflowing_add): #[doc = concat!("// 3 MAX (a = 3 × 2^", stringify!($BITS), " + 2^", stringify!($BITS), " - 1)")]
#[doc = concat!("// + 5 7 (b = 5 × 2^", stringify!($BITS), " + 7)")]
/// // ---------
#[doc = concat!("// 9 6 (sum = 9 × 2^", stringify!($BITS), " + 6)")]
/// ///
/// ``` #[doc = concat!("let (a1, a0): (", stringify!($SelfT), ", ", stringify!($SelfT), ") = (3, ", stringify!($SelfT), "::MAX);")]
/// #![feature(bigint_helper_methods)] #[doc = concat!("let (b1, b0): (", stringify!($SelfT), ", ", stringify!($SelfT), ") = (5, 7);")]
#[doc = concat!("assert_eq!(5_", stringify!($SelfT), ".carrying_add(2, false), 5_", stringify!($SelfT), ".overflowing_add(2));")] /// let carry0 = false;
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(1, false), ", stringify!($SelfT), "::MAX.overflowing_add(1));")] ///
/// let (sum0, carry1) = a0.carrying_add(b0, carry0);
/// assert_eq!(carry1, true);
/// let (sum1, carry2) = a1.carrying_add(b1, carry1);
/// assert_eq!(carry2, false);
///
/// assert_eq!((sum1, sum0), (9, 6));
/// ``` /// ```
#[unstable(feature = "bigint_helper_methods", issue = "85532")] #[unstable(feature = "bigint_helper_methods", issue = "85532")]
#[rustc_const_unstable(feature = "const_bigint_helper_methods", issue = "85532")] #[rustc_const_unstable(feature = "const_bigint_helper_methods", issue = "85532")]
@ -1563,22 +1568,35 @@ pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
(a as Self, b) (a as Self, b)
} }
/// Calculates `self - rhs - borrow` without the ability to overflow. /// Calculates `self` − `rhs` − `borrow` and returns a tuple
/// containing the difference and the output borrow.
/// ///
/// Performs "ternary subtraction" which takes in an extra bit to subtract, and may return /// Performs "ternary subtraction" by subtracting both an integer
/// an additional bit of overflow. This allows for chaining together multiple subtractions /// operand and a borrow-in bit from `self`, and returns an output
/// to create "big integers" which represent larger values. /// integer and a borrow-out bit. This allows chaining together multiple
/// subtractions to create a wider subtraction, and can be useful for
/// bignum subtraction.
/// ///
/// # Examples /// # Examples
/// ///
/// Basic usage
///
/// ``` /// ```
/// #![feature(bigint_helper_methods)] /// #![feature(bigint_helper_methods)]
#[doc = concat!("assert_eq!(5", stringify!($SelfT), ".borrowing_sub(2, false), (3, false));")] ///
#[doc = concat!("assert_eq!(5", stringify!($SelfT), ".borrowing_sub(2, true), (2, false));")] #[doc = concat!("// 9 6 (a = 9 × 2^", stringify!($BITS), " + 6)")]
#[doc = concat!("assert_eq!(0", stringify!($SelfT), ".borrowing_sub(1, false), (", stringify!($SelfT), "::MAX, true));")] #[doc = concat!("// - 5 7 (b = 5 × 2^", stringify!($BITS), " + 7)")]
#[doc = concat!("assert_eq!(0", stringify!($SelfT), ".borrowing_sub(1, true), (", stringify!($SelfT), "::MAX - 1, true));")] /// // ---------
#[doc = concat!("// 3 MAX (diff = 3 × 2^", stringify!($BITS), " + 2^", stringify!($BITS), " - 1)")]
///
#[doc = concat!("let (a1, a0): (", stringify!($SelfT), ", ", stringify!($SelfT), ") = (9, 6);")]
#[doc = concat!("let (b1, b0): (", stringify!($SelfT), ", ", stringify!($SelfT), ") = (5, 7);")]
/// let borrow0 = false;
///
/// let (diff0, borrow1) = a0.borrowing_sub(b0, borrow0);
/// assert_eq!(borrow1, true);
/// let (diff1, borrow2) = a1.borrowing_sub(b1, borrow1);
/// assert_eq!(borrow2, false);
///
#[doc = concat!("assert_eq!((diff1, diff0), (3, ", stringify!($SelfT), "::MAX));")]
/// ``` /// ```
#[unstable(feature = "bigint_helper_methods", issue = "85532")] #[unstable(feature = "bigint_helper_methods", issue = "85532")]
#[rustc_const_unstable(feature = "const_bigint_helper_methods", issue = "85532")] #[rustc_const_unstable(feature = "const_bigint_helper_methods", issue = "85532")]