@@ -1491,6 +1491,20 @@ macro_rules! uint_impl {
14911491 without modifying the original"]
14921492 #[ inline]
14931493 pub const fn checked_ilog( self , base: Self ) -> Option <u32 > {
1494+ // Inform compiler of optimizations when the base is known at
1495+ // compile time and there's a cheaper method available.
1496+ //
1497+ // Note: Like all optimizations, this is not guaranteed to be
1498+ // applied by the compiler. If you want those specific bases,
1499+ // use `.checked_ilog2()` or `.checked_ilog10()` directly.
1500+ if core:: intrinsics:: is_val_statically_known( base) {
1501+ if base == 2 {
1502+ return self . checked_ilog2( ) ;
1503+ } else if base == 10 {
1504+ return self . checked_ilog10( ) ;
1505+ }
1506+ }
1507+
14941508 if self <= 0 || base <= 1 {
14951509 None
14961510 } else if self < base {
@@ -2447,7 +2461,7 @@ macro_rules! uint_impl {
24472461 }
24482462
24492463 /// Calculates `self` + `rhs` + `carry` and returns a tuple containing
2450- /// the sum and the output carry.
2464+ /// the sum and the output carry (in that order) .
24512465 ///
24522466 /// Performs "ternary addition" of two integer operands and a carry-in
24532467 /// bit, and returns an output integer and a carry-out bit. This allows
@@ -2465,8 +2479,6 @@ macro_rules! uint_impl {
24652479 /// # Examples
24662480 ///
24672481 /// ```
2468- /// #![feature(bigint_helper_methods)]
2469- ///
24702482 #[ doc = concat!( "// 3 MAX (a = 3 × 2^" , stringify!( $BITS) , " + 2^" , stringify!( $BITS) , " - 1)" ) ]
24712483 #[ doc = concat!( "// + 5 7 (b = 5 × 2^" , stringify!( $BITS) , " + 7)" ) ]
24722484 /// // ---------
@@ -2483,7 +2495,7 @@ macro_rules! uint_impl {
24832495 ///
24842496 /// assert_eq!((sum1, sum0), (9, 6));
24852497 /// ```
2486- #[ unstable ( feature = "bigint_helper_methods " , issue = "85532 " ) ]
2498+ #[ stable ( feature = "unsigned_bigint_helpers " , since = "CURRENT_RUSTC_VERSION " ) ]
24872499 #[ rustc_const_unstable( feature = "bigint_helper_methods" , issue = "85532" ) ]
24882500 #[ must_use = "this returns the result of the operation, \
24892501 without modifying the original"]
@@ -2559,8 +2571,6 @@ macro_rules! uint_impl {
25592571 /// # Examples
25602572 ///
25612573 /// ```
2562- /// #![feature(bigint_helper_methods)]
2563- ///
25642574 #[ doc = concat!( "// 9 6 (a = 9 × 2^" , stringify!( $BITS) , " + 6)" ) ]
25652575 #[ doc = concat!( "// - 5 7 (b = 5 × 2^" , stringify!( $BITS) , " + 7)" ) ]
25662576 /// // ---------
@@ -2577,7 +2587,7 @@ macro_rules! uint_impl {
25772587 ///
25782588 #[ doc = concat!( "assert_eq!((diff1, diff0), (3, " , stringify!( $SelfT) , "::MAX));" ) ]
25792589 /// ```
2580- #[ unstable ( feature = "bigint_helper_methods " , issue = "85532 " ) ]
2590+ #[ stable ( feature = "unsigned_bigint_helpers " , since = "CURRENT_RUSTC_VERSION " ) ]
25812591 #[ rustc_const_unstable( feature = "bigint_helper_methods" , issue = "85532" ) ]
25822592 #[ must_use = "this returns the result of the operation, \
25832593 without modifying the original"]
@@ -2651,10 +2661,12 @@ macro_rules! uint_impl {
26512661 /// indicating whether an arithmetic overflow would occur. If an
26522662 /// overflow would have occurred then the wrapped value is returned.
26532663 ///
2664+ /// If you want the *value* of the overflow, rather than just *whether*
2665+ /// an overflow occurred, see [`Self::carrying_mul`].
2666+ ///
26542667 /// # Examples
26552668 ///
2656- /// Please note that this example is shared among integer types, which is why why `u32`
2657- /// is used.
2669+ /// Please note that this example is shared among integer types, which is why `u32` is used.
26582670 ///
26592671 /// ```
26602672 /// assert_eq!(5u32.overflowing_mul(2), (10, false));
@@ -2670,16 +2682,38 @@ macro_rules! uint_impl {
26702682 ( a as Self , b)
26712683 }
26722684
2673- /// Calculates the complete product `self * rhs` without the possibility to overflow .
2685+ /// Calculates the complete double-width product `self * rhs`.
26742686 ///
26752687 /// This returns the low-order (wrapping) bits and the high-order (overflow) bits
2676- /// of the result as two separate values, in that order.
2688+ /// of the result as two separate values, in that order. As such,
2689+ /// `a.widening_mul(b).0` produces the same result as `a.wrapping_mul(b)`.
2690+ ///
2691+ /// If you also need to add a value and carry to the wide result, then you want
2692+ /// [`Self::carrying_mul_add`] instead.
26772693 ///
26782694 /// If you also need to add a carry to the wide result, then you want
26792695 /// [`Self::carrying_mul`] instead.
26802696 ///
2697+ /// If you just want to know *whether* the multiplication overflowed, then you
2698+ /// want [`Self::overflowing_mul`] instead.
2699+ ///
26812700 /// # Examples
26822701 ///
2702+ /// ```
2703+ /// #![feature(bigint_helper_methods)]
2704+ #[ doc = concat!( "assert_eq!(5_" , stringify!( $SelfT) , ".widening_mul(7), (35, 0));" ) ]
2705+ #[ doc = concat!( "assert_eq!(" , stringify!( $SelfT) , "::MAX.widening_mul(" , stringify!( $SelfT) , "::MAX), (1, " , stringify!( $SelfT) , "::MAX - 1));" ) ]
2706+ /// ```
2707+ ///
2708+ /// Compared to other `*_mul` methods:
2709+ /// ```
2710+ /// #![feature(bigint_helper_methods)]
2711+ #[ doc = concat!( "assert_eq!(" , stringify!( $SelfT) , "::widening_mul(1 << " , stringify!( $BITS_MINUS_ONE) , ", 6), (0, 3));" ) ]
2712+ #[ doc = concat!( "assert_eq!(" , stringify!( $SelfT) , "::overflowing_mul(1 << " , stringify!( $BITS_MINUS_ONE) , ", 6), (0, true));" ) ]
2713+ #[ doc = concat!( "assert_eq!(" , stringify!( $SelfT) , "::wrapping_mul(1 << " , stringify!( $BITS_MINUS_ONE) , ", 6), 0);" ) ]
2714+ #[ doc = concat!( "assert_eq!(" , stringify!( $SelfT) , "::checked_mul(1 << " , stringify!( $BITS_MINUS_ONE) , ", 6), None);" ) ]
2715+ /// ```
2716+ ///
26832717 /// Please note that this example is shared among integer types, which is why `u32` is used.
26842718 ///
26852719 /// ```
@@ -2706,14 +2740,13 @@ macro_rules! uint_impl {
27062740 /// additional amount of overflow. This allows for chaining together multiple
27072741 /// multiplications to create "big integers" which represent larger values.
27082742 ///
2709- /// If you don't need the `carry` , then you can use [`Self::widening_mul`] instead .
2743+ /// If you also need to add a value , then use [`Self::carrying_mul_add`] .
27102744 ///
27112745 /// # Examples
27122746 ///
27132747 /// Please note that this example is shared among integer types, which is why `u32` is used.
27142748 ///
27152749 /// ```
2716- /// #![feature(bigint_helper_methods)]
27172750 /// assert_eq!(5u32.carrying_mul(2, 0), (10, 0));
27182751 /// assert_eq!(5u32.carrying_mul(2, 10), (20, 0));
27192752 /// assert_eq!(1_000_000_000u32.carrying_mul(10, 0), (1410065408, 2));
@@ -2771,7 +2804,7 @@ macro_rules! uint_impl {
27712804 /// 789_u16.wrapping_mul(456).wrapping_add(123),
27722805 /// );
27732806 /// ```
2774- #[ unstable ( feature = "bigint_helper_methods " , issue = "85532 " ) ]
2807+ #[ stable ( feature = "unsigned_bigint_helpers " , since = "CURRENT_RUSTC_VERSION " ) ]
27752808 #[ rustc_const_unstable( feature = "bigint_helper_methods" , issue = "85532" ) ]
27762809 #[ must_use = "this returns the result of the operation, \
27772810 without modifying the original"]
@@ -2780,26 +2813,27 @@ macro_rules! uint_impl {
27802813 Self :: carrying_mul_add( self , rhs, carry, 0 )
27812814 }
27822815
2783- /// Calculates the "full multiplication" `self * rhs + carry1 + carry2`
2784- /// without the possibility to overflow.
2816+ /// Calculates the "full multiplication" `self * rhs + carry1 + carry2`.
27852817 ///
27862818 /// This returns the low-order (wrapping) bits and the high-order (overflow) bits
27872819 /// of the result as two separate values, in that order.
27882820 ///
2821+ /// This cannot overflow, as the double-width result has exactly enough
2822+ /// space for the largest possible result. This is equivalent to how, in
2823+ /// decimal, 9 × 9 + 9 + 9 = 81 + 18 = 99 = 9×10⁰ + 9×10¹ = 10² - 1.
2824+ ///
27892825 /// Performs "long multiplication" which takes in an extra amount to add, and may return an
27902826 /// additional amount of overflow. This allows for chaining together multiple
27912827 /// multiplications to create "big integers" which represent larger values.
27922828 ///
2793- /// If you don't need either `carry`, then you can use [`Self::widening_mul`] instead,
2794- /// and if you only need one `carry`, then you can use [`Self::carrying_mul`] instead.
2829+ /// If you don't need the `add` part, then you can use [`Self::carrying_mul`] instead.
27952830 ///
27962831 /// # Examples
27972832 ///
27982833 /// Please note that this example is shared between integer types,
27992834 /// which explains why `u32` is used here.
28002835 ///
28012836 /// ```
2802- /// #![feature(bigint_helper_methods)]
28032837 /// assert_eq!(5u32.carrying_mul_add(2, 0, 0), (10, 0));
28042838 /// assert_eq!(5u32.carrying_mul_add(2, 10, 10), (30, 0));
28052839 /// assert_eq!(1_000_000_000u32.carrying_mul_add(10, 0, 0), (1410065408, 2));
@@ -2816,8 +2850,6 @@ macro_rules! uint_impl {
28162850 /// using `u8` for simplicity of the demonstration.
28172851 ///
28182852 /// ```
2819- /// #![feature(bigint_helper_methods)]
2820- ///
28212853 /// fn quadratic_mul<const N: usize>(a: [u8; N], b: [u8; N]) -> [u8; N] {
28222854 /// let mut out = [0; N];
28232855 /// for j in 0..N {
@@ -2832,13 +2864,13 @@ macro_rules! uint_impl {
28322864 /// // -1 * -1 == 1
28332865 /// assert_eq!(quadratic_mul([0xFF; 3], [0xFF; 3]), [1, 0, 0]);
28342866 ///
2835- /// assert_eq!(u32::wrapping_mul(0x9e3779b9, 0x7f4a7c15), 0xCFFC982D );
2867+ /// assert_eq!(u32::wrapping_mul(0x9e3779b9, 0x7f4a7c15), 0xcffc982d );
28362868 /// assert_eq!(
28372869 /// quadratic_mul(u32::to_le_bytes(0x9e3779b9), u32::to_le_bytes(0x7f4a7c15)),
2838- /// u32::to_le_bytes(0xCFFC982D )
2870+ /// u32::to_le_bytes(0xcffc982d )
28392871 /// );
28402872 /// ```
2841- #[ unstable ( feature = "bigint_helper_methods " , issue = "85532 " ) ]
2873+ #[ stable ( feature = "unsigned_bigint_helpers " , since = "CURRENT_RUSTC_VERSION " ) ]
28422874 #[ rustc_const_unstable( feature = "bigint_helper_methods" , issue = "85532" ) ]
28432875 #[ must_use = "this returns the result of the operation, \
28442876 without modifying the original"]
0 commit comments