Skip to content

Partial-stabilize the basics from bigint_helper_methods #144494

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 38 additions & 21 deletions library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2421,7 +2421,7 @@ macro_rules! uint_impl {
}

/// Calculates `self` + `rhs` + `carry` and returns a tuple containing
/// the sum and the output carry.
/// the sum and the output carry (in that order).
///
/// Performs "ternary addition" of two integer operands and a carry-in
/// bit, and returns an output integer and a carry-out bit. This allows
Expand All @@ -2439,8 +2439,6 @@ macro_rules! uint_impl {
/// # Examples
///
/// ```
/// #![feature(bigint_helper_methods)]
///
#[doc = concat!("// 3 MAX (a = 3 × 2^", stringify!($BITS), " + 2^", stringify!($BITS), " - 1)")]
#[doc = concat!("// + 5 7 (b = 5 × 2^", stringify!($BITS), " + 7)")]
/// // ---------
Expand All @@ -2457,7 +2455,7 @@ macro_rules! uint_impl {
///
/// assert_eq!((sum1, sum0), (9, 6));
/// ```
#[unstable(feature = "bigint_helper_methods", issue = "85532")]
#[stable(feature = "unsigned_bigint_helpers", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
Expand Down Expand Up @@ -2533,8 +2531,6 @@ macro_rules! uint_impl {
/// # Examples
///
/// ```
/// #![feature(bigint_helper_methods)]
///
#[doc = concat!("// 9 6 (a = 9 × 2^", stringify!($BITS), " + 6)")]
#[doc = concat!("// - 5 7 (b = 5 × 2^", stringify!($BITS), " + 7)")]
/// // ---------
Expand All @@ -2551,7 +2547,7 @@ macro_rules! uint_impl {
///
#[doc = concat!("assert_eq!((diff1, diff0), (3, ", stringify!($SelfT), "::MAX));")]
/// ```
#[unstable(feature = "bigint_helper_methods", issue = "85532")]
#[stable(feature = "unsigned_bigint_helpers", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
Expand Down Expand Up @@ -2625,6 +2621,9 @@ macro_rules! uint_impl {
/// indicating whether an arithmetic overflow would occur. If an
/// overflow would have occurred then the wrapped value is returned.
///
/// If you want the *value* of the overflow, rather than just *whether*
/// an overflow occurred, see [`Self::carrying_mul`].
///
/// # Examples
///
/// Please note that this example is shared between integer types.
Expand All @@ -2644,25 +2643,44 @@ macro_rules! uint_impl {
(a as Self, b)
}

/// Calculates the complete product `self * rhs` without the possibility to overflow.
/// Calculates the complete double-width product `self * rhs`.
///
/// 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. As such,
/// `a.widening_mul(b).0` produces the same result as `a.wrapping_mul(b)`.
///
/// If you also need to add a value and carry to the wide result, then you want
/// [`Self::carrying_mul_add`] instead.
///
/// If you also need to add a carry to the wide result, then you want
/// [`Self::carrying_mul`] instead.
///
/// If you just want to know *whether* the multiplication overflowed, then you
/// want [`Self::overflowing_mul`] instead.
///
/// # Examples
///
/// ```
#[doc = concat!("assert_eq!(5_", stringify!($SelfT), ".widening_mul(7), (35, 0));")]
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.widening_mul(", stringify!($SelfT), "::MAX), (1, ", stringify!($SelfT), "::MAX - 1));")]
/// ```
///
/// Compared to other `*_mul` methods:
/// ```
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::widening_mul(1 << ", stringify!($BITS_MINUS_ONE), ", 6), (0, 3));")]
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::overflowing_mul(1 << ", stringify!($BITS_MINUS_ONE), ", 6), (0, true));")]
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::wrapping_mul(1 << ", stringify!($BITS_MINUS_ONE), ", 6), 0);")]
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::checked_mul(1 << ", stringify!($BITS_MINUS_ONE), ", 6), None);")]
/// ```
///
/// Please note that this example is shared between integer types.
/// Which explains why `u32` is used here.
///
/// ```
/// #![feature(bigint_helper_methods)]
/// assert_eq!(5u32.widening_mul(2), (10, 0));
/// assert_eq!(1_000_000_000u32.widening_mul(10), (1410065408, 2));
/// ```
#[unstable(feature = "bigint_helper_methods", issue = "85532")]
#[stable(feature = "unsigned_bigint_helpers", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
Expand All @@ -2689,7 +2707,6 @@ macro_rules! uint_impl {
/// Which explains why `u32` is used here.
///
/// ```
/// #![feature(bigint_helper_methods)]
/// assert_eq!(5u32.carrying_mul(2, 0), (10, 0));
/// assert_eq!(5u32.carrying_mul(2, 10), (20, 0));
/// assert_eq!(1_000_000_000u32.carrying_mul(10, 0), (1410065408, 2));
Expand Down Expand Up @@ -2747,7 +2764,7 @@ macro_rules! uint_impl {
/// 789_u16.wrapping_mul(456).wrapping_add(123),
/// );
/// ```
#[unstable(feature = "bigint_helper_methods", issue = "85532")]
#[stable(feature = "unsigned_bigint_helpers", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
Expand All @@ -2756,12 +2773,15 @@ macro_rules! uint_impl {
Self::carrying_mul_add(self, rhs, carry, 0)
}

/// Calculates the "full multiplication" `self * rhs + carry1 + carry2`
/// without the possibility to overflow.
/// Calculates the "full multiplication" `self * rhs + carry1 + carry2`.
///
/// This returns the low-order (wrapping) bits and the high-order (overflow) bits
/// of the result as two separate values, in that order.
///
/// This cannot overflow, as the double-width result has exactly enough
/// space for the largest possible result. This is equivalent to how, in
/// decimal, 9 × 9 + 9 + 9 = 81 + 18 = 99 = 9×10⁰ + 9×10¹ = 10² - 1.
///
/// Performs "long multiplication" which takes in an extra amount to add, and may return an
/// additional amount of overflow. This allows for chaining together multiple
/// multiplications to create "big integers" which represent larger values.
Expand All @@ -2775,7 +2795,6 @@ macro_rules! uint_impl {
/// which explains why `u32` is used here.
///
/// ```
/// #![feature(bigint_helper_methods)]
/// assert_eq!(5u32.carrying_mul_add(2, 0, 0), (10, 0));
/// assert_eq!(5u32.carrying_mul_add(2, 10, 10), (30, 0));
/// assert_eq!(1_000_000_000u32.carrying_mul_add(10, 0, 0), (1410065408, 2));
Expand All @@ -2792,8 +2811,6 @@ macro_rules! uint_impl {
/// using `u8` for simplicity of the demonstration.
///
/// ```
/// #![feature(bigint_helper_methods)]
///
/// fn quadratic_mul<const N: usize>(a: [u8; N], b: [u8; N]) -> [u8; N] {
/// let mut out = [0; N];
/// for j in 0..N {
Expand All @@ -2808,13 +2825,13 @@ macro_rules! uint_impl {
/// // -1 * -1 == 1
/// assert_eq!(quadratic_mul([0xFF; 3], [0xFF; 3]), [1, 0, 0]);
///
/// assert_eq!(u32::wrapping_mul(0x9e3779b9, 0x7f4a7c15), 0xCFFC982D);
/// assert_eq!(u32::wrapping_mul(0x9e3779b9, 0x7f4a7c15), 0xcffc982d);
/// assert_eq!(
/// quadratic_mul(u32::to_le_bytes(0x9e3779b9), u32::to_le_bytes(0x7f4a7c15)),
/// u32::to_le_bytes(0xCFFC982D)
/// u32::to_le_bytes(0xcffc982d)
/// );
/// ```
#[unstable(feature = "bigint_helper_methods", issue = "85532")]
#[stable(feature = "unsigned_bigint_helpers", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
Expand Down
Loading