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