@@ -1491,6 +1491,20 @@ macro_rules! uint_impl {
1491
1491
without modifying the original"]
1492
1492
#[ inline]
1493
1493
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
+
1494
1508
if self <= 0 || base <= 1 {
1495
1509
None
1496
1510
} else if self < base {
@@ -2447,7 +2461,7 @@ macro_rules! uint_impl {
2447
2461
}
2448
2462
2449
2463
/// 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) .
2451
2465
///
2452
2466
/// Performs "ternary addition" of two integer operands and a carry-in
2453
2467
/// bit, and returns an output integer and a carry-out bit. This allows
@@ -2465,8 +2479,6 @@ macro_rules! uint_impl {
2465
2479
/// # Examples
2466
2480
///
2467
2481
/// ```
2468
- /// #![feature(bigint_helper_methods)]
2469
- ///
2470
2482
#[ doc = concat!( "// 3 MAX (a = 3 × 2^" , stringify!( $BITS) , " + 2^" , stringify!( $BITS) , " - 1)" ) ]
2471
2483
#[ doc = concat!( "// + 5 7 (b = 5 × 2^" , stringify!( $BITS) , " + 7)" ) ]
2472
2484
/// // ---------
@@ -2483,7 +2495,7 @@ macro_rules! uint_impl {
2483
2495
///
2484
2496
/// assert_eq!((sum1, sum0), (9, 6));
2485
2497
/// ```
2486
- #[ unstable ( feature = "bigint_helper_methods " , issue = "85532 " ) ]
2498
+ #[ stable ( feature = "unsigned_bigint_helpers " , since = "CURRENT_RUSTC_VERSION " ) ]
2487
2499
#[ rustc_const_unstable( feature = "bigint_helper_methods" , issue = "85532" ) ]
2488
2500
#[ must_use = "this returns the result of the operation, \
2489
2501
without modifying the original"]
@@ -2559,8 +2571,6 @@ macro_rules! uint_impl {
2559
2571
/// # Examples
2560
2572
///
2561
2573
/// ```
2562
- /// #![feature(bigint_helper_methods)]
2563
- ///
2564
2574
#[ doc = concat!( "// 9 6 (a = 9 × 2^" , stringify!( $BITS) , " + 6)" ) ]
2565
2575
#[ doc = concat!( "// - 5 7 (b = 5 × 2^" , stringify!( $BITS) , " + 7)" ) ]
2566
2576
/// // ---------
@@ -2577,7 +2587,7 @@ macro_rules! uint_impl {
2577
2587
///
2578
2588
#[ doc = concat!( "assert_eq!((diff1, diff0), (3, " , stringify!( $SelfT) , "::MAX));" ) ]
2579
2589
/// ```
2580
- #[ unstable ( feature = "bigint_helper_methods " , issue = "85532 " ) ]
2590
+ #[ stable ( feature = "unsigned_bigint_helpers " , since = "CURRENT_RUSTC_VERSION " ) ]
2581
2591
#[ rustc_const_unstable( feature = "bigint_helper_methods" , issue = "85532" ) ]
2582
2592
#[ must_use = "this returns the result of the operation, \
2583
2593
without modifying the original"]
@@ -2651,10 +2661,12 @@ macro_rules! uint_impl {
2651
2661
/// indicating whether an arithmetic overflow would occur. If an
2652
2662
/// overflow would have occurred then the wrapped value is returned.
2653
2663
///
2664
+ /// If you want the *value* of the overflow, rather than just *whether*
2665
+ /// an overflow occurred, see [`Self::carrying_mul`].
2666
+ ///
2654
2667
/// # Examples
2655
2668
///
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.
2658
2670
///
2659
2671
/// ```
2660
2672
/// assert_eq!(5u32.overflowing_mul(2), (10, false));
@@ -2670,16 +2682,38 @@ macro_rules! uint_impl {
2670
2682
( a as Self , b)
2671
2683
}
2672
2684
2673
- /// Calculates the complete product `self * rhs` without the possibility to overflow .
2685
+ /// Calculates the complete double-width product `self * rhs`.
2674
2686
///
2675
2687
/// 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.
2677
2693
///
2678
2694
/// If you also need to add a carry to the wide result, then you want
2679
2695
/// [`Self::carrying_mul`] instead.
2680
2696
///
2697
+ /// If you just want to know *whether* the multiplication overflowed, then you
2698
+ /// want [`Self::overflowing_mul`] instead.
2699
+ ///
2681
2700
/// # Examples
2682
2701
///
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
+ ///
2683
2717
/// Please note that this example is shared among integer types, which is why `u32` is used.
2684
2718
///
2685
2719
/// ```
@@ -2706,14 +2740,13 @@ macro_rules! uint_impl {
2706
2740
/// additional amount of overflow. This allows for chaining together multiple
2707
2741
/// multiplications to create "big integers" which represent larger values.
2708
2742
///
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`] .
2710
2744
///
2711
2745
/// # Examples
2712
2746
///
2713
2747
/// Please note that this example is shared among integer types, which is why `u32` is used.
2714
2748
///
2715
2749
/// ```
2716
- /// #![feature(bigint_helper_methods)]
2717
2750
/// assert_eq!(5u32.carrying_mul(2, 0), (10, 0));
2718
2751
/// assert_eq!(5u32.carrying_mul(2, 10), (20, 0));
2719
2752
/// assert_eq!(1_000_000_000u32.carrying_mul(10, 0), (1410065408, 2));
@@ -2771,7 +2804,7 @@ macro_rules! uint_impl {
2771
2804
/// 789_u16.wrapping_mul(456).wrapping_add(123),
2772
2805
/// );
2773
2806
/// ```
2774
- #[ unstable ( feature = "bigint_helper_methods " , issue = "85532 " ) ]
2807
+ #[ stable ( feature = "unsigned_bigint_helpers " , since = "CURRENT_RUSTC_VERSION " ) ]
2775
2808
#[ rustc_const_unstable( feature = "bigint_helper_methods" , issue = "85532" ) ]
2776
2809
#[ must_use = "this returns the result of the operation, \
2777
2810
without modifying the original"]
@@ -2780,26 +2813,27 @@ macro_rules! uint_impl {
2780
2813
Self :: carrying_mul_add( self , rhs, carry, 0 )
2781
2814
}
2782
2815
2783
- /// Calculates the "full multiplication" `self * rhs + carry1 + carry2`
2784
- /// without the possibility to overflow.
2816
+ /// Calculates the "full multiplication" `self * rhs + carry1 + carry2`.
2785
2817
///
2786
2818
/// This returns the low-order (wrapping) bits and the high-order (overflow) bits
2787
2819
/// of the result as two separate values, in that order.
2788
2820
///
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
+ ///
2789
2825
/// Performs "long multiplication" which takes in an extra amount to add, and may return an
2790
2826
/// additional amount of overflow. This allows for chaining together multiple
2791
2827
/// multiplications to create "big integers" which represent larger values.
2792
2828
///
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.
2795
2830
///
2796
2831
/// # Examples
2797
2832
///
2798
2833
/// Please note that this example is shared between integer types,
2799
2834
/// which explains why `u32` is used here.
2800
2835
///
2801
2836
/// ```
2802
- /// #![feature(bigint_helper_methods)]
2803
2837
/// assert_eq!(5u32.carrying_mul_add(2, 0, 0), (10, 0));
2804
2838
/// assert_eq!(5u32.carrying_mul_add(2, 10, 10), (30, 0));
2805
2839
/// assert_eq!(1_000_000_000u32.carrying_mul_add(10, 0, 0), (1410065408, 2));
@@ -2816,8 +2850,6 @@ macro_rules! uint_impl {
2816
2850
/// using `u8` for simplicity of the demonstration.
2817
2851
///
2818
2852
/// ```
2819
- /// #![feature(bigint_helper_methods)]
2820
- ///
2821
2853
/// fn quadratic_mul<const N: usize>(a: [u8; N], b: [u8; N]) -> [u8; N] {
2822
2854
/// let mut out = [0; N];
2823
2855
/// for j in 0..N {
@@ -2832,13 +2864,13 @@ macro_rules! uint_impl {
2832
2864
/// // -1 * -1 == 1
2833
2865
/// assert_eq!(quadratic_mul([0xFF; 3], [0xFF; 3]), [1, 0, 0]);
2834
2866
///
2835
- /// assert_eq!(u32::wrapping_mul(0x9e3779b9, 0x7f4a7c15), 0xCFFC982D );
2867
+ /// assert_eq!(u32::wrapping_mul(0x9e3779b9, 0x7f4a7c15), 0xcffc982d );
2836
2868
/// assert_eq!(
2837
2869
/// quadratic_mul(u32::to_le_bytes(0x9e3779b9), u32::to_le_bytes(0x7f4a7c15)),
2838
- /// u32::to_le_bytes(0xCFFC982D )
2870
+ /// u32::to_le_bytes(0xcffc982d )
2839
2871
/// );
2840
2872
/// ```
2841
- #[ unstable ( feature = "bigint_helper_methods " , issue = "85532 " ) ]
2873
+ #[ stable ( feature = "unsigned_bigint_helpers " , since = "CURRENT_RUSTC_VERSION " ) ]
2842
2874
#[ rustc_const_unstable( feature = "bigint_helper_methods" , issue = "85532" ) ]
2843
2875
#[ must_use = "this returns the result of the operation, \
2844
2876
without modifying the original"]
0 commit comments