@@ -1374,59 +1374,26 @@ macro_rules! int_impl {
1374
1374
#[ rustc_const_stable( feature = "const_int_pow" , since = "1.50.0" ) ]
1375
1375
#[ must_use = "this returns the result of the operation, \
1376
1376
without modifying the original"]
1377
- #[ rustc_allow_const_fn_unstable( is_val_statically_known, const_int_unchecked_arith) ]
1378
1377
#[ inline]
1379
1378
pub const fn checked_pow( self , mut exp: u32 ) -> Option <Self > {
1380
- // SAFETY: This path has the same behavior as the other.
1381
- if unsafe { intrinsics:: is_val_statically_known( self ) }
1382
- && self . unsigned_abs( ) . is_power_of_two( )
1383
- {
1384
- if self == 1 { // Avoid divide by zero
1385
- return Some ( 1 ) ;
1386
- }
1387
- if self == -1 { // Avoid divide by zero
1388
- return Some ( if exp & 1 != 0 { -1 } else { 1 } ) ;
1389
- }
1390
- // SAFETY: We just checked this is a power of two. and above zero.
1391
- let power_used = unsafe { intrinsics:: cttz_nonzero( self . wrapping_abs( ) ) as u32 } ;
1392
- if exp > Self :: BITS / power_used { return None ; } // Division of constants is free
1393
-
1394
- // SAFETY: exp <= Self::BITS / power_used
1395
- let res = unsafe { intrinsics:: unchecked_shl(
1396
- 1 as Self ,
1397
- intrinsics:: unchecked_mul( power_used, exp) as Self
1398
- ) } ;
1399
- // LLVM doesn't always optimize out the checks
1400
- // at the ir level.
1401
-
1402
- let sign = self . is_negative( ) && exp & 1 != 0 ;
1403
- if !sign && res == Self :: MIN {
1404
- None
1405
- } else if sign {
1406
- Some ( res. wrapping_neg( ) )
1407
- } else {
1408
- Some ( res)
1409
- }
1410
- } else {
1411
- if exp == 0 {
1412
- return Some ( 1 ) ;
1413
- }
1414
- let mut base = self ;
1415
- let mut acc: Self = 1 ;
1416
-
1417
- while exp > 1 {
1418
- if ( exp & 1 ) == 1 {
1419
- acc = try_opt!( acc. checked_mul( base) ) ;
1420
- }
1421
- exp /= 2 ;
1422
- base = try_opt!( base. checked_mul( base) ) ;
1379
+ if exp == 0 {
1380
+ return Some ( 1 ) ;
1381
+ }
1382
+ let mut base = self ;
1383
+ let mut acc: Self = 1 ;
1384
+
1385
+ while exp > 1 {
1386
+ if ( exp & 1 ) == 1 {
1387
+ acc = try_opt!( acc. checked_mul( base) ) ;
1423
1388
}
1424
- // since exp!=0, finally the exp must be 1.
1425
- // Deal with the final bit of the exponent separately, since
1426
- // squaring the base afterwards is not necessary and may cause a
1427
- // needless overflow.
1428
- acc. checked_mul( base)
1389
+ exp /= 2 ;
1390
+ base = try_opt!( base. checked_mul( base) ) ;
1429
1391
}
1392
+ // since exp!=0, finally the exp must be 1.
1393
+ // Deal with the final bit of the exponent separately, since
1394
+ // squaring the base afterwards is not necessary and may cause a
1395
+ // needless overflow.
1396
+ acc. checked_mul( base)
1430
1397
}
1431
1398
1432
1399
/// Strict exponentiation. Computes `self.pow(exp)`, panicking if
@@ -2091,58 +2058,27 @@ macro_rules! int_impl {
2091
2058
#[ rustc_const_stable( feature = "const_int_pow" , since = "1.50.0" ) ]
2092
2059
#[ must_use = "this returns the result of the operation, \
2093
2060
without modifying the original"]
2094
- #[ rustc_allow_const_fn_unstable( is_val_statically_known, const_int_unchecked_arith) ]
2095
2061
#[ inline]
2096
2062
pub const fn wrapping_pow( self , mut exp: u32 ) -> Self {
2097
- // SAFETY: This path has the same behavior as the other.
2098
- if unsafe { intrinsics:: is_val_statically_known( self ) }
2099
- && self . unsigned_abs( ) . is_power_of_two( )
2100
- {
2101
- if self == 1 { // Avoid divide by zero
2102
- return 1 ;
2103
- }
2104
- if self == -1 { // Avoid divide by zero
2105
- return if exp & 1 != 0 { -1 } else { 1 } ;
2106
- }
2107
- // SAFETY: We just checked this is a power of two. and above zero.
2108
- let power_used = unsafe { intrinsics:: cttz_nonzero( self . wrapping_abs( ) ) as u32 } ;
2109
- if exp > Self :: BITS / power_used { return 0 ; } // Division of constants is free
2110
-
2111
- // SAFETY: exp <= Self::BITS / power_used
2112
- let res = unsafe { intrinsics:: unchecked_shl(
2113
- 1 as Self ,
2114
- intrinsics:: unchecked_mul( power_used, exp) as Self
2115
- ) } ;
2116
- // LLVM doesn't always optimize out the checks
2117
- // at the ir level.
2118
-
2119
- let sign = self . is_negative( ) && exp & 1 != 0 ;
2120
- if sign {
2121
- res. wrapping_neg( )
2122
- } else {
2123
- res
2124
- }
2125
- } else {
2126
- if exp == 0 {
2127
- return 1 ;
2128
- }
2129
- let mut base = self ;
2130
- let mut acc: Self = 1 ;
2131
-
2132
- while exp > 1 {
2133
- if ( exp & 1 ) == 1 {
2134
- acc = acc. wrapping_mul( base) ;
2135
- }
2136
- exp /= 2 ;
2137
- base = base. wrapping_mul( base) ;
2138
- }
2063
+ if exp == 0 {
2064
+ return 1 ;
2065
+ }
2066
+ let mut base = self ;
2067
+ let mut acc: Self = 1 ;
2139
2068
2140
- // since exp!=0, finally the exp must be 1.
2141
- // Deal with the final bit of the exponent separately, since
2142
- // squaring the base afterwards is not necessary and may cause a
2143
- // needless overflow.
2144
- acc. wrapping_mul( base)
2069
+ while exp > 1 {
2070
+ if ( exp & 1 ) == 1 {
2071
+ acc = acc. wrapping_mul( base) ;
2072
+ }
2073
+ exp /= 2 ;
2074
+ base = base. wrapping_mul( base) ;
2145
2075
}
2076
+
2077
+ // since exp!=0, finally the exp must be 1.
2078
+ // Deal with the final bit of the exponent separately, since
2079
+ // squaring the base afterwards is not necessary and may cause a
2080
+ // needless overflow.
2081
+ acc. wrapping_mul( base)
2146
2082
}
2147
2083
2148
2084
/// Calculates `self` + `rhs`
@@ -2625,68 +2561,36 @@ macro_rules! int_impl {
2625
2561
#[ rustc_const_stable( feature = "const_int_pow" , since = "1.50.0" ) ]
2626
2562
#[ must_use = "this returns the result of the operation, \
2627
2563
without modifying the original"]
2628
- #[ rustc_allow_const_fn_unstable( is_val_statically_known, const_int_unchecked_arith) ]
2629
2564
#[ inline]
2630
2565
pub const fn overflowing_pow( self , mut exp: u32 ) -> ( Self , bool ) {
2631
- // SAFETY: This path has the same behavior as the other.
2632
- if unsafe { intrinsics:: is_val_statically_known( self ) }
2633
- && self . unsigned_abs( ) . is_power_of_two( )
2634
- {
2635
- if self == 1 { // Avoid divide by zero
2636
- return ( 1 , false ) ;
2637
- }
2638
- if self == -1 { // Avoid divide by zero
2639
- return ( if exp & 1 != 0 { -1 } else { 1 } , false ) ;
2640
- }
2641
- // SAFETY: We just checked this is a power of two. and above zero.
2642
- let power_used = unsafe { intrinsics:: cttz_nonzero( self . wrapping_abs( ) ) as u32 } ;
2643
- if exp > Self :: BITS / power_used { return ( 0 , true ) ; } // Division of constants is free
2644
-
2645
- // SAFETY: exp <= Self::BITS / power_used
2646
- let res = unsafe { intrinsics:: unchecked_shl(
2647
- 1 as Self ,
2648
- intrinsics:: unchecked_mul( power_used, exp) as Self
2649
- ) } ;
2650
- // LLVM doesn't always optimize out the checks
2651
- // at the ir level.
2652
-
2653
- let sign = self . is_negative( ) && exp & 1 != 0 ;
2654
- let overflow = res == Self :: MIN ;
2655
- if sign {
2656
- ( res. wrapping_neg( ) , overflow)
2657
- } else {
2658
- ( res, overflow)
2659
- }
2660
- } else {
2661
- if exp == 0 {
2662
- return ( 1 , false ) ;
2663
- }
2664
- let mut base = self ;
2665
- let mut acc: Self = 1 ;
2666
- let mut overflown = false ;
2667
- // Scratch space for storing results of overflowing_mul.
2668
- let mut r;
2669
-
2670
- while exp > 1 {
2671
- if ( exp & 1 ) == 1 {
2672
- r = acc. overflowing_mul( base) ;
2673
- acc = r. 0 ;
2674
- overflown |= r. 1 ;
2675
- }
2676
- exp /= 2 ;
2677
- r = base. overflowing_mul( base) ;
2678
- base = r. 0 ;
2566
+ if exp == 0 {
2567
+ return ( 1 , false ) ;
2568
+ }
2569
+ let mut base = self ;
2570
+ let mut acc: Self = 1 ;
2571
+ let mut overflown = false ;
2572
+ // Scratch space for storing results of overflowing_mul.
2573
+ let mut r;
2574
+
2575
+ while exp > 1 {
2576
+ if ( exp & 1 ) == 1 {
2577
+ r = acc. overflowing_mul( base) ;
2578
+ acc = r. 0 ;
2679
2579
overflown |= r. 1 ;
2680
2580
}
2681
-
2682
- // since exp!=0, finally the exp must be 1.
2683
- // Deal with the final bit of the exponent separately, since
2684
- // squaring the base afterwards is not necessary and may cause a
2685
- // needless overflow.
2686
- r = acc. overflowing_mul( base) ;
2687
- r. 1 |= overflown;
2688
- r
2581
+ exp /= 2 ;
2582
+ r = base. overflowing_mul( base) ;
2583
+ base = r. 0 ;
2584
+ overflown |= r. 1 ;
2689
2585
}
2586
+
2587
+ // since exp!=0, finally the exp must be 1.
2588
+ // Deal with the final bit of the exponent separately, since
2589
+ // squaring the base afterwards is not necessary and may cause a
2590
+ // needless overflow.
2591
+ r = acc. overflowing_mul( base) ;
2592
+ r. 1 |= overflown;
2593
+ r
2690
2594
}
2691
2595
2692
2596
/// Raises self to the power of `exp`, using exponentiation by squaring.
@@ -2704,68 +2608,28 @@ macro_rules! int_impl {
2704
2608
#[ rustc_const_stable( feature = "const_int_pow" , since = "1.50.0" ) ]
2705
2609
#[ must_use = "this returns the result of the operation, \
2706
2610
without modifying the original"]
2707
- #[ rustc_allow_const_fn_unstable( is_val_statically_known, const_int_unchecked_arith) ]
2708
2611
#[ inline]
2709
2612
#[ rustc_inherit_overflow_checks]
2710
- #[ track_caller] // Hides the hackish overflow check for powers of two.
2711
2613
pub const fn pow( self , mut exp: u32 ) -> Self {
2712
- // SAFETY: This path has the same behavior as the other.
2713
- if unsafe { intrinsics:: is_val_statically_known( self ) }
2714
- && self . unsigned_abs( ) . is_power_of_two( )
2715
- {
2716
- if self == 1 { // Avoid divide by zero
2717
- return 1 ;
2718
- }
2719
- if self == -1 { // Avoid divide by zero
2720
- return if exp & 1 != 0 { -1 } else { 1 } ;
2721
- }
2722
- // SAFETY: We just checked this is a power of two. and above zero.
2723
- let power_used = unsafe { intrinsics:: cttz_nonzero( self . wrapping_abs( ) ) as u32 } ;
2724
- if exp > Self :: BITS / power_used { // Division of constants is free
2725
- #[ allow( arithmetic_overflow) ]
2726
- return Self :: MAX * Self :: MAX * 0 ;
2727
- }
2614
+ if exp == 0 {
2615
+ return 1 ;
2616
+ }
2617
+ let mut base = self ;
2618
+ let mut acc = 1 ;
2728
2619
2729
- // SAFETY: exp <= Self::BITS / power_used
2730
- let res = unsafe { intrinsics:: unchecked_shl(
2731
- 1 as Self ,
2732
- intrinsics:: unchecked_mul( power_used, exp) as Self
2733
- ) } ;
2734
- // LLVM doesn't always optimize out the checks
2735
- // at the ir level.
2736
-
2737
- let sign = self . is_negative( ) && exp & 1 != 0 ;
2738
- #[ allow( arithmetic_overflow) ]
2739
- if !sign && res == Self :: MIN {
2740
- // So it panics.
2741
- _ = Self :: MAX * Self :: MAX ;
2742
- }
2743
- if sign {
2744
- res. wrapping_neg( )
2745
- } else {
2746
- res
2747
- }
2748
- } else {
2749
- if exp == 0 {
2750
- return 1 ;
2751
- }
2752
- let mut base = self ;
2753
- let mut acc = 1 ;
2754
-
2755
- while exp > 1 {
2756
- if ( exp & 1 ) == 1 {
2757
- acc = acc * base;
2758
- }
2759
- exp /= 2 ;
2760
- base = base * base;
2620
+ while exp > 1 {
2621
+ if ( exp & 1 ) == 1 {
2622
+ acc = acc * base;
2761
2623
}
2762
-
2763
- // since exp!=0, finally the exp must be 1.
2764
- // Deal with the final bit of the exponent separately, since
2765
- // squaring the base afterwards is not necessary and may cause a
2766
- // needless overflow.
2767
- acc * base
2624
+ exp /= 2 ;
2625
+ base = base * base;
2768
2626
}
2627
+
2628
+ // since exp!=0, finally the exp must be 1.
2629
+ // Deal with the final bit of the exponent separately, since
2630
+ // squaring the base afterwards is not necessary and may cause a
2631
+ // needless overflow.
2632
+ acc * base
2769
2633
}
2770
2634
2771
2635
/// Returns the square root of the number, rounded down.
0 commit comments