33use crate :: cmp:: Ordering ;
44use crate :: fmt;
55use crate :: hash:: { Hash , Hasher } ;
6+ use crate :: hint;
67use crate :: intrinsics;
78use crate :: marker:: { Freeze , StructuralPartialEq } ;
89use crate :: ops:: { BitOr , BitOrAssign , Div , DivAssign , Neg , Rem , RemAssign } ;
@@ -604,7 +605,6 @@ macro_rules! nonzero_integer {
604605 }
605606
606607 nonzero_integer_signedness_dependent_methods! {
607- Self = $Ty,
608608 Primitive = $signedness $Int,
609609 UnsignedPrimitive = $Uint,
610610 }
@@ -823,7 +823,7 @@ macro_rules! nonzero_integer {
823823 }
824824 }
825825
826- nonzero_integer_signedness_dependent_impls!( $Ty $ signedness $Int) ;
826+ nonzero_integer_signedness_dependent_impls!( $signedness $Int) ;
827827 } ;
828828
829829 ( Self = $Ty: ident, Primitive = unsigned $Int: ident $( , ) ?) => {
@@ -849,7 +849,7 @@ macro_rules! nonzero_integer {
849849
850850macro_rules! nonzero_integer_signedness_dependent_impls {
851851 // Impls for unsigned nonzero types only.
852- ( $Ty : ident unsigned $Int: ty) => {
852+ ( unsigned $Int: ty) => {
853853 #[ stable( feature = "nonzero_div" , since = "1.51.0" ) ]
854854 impl Div <NonZero <$Int>> for $Int {
855855 type Output = $Int;
@@ -897,7 +897,7 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
897897 }
898898 } ;
899899 // Impls for signed nonzero types only.
900- ( $Ty : ident signed $Int: ty) => {
900+ ( signed $Int: ty) => {
901901 #[ stable( feature = "signed_nonzero_neg" , since = "1.71.0" ) ]
902902 impl Neg for NonZero <$Int> {
903903 type Output = Self ;
@@ -918,7 +918,6 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
918918macro_rules! nonzero_integer_signedness_dependent_methods {
919919 // Associated items for unsigned nonzero types only.
920920 (
921- Self = $Ty: ident,
922921 Primitive = unsigned $Int: ident,
923922 UnsignedPrimitive = $Uint: ty,
924923 ) => {
@@ -1224,11 +1223,60 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
12241223
12251224 intrinsics:: ctpop( self . get( ) ) < 2
12261225 }
1226+
1227+ /// Returns the square root of the number, rounded down.
1228+ ///
1229+ /// # Examples
1230+ ///
1231+ /// Basic usage:
1232+ /// ```
1233+ /// #![feature(isqrt)]
1234+ /// # use std::num::NonZero;
1235+ /// #
1236+ /// # fn main() { test().unwrap(); }
1237+ /// # fn test() -> Option<()> {
1238+ #[ doc = concat!( "let ten = NonZero::new(10" , stringify!( $Int) , ")?;" ) ]
1239+ #[ doc = concat!( "let three = NonZero::new(3" , stringify!( $Int) , ")?;" ) ]
1240+ ///
1241+ /// assert_eq!(ten.isqrt(), three);
1242+ /// # Some(())
1243+ /// # }
1244+ #[ unstable( feature = "isqrt" , issue = "116226" ) ]
1245+ #[ rustc_const_unstable( feature = "isqrt" , issue = "116226" ) ]
1246+ #[ must_use = "this returns the result of the operation, \
1247+ without modifying the original"]
1248+ #[ inline]
1249+ pub const fn isqrt( self ) -> Self {
1250+ // The algorithm is based on the one presented in
1251+ // <https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)>
1252+ // which cites as source the following C code:
1253+ // <https://web.archive.org/web/20120306040058/http://medialab.freaknet.org/martin/src/sqrt/sqrt.c>.
1254+
1255+ let mut op = self . get( ) ;
1256+ let mut res = 0 ;
1257+ let mut one = 1 << ( self . ilog2( ) & !1 ) ;
1258+
1259+ while one != 0 {
1260+ if op >= res + one {
1261+ op -= res + one;
1262+ res = ( res >> 1 ) + one;
1263+ } else {
1264+ res >>= 1 ;
1265+ }
1266+ one >>= 2 ;
1267+ }
1268+
1269+ // SAFETY: The result fits in an integer with half as many bits.
1270+ // Inform the optimizer about it.
1271+ unsafe { hint:: assert_unchecked( res < 1 << ( Self :: BITS / 2 ) ) } ;
1272+
1273+ // SAFETY: The result is positive.
1274+ unsafe { Self :: new_unchecked( res) }
1275+ }
12271276 } ;
12281277
12291278 // Associated items for signed nonzero types only.
12301279 (
1231- Self = $Ty: ident,
12321280 Primitive = signed $Int: ident,
12331281 UnsignedPrimitive = $Uint: ty,
12341282 ) => {
0 commit comments