@@ -634,6 +634,46 @@ $EndFeature, "
634634 }
635635 }
636636
637+ doc_comment! {
638+ concat!( "Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
639+ overflow occurred.
640+
641+ # Examples
642+
643+ Basic usage:
644+
645+ ```
646+ #![feature(no_panic_pow)]
647+ " , $Feature, "assert_eq!(8" , stringify!( $SelfT) , ".checked_pow(2), Some(64));
648+ assert_eq!(" , stringify!( $SelfT) , "::max_value().checked_pow(2), None);" ,
649+ $EndFeature, "
650+ ```" ) ,
651+
652+ #[ unstable( feature = "no_panic_pow" , issue = "48320" ) ]
653+ #[ inline]
654+ pub fn checked_pow( self , mut exp: u32 ) -> Option <Self > {
655+ let mut base = self ;
656+ let mut acc: Self = 1 ;
657+
658+ while exp > 1 {
659+ if ( exp & 1 ) == 1 {
660+ acc = acc. checked_mul( base) ?;
661+ }
662+ exp /= 2 ;
663+ base = base. checked_mul( base) ?;
664+ }
665+
666+ // Deal with the final bit of the exponent separately, since
667+ // squaring the base afterwards is not necessary and may cause a
668+ // needless overflow.
669+ if exp == 1 {
670+ acc = acc. checked_mul( base) ?;
671+ }
672+
673+ Some ( acc)
674+ }
675+ }
676+
637677 doc_comment! {
638678 concat!( "Saturating integer addition. Computes `self + rhs`, saturating at the numeric
639679bounds instead of overflowing.
@@ -713,6 +753,34 @@ $EndFeature, "
713753 }
714754 }
715755
756+ doc_comment! {
757+ concat!( "Saturating integer exponentiation. Computes `self.pow(exp)`,
758+ saturating at the numeric bounds instead of overflowing.
759+
760+ # Examples
761+
762+ Basic usage:
763+
764+ ```
765+ #![feature(no_panic_pow)]
766+ " , $Feature, "use std::" , stringify!( $SelfT) , ";
767+
768+ assert_eq!((-4" , stringify!( $SelfT) , ").saturating_pow(3), -64);
769+ assert_eq!(" , stringify!( $SelfT) , "::MIN.saturating_pow(2), " , stringify!( $SelfT) , "::MAX);
770+ assert_eq!(" , stringify!( $SelfT) , "::MIN.saturating_pow(3), " , stringify!( $SelfT) , "::MIN);" ,
771+ $EndFeature, "
772+ ```" ) ,
773+ #[ unstable( feature = "no_panic_pow" , issue = "48320" ) ]
774+ #[ inline]
775+ pub fn saturating_pow( self , exp: u32 ) -> Self {
776+ match self . checked_pow( exp) {
777+ Some ( x) => x,
778+ None if self < 0 && exp % 2 == 1 => Self :: min_value( ) ,
779+ None => Self :: max_value( ) ,
780+ }
781+ }
782+ }
783+
716784 doc_comment! {
717785 concat!( "Wrapping (modular) addition. Computes `self + rhs`, wrapping around at the
718786boundary of the type.
@@ -947,6 +1015,46 @@ $EndFeature, "
9471015 }
9481016 }
9491017
1018+ doc_comment! {
1019+ concat!( "Wrapping (modular) exponentiation. Computes `self.pow(exp)`,
1020+ wrapping around at the boundary of the type.
1021+
1022+ # Examples
1023+
1024+ Basic usage:
1025+
1026+ ```
1027+ #![feature(no_panic_pow)]
1028+ " , $Feature, "assert_eq!(3" , stringify!( $SelfT) , ".wrapping_pow(4), 81);
1029+ assert_eq!(3i8.wrapping_pow(5), -13);
1030+ assert_eq!(3i8.wrapping_pow(6), -39);" ,
1031+ $EndFeature, "
1032+ ```" ) ,
1033+ #[ unstable( feature = "no_panic_pow" , issue = "48320" ) ]
1034+ #[ inline]
1035+ pub fn wrapping_pow( self , mut exp: u32 ) -> Self {
1036+ let mut base = self ;
1037+ let mut acc: Self = 1 ;
1038+
1039+ while exp > 1 {
1040+ if ( exp & 1 ) == 1 {
1041+ acc = acc. wrapping_mul( base) ;
1042+ }
1043+ exp /= 2 ;
1044+ base = base. wrapping_mul( base) ;
1045+ }
1046+
1047+ // Deal with the final bit of the exponent separately, since
1048+ // squaring the base afterwards is not necessary and may cause a
1049+ // needless overflow.
1050+ if exp == 1 {
1051+ acc = acc. wrapping_mul( base) ;
1052+ }
1053+
1054+ acc
1055+ }
1056+ }
1057+
9501058 doc_comment! {
9511059 concat!( "Calculates `self` + `rhs`
9521060
@@ -1202,6 +1310,56 @@ $EndFeature, "
12021310 doc_comment! {
12031311 concat!( "Raises self to the power of `exp`, using exponentiation by squaring.
12041312
1313+ Returns a tuple of the exponentiation along with a bool indicating
1314+ whether an overflow happened.
1315+
1316+ # Examples
1317+
1318+ Basic usage:
1319+
1320+ ```
1321+ #![feature(no_panic_pow)]
1322+ " , $Feature, "assert_eq!(3" , stringify!( $SelfT) , ".overflowing_pow(4), (81, false));
1323+ assert_eq!(3i8.overflowing_pow(5), (-13, true));" ,
1324+ $EndFeature, "
1325+ ```" ) ,
1326+ #[ unstable( feature = "no_panic_pow" , issue = "48320" ) ]
1327+ #[ inline]
1328+ pub fn overflowing_pow( self , mut exp: u32 ) -> ( Self , bool ) {
1329+ let mut base = self ;
1330+ let mut acc: Self = 1 ;
1331+ let mut overflown = false ;
1332+ // Scratch space for storing results of overflowing_mul.
1333+ let mut r;
1334+
1335+ while exp > 1 {
1336+ if ( exp & 1 ) == 1 {
1337+ r = acc. overflowing_mul( base) ;
1338+ acc = r. 0 ;
1339+ overflown |= r. 1 ;
1340+ }
1341+ exp /= 2 ;
1342+ r = base. overflowing_mul( base) ;
1343+ base = r. 0 ;
1344+ overflown |= r. 1 ;
1345+ }
1346+
1347+ // Deal with the final bit of the exponent separately, since
1348+ // squaring the base afterwards is not necessary and may cause a
1349+ // needless overflow.
1350+ if exp == 1 {
1351+ r = acc. overflowing_mul( base) ;
1352+ acc = r. 0 ;
1353+ overflown |= r. 1 ;
1354+ }
1355+
1356+ ( acc, overflown)
1357+ }
1358+ }
1359+
1360+ doc_comment! {
1361+ concat!( "Raises self to the power of `exp`, using exponentiation by squaring.
1362+
12051363# Examples
12061364
12071365Basic usage:
@@ -1887,6 +2045,44 @@ assert_eq!(0x10", stringify!($SelfT), ".checked_shr(129), None);", $EndFeature,
18872045 }
18882046 }
18892047
2048+ doc_comment! {
2049+ concat!( "Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
2050+ overflow occurred.
2051+
2052+ # Examples
2053+
2054+ Basic usage:
2055+
2056+ ```
2057+ #![feature(no_panic_pow)]
2058+ " , $Feature, "assert_eq!(2" , stringify!( $SelfT) , ".checked_pow(5), Some(32));
2059+ assert_eq!(" , stringify!( $SelfT) , "::max_value().checked_pow(2), None);" , $EndFeature, "
2060+ ```" ) ,
2061+ #[ unstable( feature = "no_panic_pow" , issue = "48320" ) ]
2062+ #[ inline]
2063+ pub fn checked_pow( self , mut exp: u32 ) -> Option <Self > {
2064+ let mut base = self ;
2065+ let mut acc: Self = 1 ;
2066+
2067+ while exp > 1 {
2068+ if ( exp & 1 ) == 1 {
2069+ acc = acc. checked_mul( base) ?;
2070+ }
2071+ exp /= 2 ;
2072+ base = base. checked_mul( base) ?;
2073+ }
2074+
2075+ // Deal with the final bit of the exponent separately, since
2076+ // squaring the base afterwards is not necessary and may cause a
2077+ // needless overflow.
2078+ if exp == 1 {
2079+ acc = acc. checked_mul( base) ?;
2080+ }
2081+
2082+ Some ( acc)
2083+ }
2084+ }
2085+
18902086 doc_comment! {
18912087 concat!( "Saturating integer addition. Computes `self + rhs`, saturating at
18922088the numeric bounds instead of overflowing.
@@ -1953,6 +2149,32 @@ assert_eq!((", stringify!($SelfT), "::MAX).saturating_mul(10), ", stringify!($Se
19532149 }
19542150 }
19552151
2152+ doc_comment! {
2153+ concat!( "Saturating integer exponentiation. Computes `self.pow(exp)`,
2154+ saturating at the numeric bounds instead of overflowing.
2155+
2156+ # Examples
2157+
2158+ Basic usage:
2159+
2160+ ```
2161+ #![feature(no_panic_pow)]
2162+ " , $Feature, "use std::" , stringify!( $SelfT) , ";
2163+
2164+ assert_eq!(4" , stringify!( $SelfT) , ".saturating_pow(3), 64);
2165+ assert_eq!(" , stringify!( $SelfT) , "::MAX.saturating_pow(2), " , stringify!( $SelfT) , "::MAX);" ,
2166+ $EndFeature, "
2167+ ```" ) ,
2168+ #[ unstable( feature = "no_panic_pow" , issue = "48320" ) ]
2169+ #[ inline]
2170+ pub fn saturating_pow( self , exp: u32 ) -> Self {
2171+ match self . checked_pow( exp) {
2172+ Some ( x) => x,
2173+ None => Self :: max_value( ) ,
2174+ }
2175+ }
2176+ }
2177+
19562178 doc_comment! {
19572179 concat!( "Wrapping (modular) addition. Computes `self + rhs`,
19582180wrapping around at the boundary of the type.
@@ -2147,6 +2369,44 @@ assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);", $EndFeature, "
21472369 }
21482370 }
21492371
2372+ doc_comment! {
2373+ concat!( "Wrapping (modular) exponentiation. Computes `self.pow(exp)`,
2374+ wrapping around at the boundary of the type.
2375+
2376+ # Examples
2377+
2378+ Basic usage:
2379+
2380+ ```
2381+ #![feature(no_panic_pow)]
2382+ " , $Feature, "assert_eq!(3" , stringify!( $SelfT) , ".wrapping_pow(5), 243);
2383+ assert_eq!(3u8.wrapping_pow(6), 217);" , $EndFeature, "
2384+ ```" ) ,
2385+ #[ unstable( feature = "no_panic_pow" , issue = "48320" ) ]
2386+ #[ inline]
2387+ pub fn wrapping_pow( self , mut exp: u32 ) -> Self {
2388+ let mut base = self ;
2389+ let mut acc: Self = 1 ;
2390+
2391+ while exp > 1 {
2392+ if ( exp & 1 ) == 1 {
2393+ acc = acc. wrapping_mul( base) ;
2394+ }
2395+ exp /= 2 ;
2396+ base = base. wrapping_mul( base) ;
2397+ }
2398+
2399+ // Deal with the final bit of the exponent separately, since
2400+ // squaring the base afterwards is not necessary and may cause a
2401+ // needless overflow.
2402+ if exp == 1 {
2403+ acc = acc. wrapping_mul( base) ;
2404+ }
2405+
2406+ acc
2407+ }
2408+ }
2409+
21502410 doc_comment! {
21512411 concat!( "Calculates `self` + `rhs`
21522412
@@ -2353,7 +2613,55 @@ assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(132), (0x1, true));", $E
23532613 pub fn overflowing_shr( self , rhs: u32 ) -> ( Self , bool ) {
23542614 ( self . wrapping_shr( rhs) , ( rhs > ( $BITS - 1 ) ) )
23552615 }
2616+ }
23562617
2618+ doc_comment! {
2619+ concat!( "Raises self to the power of `exp`, using exponentiation by squaring.
2620+
2621+ Returns a tuple of the exponentiation along with a bool indicating
2622+ whether an overflow happened.
2623+
2624+ # Examples
2625+
2626+ Basic usage:
2627+
2628+ ```
2629+ #![feature(no_panic_pow)]
2630+ " , $Feature, "assert_eq!(3" , stringify!( $SelfT) , ".overflowing_pow(5), (243, false));
2631+ assert_eq!(3u8.overflowing_pow(6), (217, true));" , $EndFeature, "
2632+ ```" ) ,
2633+ #[ unstable( feature = "no_panic_pow" , issue = "48320" ) ]
2634+ #[ inline]
2635+ pub fn overflowing_pow( self , mut exp: u32 ) -> ( Self , bool ) {
2636+ let mut base = self ;
2637+ let mut acc: Self = 1 ;
2638+ let mut overflown = false ;
2639+ // Scratch space for storing results of overflowing_mul.
2640+ let mut r;
2641+
2642+ while exp > 1 {
2643+ if ( exp & 1 ) == 1 {
2644+ r = acc. overflowing_mul( base) ;
2645+ acc = r. 0 ;
2646+ overflown |= r. 1 ;
2647+ }
2648+ exp /= 2 ;
2649+ r = base. overflowing_mul( base) ;
2650+ base = r. 0 ;
2651+ overflown |= r. 1 ;
2652+ }
2653+
2654+ // Deal with the final bit of the exponent separately, since
2655+ // squaring the base afterwards is not necessary and may cause a
2656+ // needless overflow.
2657+ if exp == 1 {
2658+ r = acc. overflowing_mul( base) ;
2659+ acc = r. 0 ;
2660+ overflown |= r. 1 ;
2661+ }
2662+
2663+ ( acc, overflown)
2664+ }
23572665 }
23582666
23592667 doc_comment! {
0 commit comments