Skip to content

Commit f228458

Browse files
committed
Tidy up bigint mul methods
1 parent dd84b7d commit f228458

File tree

11 files changed

+388
-123
lines changed

11 files changed

+388
-123
lines changed

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
#![cfg_attr(bootstrap, feature(do_not_recommend))]
111111
#![feature(array_ptr_get)]
112112
#![feature(asm_experimental_arch)]
113+
#![feature(bigint_helper_methods)]
113114
#![feature(const_carrying_mul_add)]
114115
#![feature(const_eval_select)]
115116
#![feature(const_typed_swap)]

library/core/src/num/int_macros.rs

+108
Original file line numberDiff line numberDiff line change
@@ -2512,6 +2512,114 @@ macro_rules! int_impl {
25122512
(a as Self, b)
25132513
}
25142514

2515+
/// Calculates the complete product `self * rhs` without the possibility to overflow.
2516+
///
2517+
/// This returns the low-order (wrapping) bits and the high-order (overflow) bits
2518+
/// of the result as two separate values, in that order.
2519+
///
2520+
/// If you also need to add a carry to the wide result, then you want
2521+
/// [`Self::carrying_mul`] instead.
2522+
///
2523+
/// # Examples
2524+
///
2525+
/// Basic usage:
2526+
///
2527+
/// Please note that this example is shared between integer types.
2528+
/// Which explains why `i32` is used here.
2529+
///
2530+
/// ```
2531+
/// #![feature(bigint_helper_methods)]
2532+
/// assert_eq!(5i32.widening_mul(-2), (4294967286, -1));
2533+
/// assert_eq!(1_000_000_000i32.widening_mul(-10), (2884901888, -3));
2534+
/// ```
2535+
#[unstable(feature = "bigint_helper_methods", issue = "85532")]
2536+
#[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")]
2537+
#[must_use = "this returns the result of the operation, \
2538+
without modifying the original"]
2539+
#[inline]
2540+
pub const fn widening_mul(self, rhs: Self) -> ($UnsignedT, Self) {
2541+
Self::carrying_mul_add(self, rhs, 0, 0)
2542+
}
2543+
2544+
/// Calculates the "full multiplication" `self * rhs + carry`
2545+
/// without the possibility to overflow.
2546+
///
2547+
/// This returns the low-order (wrapping) bits and the high-order (overflow) bits
2548+
/// of the result as two separate values, in that order.
2549+
///
2550+
/// Performs "long multiplication" which takes in an extra amount to add, and may return an
2551+
/// additional amount of overflow. This allows for chaining together multiple
2552+
/// multiplications to create "big integers" which represent larger values.
2553+
///
2554+
/// If you don't need the `carry`, then you can use [`Self::widening_mul`] instead.
2555+
///
2556+
/// # Examples
2557+
///
2558+
/// Basic usage:
2559+
///
2560+
/// Please note that this example is shared between integer types.
2561+
/// Which explains why `i32` is used here.
2562+
///
2563+
/// ```
2564+
/// #![feature(bigint_helper_methods)]
2565+
/// assert_eq!(5i32.carrying_mul(-2, 0), (4294967286, -1));
2566+
/// assert_eq!(5i32.carrying_mul(-2, 10), (0, 0));
2567+
/// assert_eq!(1_000_000_000i32.carrying_mul(-10, 0), (2884901888, -3));
2568+
/// assert_eq!(1_000_000_000i32.carrying_mul(-10, 10), (2884901898, -3));
2569+
#[doc = concat!("assert_eq!(",
2570+
stringify!($SelfT), "::MAX.carrying_mul(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX), ",
2571+
"(", stringify!($SelfT), "::MAX.unsigned_abs() + 1, ", stringify!($SelfT), "::MAX / 2));"
2572+
)]
2573+
/// ```
2574+
#[unstable(feature = "bigint_helper_methods", issue = "85532")]
2575+
#[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")]
2576+
#[must_use = "this returns the result of the operation, \
2577+
without modifying the original"]
2578+
#[inline]
2579+
pub const fn carrying_mul(self, rhs: Self, carry: Self) -> ($UnsignedT, Self) {
2580+
Self::carrying_mul_add(self, rhs, carry, 0)
2581+
}
2582+
2583+
/// Calculates the "full multiplication" `self * rhs + carry1 + carry2`
2584+
/// without the possibility to overflow.
2585+
///
2586+
/// This returns the low-order (wrapping) bits and the high-order (overflow) bits
2587+
/// of the result as two separate values, in that order.
2588+
///
2589+
/// Performs "long multiplication" which takes in an extra amount to add, and may return an
2590+
/// additional amount of overflow. This allows for chaining together multiple
2591+
/// multiplications to create "big integers" which represent larger values.
2592+
///
2593+
/// If you don't need either `carry`, then you can use [`Self::widening_mul`] instead,
2594+
/// and if you only need one `carry`, then you can use [`Self::carrying_mul`] instead.
2595+
///
2596+
/// # Examples
2597+
///
2598+
/// Basic usage:
2599+
///
2600+
/// Please note that this example is shared between integer types.
2601+
/// Which explains why `i32` is used here.
2602+
///
2603+
/// ```
2604+
/// #![feature(bigint_helper_methods)]
2605+
/// assert_eq!(5i32.carrying_mul_add(-2, 0, 0), (4294967286, -1));
2606+
/// assert_eq!(5i32.carrying_mul_add(-2, 10, 10), (10, 0));
2607+
/// assert_eq!(1_000_000_000i32.carrying_mul_add(-10, 0, 0), (2884901888, -3));
2608+
/// assert_eq!(1_000_000_000i32.carrying_mul_add(-10, 10, 10), (2884901908, -3));
2609+
#[doc = concat!("assert_eq!(",
2610+
stringify!($SelfT), "::MAX.carrying_mul_add(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX), ",
2611+
"(", stringify!($UnsignedT), "::MAX, ", stringify!($SelfT), "::MAX / 2));"
2612+
)]
2613+
/// ```
2614+
#[unstable(feature = "bigint_helper_methods", issue = "85532")]
2615+
#[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")]
2616+
#[must_use = "this returns the result of the operation, \
2617+
without modifying the original"]
2618+
#[inline]
2619+
pub const fn carrying_mul_add(self, rhs: Self, carry: Self, add: Self) -> ($UnsignedT, Self) {
2620+
intrinsics::carrying_mul_add(self, rhs, carry, add)
2621+
}
2622+
25152623
/// Calculates the divisor when `self` is divided by `rhs`.
25162624
///
25172625
/// Returns a tuple of the divisor along with a boolean indicating whether an arithmetic overflow would

0 commit comments

Comments
 (0)