@@ -634,6 +634,194 @@ macro_rules! uint_impl {
634
634
}
635
635
}
636
636
637
+ /// Returns the logarithm of the number with respect to an arbitrary base.
638
+ ///
639
+ /// This method may not be optimized owing to implementation details;
640
+ /// `log2` can produce results more efficiently for base 2, and `log10`
641
+ /// can produce results more efficiently for base 10.
642
+ ///
643
+ /// # Panics
644
+ ///
645
+ /// When the number is negative, zero, or if the base is not at least 2;
646
+ /// it panics in debug mode and the return value is wrapped to 0 in
647
+ /// release mode (the only situation in which the method can return 0).
648
+ ///
649
+ /// # Examples
650
+ ///
651
+ /// ```
652
+ /// #![feature(int_log)]
653
+ #[ doc = concat!( "assert_eq!(5" , stringify!( $SelfT) , ".log(5), 1);" ) ]
654
+ /// ```
655
+ #[ unstable( feature = "int_log" , issue = "70887" ) ]
656
+ #[ must_use = "this returns the result of the operation, \
657
+ without modifying the original"]
658
+ #[ inline]
659
+ #[ track_caller]
660
+ #[ rustc_inherit_overflow_checks]
661
+ #[ allow( arithmetic_overflow) ]
662
+ pub const fn log( self , base: Self ) -> Self {
663
+ match self . checked_log( base) {
664
+ Some ( n) => n,
665
+ None => {
666
+ // In debug builds, trigger a panic on None.
667
+ // This should optimize completely out in release builds.
668
+ let _ = Self :: MAX + 1 ;
669
+
670
+ 0
671
+ } ,
672
+ }
673
+ }
674
+
675
+ /// Returns the base 2 logarithm of the number.
676
+ ///
677
+ /// # Panics
678
+ ///
679
+ /// When the number is negative or zero it panics in debug mode and
680
+ /// the return value is wrapped to 0 in release mode (the only situation in
681
+ /// which the method can return 0).
682
+ ///
683
+ /// # Examples
684
+ ///
685
+ /// ```
686
+ /// #![feature(int_log)]
687
+ #[ doc = concat!( "assert_eq!(2" , stringify!( $SelfT) , ".log2(), 1);" ) ]
688
+ /// ```
689
+ #[ unstable( feature = "int_log" , issue = "70887" ) ]
690
+ #[ must_use = "this returns the result of the operation, \
691
+ without modifying the original"]
692
+ #[ inline]
693
+ #[ track_caller]
694
+ #[ rustc_inherit_overflow_checks]
695
+ #[ allow( arithmetic_overflow) ]
696
+ pub const fn log2( self ) -> Self {
697
+ match self . checked_log2( ) {
698
+ Some ( n) => n,
699
+ None => {
700
+ // In debug builds, trigger a panic on None.
701
+ // This should optimize completely out in release builds.
702
+ let _ = Self :: MAX + 1 ;
703
+
704
+ 0
705
+ } ,
706
+ }
707
+ }
708
+
709
+ /// Returns the base 10 logarithm of the number.
710
+ ///
711
+ /// # Panics
712
+ ///
713
+ /// When the number is negative or zero it panics in debug mode and the
714
+ /// return value is wrapped to 0 in release mode (the only situation in
715
+ /// which the method can return 0).
716
+ ///
717
+ /// # Example
718
+ ///
719
+ /// ```
720
+ /// #![feature(int_log)]
721
+ #[ doc = concat!( "assert_eq!(10" , stringify!( $SelfT) , ".log10(), 1);" ) ]
722
+ /// ```
723
+ #[ unstable( feature = "int_log" , issue = "70887" ) ]
724
+ #[ must_use = "this returns the result of the operation, \
725
+ without modifying the original"]
726
+ #[ inline]
727
+ #[ track_caller]
728
+ #[ rustc_inherit_overflow_checks]
729
+ #[ allow( arithmetic_overflow) ]
730
+ pub const fn log10( self ) -> Self {
731
+ match self . checked_log10( ) {
732
+ Some ( n) => n,
733
+ None => {
734
+ // In debug builds, trigger a panic on None.
735
+ // This should optimize completely out in release builds.
736
+ let _ = Self :: MAX + 1 ;
737
+
738
+ 0
739
+ } ,
740
+ }
741
+ }
742
+
743
+ /// Returns the logarithm of the number with respect to an arbitrary base.
744
+ ///
745
+ /// Returns `None` if the number is zero, or if the base is not at least 2.
746
+ ///
747
+ /// This method may not be optimized owing to implementation details;
748
+ /// `checked_log2` can produce results more efficiently for base 2, and
749
+ /// `checked_log10` can produce results more efficiently for base 10.
750
+ ///
751
+ /// # Examples
752
+ ///
753
+ /// ```
754
+ /// #![feature(int_log)]
755
+ #[ doc = concat!( "assert_eq!(5" , stringify!( $SelfT) , ".checked_log(5), Some(1));" ) ]
756
+ /// ```
757
+ #[ unstable( feature = "int_log" , issue = "70887" ) ]
758
+ #[ must_use = "this returns the result of the operation, \
759
+ without modifying the original"]
760
+ #[ inline]
761
+ pub const fn checked_log( self , base: Self ) -> Option <Self > {
762
+ if self <= 0 || base <= 1 {
763
+ None
764
+ } else {
765
+ let mut n = 0 ;
766
+ let mut r = self ;
767
+
768
+ // Optimization for 128 bit wide integers.
769
+ if Self :: BITS == 128 {
770
+ let b = Self :: log2( self ) / ( Self :: log2( base) + 1 ) ;
771
+ n += b;
772
+ r /= base. pow( b as u32 ) ;
773
+ }
774
+
775
+ while r >= base {
776
+ r /= base;
777
+ n += 1 ;
778
+ }
779
+ Some ( n)
780
+ }
781
+ }
782
+
783
+ /// Returns the base 2 logarithm of the number.
784
+ ///
785
+ /// Returns `None` if the number is zero.
786
+ ///
787
+ /// # Examples
788
+ ///
789
+ /// ```
790
+ /// #![feature(int_log)]
791
+ #[ doc = concat!( "assert_eq!(2" , stringify!( $SelfT) , ".checked_log2(), Some(1));" ) ]
792
+ /// ```
793
+ #[ unstable( feature = "int_log" , issue = "70887" ) ]
794
+ #[ must_use = "this returns the result of the operation, \
795
+ without modifying the original"]
796
+ #[ inline]
797
+ pub const fn checked_log2( self ) -> Option <Self > {
798
+ if self <= 0 {
799
+ None
800
+ } else {
801
+ // SAFETY: We just checked that this number is positive
802
+ let log = ( Self :: BITS - 1 ) as Self - unsafe { intrinsics:: ctlz_nonzero( self ) } ;
803
+ Some ( log)
804
+ }
805
+ }
806
+
807
+ /// Returns the base 10 logarithm of the number.
808
+ ///
809
+ /// Returns `None` if the number is zero.
810
+ ///
811
+ /// # Examples
812
+ ///
813
+ /// ```
814
+ /// #![feature(int_log)]
815
+ #[ doc = concat!( "assert_eq!(10" , stringify!( $SelfT) , ".checked_log10(), Some(1));" ) ]
816
+ /// ```
817
+ #[ unstable( feature = "int_log" , issue = "70887" ) ]
818
+ #[ must_use = "this returns the result of the operation, \
819
+ without modifying the original"]
820
+ #[ inline]
821
+ pub const fn checked_log10( self ) -> Option <Self > {
822
+ self . checked_log( 10 )
823
+ }
824
+
637
825
/// Checked negation. Computes `-self`, returning `None` unless `self ==
638
826
/// 0`.
639
827
///
0 commit comments