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 } ;
@@ -606,7 +607,6 @@ macro_rules! nonzero_integer {
606607 }
607608
608609 nonzero_integer_signedness_dependent_methods! {
609- Self = $Ty,
610610 Primitive = $signedness $Int,
611611 UnsignedPrimitive = $Uint,
612612 }
@@ -825,7 +825,7 @@ macro_rules! nonzero_integer {
825825 }
826826 }
827827
828- nonzero_integer_signedness_dependent_impls!( $Ty $ signedness $Int) ;
828+ nonzero_integer_signedness_dependent_impls!( $signedness $Int) ;
829829 } ;
830830
831831 ( Self = $Ty: ident, Primitive = unsigned $Int: ident $( , ) ?) => {
@@ -851,7 +851,7 @@ macro_rules! nonzero_integer {
851851
852852macro_rules! nonzero_integer_signedness_dependent_impls {
853853 // Impls for unsigned nonzero types only.
854- ( $Ty : ident unsigned $Int: ty) => {
854+ ( unsigned $Int: ty) => {
855855 #[ stable( feature = "nonzero_div" , since = "1.51.0" ) ]
856856 impl Div <NonZero <$Int>> for $Int {
857857 type Output = $Int;
@@ -899,7 +899,7 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
899899 }
900900 } ;
901901 // Impls for signed nonzero types only.
902- ( $Ty : ident signed $Int: ty) => {
902+ ( signed $Int: ty) => {
903903 #[ stable( feature = "signed_nonzero_neg" , since = "1.71.0" ) ]
904904 impl Neg for NonZero <$Int> {
905905 type Output = Self ;
@@ -920,7 +920,6 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
920920macro_rules! nonzero_integer_signedness_dependent_methods {
921921 // Associated items for unsigned nonzero types only.
922922 (
923- Self = $Ty: ident,
924923 Primitive = unsigned $Int: ident,
925924 UnsignedPrimitive = $Uint: ty,
926925 ) => {
@@ -1226,11 +1225,62 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
12261225
12271226 intrinsics:: ctpop( self . get( ) ) < 2
12281227 }
1228+
1229+ /// Returns the square root of the number, rounded down.
1230+ ///
1231+ /// # Examples
1232+ ///
1233+ /// Basic usage:
1234+ /// ```
1235+ /// #![feature(isqrt)]
1236+ /// # use std::num::NonZero;
1237+ /// #
1238+ /// # fn main() { test().unwrap(); }
1239+ /// # fn test() -> Option<()> {
1240+ #[ doc = concat!( "let ten = NonZero::new(10" , stringify!( $Int) , ")?;" ) ]
1241+ #[ doc = concat!( "let three = NonZero::new(3" , stringify!( $Int) , ")?;" ) ]
1242+ ///
1243+ /// assert_eq!(ten.isqrt(), three);
1244+ /// # Some(())
1245+ /// # }
1246+ #[ unstable( feature = "isqrt" , issue = "116226" ) ]
1247+ #[ rustc_const_unstable( feature = "isqrt" , issue = "116226" ) ]
1248+ #[ must_use = "this returns the result of the operation, \
1249+ without modifying the original"]
1250+ #[ inline]
1251+ pub const fn isqrt( self ) -> Self {
1252+ // The algorithm is based on the one presented in
1253+ // <https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)>
1254+ // which cites as source the following C code:
1255+ // <https://web.archive.org/web/20120306040058/http://medialab.freaknet.org/martin/src/sqrt/sqrt.c>.
1256+
1257+ let mut op = self . get( ) ;
1258+ let mut res = 0 ;
1259+ let mut one = 1 << ( self . ilog2( ) & !1 ) ;
1260+
1261+ while one != 0 {
1262+ if op >= res + one {
1263+ op -= res + one;
1264+ res = ( res >> 1 ) + one;
1265+ } else {
1266+ res >>= 1 ;
1267+ }
1268+ one >>= 2 ;
1269+ }
1270+
1271+ // SAFETY: The result fits in an integer with half as many bits.
1272+ // Inform the optimizer about it.
1273+ unsafe {
1274+ hint:: assert_unchecked( res < 1 << ( Self :: BITS / 2 ) ) ;
1275+ }
1276+
1277+ // SAFETY: The result is positive.
1278+ unsafe { Self :: new_unchecked( res) }
1279+ }
12291280 } ;
12301281
12311282 // Associated items for signed nonzero types only.
12321283 (
1233- Self = $Ty: ident,
12341284 Primitive = signed $Int: ident,
12351285 UnsignedPrimitive = $Uint: ty,
12361286 ) => {
0 commit comments