@@ -1491,17 +1491,19 @@ macro_rules! uint_impl {
14911491 without modifying the original"]
14921492 #[ inline]
14931493 pub const fn checked_ilog( self , base: Self ) -> Option <u32 > {
1494- if self <= 0 || base <= 1 {
1495- None
1496- } else if self < base {
1497- Some ( 0 )
1498- } else {
1499- // Since base >= self, n >= 1
1494+ // Preconditions for calling inner function `slow_ilog`:
1495+ //
1496+ // 1: base >= 2
1497+ // 2: x >= 1
1498+ // 3: x >= base
1499+ #[ inline( always) ]
1500+ const fn slow_ilog( x: $SelfT, base: $SelfT) -> u32 {
1501+ // Since x >= base, n >= 1
15001502 let mut n = 1 ;
15011503 let mut r = base;
15021504
15031505 // Optimization for 128 bit wide integers.
1504- if Self :: BITS == 128 {
1506+ if <$SelfT> :: BITS == 128 {
15051507 // The following is a correct lower bound for ⌊log(base,self)⌋ because
15061508 //
15071509 // log(base,self) = log(2,self) / log(2,base)
@@ -1510,15 +1512,59 @@ macro_rules! uint_impl {
15101512 // hence
15111513 //
15121514 // ⌊log(base,self)⌋ ≥ ⌊ ⌊log(2,self)⌋ / (⌊log(2,base)⌋ + 1) ⌋ .
1513- n = self . ilog2( ) / ( base. ilog2( ) + 1 ) ;
1515+ n = x . ilog2( ) / ( base. ilog2( ) + 1 ) ;
15141516 r = base. pow( n) ;
15151517 }
15161518
1517- while r <= self / base {
1519+ while r <= x / base {
15181520 n += 1 ;
15191521 r *= base;
15201522 }
1521- Some ( n)
1523+ n
1524+ }
1525+
1526+ if core:: intrinsics:: is_val_statically_known( self ) {
1527+ if self <= 0 { // precondition 2
1528+ None
1529+ } else if core:: intrinsics:: is_val_statically_known( base) {
1530+ if base <= 1 { // precondition 1
1531+ None
1532+ } else if self < base { // precondition 3
1533+ Some ( 0 )
1534+ } else if base == 2 {
1535+ self . checked_ilog2( )
1536+ } else if base == 10 {
1537+ self . checked_ilog10( )
1538+ } else { // all preconditions satisfied
1539+ Some ( slow_ilog( self , base) )
1540+ }
1541+ } else if base <= 1 { // precondition 1
1542+ None
1543+ } else if self < base { // precondition 3
1544+ Some ( 0 )
1545+ } else { // all preconditions satisfied
1546+ Some ( slow_ilog( self , base) )
1547+ }
1548+ } else if core:: intrinsics:: is_val_statically_known( base) {
1549+ if base <= 1 { // precondition 1
1550+ None
1551+ } else if base == 2 {
1552+ self . checked_ilog2( )
1553+ } else if base == 10 {
1554+ self . checked_ilog10( )
1555+ } else if self <= 0 { // precondition 2
1556+ None
1557+ } else if self < base { // precondition 3
1558+ Some ( 0 )
1559+ } else { // all preconditions satisfied
1560+ Some ( slow_ilog( self , base) )
1561+ }
1562+ } else if self <= 0 || base <= 1 { // preconditions 1 and 2
1563+ None
1564+ } else if self < base { // precondition 3
1565+ Some ( 0 )
1566+ } else { // all preconditions satisfied
1567+ Some ( slow_ilog( self , base) )
15221568 }
15231569 }
15241570
0 commit comments